LLM 适配器:厂商协议译成 harness 词汇
Agent Loop 调用 ctx.llm.stream() 时,底下可能是 DeepSeek、OpenAI 或别的厂商,SSE 格式各不相同。DeepSeek-Harness(dsh)把「消息 / 内容块 / StreamChunk」定为提供方无关的词汇表,具体协议由适配器翻译。换厂商等于换适配器,Loop 与会话日志只认世界语。
词汇表与适配器
ctx.llm 定义 Message、Content Block(text、reasoning、tool-call、tool-result 等)和流式分片:block-start、text-delta、finish 等。适配器如 dsh-llm-deepseek、dsh-llm-pi-ai 实现同一 LlmAdapter 接口,在挂载时注册到路由表。
1 | - name: '@deepseek-ai/dsh-llm' |
1 | for await (const chunk of ctx.llm.stream({ |
每个流恰好以一个终止 finish 结束:stop、tool-calls、max-tokens,或带稳定错误码的 error / aborted。消费方按 failure.code 路由(RATE_LIMIT、NO_ADAPTER、CONTEXT_WINDOW_EXCEEDED 等),不解析消息文本。
冻结、组装与重试边界
stream() 查找路由、对照精确模型能力校验、把请求深度冻结后再委派适配器——保证「模型可见即已记录」,扩展改不了已发出的请求快照。BlockAssembler 是唯一分片组装算法:可宽容地从纯 text-delta 建 partial,已对 block-end 关闭的块再来的 delta 会被忽略。
ctx.llm 从不自己重试;一次 stream 就是一次提供方尝试。重试落在 @deepseek-ai/dsh-llm-retry,挂在 Agent 失败步骤扩展点上,策略可按厂商替换。适配器卸载时路由从注册表消失,仍是 Cordis 可逆副作用。
核心在 packages/llm/llm/:types.ts 定协议,assembler.ts 拼块,error.ts / adapter-failure.ts 归一化终止分片。模型一旦发出 tool-call,执行走 ctx.tools 的统一流水线——下一章拆那条传送带。
LLM 适配器:厂商协议译成 harness 词汇