← 工程化与 LLMOps

调用大模型失败时,报错怎么翻译给用户?哪些错误重试也没用?

高频 中等 调用日志与链路追踪 · 第 3 / 3 问 更新于 2026/09/29
LLMOps错误处理重试模型调用可观测性
本题落地项目AI Agent旅游行程智能规划平台

简化版

模型服务的报错是英文 JSON 或框架包装过的异常,直接弹到页面上没人看得懂。统一出口要把它翻译成「该去哪里改什么」:欠费去充值,Key 无效去模型配置页检查密钥,模型名不存在去核对名称,输入太长去精简正文,429 限流稍后重试,超时检查网络和接口地址。翻译的同时按可重试性分类:欠费、Key 无效、模型名写错属于账户和配置问题,重试多少次都不会好,批量任务遇到就应该立即停;限流、超时、服务端 5xx 可以退避后重试;输入超长和输出被截断要改输入或上限,原样重试没有意义。框架自带的自动重试次数要设小,避免 Key 填错时把额度浪费在反复重试上。

详细版

报错典型特征翻译成重试有没有用
欠费、额度用完平台欠费码、insufficient_quota去平台充值没用
Key 无效HTTP 401、invalid_api_key去模型配置页检查密钥没用
模型名不存在model_not_found、HTTP 404核对模型名称没用
输入超长context_length_exceeded精简输入原样重试没用
输出被截断HTTP 200,结束原因 length调大最大输出或精简输入原样重试没用
限流HTTP 429稍后重试退避后有用
超时、连不上超时异常、连接异常检查网络和接口地址偶发时有用

落地要点:

  1. 翻译规则只写一份,放在统一调用出口里,对话、向量、Agent 三种调用共用。
  2. 没匹配上的报错不丢,截断原文后返回,保留排查线索。
  3. 翻译后的原因写进调用日志,页面、日志看到的是同一句话。
  4. 批量任务按可重试性决定去留:单条偶发失败记下来继续,遇到重试无用的错误立即停。

完整版教学

一、报错长什么样

模型调用失败时,调用方拿到的东西有三种形态:

HTTP 错误响应    状态码 401 / 404 / 429 / 500,响应体是服务商自己的 JSON:
                 {"error": {"code": "invalid_api_key", "message": "Incorrect API key ..."}}
框架包装的异常    SDK 把 HTTP 错误包成运行时异常,信息在 message 里,
                 网络问题的真实原因常常藏在 getCause() 里
看起来成功的失败  HTTP 200,但结束原因是 length,正文只有半截

第三种最容易漏掉:它不算报错,框架不会抛异常,只有主动检查结束原因才能发现。前两种直接抛给页面,用户看到的是一大段英文加状态码,既看不懂,也不知道该去改哪里。

二、按「该去哪里改」翻译

翻译的目标不是把英文换成中文,而是告诉看到提示的人下一步做什么:

翻译前翻译后
Incorrect API key providedAPI Key 无效,请到【AI 模型配置】检查密钥是否填错或已失效
The model xxx does not exist模型名不存在,请到【AI 模型配置】核对模型名称
This model's maximum context length is ...输入正文太长,超出了模型单次能处理的上限,请精简后重试
Rate limit reached请求太频繁被平台限流,请稍后重试
Read timed out连不上模型服务或等待超时,请检查网络和接口地址

识别时优先看稳定的错误码和状态码,其次再看错误信息里的关键字。不同服务商用词不同,比如欠费有的叫 insufficient_quota,有的叫 Arrearage,关键字要按实际接入的服务商补全。一条都没匹配上时,把原文截断到一两百字返回,保留排查线索。

记忆钩子:好的报错提示回答三个问题:出了什么问题、去哪里改、改完要不要重试。

三、按可重试性分三类

翻译之外,更重要的是判断「再试一次有没有用」:

类别例子处理
重试无用欠费、Key 无效、模型名不存在、没有模型权限不重试,立即报错,批量任务立即停
改了再试输入超长、输出被截断、参数不合法不原样重试,提示改输入或调上限
稍后可能好限流、超时、服务端 5xx有限次数退避重试

第一类的本质是账户或配置问题,只有人去改了配置才会好。把它和第三类混在一起统一重试,Key 填错一次,每个请求都要白试好几遍。

四、框架自动重试设多少

很多 SDK 自带失败重试,默认可能是两三次。重试次数直接影响两件事:

最坏耗时 = 单次超时 × (重试次数 + 1)
单次超时 90 秒、重试 1 次:最坏 180 秒
单次超时 90 秒、重试 3 次:最坏 360 秒

Key 填错时的无效请求数 = 调用次数 × (重试次数 + 1)
100 次调用、重试 3 次:400 次注定失败的请求
100 次调用、重试 1 次:200 次

所以自动重试设成 1 次左右就够:能扛住偶发的网络抖动,又不会在配置错误时把等待时间和请求数成倍放大。更精细的做法是只对第三类错误重试,但这要在框架的重试机制之外自己写判断。

五、批量任务:遇到重试无用的错误立即停

批量向量化、批量生成这类任务一次要调几百上千次模型。按单条处理失败的常见写法是「记下原因,继续下一条」,这对偶发失败是对的,对配置错误却是灾难:

500 个片段,API Key 填错:
  逐条继续:500 次调用全部失败,最后得到一句「500 条失败」
  识别到重试无用立即停:第 1 条失败就停,提示「API Key 无效,请到模型配置检查密钥」

判断依据就是第三节的分类:翻译后的原因如果属于「重试无用」,立即结束整个任务,并把原因和已经成功的条数一起告诉用户。

六、翻译规则只写一份

项目里调用模型的地方很多:普通对话、流式对话、向量化、带工具的 Agent。每处各写一套 try-catch 和翻译,很快就会不一致:同一个 Key 错误,这个页面说「密钥无效」,那个页面说「调用失败:401」。正确的做法是把翻译放进统一调用出口的一个函数里,各处失败都调它;重试无用的判断也基于同一个函数的翻译结果,而不是另写一套关键字匹配。

翻译后的原因同时写进调用日志的失败原因列。这样管理员在日志页看到的,和用户在页面上看到的是同一句话,排查时对得上。

七、常见误区与追问

  • 误区:把服务商的报错原样返回给页面,信息最全。 用户看不懂、不知道去哪改,翻译成可操作的中文,原文留在日志里。
  • 误区:所有失败都重试几次更稳。 欠费、Key 无效、模型名错误重试多少次都一样,只会放大等待时间和请求数。
  • 误区:HTTP 200 就是调用成功。 输出撞上最大长度时照样返回 200,正文只有半截,要检查结束原因。
  • 误区:批量任务单条失败就记下来继续,总没错。 配置类错误会让每一条都失败,应该识别出来立即停。
  • 追问:翻译规则按错误码匹配还是按文字匹配? 优先错误码和状态码,文字关键字作为补充,并按实际接入的服务商补全。
  • 追问:没匹配上任何规则的报错怎么办? 截断原文后返回,保留排查线索,同时写进日志。

八、加强记忆

模型报错先翻译、再分类。翻译按「去哪里改」写:欠费去充值、Key 和模型名去配置页、输入太长去精简、限流稍后试、超时查网络,没匹配上的截断原文保留线索。分类按可重试性:账户和配置问题重试无用,批量任务遇到立即停;输入超长和输出截断改了再试;限流、超时、5xx 有限退避重试。框架自动重试设小,最坏耗时是单次超时乘以重试次数加一。翻译规则只写一份放在统一出口,结果写进调用日志,页面和日志看到的是同一句话。

项目实战落地

项目里怎么做的

《AI Agent旅游行程智能规划平台》的统一出口 AiChatService 里只有一个翻译函数 describeModelError,调用对话模型、向量模型、行程编排三处失败都用它:

识别关键字翻译成
Arrearage、insufficient_quota、overdue模型平台账户欠费或免费额度已用完,请先到平台充值
Invalid API-key、invalid_api_key、401API Key 无效,请到【AI模型配置】检查密钥
model_not_found、Model not exist模型名不存在,请到【AI模型配置】核对模型名称
context_length_exceeded 等输入正文太长,超出了模型单次能处理的上限
JSON 解析异常的特征文字工具参数不完整(输出被截断),请调大该用途的最大输出
429、rate_limit、Throttling请求太频繁被平台限流,请稍后重试
timed out、timeout、Connection连不上模型服务或等待超时,请检查网络和接口地址

没匹配上时截断到 200 字返回原文。欠费、Key 无效、模型名不存在这三句提示定义成常量,isFatalModelError 按「翻译后的原因里含这三句之一」判断重试也没用,批量向量化靠它决定是否提前停。模型工厂的自动重试 MAX_RETRIES = 1,单次超时 90 秒。

《AI Agentic RAG高级企业知识库平台》有两个翻译函数,按调用方式分工:走 httpx 的重排接口拿得到响应对象,按状态码翻译(401 Key 无效、403 没有该模型权限、404 地址或模型名不存在、429 太频繁或额度用尽);走 LangChain SDK 的对话和向量模型拿到的是异常,按异常文本翻译。

为什么这样取舍

  • 重试只设 1 次。 失败后只再试一次,避免 Key 填错时把额度浪费在反复重试上。
  • 重试无用的判断基于翻译结果。 三句提示是常量,翻译和判断用同一份规则,不会出现「翻译成 Key 无效却被当成可重试」的情况。
  • 两种翻译入口。 状态码只有直接拿到 HTTP 响应时才有;SDK 把错误包成异常之后,只能看异常文本。

翻译后的原因会写进调用日志的失败原因列,日志字段见「大模型应用日志应该记录哪些字段?」。

面试官还会追问

  • 旅游项目批量向量化一篇文档时遇到重试无用的错误中断了,已经成功的片段怎么处理?中断提示里会写什么?
  • 一篇文档的片段全部向量化失败时,页面上看到的是哪一次失败的原因?

学完《AI Agent旅游行程智能规划平台》,上面这些追问你都会迎刃而解。

本题落地项目地狱锤炼AI Agent旅游行程智能规划平台基于 SpringBoot + LangChain4j、攻略知识库 RAG、MySQL 向量检索、Function Calling 与数据库驱动工具中心,实现候选池预热与工具收窄、多城联游行程编排、14 条代码硬校验驱动的反思重排、教训记忆与多版本对比、三道闸防空转、编排前探活、预算测算和 Agent 执行时间线,覆盖从需求识别到行程交付的完整闭环。SpringbootLangChain4JAgentRAGFunction Calling源码+SQL喂饭学习教程配套面试文档环境安装文档项目运行文档 学习这个项目 也可以学AI Agentic RAG高级企业知识库平台地狱锤炼 查看项目