Jev 常见报错排查与修复

更新于 适用版本 Jev 1.13

每个 Jev 集成都会撞上同一小撮故障,而几乎每一个都有很短的修复路径。这篇是排查手册:HTTP 报错的”症状→原因→修复”表、占了大部分”API 坏了”报告的 JSON 解析陷阱,以及 confidence 数值不对劲时怎么办。从上往下过一遍,绝大多数问题不用提工单就能解决。

TL;DR: 401 找 Key;404 找模型 slug;429 退避减速;解析失败说明 message content 没做 JSON 加载;confidence 奇怪多半是问题太含糊。动手前先查下面的表,并第一时间到 OpenRouter 模型页确认确切的 model slug——它是最常见的元凶。

HTTP 报错:症状、原因、修复

报错常见原因修复
401 Unauthorized环境里没有 Key、变量读错、或 Key 已作废在调用所在的同一 shell 打印变量;必要时到 OpenRouter 重建 Key;确认带了 Bearer 前缀
404 / 未知模型模型 slug 写错或过期到 OpenRouter 模型页确认确切 slug(写作本文时列表值为 typesafe/jev-1.13;slug 随版本变化)后重发
429 Too Many Requests触发限流或消费上限指数退避加抖动;检查 Key 级限额与余额;对并发调用做批处理或节流
400 Bad RequestJSON 请求体格式错或缺必填字段本地先校验请求体能解析;核对 OpenAI 兼容字段名(modelmessages
5xx 服务端错误渠道上游问题退避重试 2–3 次,然后排队并告警;不要硬刚

一个最小重试封装,把 429 和 5xx 的处理收在一处:

import json, os, time, requests

def ask_jev_with_retry(prompt: str, max_retries: int = 3) -> dict:
    # Confirm the exact model slug on the OpenRouter model page
    for attempt in range(max_retries):
        resp = requests.post(
            "https://openrouter.ai/api/v1/chat/completions",
            headers={"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"},
            json={
                "model": "typesafe/jev-1.13",
                "messages": [{"role": "user", "content": prompt}],
            },
            timeout=30,
        )
        if resp.status_code == 200:
            return json.loads(resp.json()["choices"][0]["message"]["content"])
        if resp.status_code in (429, 500, 502, 503):
            time.sleep(2 ** attempt)  # 指数退避
            continue
        resp.raise_for_status()  # 401/404/400 在这里带着上下文抛出
    raise RuntimeError("Jev call failed after retries")

封装在成功时返回 fixture 形态的答案;响应形态为示例数据(example fixture),正式字段名以官方文档为准。官方 TypeSafe AI 渠道自己的错误码与重试建议,以 typesafe.ai 官方文档为准。

解析失败:常见嫌疑人

大部分”API 坏了”的报告,最后都发现是客户端这边的坑:

  1. 把 content 当字典用。 message content 是 JSON 字符串。resp.json()["choices"][0]["message"]["content"] 拿到的是字符串;访问 answerconfidence 之前先 json.loads
  2. 把响应壳当答案。 answer 在解析后的 content 里,不在 HTTP 响应的顶层。HTTP 壳是 OpenAI 兼容的,判断载荷在里面——示例数据(example fixture),正式字段名以官方文档为准:
{
  "answer": "billing",
  "confidence": 0.94,
  "rationale": "The message disputes a charge amount rather than reporting a bug."
}
  1. 对坏载荷零防御。 罕见,但解析要包 try,先重试一次再叫人:
try:
    result = json.loads(resp.json()["choices"][0]["message"]["content"])
except (json.JSONDecodeError, KeyError):
    result = ask_jev_with_retry(prompt)  # 重试一次,然后告警

重试返回新的 fixture 形态答案;响应形态为示例数据(example fixture),正式字段名以官方文档为准。

confidence 异常

confidence 看起来不对时,按这个清单往下查:

这些都不奏效时,取一条输入,用《第一次调用》教程的最小请求单独跑一遍——剩余问题多半是意外混进 prompt 的状态。product FAQ 打分那个 case 展示了把这套检查做成自动化环节的完整管线。

本文适用版本 Jev 1.13。

常见问题

调用 Jev 一直报 404 怎么回事?

几乎都是模型 slug 写错或过期。到 OpenRouter 模型页核对当前 id——slug 会随版本变化——再用确切的值重发。

API 返回 200 但代码解析失败,为什么?

message content 是 JSON 字符串不是对象。先用 JSON 加载器解析,遇到罕见的坏载荷先重试一次再告警。

confidence 分数看起来不对——全高或全低,怎么办?

先检查问题有没有说清题型和边界;confidence 漂移通常是输入在漂,不是模型的锅。然后回看问题设计指南。

继续阅读