流式、结构化输出与工具执行
一条响应有展示状态与业务状态
收到文字可以刷新界面;收到最终完成事件才能冻结响应;通过 schema、业务和权限检查后才可提交结果。TCP/HTTP 流关闭只表示传输结束,可能是断线。若把“没有更多数据”解释为成功,截断 JSON 也会被提交。
下面是应用事件归一化的纯本地实验,不声称模拟真实供应商流。Python 3.12 保存 events.py 运行:
def consume(events):
draft='';done=False
for e in events:
if done:raise ValueError('event after terminal')
if e['type']=='delta':draft+=e['text']
elif e['type']=='complete':done=True
elif e['type']=='failed':raise RuntimeError('provider failed')
else:raise ValueError('unknown event')
return {'draft':draft,'committable':done}
assert consume([{'type':'delta','text':'hello'}])['committable'] is False
assert consume([{'type':'delta','text':'hello'},{'type':'complete'}])['committable'] is True
print('terminal boundary passed')归一化适配器将各平台事件映射为内部事件,同时保留原事件类型与 provider request ID。未知工具事件不能当作普通文本丢弃。取消后前端不能再接受旧请求的迟到结果;用业务 generation ID 判断结果仍属于当前页面。
JSON 合法为何仍可能错误
语法层解析字符串;结构层验证类型、必填和额外字段;业务层检查范围、对象存在与跨字段约束。例如 {"quantity":-2} 可是合法 JSON、合法整数 schema,却不满足正数量订单。null 与缺键应有独立含义,拒绝与截断是失败状态而非“空 JSON”。
流式 JSON 先累积,完整后再解析。可以用容错部分解析器显示草稿,但不要把草稿传进写库。原生结构化生成减少格式失败,不替代真实性核查和鉴权。详情在结构化契约。
从模型意图到服务端能力
工具声明含名称、用途、参数 schema 与结果形状。模型返回名称与参数,应用通过白名单找到函数,校验参数,取得服务端身份,检查资源权限,最后执行。MCP 负责发现与传输这些工具,它既不替模型决定何时调用,也不自动授权业务动作。
查询失败可重试,写入要有业务幂等键,删除或付款需要按产品策略确认。确认记录必须绑定具体资源、参数与有效期;用户确认 A 后模型改成 B,不能继承旧授权。循环预算同时约束步骤、时间和费用,重复相同参数且无新证据时停止。
仅复制 call ID 不保证业务幂等。模型重试可能生成新 call ID,而实际业务目标相同。业务键需要从订单意图产生,并在数据库与副作用提交一起约束。单机内存集合在重启后会丢失,不能作为生产支付防重。
练习
向事件列表追加 complete 后的 delta,要求抛出 ValueError。另构造空事件列表,确认它不允许提交。
先记录自己的输出与解释,再核对本章答案。