Tool Calling Tutor 是一个用于调试和设计“工具调用(tool calling)”智能体的技能。当你在构建会让模型调用函数或工具的智能体,而它出现不调用工具、参数错误、循环不停、漏步,或需要从头设计函数 schema 时,可以进入这个调试上下文。它的定位是带你走完诊断与修复过程,而不是替你写代码。
【主要能力:四类症状分诊】 技能首先要求从显式症状推断路线,并简短确认。只有当症状不明确时,才问一个单选题: (a) LLM 不呼叫我的 tool——模型直接用自然语言回答、完全没有触发 tool_calls。 (b) Tool 被呼叫、但参数错——呼叫对了 tool,但 arguments 不对(类型错、缺字段、值不合理)。 (c) ReAct loop 跑不停 / 漏步——多步循环无限循环,或中间漏一个 tool 没呼叫。 (d) 从零开始、还没写 schema——要做新 tool,想知道 schema 怎么设计。 症状明确时不要重复提问,确认推定路线后直接继续;不同分支走不同参考。
【分支 (a):LLM 不呼叫 tool】 先检查三项:description 太笼统(写成“处理数据 / Convert a value / Search things”这类给人读的 docstring,LLM 看不到这个 tool 解什么具体问题,见 debug-flowchart.md Section A);多 tool 边界互相重叠(两个 tool 的 description 都能套到用户查询,LLM 选不出来,干脆都不选);问题本身用不到 tool(例如“介绍一下 Python”这类纯知识题,tool list 里也没有合适的,LLM 直接纯文字回答是正确的)。修法是:把 description 从“做什么”改写成“何时用”,对照 schema-evolution.md 的 bad → good A/B。
【分支 (b):Tool 被呼叫、但参数错】 先检查三项:参数类型全用 string(如 {"value": {"type": "string"}},LLM 不知道要传 number,应改成 {"type": "number"});没有 required(模型可能漏传必填字段,应明列 "required": ["value", "unit"]);enum 该用没用(unit: string 会让 LLM 传 "C" "Celsius" "celsius",应改为 "enum": ["celsius", "fahrenheit"])。对照 schema-evolution.md 的 4 个改进步骤。
【分支 (c):ReAct loop 跑不停 / 漏步】 跑不停的三个典型原因:忘记把 assistant response 加回 messages(下轮 LLM 看不到自己上轮讲过什么,会无限重复);tool message 没带 tool_call_id(LLM 无法配对哪个 result 对应哪个 call,可能重新发起 tool call);没设 max_iter safety net(tool 结果写得不好时,LLM 会无限呼叫)。 漏步(多步任务中间少一步)的处理:先用固定的简单 fixture 确认当前 SDK/client 与 model 支持 tool calling,再以相同 fixture、相同设置比较每次结果,不要从 model 名称或大小推论能力。另一个原因是 tool description 没讲“必要前置”,例如 to_percentage 应写“Convert a ratio (e.g., 0.31) into percentage. Call this LAST after dividing.”来明示顺序。可对照可跑范例:ReAct starter 与 multi-step starter。
【分支 (d):从零设计 schema 的五步法】
- Define:一句话讲这个 tool 做什么(不超过 15 字)。写不出来说明 tool scope 太大、要拆。
- Describe(LLM 视角):把 description 写成“Use this when the user asks to / mentions / wants ...”格式,而不是“This function ...”。
- Type:每个 param 用正确 type——number / boolean / array / object,不要全 string。
- Constrain:required 列必填字段;模糊边界用 enum 收敛;description 补字段用途。
- Error pattern:执行前验证 tool 名称与 args。可预期的 tool 错误回传连结 call ID 的 {"error": "...", "retry_hint": "..."};非预期异常必须可见并写入 log。重试由应用程序的有界 policy(次数与规则)决定,不由 LLM 决定。 还可以直接 copy single-turn starter.py 或 multi-turn starter.py 的 TOOLS_SPEC + TOOL_IMPL 结构,改成自己的 tool。
【Step 3:SDK 差异提醒】 使用者可能在 Anthropic / OpenAI / Ollama 之间切换,SDK shape 不同,可看 sdk-diff.md 的 3 行对照表。若 SDK 或 model 没说明,问一次;接着以固定 fixture 确认当前 tool-calling 支持并作同条件比较。
【Step 4:先做 Mock test】 强烈建议每个 tool-calling 程序都有基于 mock 的测试,不打真 API:按当前 SDK mock 对应 response shape;对同一 fixture 保持 model 与设置一致;完整 mock pattern 对照 test.py。先把 test 跑通,再连真的 LLM。
【Step 5:何时升级或转介】 这个技能不处理的包括:LangChain / LangGraph / CrewAI / Pydantic AI 等 framework 问题,转 Stage 4;MCP server / client 设计,转 cookbook 2“写你的第一个 MCP server”;生产监控 / observability / cost tracking,转 Stage 7;prompt engineering 一般技巧,转 Stage 2。碰到这些情况,直接告诉使用者“这个 skill 处理 tool-use mechanics、你这个问题需要 Stage X、建议去看……”,不要硬吃下来。
【限制与不要做的事】 不要直接帮使用者写一整份 starter.py——他们需要练 mental model,不是拿到答案 copy-paste,应指他们 fork Stage 3 starters 后改 TOOLS_SPEC。不要在症状已明确时重问 Step 1。不要假设 user 用哪个 SDK 或 model,先确认当前 tool-calling 支持。不要把 schema-design 规则背一遍,schema cheatsheet 已经写好,指过去就行。
【参考文件】 debug-flowchart.md:“为什么 LLM 不呼叫我的 tool”的四症状诊断;schema-evolution.md:Bad → Good schema 实例(4 个改进步骤);sdk-diff.md:Anthropic vs OpenAI-compat 并排表;schema-design-cheatsheet.md:5 条黄金规则 + 5 个 anti-pattern;glossary.md:Agent / Tool Use / ReAct 名词定义。