抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

模型开启 stream=true 后,客户端能更早看到文字,接口看起来只是从一次 JSON 响应变成多次回调。实现里最常见的 bug,是每收到一个网络 chunk 就 JSON.parse,或者把每个 data: 行当成完整业务消息。

TCP/HTTP 传输分片、SSE 事件和模型增量是三层边界。它们恰好可能对齐,但协议从未保证对齐。我会先把字节流解析成完整 SSE event,再把供应商 event 归一化,最后由状态归并器构造答案。

流式响应按事件归并,不按 TCP chunk 拼字符串

模型网关第一版通常很像反向代理:统一鉴权,替换 endpoint,把 messages 转给不同供应商。真正接入多个模型后,会发现最难的不是请求字段,而是每家对流式增量、结束原因、工具调用、错误和用量的表达都不同。

如果网关只输出一套“看起来统一”的 JSON,却不保存转换前证据,线上出现空回答、工具参数残缺或 HTTP 200 后中途断流时,无法判断问题来自供应商、适配器还是客户端。我会同时保留原生协议轨和统一语义轨,两者用同一个 request ID 关联。

模型网关的双轨协议审计

OpenAI 昨天发布 Function Calling 后,模型与外部工具之间终于有了比“在文本里吐一段 JSON”更明确的接口:开发者描述函数,模型可以选择函数并生成参数。这个能力会明显降低 Agent 工具接入成本,但它解决的是参数生成,不是安全执行。

我会把模型输出叫作 tool call proposal。它必须经过协议、业务、权限和风险检查,才会变成真实调用。少了这层执行契约,JSON 越稳定,错误动作反而越容易自动落地。

Function Calling 到真实工具之间的执行契约

做 RAG 时,第一个容易陷进去的参数是 chunk_size。500 字还是 1000 字、overlap 取 50 还是 100,大家常凭几个问答效果争论。这个讨论缺少一个前提:我们希望每个 chunk 保住什么证据。

我不会先从字数出发,而是整理真实问题,为每个问题标注“最小充分证据”。切块策略能让这些证据稳定被召回,条件和结论没有被拆散,同时不带进大段无关内容,才算有效。

用问题验证切块,而不是先猜 chunk_size

把大模型接进数据平台时,我不建议第一版就让它“自动完成数据操作”。企业数据查询本身已经包含权限、成本和口径风险;再开放 INSERT、DDL 或任务发布,错误会从一条答案扩散到真实系统状态。

第一版更合适的目标是只读数据助手:根据用户权限理解问题,生成候选查询,在受控环境执行,并把 SQL、结果依据和限制交给人复核。这里的“只读”不是 Prompt 里写一句“禁止修改”,而是从身份、解析、数据库权限到运行资源的多层约束。

只读数据助手的执行隔离

把文档切块、算 embedding、写进向量索引,再接一个生成模型,几天就能搭出知识问答 Demo。这个 Demo 会让人产生一个错觉:只要相似度搜得准,企业知识库就建成了。实际运行一段时间后,问题往往不在向量库,而在知识从哪里来、何时失效、谁能看、答案引用了什么。

我把向量检索当成候选召回器。它回答的是“哪些片段在表示空间里接近这个问题”,不负责证明片段仍然有效,也不负责解决权限、冲突和业务口径。知识库是包含摄取、治理、检索、生成和反馈的一整条链路。

向量召回只是知识问答链路的一段

NL2SQL 演示很容易做出效果:准备几张表,把 schema 放进上下文,模型很快能生成一条能跑的 SQL。真正接到企业数据平台后,问题不再是“有没有 SQL”,而是这条 SQL 为什么可信。字段名写对、语法能执行,只通过了最浅的一层检查。

我把 NL2SQL 的交付物定义为“可验证查询”,不是一段字符串。除了 SQL,还要带上所用口径、对象版本、权限范围、执行计划风险和结果断言。模型负责提出候选,平台负责决定它是否有资格执行和回答。

NL2SQL 的验证边界