← 模型与 API · 第 2 篇

流式输出与结构化结果:两种不同的可靠性

理解流式事件和完整业务结果的区别,用本地 Python 示例验证结果字段,而不是把半段 JSON 当答案。

学完这一篇,你能做到

区分增量显示与最终结果校验,为拒绝、中断和字段错误设计分支。

流式输出解决“用户什么时候看到内容”,结构化输出解决“程序如何理解结果”。它们可以同时使用,但不能互相替代。

界面已经出现几个字,不代表任务已经成功。一段 JSON 的前半部分,更不能直接成为数据库更新或工具执行的依据。

先区分显示状态和业务状态

显示状态可以是等待、正在接收、已结束或中断。业务状态则可能是有结果、没有证据、明确拒绝或需要进一步执行工具。

HTTP 流中的事件边界也不等于网络数据块边界。一个事件可能被拆成多个数据块,一个数据块也可能包含多个事件。接入时使用接口支持的 SDK 或正确的 SSE 解析器。

流式结束还要看最终事件和状态。不能因为连接关闭,就默认拿到了完整答案。

JSON 结构正确,只解决一层问题

结构化输出可以让支持它的接口按照给定 schema 生成结果,但 schema 支持范围、拒绝与不完整状态仍需要查看具体文档。

结构正确不保证内容真实,也不表示请求者有权限执行结果。例如 { "amount": 100 } 是有效 JSON,却没有说明这笔操作是否被授权。

把 schema 校验、业务校验与权限检查分开。前者看字段和类型,后两者看值是否合理,以及当前用户能否进行相应操作。

本地练习最终结果校验

下面用 Python 校验一个简单契约。它不请求模型,也不解析 SSE,专门展示最终结果进入业务逻辑前的一道检查。

def validate_result(value):
    if not isinstance(value, dict):
        raise ValueError("object required")
    if set(value) != {"status", "items"}:
        raise ValueError("unexpected fields")
    if value["status"] not in {"ready", "no_evidence"}:
        raise ValueError("invalid status")
    if not isinstance(value["items"], list):
        raise ValueError("items must be a list")
    if not all(isinstance(item, str) for item in value["items"]):
        raise ValueError("items must contain strings")
    if value["status"] == "no_evidence" and value["items"]:
        raise ValueError("no_evidence must have empty items")
    return value

result = validate_result({"status": "ready", "items": ["Check sources"]})
assert result["items"] == ["Check sources"]
try:
    validate_result({"status": "no_evidence", "items": ["Made up"]})
except ValueError:
    print("Rejected inconsistent result")
else:
    raise AssertionError("invalid result accepted")

这个检查仍不能判断每条内容是否有证据。你可以继续增加来源 ID 校验,但事实核验需要相应资料与评测用例。

给中断留下明确行为

场景 界面表现 程序行为
收到增量内容 持续展示,标明生成中 只缓存,不提交业务结果
收到完整最终结果 展示完成 校验字段、语义和权限
连接中断 告知未完成 保留明确状态,允许安全重试
模型拒绝或输出不完整 解释当前无法完成 进入独立分支,不强行解析

如果任务包含外部写操作,重试整个请求可能导致重复执行。不要把“重新生成文本”和“重新执行操作”做成同一个无条件按钮。

下一步

给你的界面补上等待、接收、完成和中断四种状态。再准备三份本地数据:有效结果、字段错误、业务矛盾。

让这些输入走同一个校验入口,确认它们分别进入正确分支。完成这一步,再接入真实流式接口。

资料来源与延伸阅读

资料核验:2026-11-10。本文为原创工程讲解,教学示例不代表线上实测。