docs(tool-emulation): 添加工具调用模拟实现清单与方法论文档

- 创建英文版工具模拟实现清单,涵盖13个核心实现面
- 添加中文版工具模拟实现清单,详细说明各项验收标准
- 编写英文版工具模拟方法论文档,阐述核心实现模式
- 补充中文版方法论文档,包括多轮调用与重试策略指导
- 实现HTTP API服务器测试,验证工具历史保持功能
- 新增工具模拟核心模块,包含工具定义提取与注入功能
- 添加拒绝检测、动作块解析等关键工具模拟组件
This commit is contained in:
coolxll
2026-03-30 15:35:23 +08:00
parent eded45eb5d
commit df69105329
6 changed files with 1706 additions and 0 deletions

View 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. 流式工具事件细化