一个 Agent 在本地跑通,并不意味着它已经具备稳定运行的能力。
模型接口会超时,搜索服务会返回 503,数据库连接可能中断,Tool 也可能因为参数错误抛出异常。Agent 又通常包含多轮“模型 → Tool → 模型”的执行循环,其中任何一步失败,都可能影响整个任务。
因此,Agent 的错误处理需要回答几个具体问题:什么错误可以重试,什么时候应该切换备用模型,哪些 Tool 异常可以交给模型重新处理,哪些错误必须立即终止。
本文主要介绍 LangChain Agent 在真实运行环境中可能遇到的各类故障,以及如何通过重试、Fallback、超时与异常恢复等机制加以应对。
一、Agent故障来源
普通模型调用的链路比较简单:
用户请求
↓
模型调用
↓
返回结果
如果模型请求失败,捕获异常并返回错误即可。
Agent 的链路更长:
用户请求
↓
模型判断
↓
调用搜索 Tool
↓
模型读取结果
↓
调用数据库 Tool
↓
模型继续判断
↓
返回结果
在 LangChain 中,create_agent 创建的 Agent 会让模型与 Tool 在循环中持续交互,直到模型生成最终响应或运行被停止。
因此,一次 Agent 执行中可能存在多个可能的故障来源。
模型层可能遇到网络错误、Rate Limit、服务端故障和请求超时。
Tool 层还会引入数据库、HTTP API、文件系统和业务代码产生的异常。
执行链路也会产生新的问题。例如前三步已经成功,第四步失败,此时从头重新执行,很可能重复已经完成的操作。
从处理方式来看,常见的恢复路径可以归纳为四类:
失败
├─ Retry(重试)—— 再执行一次
├─ Fallback(回退)—— 切换备用实现
├─ Recover(恢复)—— 把错误交回 Agent
└─ Fail(失败)—— 终止当前运行
不同机制针对的故障类型并不相同。
二、错误恢复边界
先看两个简单场景。
在一个 Agent 中调用了两个不同的服务。
Agent 调用天气服务时收到:
HTTP 503 Service Unavailable
服务可能只是短暂抖动。等待一秒重新请求,有机会恢复。这类情况属于瞬时错误(Transient Failure)。
另一个 Tool 收到:
city=""
随后抛出:
ValueError: city 不能为空
相同参数执行十次,结果通常仍然一样。此时重复请求没有意义,模型需要修改调用参数。
实际项目中的错误大致可以这样区分:
| 类型 | 典型情况 | 常见处理 |
|---|---|---|
| 瞬时错误 | 429、503、连接中断 | Retry |
| 服务故障 | 模型供应商不可用 | Retry、Fallback |
| 输入错误 | Tool 参数非法 | 返回模型重新处理 |
| 超时 | 外部服务长时间无响应 | Timeout、Retry |
| 业务拒绝 | 权限不足、余额不足 | 返回业务错误 |
| 程序错误 | TypeError、代码 Bug | 终止并记录 |
关于 Retry 策略,需要注意:相同输入再次执行时,如果成功概率会明显提高,Retry 才有价值。
SQL 写错、API Key 失效、参数结构不合法,都很难通过等待几秒自行恢复。对这些错误反复 Retry,只会增加响应时间和调用成本。
三、重试机制
LangChain 提供 ModelRetryMiddleware 和 ToolRetryMiddleware,分别处理模型调用和 Tool 执行过程中出现的可重试异常。
以 Tool 为例:
from langchain.agents import create_agent
from langchain.agents.middleware import ToolRetryMiddleware
from langchain.tools import tool
@tool
def search_docs(query: str) -> str:
"""Search technical documentation."""
return f"Search result for: {query}"
agent = create_agent(
model="openai:gpt-5",
tools=[search_docs],
middleware=[
ToolRetryMiddleware(
max_retries=3,
initial_delay=1.0,
backoff_factor=2.0,
max_delay=10.0,
retry_on=(ConnectionError, TimeoutError),
on_failure="continue",
)
],
)
max_retries=3 表示首次失败以后,最多额外尝试三次。
initial_delay 与 backoff_factor 控制重试间隔。忽略随机抖动时,过程大致是:
第一次失败
等待约 1 秒
第二次失败
等待约 2 秒
第三次失败
等待约 4 秒
这种策略称为指数退避(Exponential Backoff)。
如果几十个 Agent 同时碰到下游服务出问题,所有请求马上重发,很可能让服务压力雪上加霜。用指数退避配合随机抖动,能避免大量请求在同一时刻扎堆重试。
模型调用可以采用相同机制:
from langchain.agents.middleware import ModelRetryMiddleware
agent = create_agent(
model="openai:gpt-5",
tools=[search_docs],
middleware=[
ModelRetryMiddleware(
max_retries=3,
initial_delay=1.0,
backoff_factor=2.0,
retry_on=(ConnectionError, TimeoutError),
on_failure="error",
)
],
)
这里需要重点关注 retry_on。
生产系统通常应明确哪些异常允许重试。例如连接中断和超时可以重试,而参数错误、权限错误和程序 Bug 往往应直接向上传播。
上例运行结果:
Model request failed: TimeoutError
Retrying after 1s...
Model request failed: TimeoutError
Retrying after 2s...
Model request succeeded
Agent completed successfully
从结果可以看到,Retry 没有改变执行目标,也没有更换模型。系统只是再次执行了同一个操作。
四、Fallback机制
如果同一个服务连续失败,继续原封不动地重试不一定是好办法。
这时可以使用 Fallback,也就是准备一组备用模型或服务。
两者的执行关系可以简单表示为:
Retry
Model A
↓
Model A
↓
Model A
Fallback
Model A
↓
Model B
↓
Model C
LangChain 的 ModelFallbackMiddleware 可以在主模型失败后,按照配置顺序尝试其他模型。
from langchain.agents import create_agent
from langchain.agents.middleware import (
ModelFallbackMiddleware,
ModelRetryMiddleware,
)
agent = create_agent(
model="openai:gpt-5",
tools=[search_docs],
middleware=[
ModelRetryMiddleware(
max_retries=2,
on_failure="error",
),
ModelFallbackMiddleware(
"openai:gpt-5-mini",
),
],
)
这套配置表达的运行策略是:
调用主模型
↓
失败
↓
再次调用主模型
↓
仍然失败
↓
尝试备用模型
Fallback 需要特别关注模型能力是否兼容。
如果 Agent 使用 Tool Calling、结构化输出或者多模态能力,备用模型也需要支持相应功能。
否则可能出现:
主模型失败
↓
切换备用模型
↓
备用模型缺少所需能力
↓
再次失败
因此,备用模型应该经过实际验证,确保它能够完成当前 Agent 所需要的任务。
上述示例输出如下:
Primary model request failed
Retry 1 failed
Retry 2 failed
Fallback model selected
Request succeeded
Agent completed
这里形成了两层恢复机制:短暂故障由 Retry 处理,主服务持续不可用时再进入 Fallback。
五、Tool异常恢复
我们先看一个具体场景。
假设模型生成了错误调用:
get_order(order_id="")
Tool 随后抛出:
ValueError: order_id 不能为空
如果直接终止 Agent,本次任务到这里结束。
但这条错误信息对模型其实有价值。模型看到 order_id 不能为空 后,可以修改 Tool Call,再执行一次:
Tool 执行失败
↓
错误信息返回模型
↓
模型重新判断
↓
生成新的 Tool Call
这个过程与普通 Retry 有明显区别。
Retry 会重新执行相同调用:
get_order(order_id="")
↓
get_order(order_id="")
Agent Recovery 则允许模型修改参数:
get_order(order_id="")
↓
收到错误信息
↓
get_order(order_id="ORDER-100001")
ToolRetryMiddleware 在重试耗尽后,可以通过 on_failure="continue" 把错误作为 Tool 消息返回给 Agent。
LangChain 还提供 ToolErrorMiddleware,用于将 Tool 异常转换为模型能够理解的受控错误信息。
from langchain.agents import create_agent
from langchain.agents.middleware import (
ToolErrorMiddleware,
ToolRetryMiddleware,
)
def handle_tool_error(exc, request):
if isinstance(exc, ValueError):
return (
f"{request.tool_call['name']} received invalid arguments. "
"Please correct the arguments and try again."
)
return None
agent = create_agent(
model="openai:gpt-5",
tools=[search_docs],
middleware=[
ToolRetryMiddleware(
max_retries=2,
on_failure="error",
),
ToolErrorMiddleware(
on_error=handle_tool_error,
),
],
)
Middleware 的组合顺序会影响异常传播。
如果希望 Tool 先自动重试,重试耗尽后再进入错误转换,需要确保最终异常能够继续传递到负责处理它的 Middleware。
上面示例输出:
Tool call:
search_docs(query="")
Tool error:
ValueError
Agent receives:
search_docs received invalid arguments.
Please correct the arguments and try again.
Tool call:
search_docs(query="LangChain middleware")
Tool succeeded
一般来说,网络超时、503 等瞬时故障更适合 Retry;参数错误、查询条件错误等模型有能力修正的问题,更适合把错误重新放回 Agent 的上下文。
六、超时边界
还有一类问题不会立即抛出异常:
Agent
↓
External API
↓
一直等待……
如果没有设置 Timeout,Agent 可能长时间占用连接和执行资源。
因此,凡是调用外部服务,都应该考虑明确的时间边界。
普通 HTTP Tool 可以直接在 HTTP Client 中设置:
import httpx
from langchain.tools import tool
@tool
def query_service(keyword: str) -> str:
"""Query an external service."""
response = httpx.get(
"https://api.example.com/search",
params={"q": keyword},
timeout=5.0,
)
response.raise_for_status()
return response.text
超过五秒后,HTTP Client 会抛出超时异常。外层 Retry 再决定是否重新请求:
Timeout
↓
判断异常类型
↓
Retry
↓
仍然失败
↓
Fallback / Recover / Fail
模型客户端同样应该根据实际 SDK 提供的配置设置请求超时。
错误处理离故障源越近,通常越容易准确判断发生了什么。
七、组合策略
生产环境中的错误处理通常由多种机制组成。
一条比较清晰的执行路径是:
实际项目中可以按照故障位置来安排处理逻辑。
HTTP 超时由 HTTP Client 控制。
Tool 参数错误在 Tool 边界转换成清晰的错误信息。
模型服务的瞬时故障交给 ModelRetryMiddleware。
主模型持续不可用时,再进入模型 Fallback。
权限错误、配置错误以及程序 Bug,则应向上传播,并交给日志、Trace 和应用层异常处理机制记录。
此外,对于涉及写操作或与外部系统交互的 Tool,应配合使用幂等键、事务状态检查,或加入重复请求保护机制。
像查询天气、搜索文档等读操作通常比较适合自动 Retry;而支付、退款、发消息等操作则应先解决幂等问题。
总结
本文讨论了 Agent 运行过程中几种最常见的故障处理方式。
Timeout 负责限制等待时间,Retry 适合处理具有恢复概率的瞬时故障,Fallback 用于主服务持续不可用时切换备用路径,Tool Error Recovery 则允许模型根据错误信息重新调整参数和执行策略。
实际项目中,应先区分错误类型和副作用,再决定恢复方式;涉及写操作时,还需要配合幂等、事务和状态检查,避免一次故障演变成重复执行。
社区讨论
参与讨论
有问题或想法?欢迎继续讨论。