28ca43ccb2
将 note、pdd、prd、roadmap 四类文档分别归入 `design/` 下对应子目录中,并新增 `.gitkeep` 占位文件
341 lines
13 KiB
Markdown
341 lines
13 KiB
Markdown
# 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<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 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<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 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` 测试计数和状态与代码一致
|