有时候你根本不想真的调工具。你只是想让模型输出一段结构化的 JSON,带着特定的字段和类型。最靠谱的办法?定义一个”虚拟工具”,强制模型去调用它。
怎么运作
- 定义一个工具,
input_schema描述你想要的精确 JSON 结构。 - 用
tool_choice强制指定这个工具:{"type": "tool", "name": "extract_data"}。 - 模型”调用”这个工具,生成符合你 schema 的参数。
- 你忽略工具调用机制本身,直接拿
input字段当结构化输出用。
这个工具永远不会被执行。背后没有真实的函数。你只是借用 tool_use 的机制来做结构化输出。
为什么比在 prompt 里要求 JSON 更好
在 prompt 里让模型”用 JSON 格式回复”是不可靠的。模型可能用 markdown 代码块包一层,在 JSON 前面加解释文字,用略有不同的字段名,或者偶尔产出无效 JSON。
强制 tool_use 把这些问题全消灭了。input 字段保证是符合你定义的 schema 的合法 JSON——类型正确、必填字段齐全、结构完整。Schema 就是契约。
结构有保证,值没有
这是关键区别。带 schema 的 tool_use 保证的是结构正确:合法 JSON、类型对、必填字段都在。它不保证语义正确:值可能是错的,加总可能对不上,日期顺序可能乱。
如果你的 schema 说 amount 是 number,你一定会拿到一个 number。但它可能是个错误的 number。结构校验和语义校验是两回事。生产系统里两个都得有。
在 API 看来,没有区别
“真”工具调用和用于结构化输出的”虚拟”工具在技术上毫无区别。同样的定义格式、同样的 tool_use 响应、什么都一样。区别纯粹在你的应用层:你是拿参数去执行什么,还是直接当数据消费?
一句话总结: 强制调用虚拟工具可以拿到保证符合 schema 的 JSON——但别忘了,结构正确不等于值也对。