# 风险评估、迁移路径与验收标准 > 本文档从 `9-llm-provider-unified-interface.md` 拆分而来,包含 §10 风险评估 + §11 类型差异总结 + §12 迁移路径 + §13 验收标准。 > > **相关文件:** > - [9a-background-and-architecture.md](9a-background-and-architecture.md) — 背景与架构总览 > - [9b-ir-type-system.md](9b-ir-type-system.md) — IR 类型体系 > - [9c-llm-provider-trait.md](9c-llm-provider-trait.md) — LlmProvider Trait 设计 > - [9d-provider-implementations.md](9d-provider-implementations.md) — Provider 实现策略 > - [9e-llm-cycle-and-upstream.md](9e-llm-cycle-and-upstream.md) — LlmCycle 改造与上层适配 > - [9f-edge-cases.md](9f-edge-cases.md) — 边界情况 ## 10. 风险评估 | 风险 | 等级 | 缓解措施 | |------|------|----------| | ContentField::String 与 Vec 的统一导致文本消息需要包装 | 低 | Message::user("text") 便捷函数自动包装 | | 无法完整覆盖 OpenAI 所有参数 | 中 | extra 逃生舱兜底 | | IR ↔ OpenAI 的转换有性能开销 | 低 | 纯字段映射,相对 HTTP 延迟可忽略 | | HookContext 引用类型变更影响 Hook 实现 | 中 | 影响范围小(主要为测试代码) | | LlmCycle 返回类型变化破坏上层 | 中 | 提供兼容层 + From 转换 | | compact.rs 需要适配新 Message 类型 | 低 | 核心逻辑不变,仅改类型匹配 | | 流式事件格式变化破坏现有 StreamEvent 使用者 | 中 | 影响 LlmCycle::submit_stream 的调用者(主要是测试层) | | ProviderType 枚举需要扩展 | 低 | 新增变体即可 | --- ## 11. 当前类型与 IR 的差异总结 | 当前类型 | 方案 C IR | 核心变化 | |---------|----------|---------| | `ChatRequest` (= `OpenaiChatRequest`) | `MessageRequest` | 独立类型,不绑定 OpenAI | | `ChatResponse` | `MessageResponse` | 独立类型,content 用 ContentBlock | | `OpenaiChatMessage` | `Message` | tool_calls 融入 content | | `ContentField` | `Vec` | 统一为数组,不再有 String variant | | `OpenaiContentPart` | `ContentBlock` | 新增 ToolUse/ToolResult/Thinking/Extension | | `FinishReason` | `StopReason` | 语义化(如 tool_calls → ToolUse) | | `OpenaiChatChunk` | — | 移除(StreamEvent 取代)| | `OpenaiChatResponse` | — | 不再暴露(Provider 内部使用)| | `OpenaiToolCall` | `ContentBlock::ToolUse` | 融入 content block | | `OpenaiToolDefinition` | `ToolDefinition` | 不变 | | `Usage` | `Usage` | 不变 | | `StreamEvent` | `StreamEvent` | 扩展(ThinkingDelta、MessageStart、ToolCallStart 等) | --- ## 12. 迁移路径 ### Phase 1:定义 IR 类型 + From 转换 - 新增 `src/llm/types/ir.rs`,包含完整的 IR 类型定义 - 实现 IR ↔ 现有类型的 `From`/`Into` trait - 新增 `pub type` 别名保持现有代码可编译 - ✅ 零已有代码改动 ### Phase 2:重写 LlmProvider trait - 修改 `src/llm/provider.rs`:trait 签名改为 IR 类型 - 重构 `OpenaiProvider`:内部 IR → OpenAI → IR 转换 - 新增 `chat_stream` 的 `StreamEvent` 实现 - 新增 `capabilities()` 方法 - ❌ OpenaiProvider 需重构;LlmCycle 暂时不兼容 ### Phase 3:适配 LlmCycle - LlmCycle 内部消息历史改为 `Vec` - `build_request` 改为生成 `MessageRequest` - tool 循环逻辑改为遍历 `ContentBlock` - `HookContext` 引用改为 `MessageRequest` - `compact.rs` 适配新消息类型 - ❌ LlmCycle API 变更;AgentSession 需适配 ### Phase 4:实现 AnthropicProvider + 清理 - 新增 `src/llm/provider/anthropic.rs` - 实现 IR ↔ Anthropic JSON 映射 + 流式转换 - 移除旧的 `parse_chunk_stream`、`ChunkToEventStream` - 清理不再需要的旧类型公开使用 - 补测试 --- ## 13. 验收标准 | 编号 | 标准 | 验证方式 | |------|------|----------| | A1 | `OpenaiProvider` 通过 IR trait 正常工作 | 现有测试通过 + ChatCompletion 集成测试 | | A2 | `AnthropicProvider` 通过 IR trait 正常工作 | Anthropic Messages API 集成测试 | | A3 | Tool 循环在 IR 上正确工作(在 content 中检测 ToolUse) | `submit_with_tools` 测试通过 | | A4 | 流式事件包含 ThinkingDelta 等新类型 | Provider 流式测试 | | A5 | ProviderCapabilities 正确描述 Provider 特性 | 单元测试 | | A6 | `extra` 逃生舱可传递 Provider 特有参数 | 测试各 Provider 的 extra 参数 | | A7 | 兼容层保持旧 API 可用 | 旧代码编译通过 | | A8 | `compact.rs` 在 IR 上正常工作 | 压缩测试通过 | | A9 | HookContext 使用 MessageRequest | Hook 测试通过 | | A10 | AgentSession 编译通过 | 编译检查 |