函数调用(tool use)在中转站上的兼容性差异与自测方法
为什么工具调用最容易出问题
文本生成的质量差异,你一眼就能看出来。工具调用不行 —— 它的失败往往是静默的:
- 参数被写坏了,模型不会报错,只是执行了一个错误的动作;
- 多轮调用时上下文丢了,表现为「Agent 突然忘了前面做过什么」;
- 流式下的工具调用分块出错,表现为「工具调用到一半停了」。
更麻烦的是,这些问题在简单测试里不会出现。所以做 Agent 类应用,工具调用必须单独验证。
三家的结构差异
OpenAI
- 请求:
tools(数组,元素是{"type":"function","function":{...}})+tool_choice - 返回:
message.tool_calls,其中function.arguments是 JSON 字符串(不是对象) - 回传结果:role 为
tool的消息,带tool_call_id
Anthropic
- 请求:
tools(元素是{"name","description","input_schema"},没有外层 function 包装) - 返回:
content数组里的{"type":"tool_use","id","name","input"},input是 已解析的对象 - 回传结果:
content里的{"type":"tool_result","tool_use_id","content"}
Gemini
- 请求:
tools[].functionDeclarations - 返回:
functionCall部分
差异点总结:arguments 是字符串还是对象、包装层级有几层、回传时用什么字段关联。这三处就是转换时最容易出错的地方。
三类常见故障
故障一:arguments 的双重编码
最常见的 bug。OpenAI 的 arguments 是字符串,Anthropic 的 input 是对象。
如果网关在转换时把已经是字符串的 arguments 又序列化一次(或者反过来,把对象当成字符串直接透传),你会得到:
- 参数变成一个被转义的字符串:
"{\"city\":\"北京\"}"而不是{"city":"北京"} - 或者解析失败,工具收到空参数
症状:工具确实被调用了,但参数不对。
自测:设计一个必须带参数的简单工具(比如 get_weather(city)),看最终传入的参数对不对。
故障二:多轮调用的上下文丢失
Agent 的典型流程是「模型请求工具 → 你执行 → 把结果回传 → 模型继续」。这要求网关能正确地把 tool_use / tool_result(或 tool_calls / role=tool)在往返之间保持结构一致。
如果网关在某一轮把工具结果降级成了普通文本消息,模型就失去了「这是我刚才调用的结果」这个语义,表现为:
- 反复调用同一个工具
- 收到结果后仍然说「我没有获取到信息」
自测:设计一个两轮工具调用(第一次查天气,第二次根据天气给建议),看第二轮是否正常。
故障三:流式下的工具调用分块
非流式下工具调用是完整的 JSON;流式下它会被切成多个 delta 分片,需要客户端或网关按 index 拼接。
如果拼接逻辑出错,会出现参数只收到一部分的情况(比如 city 收到了,date 丢了)。
自测:同一个工具调用,分别用流式和非流式各跑一次,比对最终参数。
十分钟自测流程
准备一个带两个参数的工具:
{
"name": "book_room",
"description": "预订会议室",
"parameters": {
"type": "object",
"properties": {
"room": {"type": "string", "description": "会议室名称"},
"people": {"type": "integer", "description": "人数"}
},
"required": ["room", "people"]
}
}
然后依次跑四个用例:
| # | 用例 | 检查点 |
|---|---|---|
| 1 | 单轮调用,非流式 | 两个参数都正确解析;arguments 不是双重编码的字符串 |
| 2 | 单轮调用,流式 | 分片拼接后参数完整 |
| 3 | 多轮:调用 → 回传结果 → 继续 | 第二轮能引用上一轮结果 |
| 4 | 调用一个不存在的工具 | 返回的是结构化错误,而不是静默成功 |
四个用例全过,说明这家站的工具调用链路可用。任何一个失败,都会在真实 Agent 场景里造成难以定位的故障。
对不同场景的意义
- 纯文本对话:工具调用不通过也没关系,可以忽略本文。
- 编程助手(Claude Code / Cursor / Cline):必须过。这类工具的核心机制就是工具调用 —— 读文件、改文件、跑命令全靠它。行业里反复出现的一个经验是:客户端接入中转站后出现「工具行为异常」,第一嫌疑人就是中转站的协议转换层,而不是客户端。
- Agent / 工作流(Dify、FastGPT、自研):必须过,且要测多轮。
- RAG 应用:如果只做检索 + 生成,可以不测工具调用;一旦用了 function 来做检索路由,就必须测。
一个务实的建议
如果你在做 Agent 类产品,把「工具调用自测」写进你的供应商接入清单,和「能不能连通」放在同一级。
连通性有问题,你五分钟就知道;工具调用有问题,你可能两周后才发现,而且会先怀疑自己的代码。
这篇文章对你有帮助吗?如果你在实际使用中发现了文中没提到的情况,欢迎 提交纠错或补充,我们会核验后更新到正文里。
相关文章
顺着看下去:本站收录的部分中转站
本文没有指向特定模型系列,下面是本站收录站点中综合评分靠前的几家,供你顺着看下去。排序依据是评分与可用率,不构成推荐。