# v0.1 发布实施计划 > 状态:待实施 > 关联文档:`docs/roadmap.md`、`docs/8-examples-plan.md`、`docs/10c-phase2-llm-cycle-simplify.md` ## 背景与目标 AG Core 已完成 Phase 0-4c 全部 7 个 Phase 的核心功能,以及 Provider IR 重构(新类型系统 + Anthropic/DeepSeek/Qwen Provider)+ LlmCycle 简化(IR 消息类型切换 + 桥接层移除)。 **当前基线**: - `cargo build` — ✅ 通过(5 个 warning) - `cargo test` — ❌ 编译失败(4 个 error:session.rs/cycle.rs 测试模块中 `ContentBlock`/`ProviderCapabilities`/`ProviderFeatures` 导入缺失,均为 Provider IR 重构后未同步的回归) - LlmCycle 简化合并前全量测试为 177 通过,合并后尚未跑通过过全量测试 v0.1 发布的阻塞项不是"功能不足",而是"已有功能不能被用户快速看见和使用"。本计划聚焦于: 1. **扫清技术债** — composer.rs 迁移、锁修复、clippy 清零 2. **提供可离线运行的示例** — 让用户 5 分钟内上手 3. **补充面向用户的文档** — README、MockProvider、错误消息友好化 4. **完成发布前准备** — CI 验证、Roadmap 同步、版本标记 --- ## 总体时间线 预计 8-10 个工作日(2 周),分为两条并行线: ``` Week 1 ────┬── 测试修复 + 技术债扫清 │ ├ T0 测试编译回归修复(~0.5d)← ⚠️ 任何改动前的前置步骤 │ ├ T1.1 composer.rs IR 迁移(~1d) │ ├ T1.2 knowledge.rs 锁修复(~0.5d) │ ├ T1.3 旧类型废弃标记(~0.5d) │ └ T1.4 clippy 清零(~0.5d) │ ├── 示例 + 开发者体验 │ ├ T2.0 MockProvider 公开化(~0.5d) │ ├ T2.1 4个🥇示例(~2-3d,可并行) │ └ T3.1 README 初稿(~1d,并行) │ Week 2 ────┬── 示例继续 │ ├ T2.2 3个🥈示例(~2d) │ └ T3.2 错误消息 review(~0.5d) │ └── 发布准备 ├ T3.3 README 定稿(~1d) ├ T4.1 CI 示例验证(~0.5d) ├ T4.2 Roadmap 更新(~0.5d) ├ T4.3 CHANGELOG 初始化(~0.5d) └ T4.4 v0.1 tag(~0.5d) ``` --- ## 实施步骤 ### Phase A — 测试修复 + 技术债扫清(Week 1 前半) > **重要**:Task A0 是后续所有任务的前提——不修复测试编译,所有 Task 的验收条件(`cargo test` 全通过)都不可执行。 #### Task A0:修复测试编译回归(~0.5d) **问题**:Provider IR 重构后,`ContentBlock`/`ProviderCapabilities`/`ProviderFeatures` 被移到新位置,但 2 个测试模块的导入未同步,导致 `cargo test` 编译失败。 **涉及文件**: - `src/agent/session.rs` — 测试模块缺少 `ContentBlock` 导入 - `src/llm/cycle.rs` — 测试模块缺少 `ProviderCapabilities`/`ProviderFeatures` 导入 **修复方案**:在相应测试模块内补全 `use` 语句(每处加一行即可)。 **额外收益**:修复后 `convert.rs` 中 2 处 `irrefutable if let` 警告也一并修正(改为 `let`),减少 clippy 基数。 **前置依赖**:无 **验收条件**: - `cargo test` 全量编译通过 - `cargo test` 全量运行通过 --- #### Task A1:`composer.rs` IR 迁移(~1d) **前置依赖**:Task A0(否则无法通过 `cargo test` 验证) **涉及文件**: - `src/prompt/composer.rs` — 主要改动 - `src/prompt/mod.rs` — 类型重导出 **改动范围**:约 60 处 `OpenaiChatMessage` → `Message`,`ContentField`/`OpenaiContentPart` → `ContentBlock` **具体清单**: 1. `PromptComposer` 内部 `messages` 字段类型 `Vec` → `Vec` 2. 所有 `.system_text()`/`.user_text()`/`.assistant_text()`/`.developer_text()`/`.tool_result()` 构造方法 — 新 `Message` 已有同名方法,直接替换调用 3. 所有 `xx_content()`/`xx_contents()` 方法 — `ContentBlock` 替代 `ContentField`/`OpenaiContentPart` 4. `set_message_name()` — 新 `Message` 是扁平 enum,无 `name` 字段,移除或忽略 5. `build()` 返回类型 `Vec` → `Vec` 6. `validate_messages()` 消息校验函数 — `OpenaiChatMessage::Tool { .. }` → `Message::ToolResult { .. }`,`tool_calls` 从 `Assistant` 变体的 `ContentBlock::ToolUse` 中提取 **测试**:内联测试中 `OpenaiChatMessage::Tool { .. }` pattern match 需同步更新 **验收条件**: - `cargo build` 无错误 - `cargo test` 中 prompt 模块测试全通过 - 无新增 clippy 警告 --- #### Task A2:`knowledge.rs` 锁修复(~0.5d) **涉及文件**:`src/memory/knowledge.rs` **问题**:`std::sync::Mutex` guard 在 `search()` 方法中跨 `.await` 持有,可能在高并发下阻塞 tokio 工作线程 **修复方案**:`std::sync::Mutex>` → `tokio::sync::Mutex>` **影响范围**:5 处 `.lock().unwrap()` 调用(`rebuild_index`、`add_page`、`delete_page`、`search`、`get_index`) **验收条件**: - `cargo build` 无错误 - `cargo test` 中 memory 模块测试全通过 - clippy 不再报 `await_holding_lock` 警告 --- #### Task A3:旧类型公开 API 废弃标记(~0.5d) **涉及文件**:`src/llm/types/mod.rs` **改动**: - `ChatResponse` struct 加 `#[deprecated(since = "0.1.0", note = "请改用 MessageResponse")]` - `ToolDefinition` 类型别名加 `#[deprecated]`(如果仍公开) - 保留结构体定义(OpenAI `chat_inner()` 内部转换层仍然在用),不删除 **验收条件**: - `cargo build` 产生废弃警告(期望行为)但不产生编译错误 - 外部调用方能看到有用提示 --- #### Task A4:clippy 警告清零(~0.5d) 当前剩余 8 个: | # | 警告类型 | 文件 | 修复方式 | |---|---------|------|---------| | 1 | irrefutable `if let` | — | 改为直接 `let` | | 2 | `with_plan_step_index` 未用 | `src/llm/hooks.rs` | 加 `#[allow(dead_code)]` | | 3-5 | 字段未读(api_key, stop_sequence, next_block_index) | `anthropic.rs`, `response_v2.rs` | 加 `#[allow(dead_code)]` | | 6 | 手动前缀剥离 | — | 用 `strip_prefix()` | | 7 | MutexGuard 跨 await | knowledge.rs | Task A2 修复后自动消失 | | 8 | `if` 相同分支 | retriever.rs | 合并条件 | **验收条件**:`cargo clippy --lib -p agcore` 0 警告 --- ### Phase B — 示例实现(Week 1 后半 ~ Week 2 前半) #### Task B0:MockProvider 公开化(~0.5d) **涉及文件**: - `src/llm/mock.rs` — 新建,公开 `MockProvider` struct - `src/llm/mod.rs` — 加 `pub mod mock;` - `src/agent/session.rs` — 测试中 `MockProvider` 改为引用 `crate::llm::mock::MockProvider` **MockProvider 接口**: ```rust pub struct MockProvider { .. } impl MockProvider { pub fn new(responses: Vec) -> Self; pub fn chat(&self, request: MessageRequest) -> Result; pub fn chat_stream(&self, request: MessageRequest) -> Result> + Send>>, LlmError>; } ``` **决策**:同时实现 `chat_stream`,从 `MessageResponse` 拆解为 `StreamEvent::ContentBlockStart + ContentBlockDelta * N + MessageComplete` 序列,使流式示例也能不依赖 API key。 **验收条件**: - 公开 `MockProvider` 可被外部 crate 引用 - `cargo test` 中所有 session 测试通过 - `agent_session_demo.rs` 示例可引用 `MockProvider` 并运行 --- #### Task B1:🥇 示例 × 4(~2-3d,可并行) 4 个示例相互无依赖,按技术债消除进度安排: | # | 示例 | 代码量 | 前置依赖 | 说明 | |---|------|--------|---------|------| | B1a | `agent_session_demo.rs` | ~100 行 | Task B0 | AgentBuilder → AgentSession → submit_turn → SessionMemory 完整链路 | | B1b | `custom_tool.rs` | ~80 行 | 无 | 实现模拟工具 → ToolRegistry 注册 → invoke/invoke_all → PermissionChecker | | B1c | `prompt_composer.rs` | ~60 行 | Task A1 | 模板变量插值 → PromptComposer 构建消息链 → 断言验证,纯离线 | | B1d | `task_agent_demo.rs` | ~70 行 | 无 | 构造 JSON → JsonPlanParser → Plan → Step 状态机 → Hook 事件 | 每个示例的详细设计见 `docs/8-examples-plan.md`,按该文档直接实现。 **验收条件**: - `cargo run --example prompt_composer` → 成功退出 - `cargo run --example custom_tool` → 成功退出 - `cargo run --example agent_session_demo` → 成功退出 - `cargo run --example task_agent_demo` → 成功退出 --- #### Task B2:🥈 示例 × 3(~2d) | # | 示例 | 代码量 | 前置依赖 | |---|------|--------|---------| | B2a | `conversation_memory_demo.rs` | ~70 行 | 无 | | B2b | `knowledge_search_demo.rs` | ~60 行 | 无 | | B2c | `streaming_events_demo.rs` | ~80 行 | Task B0(MockProvider 需支持 `chat_stream`) | **验收条件**:额外 3 个示例均可 `cargo run` 成功退出 --- ### Phase C — 开发者体验 + 文档(Week 2 后半,与 Phase B 后段并行) #### Task C1:README 完整版(~1.5d) **涉及文件**:`README.md` **内容结构**: ``` # AG Core ## 这是什么? ← 一句话定位 ## 快速上手 ← cargo add + MockProvider 示例 ## 核心模块 ← 7 个模块一句话说明 ## 架构关系图 ← ASCII 或 Mermaid ## 模块依赖关系 ← 依赖关系图 + 说明 ## 环境变量 ← 当前支持的环境变量表 ## 参考项目 ← OpenClaw / Hermes / OpenHuman / OpenHarness ## 许可证 ← MIT / Apache-2.0 ``` **要求**:快速上手代码段在提交前必须真实编译通过。 --- #### Task C2:错误消息友好化 review(~0.5d) **涉及文件**: - `src/agent/error.rs` — AgentError 消息 - `src/llm/error.rs` — LlmError 消息 - `src/tools/error.rs` — ToolError 消息 - `src/memory/error.rs` — MemoryError 消息 - `src/prompt/error.rs` — PromptError 消息 **检查标准**: - 用户能理解"哪里错了" - 有可操作的建议("请检查 API key"、"请配置环境变量 LLM_API_KEY") - 无英文残留的工程师视角消息 --- ### Phase D — 发布准备(Week 2 末) #### Task D1:CI 示例验证集成(~0.5d) - 确认 `cargo build` 无新增警告 - 确认 `cargo test` 全部通过(退出码 0) - 确认 `cargo test --examples` 全部通过 - 确认 `cargo clippy --lib -p agcore` 0 警告 #### Task D2:Roadmap 更新(~0.5d) 更新 `docs/roadmap.md`: - Phase 2 状态更新为 ✅ 全部交付物已完成(Provider IR 重构 + LlmCycle 简化) - 测试计数更新为 D1 确认的最终实际数值 - 移除 clippy 警告计数 - 添加 v0.1 发布里程碑 #### Task D3:依赖裁剪(~0.5d,非阻塞,可跳过) `tokio = { features = ["full"] }` → 按需 feature(`rt`、`macros`、`sync`、`time`、`net`) **理由**:减少编译时间 + 减少安全面。时间不够可延后到 v0.2。 #### Task D4:CHANGELOG 初始化(~0.5d) **涉及文件**:`CHANGELOG.md` **内容要求**: - 版本号:`v0.1.0` - 发布日期:标记当天 - 变更摘要:Phase 0-4c(LLM 调用周期、提示词工程、工具系统、记忆系统、Agent 运行时、任务执行、会话级记忆)+ Provider IR 重构(统一类型系统 + Anthropic/DeepSeek/Qwen 适配)+ LlmCycle 简化 - 格式参考 [Keep a Changelog](https://keepachangelog.com/) 规范 **验收条件**: - `CHANGELOG.md` 文件存在,内容与当前版本一致 - 文件随 tag commit 一起提交 --- #### Task D5:版本标记(~0.5d) ```bash git tag v0.1.0 && git push --tags ``` --- ## 并行机会 | 并行组 | 包含任务 | 说明 | |--------|---------|------| | 组 0 | A0 | 单独执行,后续所有 Task 的前提 | | 组 1 | A1 + A2 + A3 | A0 完成后可并行修 | | 组 2 | B1a + B1b + B1d | 三个示例无前置依赖(B1a 需等 B0,B1c 需等 A1) | | 组 3 | C1 + C2 + D2 | README / 错误消息 / Roadmap 更新,纯文档工作 | | 组 4 | D1 + D3 | CI 验证 + 依赖裁剪,可并行 | --- ## 风险与应对 | 风险 | 影响 | 概率 | 应对 | |------|------|------|------| | A0 修复后仍有未发现的测试回归 | 🔴 后续 Task 验收不可信 | 低 | `cargo test` 全量通过后才启动 A1 | | composer.rs 迁移发现未预见的 API 依赖 | 🔴 A1 延期 | 低 | 保持每次 commit 可编译;分 2 次提交(先私有不影响构建,再改返回类型) | | MockProvider stream 实现比预期复杂 | 🟡 B2c 延期 | 中 | 先简化实现(只支持基本 text delta),复杂 case 留给 v0.2 | | 示例与库 API 不同步 | 🟡 持续风险 | 中 | 所有示例纳入 `cargo test --examples` 作为 CI gate | | clippy `#[allow(dead_code)]` 积累过多 | 🟢 低 | 高 | v0.2 发布前专门 review 一次允许列表 | | tokio feature 裁剪导致编译失败 | 🟡 D3 延期 | 低 | 裁剪前确认现有 feature 覆盖所有 `tokio::` 调用点 | --- ## 验收标准 1. **代码质量**:`cargo build` 0 错误,`cargo clippy --lib -p agcore` 0 警告 2. **测试覆盖**:`cargo test` 全量编译通过且全部运行通过,`cargo test --examples` 全通过 3. **示例可用**:4 个🥇 + 3 个🥈共 7 个示例均可离线 `cargo run` 成功退出 4. **文档完整**:README 包含快速上手 + 架构概览,错误消息全部友好化 5. **版本标记**:`git tag v0.1.0` 6. **Roadmap 同步**:`docs/roadmap.md` 测试计数和状态与代码一致