Moonshot API 的报错不能只看状态码。同样是 429,可能是集群过载、账户限流,也可能是余额不足;同样是 401,可能是 Key 写错,也可能是中国站和国际站混用。2026 年平台入口迁移和旧模型下线,又让 404 明显增多。
本文按“先定位、再分类、后修复”的顺序,拆解 401、404、429、上下文超长和超时五类问题,给出可复用的重试代码和支持工单清单。模型与价格以站内模型价格为准。
说明:Moonshot、Kimi 是其权利人的商标。错误类型、限流档位和下线时间可能调整,本文以 2026 年 10 月的官方文档和常见情况为例,最终以官方文档为准。
一、先固定三个字段
排障时先收集三样东西:HTTP 状态码、error.type、请求标识。Moonshot 的错误响应通常包含 error.message 和 error.type,具体字段以当前接口返回为准。请求标识可能出现在错误体、响应头或控制台日志中,不同版本位置不同,不要假设只有一种来源。
日志至少记录:时间(带时区)、状态码、error.type、模型名、Base URL 所属站点、是否流式、SDK 版本、重试次数、usage 和请求标识。不要记录完整 Key,也不要记录含敏感信息的提示词。
有了这三样,才能判断问题出在配置、账号还是服务端。下面逐类展开。
二、401:先查站点,再查 Key
Moonshot 分中国站和国际站:中国站入口 platform.kimi.com,接口 https://api.moonshot.cn/v1;国际站 platform.kimi.ai,接口 https://api.moonshot.ai/v1。两站账号、余额、Key 完全独立,拿中国站 Key 调国际站地址会返回 401 invalid_authentication_error。
按这个顺序排查:
- Key 是否来自当前 Base URL 对应的站点,而不是另一个站或另一个账号。
- 是否混用了开放平台 Key 和 Kimi Code 等其他产品线的 Key,两者不通用。
- 请求头是否为
Authorization: Bearer <key>,值前后有没有空格、换行或引号。 - 环境变量是否真的加载,可以只打印 Key 的前几位确认。
- Key 是否被删除、轮换,或项目权限已被回收。
- 本地是否还残留旧代理、旧环境变量或路由工具的配置,覆盖了当前请求。
错误类型上,invalid_authentication_error 多指 Key 格式或站点不匹配,incorrect_api_key_error 多指 Key 缺失或错误。两者都先修凭证,不要急着重试。
三、404:多数是模型下线,不是接口消失
2026 年最容易被忽略的 404 来源是模型生命周期。官方模型页列出的下线记录包括:
moonshot-v1全系列,含moonshot-v1-8k、-32k、-128k、-auto和视觉预览版,2026 年 8 月 31 日下线,推荐迁移到kimi-k3。kimi-k2系列,含kimi-k2-0905-preview、kimi-k2-0711-preview、kimi-k2-turbo-preview和思考版,2026 年 5 月 25 日下线。kimi-latest于 2026 年 1 月 28 日下线,kimi-thinking-preview于 2025 年 11 月 11 日下线。
其他常见 404 原因:
- OpenAI SDK 没有设置
base_url,请求发到了默认的 OpenAI 地址,返回模型不存在。 - 模型名拼写错误,或账号档位无权访问该型号。
- 路径多了或少了
/v1,或客户端把 Base URL 和完整路径拼重。 - 中国站与国际站可用的模型名不同。
用同一个 Key 拉模型列表,确认账号实际能看到什么:
curl "https://api.moonshot.cn/v1/models" \
-H "Authorization: Bearer $MOONSHOT_API_KEY"
列表里没有的型号不要靠猜。模型列表能返回、聊天接口仍 404 时,重点检查路径拼接和客户端配置。
四、429:三种类型,处理方式完全不同
429 是排查里最容易误判的一类。先看 error.type:
error.type |
含义 | 能否重试 | 处理方式 |
|---|---|---|---|
engine_overloaded_error |
集群过载,容量紧张 | 可以 | 按 Retry-After 退避,降低并发 |
rate_limit_reached_error |
组织级并发、RPM、TPM 或 TPD 超限 | 部分可以 | 降速、等待、提升账户档位 |
exceeded_current_quota_error |
欠费、余额不足、代金券失效 | 不要重试 | 检查余额并充值 |
Moonshot 的限流档位按账户累计充值额划分 Tier0 到 Tier5,充值赠券通常不计入累计额。档位同时约束并发数、每分钟请求数、每分钟 Token 数和每天 Token 数:低档位并发可能只有个位数,高档位可到百级并发;RPM 从个位数到数百,TPM 从几十万到数百万。Tier0 还有每日 Token 上限,超限后通常要等次日重置。
几个容易踩的坑:
- OpenAI SDK 默认会对 408、409、429 和 5xx 自动重试,最多共三次。低档位账户一次失败可能被放大成多次请求,很快耗尽 RPM。生产环境要显式设置
max_retries。 - 联网搜索等工具有独立的 QPS 限制,和聊天接口的 RPM、TPM 分开计算,超限同样返回 429。
- 被 429 中断的请求通常不计费,但重试成功后会正常计费,不要因为“不扣费”就无限重试。
- 限额和档位对不上时,先确认是否用了别的账号的 Key。
五、400:上下文超长与参数错误
上下文超长通常返回 400 invalid_request_error,错误消息会提示输入 Token 超限。注意判断口径是“输入 + 输出上限”是否超过模型窗口,而不是只看输入。
常见触发方式:
- 历史消息无限增长,多轮对话从未裁剪。
- 把整份文档塞进 1M 上下文,同时又设置了很大的输出上限。
- 文件接口上传超过 100MB、上传空文件,或
purpose取值不在允许列表。 - 输出触发了
content_filter,这类过滤也可能由模型输出触发,不只检查输入。
处理顺序是:先估算输入 Token,再给输出留空间;长文档分段摘要并保留引用;多轮对话做滑动窗口;结构化输出用工具调用,减少无效长文本。
另外,finish_reason=length 不是报错,而是输出达到了上限。需要更长结果时,分段请求或使用续写能力,不要直接把上限调到超过模型允许值。
六、超时、499 与流式
Moonshot 的网关对非流式请求有等待上限,官方文档提到 504 可能在 900 秒后出现。长文生成、长文档分析和代码 Agent 最容易遇到。
按这个顺序处理:
- 非流式改流式,设置
stream=True,让连接持续有数据返回。 - 连接超时设短,读取超时按最长生成时间设置,不要沿用 SDK 默认值。
- 检查公司代理、网关和本地路由工具是否提前断开连接,这类中断可能表现为 499
client_closed_request。 - 用输出上限控制单次生成长度,超长任务拆分。
- 流式场景看首 Token 延迟;TTFT 突然升高通常是上游拥塞或提示词变长。
- 记录每次超时的请求标识和耗时,区分模型慢、网络慢还是代理慢。
流式不会降低单价,但能减少“等到超时再重试”的重复消耗。读取超时不要沿用非流式的短值,否则连接会在正常生成时被客户端自己切断。
七、重试与退避怎么写
重试只适合瞬时错误。401、403、404、内容安全和余额不足不要自动重试;429 要先分类;5xx 可以退避。已经产生副作用的业务,先用幂等键或状态查询确认是否执行过。
import random
import time
from openai import OpenAI, APIStatusError, RateLimitError
client = OpenAI(
api_key="你的密钥",
base_url="https://api.moonshot.cn/v1",
max_retries=0, # 关闭 SDK 自动重试
)
RETRYABLE_TYPES = {"engine_overloaded_error", "server_error",
"server_unavailable", "client_closed_request"}
def ask(prompt: str, retries: int = 4) -> str:
for attempt in range(retries):
try:
resp = client.chat.completions.create(
model="kimi-k3",
messages=[{"role": "user", "content": prompt}],
max_completion_tokens=1024,
)
return resp.choices[0].message.content
except RateLimitError as exc:
body = exc.body or {}
etype = (body.get("error") or {}).get("type", "")
if etype == "exceeded_current_quota_error":
raise RuntimeError("余额或额度不足,先充值")
if etype == "rate_limit_reached_error":
raise RuntimeError("账户限流,降低并发或提升档位")
wait = min(2 ** attempt, 20) + random.random()
print(etype or "overloaded", "等待", round(wait, 1), "秒")
time.sleep(wait)
except APIStatusError as exc:
if exc.status_code in (401, 403, 404):
raise
if exc.status_code >= 500:
time.sleep(min(2 ** attempt, 20) + random.random())
else:
raise
raise RuntimeError("重试次数已用完")
print(ask("说明重试的适用边界"))
有 Retry-After 响应头时优先按它等待,再叠加随机抖动,避免多实例同时重试造成二次拥塞。重试次数要有上限,并把最终失败写入告警。
八、找支持前准备什么
- 发生时间,带时区和年份,精确到秒。
- 请求标识、响应
id和usage字段。 - 模型名、Base URL、站点(中国站或国际站)、是否流式。
- HTTP 状态码、
error.type和完整错误消息。 - SDK 与客户端版本、重试配置、是否经过代理或网关。
- 最小可复现请求,一条 curl 即可。
- 账单或用量记录,用于核对是否重复计费。
- 脱敏后的日志,删除 Key、用户数据和敏感提示词。
先自己用直连 curl 复现一次,再把直连和网关的结果分开提交,能显著缩短定位时间。
常见问题
429 重试会重复扣费吗?
被 429 拒绝的请求通常不计费;重试成功后按正常请求计费。真正需要担心的是 SDK 自动重试把一次业务请求放大成多次,造成请求数和费用同时上升。
昨天还能用的模型,今天怎么 404 了?
先查官方模型页的下线记录。moonshot-v1 系列已于 2026 年 8 月 31 日下线,kimi-k2 系列和 kimi-latest 也已停止维护,按官方建议迁移到 kimi-k3。
429 提示余额不足,还需要退避重试吗?
不需要。exceeded_current_quota_error 属于账户余额或额度问题,重试不会恢复,先检查余额、欠费状态和代金券有效期。
已经用了流式,为什么还会超时?
流式降低的是首包等待,不保证连接永远不断。检查代理的 idle timeout、读取超时、输出上限和网络稳定性;也可能是上游长时间没有新 Token,触发中间设备断开。
直连正常、走网关报错,怎么判断责任方?
用同一把 Key、同一个模型、同一条请求分别打直连和网关,比较状态码、error.type、请求标识和耗时。直连成功而网关失败,重点查网关的路径、鉴权、超时和重试配置。
下一步
先在中商起航 AI 网关创建测试 Key,把 401、404、429 和超时各演练一次,再接入生产监控。可用型号与计费以模型价格为准。
相关阅读:
