5.4 KiB
5.4 KiB
Tool Calling 实现清单
这份清单覆盖 OpenAI / Anthropic 标准工具调用的完整实现。
目标是把"纯聊天 API 支持 tools 调用"拆成可逐项完成、可逐项验证的实现面。
1. Prompt Contract
- 明确告诉模型当前有可用工具,不要声称“工具不可用”
- 列出全部工具:
- 名称
- 简短描述
- 参数 schema 摘要
- 固定动作输出格式:
```json action ... ```
- 明确多轮规则:
- 独立动作可并行
- 依赖动作要等 tool result
- 无需工具时才输出普通文本
- 明确
tool_choice约束:any- 指定 tool
- 给至少一个合法 action block 示例
- 最好再给一个“tool result 回来后继续决策”的 few-shot
验收标准:
- 模型第一轮能稳定输出合法 action block
- 第二轮收到 tool result 后,不会轻易掉回普通解释文本
2. Request Normalization
- OpenAI:
- 解析
tools - 解析
tool_choice - 解析
assistant.tool_calls - 解析
tool
- 解析
- Anthropic:
- 解析
tools - 解析
tool_choice - 解析
tool_use - 解析
tool_result
- 解析
- 统一归一化成内部结构:
- tools
- choice
- messages
- history state
- 识别“当前轮没带 tools,但历史里已有 tool 调用”的场景
验收标准:
- 第二轮即使不重复传
tools,也能继续走 tool calling
3. Tool History Projection
- 把历史 assistant 工具调用重投影成 action text
- 不要把结构化历史原样丢给上游模型
- 保留:
- tool name
- arguments
- call id
- 投影结果应和真实 action block 尽量一致
验收标准:
- 模型在多轮中能“看到”自己之前做过什么动作
4. Tool Result Continuation
- tool result 不要裸塞回去
- 包装成明确续写指令:
- 当前哪个 call 的结果回来了
- 基于结果继续下一步动作
- 对空结果、错误结果、部分结果做统一包装
验收标准:
- 模型收到 tool result 后能继续:
- 再发起新工具调用
- 或输出最终答案
5. Parser Contract
- 识别:
```json action- 普通
```json
- 容忍:
- 智能引号
- 尾逗号
- 参数是字符串化 JSON
- 支持提取:
toolnameparametersargumentsinput
- 能从正文里剥离 action block
- 支持多 block
验收标准:
- 同一回复里多个 action block 都能被解析
- 正文和动作块可以正确拆分
6. Retry Policy
- 触发条件:
- 明确要求工具调用但没产出 action block
- 命中 refusal 文本
tool_choice=anytool_choice=tool
- retry 消息要更强约束:
- 必须输出 action block
- 不要解释
- 必要时必须调用指定工具
- 控制 retry 次数
- 记录 retry 原因
验收标准:
- refusal 回复能被纠偏
- retry 不会无限循环
7. Refusal Detection
- 维护 refusal 关键词表:
I don't have toolstools are unavailable没有可用的工具无法调用工具
- 识别“软拒答”:
- 只解释、不行动
- 强调环境限制
- 区分:
- 真正不该调用工具
- 本该调用工具却在推脱
验收标准:
- 常见“我没有工具”类回复能稳定触发 retry
8. Response Re-encoding
- OpenAI:
message.tool_callsfinish_reason = tool_calls
- Anthropic:
content[].tool_usestop_reason = tool_use
- 无工具时回普通文本
- 文本和工具调用共存时保持协议兼容
验收标准:
- 下游客户端无需知道上游其实不支持 native tools
9. Streaming Strategy
- OpenAI stream:
- 先发 role chunk
- 再发 text delta
- 再发 tool_calls delta
- Anthropic stream:
message_startcontent_block_startcontent_block_deltacontent_block_stopmessage_deltamessage_stop
- 如果当前实现是“先完整拿结果再合成流”,文档里要明确说明
验收标准:
- 下游看到的流式协议字段合法
10. Multi-turn State Machine
- 状态至少区分:
- 等待模型首次决策
- 已发起工具调用
- 等待 tool result
- 收到 tool result,等待下一轮决策
- 最终回答完成
- 状态切换依据应来自消息历史,而不是只看本轮字段
- 不要把“工具历史存在”误判成“必须再调工具”
验收标准:
- 一轮以上的 agent loop 稳定
11. Observability
- 打日志:
- 是否进入 tool calling
- 解析到几个 tool calls
- 是否触发 retry
- refusal 命中原因
- 最好记录:
- prompt contract 是否注入
- tool history 是否被识别
验收标准:
- 出问题时能判断是:
- prompt 不够强
- parser 失败
- retry 没触发
- 状态机断了
12. 测试矩阵
- OpenAI:
- 单轮 tool call
- 多轮 tool result 回灌
- 第二轮不重复传
tools - 指定 tool
tool_choice=any
- Anthropic:
- 单轮 tool_use
- 多轮 tool_result 回灌
- 第二轮不重复传
tools - 流式 tool_use
- 异常场景:
- refusal
- 无效 JSON
- 多 action block
- 普通文本结束
验收标准:
- 至少覆盖“第一轮调用工具”和“第二轮继续决策”两大关键场景
13. 下一步优先级
如果当前系统已经能跑,最值得优先继续做的是:
- 多轮再次发起新工具调用的 few-shot
- 基于历史状态的 retry 强化
- 更细的 refusal 分类
- parser 容错增强
- 流式工具事件细化