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

341 lines
13 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.
# 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 个 errorsession.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<OpenaiChatMessage>``Vec<Message>`
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<OpenaiChatMessage>``Vec<Message>`
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<Vec<PageIndexEntry>>``tokio::sync::Mutex<Vec<PageIndexEntry>>`
**影响范围**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 A4clippy 警告清零(~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 B0MockProvider 公开化(~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<MessageResponse>) -> Self;
pub fn chat(&self, request: MessageRequest) -> Result<MessageResponse, LlmError>;
pub fn chat_stream(&self, request: MessageRequest)
-> Result<Pin<Box<dyn Stream<Item = Result<StreamEvent, LlmError>> + 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 B0MockProvider 需支持 `chat_stream` |
**验收条件**:额外 3 个示例均可 `cargo run` 成功退出
---
### Phase C — 开发者体验 + 文档(Week 2 后半,与 Phase B 后段并行)
#### Task C1README 完整版(~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 D1CI 示例验证集成(~0.5d
- 确认 `cargo build` 无新增警告
- 确认 `cargo test` 全部通过(退出码 0
- 确认 `cargo test --examples` 全部通过
- 确认 `cargo clippy --lib -p agcore` 0 警告
#### Task D2Roadmap 更新(~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 D4CHANGELOG 初始化(~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` 测试计数和状态与代码一致