一句话定义
流式工具调用(Streaming Tool Calls)指模型决定调用某个工具后,把工具名和参数(通常是 JSON)一个 token 一个 token 地吐出来,客户端边接收边解析,而不用等整段参数生成完才一次性拿到。
为什么会出现“半截”
大模型的输出本来就是一个 token 一个 token 产生的。普通对话里这很自然——来一个字就把它追加到屏幕上。但工具调用的参数是有结构的 JSON,一旦按 token 切开,中间状态就很难看:{"city": "北 这样的片段随时会出现在缓冲区里,引号没闭合、括号没配平、转义字符只写了一半。
打个比方:你打电话订餐,接线员边听边往后厨报。听到“一份水煮鱼”就先让厨房备料,但必须等你说完“微辣、不要香菜”才能正式下单。中途任何一句都可能被听岔,所以厨房只能提前备料,不能提前开火。
半截 JSON 到底怎么处理
一句话:增量解析只用于预览和预热,最终必须以完整、校验通过的参数为准。
- 用容错解析器(partial / streaming JSON parser)对着缓冲区做“尽力解析”(best-effort parse):缺的引号括号先临时补上,解析成功就拿到当前已知字段,失败就退回上一个成功的快照。
- 只信任已经完整闭合的字段。
{"city": "北京"里的city可以用,还没写完的字段不能用。 - 有副作用的动作(下单、转账、删文件)必须等整段 JSON 收完、结构校验通过后才执行;预览类动作(发一次查询请求、在界面上显示“正在读取…”)可以提前做。
需要留意几个问题:JSON 字段顺序不保证,id 可能比 name 先到;数值会被切片,先来 1 后来 0,不能当成最终值;字符串里可能有转义;连工具名本身都可能分片到达。
和相邻概念的区别
| 概念 | 模型输出形态 | 客户端做什么 |
|---|---|---|
| 流式文本 | 纯文本逐字到达 | 追加显示即可 |
| 流式工具调用 | 工具名 + JSON 参数分片到达 | 增量解析、部分预览、完整后执行 |
| 一次性工具调用 | 参数生成完才整段返回 | 直接解析执行 |
它和工具调用(Tool Use / AI 词典:Function Calling">Function Calling)本身不是一回事:后者是“模型会不会用工具”的能力,前者是“参数怎么送到你手上”的传输方式。
对从业者的实际意义
对工程侧,它意味着客户端要多写一个状态机:维护缓冲区、处理解析失败回退、做幂等设计(同一请求别因为重试下两次单)。对产品侧,它直接决定“感知速度”——用户看到“正在搜索北京…”比盯着转圈好几秒要踏实得多。各家 API 对流式工具调用的支持程度和事件格式不完全一样,具体字段以官方文档为准。
