# LLM Provider 统一接口设计(方案 C) > 本文档已被拆分为独立的子文档以便深入推演和修改。以下保留背景与架构总览作为索引。 > > **拆分日期**:2026-06-15 > **拆分方式**:原 §1-§2 保留在本文件,§3-§13 移至 `9a`-`9g` 子文档。 > 所有"待深入推演"议题保留在对应子文档的原文位置。 --- ## 1. 背景与目标 ### 1.1 当前状态 `LlmProvider` trait 的请求/响应类型直接绑定到 OpenAI Chat Completion API 格式: ```rust pub type ChatRequest = OpenaiChatRequest; // 类型别名 pub type ChatResponse = struct { message: OpenaiChatMessage, ... }; pub type Message = OpenaiChatMessage; ``` 所有 "内部统一类型" 都是 OpenAI 格式的直接映射。这导致: | API 类型 | 兼容性 | 代价 | |----------|--------|------| | OpenAI Chat(DeepSeek、Qwen 等) | ✅ 原生兼容 | 零 | | Anthropic Messages | ❌ 语义丢失 | 需逆向映射,丢失 thinking 等特性 | | OpenAI Response API | ❌ 范式不兼容 | ChatResponse 无法表达多类型 output | | 非标自定义 API | ❌ 无扩展点 | 只能走 extra_body 逃生舱 | ### 1.2 目标 设计一套**真正与 Provider 无关的内部统一类型(IR)**,使得: 1. 所有 Provider 对外暴露的接口完全一致(统一 trait) 2. 每个 Provider 内部自行完成 IR ↔ 原生格式的映射 3. 上层(LlmCycle、AgentSession)完全感知不到具体 Provider 4. 新 Provider 只需实现一次双向映射即可接入 5. 各 API 的独有特性(thinking、内置工具等)有表达空间 ### 1.3 非目标 - 不追求覆盖所有 API 的每一个参数(90% 核心流程即可) - 不追求在不改上层代码的情况下切换 Provider(接口一致足以) - 不试图让 OpenAI Response API 的内置工具完全融入消息循环(通过逃生舱 + 可选能力 trait) --- ## 2. 架构总览 ``` ┌──────────────────────────────────────────────────────────────┐ │ 上 层(AgentSession / TaskAgent) │ │ 只与 IR 类型和 LlmProvider trait 交互 │ ├──────────────────────────────────────────────────────────────┤ │ LlmCycle │ │ 循环 / 重试 / Tool 循环 / Hook / Compact / CostTracker │ │ 内部使用 Vec + MessageRequest │ ├──────────────────────────────────────────────────────────────┤ │ LlmProvider trait(核心接口) │ │ chat(MessageRequest) → Result │ │ chat_stream(MessageRequest) → Stream │ │ capabilities() → ProviderCapabilities │ ├────────────────┬──────────────────────┬──────────────────────┤ │ OpenaiProvider │ AnthropicProvider │ DeepSeekProvider ... │ │ IR ↔ OpenAI │ IR ↔ Anthropic │ IR ↔ OpenAI 格式 │ │ JSON │ JSON │ (兼容 Chat API) │ └────────────────┴──────────────────────┴──────────────────────┘ ``` ### 2.1 分层原则 - **IR 层**:全项目唯一的内部表示,与任何具体 API 格式无关 - **Provider 层**:每个 Provider 实现 IR ↔ 原生格式的双向映射,复杂度隔离在此层 - **上层**:只与 IR 和 `LlmProvider` trait 交互,不感知具体 Provider --- ## 文件索引 ### 核心设计 | 文件 | 内容 | 包含待深入推演 | |------|------|---------------| | [9a-background-and-architecture.md](9a-background-and-architecture.md) | §1 背景与目标 + §2 架构总览 | — | | [9b-ir-type-system.md](9b-ir-type-system.md) | §3 IR 类型体系:[ContentBlock](9b-ir-type-system.md#31-contentblock--最小的内容单元)、[Message](9b-ir-type-system.md#32-message--统一消息类型)、[StopReason](9b-ir-type-system.md#33-stopreason--统一停止原因)、[MessageRequest](9b-ir-type-system.md#36-messagerequest--统一请求)、[MessageResponse](9b-ir-type-system.md#37-messageresponse--统一响应) | ToolResult 嵌套约束、extra 类型安全性 | | [9c-llm-provider-trait.md](9c-llm-provider-trait.md) | §4 LlmProvider Trait:[核心接口](9c-llm-provider-trait.md#41-核心接口)、[ProviderCapabilities](9c-llm-provider-trait.md#42-providercapabilities)、[StreamEvent](9c-llm-provider-trait.md#43-流式事件-streamevent)、[汇聚算法](9c-llm-provider-trait.md#44-partialmessageresponse--流式事件的汇聚算法) | — | | [9d-provider-implementations.md](9d-provider-implementations.md) | §5 Provider 实现:[OpenAI](9d-provider-implementations.md#51-openai-provider兼容-chat-api)、[Anthropic](9d-provider-implementations.md#52-anthropicprovidermessages-api)、[Response API](9d-provider-implementations.md#53-openai-response-api草案)、[DeepSeek/Qwen](9d-provider-implementations.md#54-deepseek--qwen-等兼容-provider-的落地策略) | OpenAI 流式转换、Anthropic 流式状态机、Response API 映射、DeepSeek/Qwen 落地 | | [9e-llm-cycle-and-upstream.md](9e-llm-cycle-and-upstream.md) | §6-§8:LlmCycle 改造(build_request、tool 循环、submit_stream、compact)+ 上层影响 + 兼容策略 | system prompt 双重表达冲突、compact 适配 | | [9f-edge-cases.md](9f-edge-cases.md) | §9 边界情况:工具定义传递、Thinking 端到端、Multiple ContentBlock、多 Choice、内置工具 | — | ### 辅助参考 | 文件 | 内容 | |------|------| | [9g-risk-and-migration.md](9g-risk-and-migration.md) | §10 风险评估 + §11 类型差异总结 + §12 迁移路径(4 Phase)+ §13 验收标准(A1-A10) | ### 待深入推演完整清单 | # | 议题 | 所在文件 | 优先级 | |---|------|---------|--------| | 1 | ToolResult 嵌套约束 | [9b-ir-type-system.md](9b-ir-type-system.md#31-contentblock--最小的内容单元) | ✅ 已推演(方案 C:运行时过滤) | | 2 | extra 的类型安全性 | [9b-ir-type-system.md](9b-ir-type-system.md#36-messagerequest--统一请求) | ✅ 已推演(方案 B:Result-based access) | | 3 | StreamEvent 汇聚为 MessageResponse 算法 | [9c-llm-provider-trait.md](9c-llm-provider-trait.md#44-partialmessageresponse--流式事件的汇聚算法) | ✅ 已推演(方案 B:显式边界 + BTreeMap 分桶) | | 4 | ToolCallStart index 归一化 | [9c-llm-provider-trait.md](9c-llm-provider-trait.md#43-流式事件-streamevent) | ✅ 已推演(自动解决,ToolCallStart 合并到 ContentBlockStart) | | 5 | OpenAI 流式转换实现 | [9d-provider-implementations.md](9d-provider-implementations.md#51-openai-provider兼容-chat-api) | ✅ 已推演(方案 A:SseByteStream 通用层 + OpenaiStreamToEvents 状态机,ToolCallEnd 依赖 finalize 兜底,忽略多 Choice) | | 6 | Anthropic 流式状态机设计 | [9d-provider-implementations.md](9d-provider-implementations.md#52-anthropicprovidermessages-api) | ✅ 已推演(轻量分发器:3 状态 + 7 种事件映射 + 零 index 映射) | | 7 | OpenAI Response API 完整映射表 | [9d-provider-implementations.md](9d-provider-implementations.md#53-openai-response-api草案) | 低 | | 8 | DeepSeek/Qwen Provider 落地策略 | [9d-provider-implementations.md](9d-provider-implementations.md#54-deepseek--qwen-等兼容-provider-的落地策略) | 低 | | 9 | system prompt 双重表达冲突 | [9e-llm-cycle-and-upstream.md](9e-llm-cycle-and-upstream.md#62-build_request--新签名) | ✅ 已推演(方案 D:移除 system 字段,IR 只留一个入口,Provider 层负责映射) | | 10 | compact 在 IR 上的改法与 token 估算 | [9e-llm-cycle-and-upstream.md](9e-llm-cycle-and-upstream.md#66-compact-逻辑调整) | ✅ 已推演(三个子议题各有方案决策 + 二维决策框架) | | 11 | Thinking signature 端到端传递 | [9f-edge-cases.md](9f-edge-cases.md#92-thinking-的端到端流程) | ✅ 已推演(方案 C:MessageComplete 兜底 + finalize 回填) |