《AI Agent 工程实战》8.3 取消、超时与泄漏:慢工具注入验证止损
并发开得越大,越怕一个慢工具拖住整轮。本节用 asyncio.timeout 给每个工具调用设墙钟上限,演示用户断开时取消如何从 run 一路传到最内层的工具,剖析忘了 await 的 Task 与 TaskGroup 失败取消两种泄漏。真跑注入一个睡 10 秒的慢工具,验证 1 秒超时后整个 run 及时止损并返回明确错误,最后给出超时值的决策表。
tag
并发开得越大,越怕一个慢工具拖住整轮。本节用 asyncio.timeout 给每个工具调用设墙钟上限,演示用户断开时取消如何从 run 一路传到最内层的工具,剖析忘了 await 的 Task 与 TaskGroup 失败取消两种泄漏。真跑注入一个睡 10 秒的慢工具,验证 1 秒超时后整个 run 及时止损并返回明确错误,最后给出超时值的决策表。
MCP 工具调用的可靠性工程:工具调用的失败模式(超时/依赖故障/幂等破坏)、超时设置与客户端策略、重试与退避、幂等工具设计(幂等键/去重)、长任务处理(进度通知/异步完成/可取消)、工具调用的背压与并发控制、失败后模型的降级路径,以及可靠性测试与可观测性。
数据访问层出问题,十有八九先出在连接池和超时上。本节给 TaskHub 定下 database/sql 四个池参数,实测并发 20 时 MaxOpenConns 从 4 到 20 让墙钟由 298ms 降到 78ms、排队由 16 次降到 0,给出按 max_connections 与实例数反推池大小的算法,并把超时预算逐层落成代码。
写后端服务时,外部调用失败是常态。网络会抖,依赖会慢,网关会返回 502,数据库也可能短暂不可用。初学者最容易写出两种极端代码:一种完全不重试,偶发错误直接暴露给用户;另一种无脑重试很多次,把一个小抖动放大成更大的压力。正确做法不是“永远重试”或“永不重试”,而是把超时、退避和幂等性一起考虑。
本文讲解 Go HTTP 服务中 ReadTimeout、WriteTimeout、IdleTimeout 和请求 context 的基本用法,帮助初学者避免服务被慢请求拖住。