Files
agcore/design/pdd/9g-risk-and-migration.md
T
徐涛 28ca43ccb2 chore(docs): 将设计文档从 docs 移至 design 目录
将 note、pdd、prd、roadmap 四类文档分别归入 `design/` 下对应子目录中,并新增 `.gitkeep` 占位文件
2026-07-23 05:45:53 +08:00

97 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 风险评估、迁移路径与验收标准
> 本文档从 `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<ContentBlock> 的统一导致文本消息需要包装 | 低 | 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<ContentBlock>` | 统一为数组,不再有 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<Message>`
- `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 编译通过 | 编译检查 |