Agent工具调用的速度优化实战
上周用 OpenAI Agents SDK(0.3.7 版,3 月 12 号刚拉的镜像)重构客服系统,差点把 token 预算烧穿。
一个“查订单状态”,单次对话调了 17 次工具。17 次。
用户等了 8 秒才出结果。我盯着 Datadog 上的 latency 曲线,心跳比曲线还快。今天想跟你聊聊这背后的问题:动态工具调用怎么设计才不翻车,以及人机协同的回环机制到底怎么落地。
先搞懂动态工具调用是什么
传统做法:提前定义死工具列表,Agent 按固定流程走。但真实场景里,用户一句话可能触发完全不同的工具组合——“我上个月买的鞋到哪了”跟“我要退货”,需要的工具链截然不同。
OpenAI Agents SDK 的动态工具调用,核心就两点:
- **运行时决策**:Agent 根据上下文实时判断该调哪个工具,不是预编排
- **工具注册制**:你可以把几百个工具注册进去,Agent 自己选,不用写 if-else 地狱
我最早接触这个是在去年 12 月,当时用 Swarm 做原型(后来合并进 Agents SDK 了),第一反应是“这不就是 function calling 的增强版吗”。但跑了几轮发现,它真正强的是上下文传递的自动化——Agent 调完工具后,结果自动注入对话历史,不需要手动拼接 prompt。
等等,这里我要更正一下。刚才说“不需要手动拼接”,其实不太准确。准确说是不用像 LangChain 那样显式管理 message history,但工具返回结果的格式还是得自己控制。我之前踩过一次坑,工具返回了完整的 API response JSON(大概 3KB),Agent 直接懵了,开始反复调用同一个工具——它以为没拿到结果。后来加了 response_format 限制,只返回 {"status": "ok", "summary": "..."} 这种精简结构,问题才消失。
三个实战案例
案例 1:电商客服的“工具爆炸”
我们接入了 47 个工具函数,涵盖订单查询、物流追踪、退款处理、优惠券核销等。
上线第一周,平均每次对话调 6.3 次工具,P99 延迟 11 秒。问题出在哪?Agent 太“勤奋”了——用户说“我看看物流”,它先调订单查询,拿到订单号再调物流接口,发现没更新又调了通知服务,最后还调了个满意度调查。
离谱。
解决办法:加了工具调用预算机制。每轮最多调 3 次,超了就强制输出中间结果给用户确认。延迟降到 2.1 秒,用户满意度反而升了。我觉得这个结果挺反直觉的——“快”比“全”重要得多。
案例 2:医疗问诊的人机协同回环
另一个项目是医疗场景,Agent 能调 23 个知识库工具和 5 个预约接口。但涉及诊断建议时,必须人工审核。我们设计了三级回环:
1. 自动档:查药品说明书、预约时间,Agent 直接处理
2. 半自动档:症状分析先出 draft,人工点确认才发
3. 人工档:涉及处方药、急重症,Agent 只收集信息,完全转人工
这里用到了 SDK 的 handoff 机制——Agent 判断需要人工时,自动把完整上下文(包括之前所有工具调用结果)打包转给人工坐席。不是简单丢个“请转人工”的 flag,而是带着结构化数据过去,人工不用重新问一遍。
嗯...这个 handoff 的实现其实有个小坑。SDK 默认会把所有 tool call history 都序列化传过去,如果你的工具返回过敏感数据(比如用户身份证号),得在 handoff 前手动过滤。我们 2 月初上线的版本漏了这点,还好 QA 在 staging 环境发现了,不然就是 P0 事故。
案例 3:踩坑——工具描述写太烂
第三个案例是反面教材。我们有个“查询库存”的工具,描述写的是“查询商品库存”。
结果 Agent 在用户问“这个有没有货”时,居然先调了商品详情工具、再调价格工具、最后才调库存——因为它不确定“库存”是不是用户要的“有没有货”。
后来把工具描述改成:“当用户询问某商品是否有货、库存数量、尺码颜色库存时调用此工具。需要传入 sku_id 和 warehouse_code”,准确率从 67% 飙到 94%。
说真的,工具描述不是写给开发看的,是写给 LLM 看的。这个认知转变帮我省了至少两周的调试时间。据我了解,Anthropic 在 2024 年 11 月发的那个 tool use best practice 文档里也强调了这一点,写得比 OpenAI 官方文档还实用——推荐去看看。
人机协同回环的设计原则
经过这几个项目,我总结了一套原则:
1. 明确“信任边界”
我们定了三条线:只读操作全自动;写操作但可逆(创建工单、发通知)自动执行 + 事后审计;写操作不可逆(退款、删除数据)必须人审。
2. 上下文要“无损传递”
转人工时最怕信息丢失。SDK 的 handoff 会把工具调用历史、中间结果、用户原始输入全部打包。我们额外加了个“摘要层”,用 gpt-4o-mini 在转接前生成 200 字摘要,人工坐席大概 5 秒内就能理解全貌。
3. 设置“回环超时”
人工处理可能等很久。我们设了 30 分钟超时——超时后自动通知用户“正在加急处理”,同时升级到主管队列。这个机制让 48 小时内的二次投诉率降了大概 40%。
一个调试技巧
SDK 的 trace 功能,能回放每次工具调用的决策过程。我习惯在 dev 环境把所有 trace 打开,重点看两类异常:
- **工具重复调用**:同一个工具连续调两次以上,大概率是描述有问题
- **工具链断裂**:Agent 调了工具 A 拿到结果,但后续没用到这个结果,说明它“忘了”为什么调
用 agents.tracing.set_tracing_export_enabled(True) 开启后,在 OpenAI Dashboard 能看到完整的调用图。这个功能帮我揪出过至少 5 个隐蔽 bug。上次群里有个做金融客服的老哥也遇到类似问题,看 trace 图才发现是 tool A 的返回格式变了(第三方 API 偷偷改的),Agent 拿不到预期字段就开始乱调 tool B。
聊了这么多,其实动态工具调用和人机协同的核心就一句话:让 Agent 做它擅长的(快速检索、批量处理),把判断和兜底留给人。
技术实现上,OpenAI Agents SDK 提供了不错的基建,但真正的挑战在于设计——怎么描述工具、怎么划信任边界、怎么设计回环。这些没有银弹,只能一个场景一个场景地磨。
你团队在用哪个 Agent 框架?遇到过工具调用失控的情况吗?评论区聊聊,我下周会写一篇关于“Agent 工具调用的成本控制策略”,到时候可以结合大家的案例一起分析。对了,上周还有个朋友跟我吐槽说他们用 CrewAI 也遇到类似的 token 爆炸问题,看来这不是某个框架的锅,是设计思路的问题。
#OpenAI #AgentsSDK #人机协同 #工程实践 #AI应用落地
读者评论 5