docs(v0.1): 添加发布实施计划文档

This commit is contained in:
徐涛
2026-07-03 14:13:30 +08:00
parent e54edbc037
commit c2c0d498ee
+340
View File
@@ -0,0 +1,340 @@
# 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` 测试计数和状态与代码一致