docs(tool-emulation): 添加工具调用模拟实现清单与方法论文档
- 创建英文版工具模拟实现清单,涵盖13个核心实现面 - 添加中文版工具模拟实现清单,详细说明各项验收标准 - 编写英文版工具模拟方法论文档,阐述核心实现模式 - 补充中文版方法论文档,包括多轮调用与重试策略指导 - 实现HTTP API服务器测试,验证工具历史保持功能 - 新增工具模拟核心模块,包含工具定义提取与注入功能 - 添加拒绝检测、动作块解析等关键工具模拟组件
This commit is contained in:
241
docs/tool-emulation-checklist.zh-CN.md
Normal file
241
docs/tool-emulation-checklist.zh-CN.md
Normal file
@@ -0,0 +1,241 @@
|
||||
# Tool Emulation 实现清单
|
||||
|
||||
这份清单是给后续迭代用的。
|
||||
|
||||
目标不是解释原理,而是把“纯聊天 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`,也能继续走 emulation
|
||||
|
||||
## 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
|
||||
- 支持提取:
|
||||
- `tool`
|
||||
- `name`
|
||||
- `parameters`
|
||||
- `arguments`
|
||||
- `input`
|
||||
- 能从正文里剥离 action block
|
||||
- 支持多 block
|
||||
|
||||
验收标准:
|
||||
|
||||
- 同一回复里多个 action block 都能被解析
|
||||
- 正文和动作块可以正确拆分
|
||||
|
||||
## 6. Retry Policy
|
||||
|
||||
- 触发条件:
|
||||
- 明确要求工具调用但没产出 action block
|
||||
- 命中 refusal 文本
|
||||
- `tool_choice=any`
|
||||
- `tool_choice=tool`
|
||||
- retry 消息要更强约束:
|
||||
- 必须输出 action block
|
||||
- 不要解释
|
||||
- 必要时必须调用指定工具
|
||||
- 控制 retry 次数
|
||||
- 记录 retry 原因
|
||||
|
||||
验收标准:
|
||||
|
||||
- refusal 回复能被纠偏
|
||||
- retry 不会无限循环
|
||||
|
||||
## 7. Refusal Detection
|
||||
|
||||
- 维护 refusal 关键词表:
|
||||
- `I don't have tools`
|
||||
- `tools are unavailable`
|
||||
- `没有可用的工具`
|
||||
- `无法调用工具`
|
||||
- 识别“软拒答”:
|
||||
- 只解释、不行动
|
||||
- 强调环境限制
|
||||
- 区分:
|
||||
- 真正不该调用工具
|
||||
- 本该调用工具却在推脱
|
||||
|
||||
验收标准:
|
||||
|
||||
- 常见“我没有工具”类回复能稳定触发 retry
|
||||
|
||||
## 8. Response Re-encoding
|
||||
|
||||
- OpenAI:
|
||||
- `message.tool_calls`
|
||||
- `finish_reason = tool_calls`
|
||||
- Anthropic:
|
||||
- `content[].tool_use`
|
||||
- `stop_reason = tool_use`
|
||||
- 无工具时回普通文本
|
||||
- 文本和工具调用共存时保持协议兼容
|
||||
|
||||
验收标准:
|
||||
|
||||
- 下游客户端无需知道上游其实不支持 native tools
|
||||
|
||||
## 9. Streaming Strategy
|
||||
|
||||
- OpenAI stream:
|
||||
- 先发 role chunk
|
||||
- 再发 text delta
|
||||
- 再发 tool_calls delta
|
||||
- Anthropic stream:
|
||||
- `message_start`
|
||||
- `content_block_start`
|
||||
- `content_block_delta`
|
||||
- `content_block_stop`
|
||||
- `message_delta`
|
||||
- `message_stop`
|
||||
- 如果当前实现是“先完整拿结果再合成流”,文档里要明确说明
|
||||
|
||||
验收标准:
|
||||
|
||||
- 下游看到的流式协议字段合法
|
||||
|
||||
## 10. Multi-turn State Machine
|
||||
|
||||
- 状态至少区分:
|
||||
- 等待模型首次决策
|
||||
- 已发起工具调用
|
||||
- 等待 tool result
|
||||
- 收到 tool result,等待下一轮决策
|
||||
- 最终回答完成
|
||||
- 状态切换依据应来自消息历史,而不是只看本轮字段
|
||||
- 不要把“工具历史存在”误判成“必须再调工具”
|
||||
|
||||
验收标准:
|
||||
|
||||
- 一轮以上的 agent loop 稳定
|
||||
|
||||
## 11. Observability
|
||||
|
||||
- 打日志:
|
||||
- 是否进入 emulation
|
||||
- 解析到几个 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. 下一步优先级
|
||||
|
||||
如果当前系统已经能跑,最值得优先继续做的是:
|
||||
|
||||
1. 多轮再次发起新工具调用的 few-shot
|
||||
2. 基于历史状态的 retry 强化
|
||||
3. 更细的 refusal 分类
|
||||
4. parser 容错增强
|
||||
5. 流式工具事件细化
|
||||
Reference in New Issue
Block a user