第 6 章:大模型能力接缝(LLM Seam)与流式调用
1. 本章定位
理解模型供应商协议如何被适配为 Agent Loop 可消费的统一异步流。
2. 学习目标
- 区分
LlmRuntime、LlmAdapter、PreparedLlmCall。 - 解释
llm/streamwaterfall。 - 追踪 chunk、重试、取消与最终错误。
- 找到 DeepSeek API 扩展字段的边界。
3. 前置知识
可把 Adapter 类比请求库的 transport adapter,把规范化 chunk 类比领域事件。局限是模型流只能消费一次,包含 reasoning、tool call、usage 和终态,且取消会跨越多个异步层。
4. 对应源码
packages/llm/llm/src/index.ts:158:PreparedLlmCall。packages/llm/llm/src/index.ts:193:LlmAdapter。packages/llm/llm/src/index.ts:326:LlmRuntime。packages/llm/llm/src/index.ts:380:registerAdapter()。packages/llm/llm/src/index.ts:890:prepareCall()。packages/llm/llm/src/index.ts:1051:stream()。packages/llm/deepseek-llm-api-extensions/src/types.ts:31:DeepSeek 扩展字段。
5. 工作原理
prepareCall() 解析 provider/model 并冻结本次 adapter registration;stream() 经过 waterfall,让插件包装、观测、替换或短路调用;Adapter 只处理鉴权、供应商请求和 wire chunk 规范化。是否进行 Agent 级重试由上层运行状态决定,不应塞进供应商解析器。
6. 执行流程
无图回退:Agent → prepareCall() → PreparedLlmCall → llm/stream waterfall → Adapter → DeepSeek API → 规范化 chunk → Agent → Session Log;可重试错误回到策略,最终错误写入日志。
7. 关键源码讲解
Prepared Call 防止热更新期间 adapter 选择漂移,也阻止重复消费同一流。DeepSeek 私有字段停留在扩展包与 Adapter 边界;Agent Loop 只依赖统一 chunk。新增 chunk 类型必须同步检查 assembler、Session schema、前端对话装配和快照测试。
8. 调试与观察方法
断点:prepareCall()、waterfall 前后、Adapter stream。观察 resolved provider/model、chunk 序列、AbortSignal、finish reason。分别测试首 chunk 前失败、部分 chunk 后失败、正常结束与取消。
9. 本章实践任务
用 mock adapter 产生 text、tool call、usage、error 四类流,断言每条流只有一个终态;再 abort 验证 transport 收到信号。无需真实 API Key。
10. 常见误区
- 在 Agent Loop 判断厂商字符串。
- 在 Adapter 决定整个 Turn 是否重试。
- 把每个 delta 当独立模型消息。
11. 自测题
- 为什么要有 Prepared Call?
- waterfall 可以做什么?
- 哪些重试属于 transport,哪些属于 Agent?
- 私有字段为何不能泄漏到 Agent?
- 新 chunk 类型有哪些下游消费者?