EP05. "进阶工具调用:细粒度流式输出 + 官方内建工具"
🔒 登录后可标记已读- 工具调用碰上 streaming,默认会先卡住、再一次性吐一大串文字——这是 API 在偷偷帮你校验 JSON 完整性,
fine_grained参数能关掉这层校验,换来更即时但可能不合法的 JSON 片段 - Claude 自带两个不用自己写 schema 的官方工具:Text Editor Tool(读写本地文件)和 Web Search Tool(联网搜索),但"自带 schema"不代表"自带实现"——文件操作还是要自己写
- Web Search Tool 可以用
allowed_domains把搜索结果锁定在特定网站(比如医疗类问题只搜nih.gov),避免拿到不可靠来源 - 这三个都是 [EP04](./EP04_工具调用基础.md) 工具调用基础之上的进阶用法,建议先啃完 EP04 的 schema/多轮循环概念再看这篇
- 前置知识:读过 [EP04](./EP04_工具调用基础.md),知道 tool schema、
stop_reason、多轮工具调用循环怎么运作
重点内容
细粒度工具调用(Fine-Grained Tool Calling)
默认行为的问题:工具调用配合 streaming 时,Claude 会发出 InputJsonEvent 事件,带两个属性:partial_json(这次新增的片段)和 snapshot(目前累积的完整 JSON)。但 API 默认会先在自己这边缓冲,等一个完整的顶层 key-value 对校验通过才发给你——结果就是"先卡住一下,然后一口气吐一大段文字",即使开了 streaming 体验也不够即时。
Fine-Grained Tool Calling 做的事:直接关掉 API 端的 JSON 校验,效果是:
- Claude 生成多少,立刻传多少,不等
- 顶层 key 之间不会有缓冲延迟
- streaming 的颗粒度更细、响应更快
启用方式:
run_conversation(
messages,
tools=[save_article_schema],
fine_grained=True
)
⚠️ 关掉校验的代价:Claude 有可能生成不合法的 JSON,比如 "word_count": undefined 这种 JS 式写法在 JSON 里是非法的。开了 fine_grained=True 之后,程序这边一定要做好容错:
try:
parsed_args = json.loads(chunk.snapshot)
except json.JSONDecodeError:
print("Received invalid JSON, continuing...")
什么时候该开:需要实时进度更新、需要尽快拿到部分结果去处理、或者「响应速度」比「内建校验带来的安全感」更重要的场景。
Text Editor Tool(文本编辑工具)
Claude 内建一个文本编辑工具,能做:
- 查看文件或目录内容
- 查看文件里指定范围的行
- 替换文件里的文字
- 新建文件
- 在指定行插入文字
- 撤销最近一次编辑
📌 关键认知:"schema 内建"不等于"实现内建"。Claude 知道这个工具的 schema 长什么样,但实际读写文件的函数,还是要你自己写。
⚠️ 不同 Claude 模型对应不同的 schema 版本,写死版本号之前先确认自己用的模型:
def get_text_edit_schema(model):
if model.startswith("claude-3-7-sonnet"):
return {
"type": "text_editor_20250124",
"name": "str_replace_editor",
}
elif model.startswith("claude-3-5-sonnet"):
return {
"type": "text_editor_20241022",
"name": "str_replace_editor",
}
💡 具体的完整版本号列表,官方平台文档里有,写代码前建议对照确认(course 页面本身有附链接)。
适合用在:需要程序化编辑文件的应用、开发环境里没有功能完整的代码编辑器可用、或者要把文件编辑能力直接整合进 Claude 驱动的应用里。
Web Search Tool(网页搜索工具)
Claude 内建联网搜索能力,会自动处理搜索这件事,不用自己接第三方搜索 API。
⚠️ 用之前要先去 platform.claude.com/settings/privacy 在组织的隐私设置里手动开启这个功能。
基本 schema,三个字段:
web_search_schema = {
"type": "web_search_20250305",
"name": "web_search",
"max_uses": 5
}
max_uses 限制 Claude 一次对话最多能搜几次——避免它无止境地连环搜索,同时又留了空间给它做多轮追加搜索。
回应里会出现的 block 类型:
| Block 类型 | 内容 |
|---|---|
| Text blocks | Claude 的说明文字 |
| ServerToolUseBlock | 记录 Claude 实际用的搜索关键词 |
| WebSearchToolResultBlock | 一整包搜索结果的容器 |
| WebSearchResultBlock | 单条搜索结果,含标题和 URL |
| Citation blocks | 引用来源的文字片段,附对应 URL |
限定搜索来源网站:用 allowed_domains 字段:
web_search_schema = {
"type": "web_search_20250305",
"name": "web_search",
"max_uses": 5,
"allowed_domains": ["nih.gov"]
}
📌 医疗类这种需要"证据基础"的查询特别适合这招——把结果锁定在权威网站(比如美国国家卫生研究院 nih.gov),不让 Claude 引用来路不明的内容。
适合用在:时事新闻、专业领域的最新信息、事实查核、任何需要最新数据支撑的研究型任务。
常见错误
- ❌ 开了
fine_grained=True却没处理json.JSONDecodeError——细粒度模式下 Claude 完全可能生成中途还不完整、甚至语法非法的 JSON 片段,不做 try-except 程序会直接崩 - ❌ 以为 Text Editor Tool 是开箱即用的——schema 是内建的,但真正读写文件的函数逻辑要自己实现,不写等于没有这个工具
- ❌ Text Editor Tool 的 schema 版本号跨模型照抄——
claude-3-7-sonnet和claude-3-5-sonnet对应的type字符串不一样,用错版本号工具可能直接调用失败 - ❌ 没去隐私设置里开启 Web Search,就直接在代码里传
web_searchschema——组织层级没开这个开关,工具调用不会生效 - ❌
max_uses设得太高或不设——容易让 Claude 为了一个简单问题反复搜索,浪费 API 调用和时间
Sources
官方文档:
- Building with the Claude API(Claude Academy 课程)— https://academy.claude.com/courses/building-with-the-claude-api