# AG Core Roadmap — v0.2.0 > 本文件聚焦 **v0.2.0 版本** 的规划与交付(Phase 5–12)。已打 `v0.2.0-rc.1` 标签。 > 返回总入口:[`roadmap.md`](./roadmap.md) ## v0.2.0 愿景 从"LLM 调用工具箱"升级为"生产可用的 Agent 服务"。解决 Rust Agent 工具箱从"能跑"到"能被人依赖"的鸿沟——持久化、配置层、上下文管理三大块补齐后,开发者可在 30 分钟内写出生产可用的 Agent 服务。 ## v0.2.0 总体范围 **总体规模**:8 个增量 Phase(Phase 5–12),17 个可验证 Step,约 2000+ 行新增代码,测试 182 → 277+。 --- ## v0.2.0 — 生产就绪(Production-Ready Core) **目标**:解决 Rust Agent 工具箱从"能跑"到"能被人依赖"的鸿沟。持久化、配置层、上下文管理三大块补齐后,开发者可在 30 分钟内写出生产可用的 Agent 服务。 **总体规模**:8 个增量 Phase(Phase 5-12),17 个可验证 Step。 ### 功能清单 #### P0 — 必须交付 | # | 功能 | 模块 | 方案要点 | |---|------|------|---------| | 1 | SqliteStore | `memory` | `rusqlite` + `bundled` feature,`MemoryStore` 的 SQLite 实现,进程重启数据不丢 | | 2 | ProviderConfig 扩展 + `from_env()` | `llm` | 补全 `timeout_secs` / `max_retries` 字段;`AG_LLM_*` 环境变量辅助函数 | | 3 | ToolDefinition IR 正式化 | `tools` | 移除 deprecated OpenAI wire 格式,替换为自定义 `ToolDef` 结构体 | | 4 | API 稳定性管理 | `*` | 公开枚举加 `#[non_exhaustive]`;CHANGELOG 记录 Breaking Changes;废弃 API 用 `#[deprecated]` 标记 | | 5 | Quick Start + 端到端示例 | `examples/` | 30 行 `main.rs` 快速开始;一个"SQLite 持久化 + Provider + 工具调用 + 多轮对话"的可运行示例(`cargo run --example`) | #### P1 — 重要但不阻塞 | # | 功能 | 模块 | 方案要点 | |---|------|------|---------| | 6 | Ollama Provider | `llm/provider` | OpenAI Compat,本地 LLM 支持,实现量极小 | | 7 | VectorRetriever trait | `memory` | 语义检索 trait 抽象(`index` / `search`),不绑定后端实现 | | 8 | 流式 `submit_turn_stream` | `agent` | `AgentSession` 新增 `submit_turn_stream()`,返回 `Stream` | | 9 | 测试补强 | `*` | wiremock Provider roundtrip 测试;多线程并发写入 MemoryStore 测试 | #### P2 — 有时间再做 | # | 功能 | 模块 | 备注 | |---|------|------|------| | 10 | MCP StreamableHttp | `tools` | 当前仅预留枚举变体 | | 11 | Gemini Provider | `llm/provider` | 协议差异大,实现成本较高 | | 12 | 文件系统 MemoryStore 后端 | `memory` | JSON/JSONL 轻量持久化 | ### ContextSlot 上下文管理 **模块归属**:`src/llm/context.rs`(与 `compact.rs` 同级) **核心概念**:`ContextSlot` 是一段带策略配置的消息列表,以 `slot_id` 为 namespace 独立持久化到 `MemoryStore`。支持三种模式、三种来源和派生关联(记录 `parent_id`)。 **核心类型**: ```rust pub struct ContextSlot { id, session_id, config, messages, store } pub struct SlotConfig { mode: SlotMode, source: SlotSource, budget, compact } pub enum SlotMode { Full, // 完整对话历史 Focused(FocusedConfig), // 聚焦:保持 LLM 注意力 Readonly, // 只读参考上下文 } pub struct FocusedConfig { keep_system, recent_turns, inject_summary } pub enum SlotSource { New, // 全新空槽,独立持久化 Derived { parent_id, strategy: DeriveStrategy }, // 从父 slot 派生 Static(Vec), // 预置消息,不持久化 } pub enum DeriveStrategy { Full, Focused(FocusedConfig) } pub struct ContextBudget { system, history, tools, tool_results, reserve } ``` **持久化 Key 命名**: - `slot_msg:{session_id}:{slot_id}:{index}` → 消息内容 - `slot_meta:{session_id}:{slot_id}` → `SlotMeta`(含 `parent_id`) - `slot_rel:{session_id}:{child_id}:parent` → `"{parent_id}"` **`AgentSession` 扩展**: - `create_slot(id, config)` — 创建新 slot - `switch_slot(id)` — 切换当前 slot - `list_slots()` — 列出所有 slot - `derive_slot(id, parent_id, strategy)` — 从父 slot 派生 **与 `ConversationMemory` 的关系**:保留不废除。`ConversationMemory` 继续服务传统对话场景。 **v0.2 不做**: - ❌ `slot.fork()` / `merge()` — 分支方法推迟到 v0.3+ - ❌ `inject_summary` 自动生成 — v0.2 仅消费端(从 `SessionMemory` 读取),生成在 v0.3+ - ❌ 血缘关系图遍历 — 只存 `parent_id`,不做查询 **依赖**:Phase 0(MemoryStore trait)、Phase 3(MemoryStore 持久化) **优先级**:P1 --- ### v0.2.0 实施计划 — 8 个增量 Phase > **编号说明**:Phase 5-12 接续 v0.1 的 Phase 0-4c,按开发顺序排列。 #### Phase 5: 热身准备(Warmup) **目标**:快速交付三个互不依赖的独立改动,建立交付节奏。 | Step | 内容 | 文件范围 | 验证标准 | |------|------|---------|---------| | **5.1** ✅ | `ProviderConfig` 扩展:补 `timeout_secs`(def=30) + `max_retries`(def=3);新增 `ProviderConfig::from_env(prefix)` | `llm/provider.rs` + 各 Provider `new()` 构造函数 | `cargo test` + `from_env()` 单元测试 | | **5.2** ✅ | `OllamaProvider`:基于 `GenericOpenaiProvider` 包装,改 base_url 为 `http://localhost:11434`;`ProviderType` 新增 `Ollama` | `llm/provider/provider.rs` + `llm/provider/ollama.rs`(新增) | `cargo build` — 纯类型级验证 | | **5.3** ✅ | 公开枚举 `#[non_exhaustive]` 前置标记:`ProviderType` / `StopReason` / `FinishReason` / `EvictionPolicy` / `SlotMode`(预置) | 各枚举定义处 | 编译通过 + `cargo clippy` 0 警告 | **实际新增**(2026-07-05 commit `98dfe6c`): - 新增文件 1 个(`llm/provider/ollama.rs`,72 行) - 修改文件 2 个(`llm/provider.rs` 加 `from_env` + `Default` + 4 个字段;`memory/store.rs` EvictionPolicy 加 `#[non_exhaustive]`) - `ProviderType::Ollama` 变体 + `FromStr` 解析("ollama" → Ollama) - `OllamaProvider::new(base_url, api_key, model, timeout_secs)` + `with_client()` 构造函数 - `ProviderConfig::from_env(prefix)` 解析 `{prefix}_API_KEY` / `{prefix}_BASE_URL` / `{prefix}_MODEL` 环境变量 - 全量测试 182 → 190(+8,phase 5 新增 from_env 与 Ollama 相关单测) - clippy 0 警告 **依赖**:无(三个 Step 互不冲突) **优先级**:P0(5.1)+ P1(5.2)+ P0 前置(5.3) **为何独立成 Phase**:三个改动零文件重叠,可以并行推进。它们是后续所有 Phase 的"门把手"——先做完热身再进入核心工作。 **状态**:✅ Phase 5 全部交付物已完成 --- #### Phase 6: ToolDefinition IR 正式化 **目标**:引入 `ToolDef` 新类型,替换已标记 `#[deprecated]` 的 `ToolDefinition`(`OpenaiToolDefinition` 别名)。 **这是 v0.2 技术风险最高的 Phase**,影响 4 个模块约 8 个文件。通过 5 个 Step 逐文件切割确保每步可编译。 | Step | 内容 | 验证标准 | |------|------|---------| | **6.1** ✅ | `types/tool.rs` 新增 `ToolDef` 结构体 + `From for OpenaiToolDefinition` + 反向 `From` | 单元测试 roundtrip | | **6.2** ✅ | `types/mod.rs` 切别名 `pub type ToolDefinition = ToolDef`;`MessageRequest.tools` 改 `Vec` | `cargo build` 编译断点 | | **6.3** ✅ | `cycle.rs` 4 个方法签名 + `registry.rs` `definitions()` 签名更新 | `cargo build` | | **6.4** ✅ | Provider 适配层(openai.rs / anthropic.rs / openai_compat.rs):`build_request()` 内做 `ToolDef → wire-format` 转换 | `cargo test` 每个 provider 测试 | | **6.5** ✅ | 所有测试/示例中 `ToolDefinition` → `ToolDef` 修复;移除旧 `#[deprecated]` alias | `cargo test --all-targets` 全绿 | **边界切割技巧**: - Step 6.1 → 6.2 之间是安全 checkpoint:新类型存在但旧代码照常编译 - Provider 层不改序列化逻辑,只加一层 `From` 转换 - 当前代码中 `ToolDefinition` 已是 `#[deprecated(since = "0.1.0")]`,用户已有迁移预期 **依赖**:无(仅与 Phase 5.3 有枚举兼容关系) **优先级**:P0 **实际新增**(2026-07-05 commit `4cf5918` / `9da9b83` / `b187519`,详见 `docs/13-phase6-tooldef-ir.md`): - 修改文件 8 个:`llm/types/tool.rs`、`llm/types/mod.rs`、`llm/types/request_v2.rs`、`llm/cycle.rs`、`llm/provider/openai.rs`、`tools/registry.rs`、`tools/mcp.rs`、`agent/agent.rs` - `ToolDef` IR(name / description / parameters,无 `strict`)新增于 `types/tool.rs`,配套双向 `From` 转换 - `OpenaiToolDefinition` 降级为 `#[doc(hidden)]`,仅供 OpenAI 适配层内部消费 - `MessageRequest.tools` 切换为 `Vec` - `ToolDefinition` 别名最终完全移除(直接使用 `ToolDef`) - 4 处 `#[allow(deprecated)]` 抑制点全部清理(cycle/registry/mcp/agent);残留 `#[allow(deprecated)]` 均与 `ChatResponse` / `with_system_prompt` 等其他弃用项无关 - 新增 roundtrip 测试 `message_request_with_tools_roundtrip`(断言 `strict` 字段不泄漏到序列化输出) - Anthropic 适配层字段名一致零改动;openai_compat/ollama 委托 `GenericOpenaiProvider` 零改动 - 全量测试 190 → 191(+1,Phase 6 新增 roundtrip);clippy 0 警告 **状态**:✅ Phase 6 全部交付物已完成 --- #### Phase 7: SqliteStore 持久化 **目标**:实现 `MemoryStore` 的 SQLite 后端,进程重启数据不丢。 **与 Phase 6 无耦合,可重叠开发。** | Step | 内容 | 文件 | 验证标准 | |------|------|-----|---------| | **7.1** ✅ | 新增 `memory/store/sqlite.rs`:`Mutex` + `spawn_blocking`,实现 `save/get/delete/list` + prefix 过滤 | `memory/store/sqlite.rs` + `Cargo.toml`(add `rusqlite`) | 单元测试 CRUD + prefix 查询 | | **7.2** ✅ | WAL 模式 + 并发安全 + 集成测试(`tokio::spawn` 10 个并发 task) | `sqlite.rs` 扩展 | 并发写入 100 轮无 race | **设计决策**: - 用 `Mutex` 而非连接池(ponytail:一个连接够用就不加 r2d2) - WAL 模式:`PRAGMA journal_mode=WAL` 解决读写锁 **依赖**:`MemoryStore` trait(v0.1 Phase 3 已就绪) **优先级**:P0 **实际新增**(2026-07-05 commit `13edacd` / `c8a91f6` / `c82af60`,详见 `docs/14-phase7-sqlite-store.md`): - 方案文档:`docs/14-phase7-sqlite-store.md`(526 行,Phase 7 设计推演与权衡记录) - 结构重组:`src/memory/store.rs` 单体文件 → `src/memory/store/{mod.rs(in_memory.rs, sqlite_store.rs)}` 模块目录;外部导入路径 `crate::memory::store::MemoryStore` 不变 - 新增文件 2 个:`src/memory/store/sqlite_store.rs`(545 行 SqliteStore 实现 + 9 个内联测试)、`src/memory/store/in_memory.rs`(266 行,结构搬移) - 核心实现要点: - `Arc>` 串行化所有 IO;`spawn_blocking` 卸载到阻塞线程池 - WAL 模式 + `synchronous=NORMAL` + `busy_timeout=5s` + `wal_autocheckpoint=1000` - `PRAGMA user_version` schema 版本管理(`INITIAL_USER_VERSION = 1`) - `created_at` 归一化为 UTC 的 RFC 3339 TEXT,字典序等价时间序 - 错误精细映射:`SqliteFailure` / `InvalidQuery` → `InvalidInput`;`FromSqlConversionFailure` → `Serialization`;其他 → `Storage` - 9 个内联测试覆盖:CRUD、upsert、prefix / since / offset+limit 过滤、10 写者 × 10 次并发写入、持久化 round-trip(重启连接不丢数据)、`InMemoryStore ↔ SqliteStore` trait-box 互换兼容性 - 依赖:`rusqlite = { version = "0.32", features = ["bundled"] }`;`time` 增补 `parsing` / `formatting` / `macros` features;`dev-dependencies` 新增 `tempfile = "3"` - 全量测试 191 → 200(+9,Phase 7 新增 SqliteStore 单测);clippy 0 警告 **状态**:✅ Phase 7 全部交付物已完成 --- #### Phase 8: MVP 集成出口(v0.2.0-rc.1 候选) **目标**:P0 五项全部交付。开发者 clone 仓库后 10 分钟跑起持久化 Agent。 | Step | 内容 | 验证标准 | |------|------|---------| | **8.1** ✅ | API 稳定性扫尾:`#[non_exhaustive]` × 14 公开枚举 + `StepStatus::Completed` 切 `MessageResponse` + CHANGELOG v0.2.0-rc.1 + Cargo.toml 0.2.0-rc.1 | `cargo doc --no-deps` 0 warning + 零 deprecated warning | | **8.2** ✅ | Quick Start 示例(57 行 `main.rs`):MockProvider + EchoTool + submit_turn 真实工具调用 | `cargo run --example quick_start` exit 0 | | **8.3** ✅ | 端到端示例:SqliteStore + AG_LLM_* from_env 自动检测 + 3 工具 + 3 轮对话 + 持久化跨连接验证 | `cargo run --example end_to_end`(Mock fallback,无需 API key)| **Phase 8 全部完成**。**已打 `v0.2.0-rc.1` 标签**。 **实际新增**(2026-07-05,7 commits): - `feat(core)` —— 14 个公开枚举追加 `#[non_exhaustive]`(P0 核心 IR + P0 Error + P1 其他) - `refactor(agent)` —— `StepStatus::Completed(ChatResponse)` → `Completed(MessageResponse)` + `task_agent_demo.rs` 清理 3 处废弃类型 - `docs` —— CHANGELOG v0.2.0-rc.1 条目 + Cargo.toml version 0.1.0 → 0.2.0-rc.1 + README 示例列表 7 → 10 - `test(core)` —— 验证 commit 1-3 零回归(test 200 passed + clippy 0 警告 + doc 0 warning) - `feat(examples)` —— `quick_start.rs`(60 行)+ `end_to_end.rs`(246 行) - `docs(roadmap)` —— 标记 Phase 8 全部完成 + M4 里程碑 ✅ - `fix(examples)` —— 实施后 PM/SA/Code Reviewer 三方审查发现 6 项问题(🔴 CalcTool 除零 panic + 🟡 drop 注释准确性 + 🟡 EchoTool 错误处理 + 💭 断言一致性 + 💭 工具两端语义统一 + 💭 trailing newline),全部修复 **依赖**:Phase 5(ProviderConfig from_env)+ Phase 6(ToolDef)+ Phase 7(SqliteStore) **优先级**:P0 **状态**:✅ Phase 8 全部交付物已完成 --- #### Phase 9: 流式体验增强 **目标**:Agent 会话支持流式输出,开发者看到实时 token。 | Step | 内容 | 文件 | 验证标准 | |------|------|-----|---------| | **9.1** ✅ | `AgentSession::submit_turn_stream(user_input) -> impl Stream` | `agent/session.rs` | 单元测试验证流事件序列:`TextDelta → ... → MessageComplete` | **注意**:tool 自动循环时流中插入 `ToolExecutionStarted` 事件,用户端 UI 显示"正在调用工具..."。 **依赖**:Phase 6(ToolDef)+ `LlmProvider.chat_stream`(v0.1 已有) **优先级**:P1 **实际新增**(2026-07-06 commit `212cfcc`,详见 `docs/16-phase9-streaming-experience.md`): - 方案文档:`docs/16-phase9-streaming-experience.md`(821 行,含状态机设计推演与边界情况) - 修改文件 3 个:`src/agent/session.rs`(+208,含 `submit_turn_stream` / `finalize_turn`)、`src/llm/cycle.rs`(+784,含 `submit_with_tools_stream` / `run_tool_loop` spawn + mpsc 状态机)、`src/llm/types/response_v2.rs`(+21,含 `StreamEvent::ToolExecutionStarted`/`Completed` 变体 + `apply_to` 元事件) - 关键设计:`CycleConfig` 加 `Clone` derive 以支持 spawn 跨 task;`finalize_turn` 手动同步状态(`submit_turn_stream` 返回流前不落库,避免半成品被 hook 误读) - 测试:新增 9 个单元测试 + 2 个集成测试(含 `submit_turn_stream_end_to_end` 端到端 mock provider 流消费 + `submit_turn_stream_triggers_turn_hooks` Hook 触发验证),全量 200 → 211(+11,0 失败) - clippy 0 警告 - 无新增外部依赖 **状态**:✅ Phase 9 全部交付物已完成 --- #### Phase 10: ContextSlot 上下文管理 **目标**:支持多上下文分区管理,Agent 可在不同 slot 之间切换。 | Step | 内容 | 验证标准 | |------|------|---------| | **10.1** ✅ | `src/agent/context.rs`:`ContextSlot` + `SlotConfig` / `SlotMode` / `FocusedConfig` / `SlotSource` / `DeriveStrategy` / `ContextBudget` / `SlotMeta` 核心类型 | `cargo build --all-targets` | | **10.2** ✅ | ContextSlot 持久化:基于 `MemoryStore` trait(不绑定 SqliteStore)实现 save/load/list/delete + slot 命名空间 key 策略 + `load_messages()` Focused 读时过滤 + `append_messages()` Readonly 阻断 + colon 注入防护 | 单元测试:持久化 roundtrip / session 隔离 / Focused 边界 / delete 保护 / 派生 / load_messages() | | **10.3** ✅ | `AgentSession` 扩展:`create_slot` / `switch_slot` / `list_slots` / `derive_slot` / `delete_slot` + `new()` 自动创建 `"default"` slot + `submit_turn`/`finalize_turn` 改造为基于当前 slot 的增量追加写回 + 新示例 `context_slot_demo` | 集成测试 + `cargo run --example context_slot_demo` exit 0 | **如何保证简单场景无感**:`AgentSession::new()` 内部检查,自动创建 `"default"` slot → `submit_turn` 默认写到 default slot。 **实际新增**(2026-07-07 commit `6359422`,详见 `docs/17-phase10-contextslot.md`): - 方案文档:`docs/17-phase10-contextslot.md`(1227 行,含 §5 推荐方案、§6 实施建议、§9 实施计划,经过 4 轮方案/计划/实施审查 + 1 轮非阻塞建议修复) - 新增文件 3 个:`src/agent/context.rs`(~430 行 ContextSlot 核心类型 + 持久化方法 + 22 个测试)、`src/agent/context.rs` 中的 `ContextSlot::filter_focused` 静态方法(被 `load_messages` 和 `derive_slot` 复用,消除代码重复)、`examples/context_slot_demo.rs`(~160 行分支对话示例:法律咨询 → 派生两个方向 → 切换 → 隔离验证 → 删除保护) - 修改文件 3 个:`src/agent.rs`(+5 行 module 声明 + re-export)、`src/agent/error.rs`(+56 行:3 个新变体 `SlotReadonly`/`SlotNotFound`/`SlotAlreadyExists` + 4 个测试)、`src/agent/session.rs`(+825/-197 行:slots 字段 + 6 个管理方法 + submit_turn/finalize_turn 改造 + 17 个测试) - 关键设计: - **模块归属**:`agent/context.rs`(零新依赖方向,遵循 `agent → memory` 已有依赖) - **持久化**:JSON blob 批次存储,每 slot 3-4 条 `MemoryItem`(`slot_data` / `slot_meta` / `slot_config` / `slot_rel`) - **submit_turn 签名不变**:方案 A(内部 `current_slot_id` 状态),向后兼容 - **Focused 模式读时过滤**:`load_messages() -> Vec`,避免 Rust 借用检查问题 - **增量追加写回**:`cycle.messages()[input_len..]` 提取本轮新增消息,确保 Focused 模式数据不丢失 - **delete_slot 双重保护**:禁止删 `"default"` + 至少保留一个 slot - **colon 注入防护**:`assert_no_colon` 在 key 构造时 panic - **错误传播**:`serde_json` / `MemoryStore` 所有错误用 `?` 传播,无静默吞掉 - 验证:211 → 254 测试(+43 新测试),clippy 0 警告,doc 0 warning,10 + 1 示例全部 exit 0 - finalize_turn 签名变更(破坏性):新增 `new_messages_from_cycle: Vec` 参数,返回从 `()` 改为 `Result<(), AgentError>`——影响 Phase 9 的 `submit_turn_stream_triggers_turn_hooks` 和 `submit_turn_stream_end_to_end` 2 个测试,已适配 **依赖**:Phase 5(`#[non_exhaustive]` 预置 SlotMode 等枚举)、Phase 7(SqliteStore 推荐持久化后端;`MemoryStore` trait 即可) **优先级**:P1 **状态**:✅ Phase 10 全部交付物已完成 --- #### Phase 11: 测试与检索补强 **目标**:补全测试覆盖 + 语义检索抽象。 | Step | 内容 | 验证标准 | |------|------|---------| | **11.1** ✅ | `VectorRetriever` trait:`index(id, embeddings)` + `search(query, k)` | 编译 + mock 测试 | | **11.2** ✅ | wiremock Provider roundtrip 测试:模拟 OpenAI/Anthropic HTTP 端点 | `cargo test` 新增 10+ roundtrip 测试 | | **11.3** ✅ | 并发测试补强:InMemoryStore + SqliteStore 多线程写入验证 | 跑 100 轮无 race | **实际新增**(2026-07-06 commit `71abe88` / `b4e5c7d`,详见 `docs/18-phase11-testing-and-retrieval.md`): - 方案文档:`docs/18-phase11-testing-and-retrieval.md`(647 行,含 11.1/11.2/11.3 设计 + 10 项架构决策 + 实施后补充 2 条偏差记录 #6 mid-stream mock 模式 + #7 429 retry-after 修复) - 新增文件 1 个:`src/memory/vector.rs`(237 行 — `VectorRetriever` trait + `InMemoryVectorRetriever` 引用实现 + `dot()` 零依赖 + 6 个内联测试) - 修改文件 5 个: - `src/memory.rs`(+2 行:module 声明 + re-export) - `src/llm/provider/openai.rs`(+8 wiremock 测试 + `handle_error_response` 429 retry-after 解析修复 5 行) - `src/llm/provider/anthropic.rs`(+4 wiremock 测试) - `src/memory/store/in_memory.rs`(+3 并发测试:100 并发写、5 写+5 读混合、15 写者容量淘汰) - `src/memory/store/sqlite_store.rs`(+2 并发测试:100 并发写、5 写+5 读混合) - 关键设计: - **零依赖 dot()**:手写点积/范数,零新增 crate 依赖 - **Wiremock 测试自包含**:每个测试独立 `MockServer::start()`,沿用现有模式 - **429 retry-after 修复**:`openai.rs` 与 `anthropic.rs` 行为对齐(5 行代码) - **偏差记录**:方案文档「已否决的方案 #6/#7」记录两处实施偏差,便于后续审计追溯 - 验证:254 → 277 测试(+23 个新测试),clippy 0 警告,doc 0 warning;并发测试连续 3 次运行稳定无 flaky - **依赖**:无(与方案一致) - **状态**:✅ Phase 11 全部交付物已完成 --- #### Phase 12: P2 锦上添花(可选) **目标**:时间允许时按优先级交付。 | 优先级 | 功能 | 实现量估计 | 备注 | |--------|------|-----------|------| | **12.1** | 文件系统 MemoryStore(JSON/JSONL) | ~80 行 | 最简单,适合练手 | | **12.2** | MCP StreamableHttp 传输 | ~150 行 | 协议还在演进 | | **12.3** | Gemini Provider | ~300 行 | 协议差异大,建议推迟到 v0.3 | **依赖**:无(独立交付) --- ### v0.2.0 Phase 依赖关系图 ```mermaid graph BT P5["Phase 5: 热身准备
ProviderConfig::from_env
Ollama Provider
#[non_exhaustive] 标记"]:::done P6["Phase 6: ToolDef IR
Provider 无关工具定义"]:::done P7["Phase 7: SqliteStore
rusqlite + WAL
9 个内联测试
持久化 round-trip"]:::done P8["Phase 8: MVP 出口
rc.1 标签
14 枚举 #[non_exhaustive]
StepStatus IR 迁移
quick_start + end_to_end"]:::done P9["Phase 9: 流式体验增强
submit_turn_stream
submit_with_tools_stream
9 单元测试 + 2 集成测试"]:::done P10["Phase 10: ContextSlot
ContextSlot 类型
JSON blob 持久化
AgentSession 集成
43 个新测试"]:::done P11["Phase 11: 测试与检索补强
VectorRetriever trait
12 wiremock tests
5 并发测试"]:::done P12["Phase 12
P2 锦上添花"]:::p2 P8 --> P5 P8 --> P6 P8 --> P7 P9 --> P6 P10 --> P7 P10 --> P8 P11 -.-> P7 classDef done fill:#4ade80,stroke:#16a34a,color:#1a1a1a classDef warmup fill:#e2e8f0,stroke:#94a3b8 classDef core fill:#fbbf24,stroke:#d97706 classDef mvp fill:#4ade80,stroke:#16a34a classDef p1 fill:#93c5fd,stroke:#2563eb classDef p2 fill:#c4b5fd,stroke:#7c3aed ``` --- ### 关键里程碑 | 里程碑 | Phase 完成条件 | 可验证指标 | 状态 | |--------|---------------|-----------|------| | **M1** | Phase 5 | 热身三项完成:`from_env()` 可用 / Ollama 类型存在 / `#[non_exhaustive]` 就位 | ✅ 2026-07-05 | | **M2** | Phase 6 | `ToolDef` 全量切换,`cargo test --all-targets` 全绿 | ✅ 2026-07-05 | | **M3** | Phase 7 | SqliteStore CRUD + 并发测试通过,进程重启数据不丢 | ✅ 2026-07-05 | | **M4** | **Phase 8 (rc.1)** | P0 五项全部交付,`cargo run --example quick_start` 跑通 | ✅ 2026-07-05 | | **M5** | Phase 9 | `submit_turn_stream` 流式事件序列验证通过 | ✅ 2026-07-06 | | **M6** | Phase 10 | ContextSlot 创建/切换/派生集成测试通过 | ✅ 2026-07-07 | | **M7** | Phase 11 | wiremock + 并发测试补强,测试总量 200+ | ✅ 2026-07-06 | | **M8** | Phase 12(可选) | P2 功能按需交付 | ⏳ |