将 note、pdd、prd、roadmap 四类文档分别归入 `design/` 下对应子目录中,并新增 `.gitkeep` 占位文件
26 KiB
Phase 8 — MVP 集成出口实现方案
- 文档编号:15
- 标题:Phase 8 — MVP 集成出口实现方案
- 日期:2026-07-05
- 状态:已定稿
- 涉及模块:全局(llm/types、agent、tools、memory、prompt、examples)
- 关联文档:roadmap.md(§Phase 8)、14-phase7-sqlite-store.md
1. 背景与目标
Phase 5-7 已交付 P0 功能闭环:ProviderConfig from_env()(Phase 5)、ToolDef IR 正式化(Phase 6)、SqliteStore 持久化(Phase 7)。当前 200 个测试全绿、clippy 0 警告,但缺乏一个"可被人依赖"的集成出口。
Phase 8 的目标是完成 API 稳定性扫尾 + Quick Start 示例 + 端到端示例,产出 v0.2.0-rc.1 标签。三个 Step 分别对应三类用户群体:
| Step | 受众 | 交付物 |
|---|---|---|
| 8.1 | 存量升级者(v0.1 → v0.2) | API 稳定性扫尾 + CHANGELOG |
| 8.2 | 新用户评估者("30 秒决定要不要用") | Quick Start 示例 |
| 8.3 | 技术决策者("这框架能跑真实场景吗") | 端到端集成示例 |
2. 当前状态
| 度量 | 数值 |
|---|---|
cargo test --all-targets |
✅ 200 passed / 0 failed |
cargo clippy --all-targets -- -D warnings |
✅ 0 警告 |
已存在 #[non_exhaustive] 枚举 |
4 个(StopReason / FinishReason / EvictionPolicy / ProviderType) |
已存在 #[deprecated] 项 |
3 个(ChatResponse / ToolDefinition / task_agent_demo 中旧类型使用) |
| 已有示例 | 8 个 |
StepStatus::Completed 使用类型 |
ChatResponse(已 #[deprecated]) |
2.1 关键技术债
// agent/task.rs —— StepStatus 当前使用已废弃类型
#[allow(deprecated)]
pub enum StepStatus {
Completed(ChatResponse), // ← ChatResponse 已在 0.1.0 标记 #[deprecated]
...
}
task_agent_demo.rs 中同时使用了 ChatResponse / OpenaiChatMessage / FinishReason 三个废弃类型,入口处有 #![allow(deprecated)]。
3. 实施方案
3.1 Step 8.1 — API 稳定性扫尾
拆为 4 个增量 commit:
| Commit | 内容 | 涉及文件 |
|---|---|---|
| commit 1 | 14 个公开枚举追加 #[non_exhaustive] |
各枚举定义文件(详见 §3.1.1) |
| commit 2 | StepStatus::Completed(ChatResponse) → Completed(MessageResponse) + task_agent_demo.rs 清理全部 3 个废弃类型(ChatResponse / OpenaiChatMessage / FinishReason),移除 #![allow(deprecated)] |
src/agent/task.rs、examples/task_agent_demo.rs |
| commit 3 | CHANGELOG v0.2 条目 + Cargo.toml version → 0.2.0-rc.1 + README 更新 |
CHANGELOG.md、Cargo.toml、README.md |
| commit 4 | 验证:cargo test + clippy + cargo doc 零告警 |
无代码改动 |
3.1.1 #[non_exhaustive] 追加清单(14 个枚举)
按优先级分级:
| 优先级 | 枚举 | 模块路径 | 理由 |
|---|---|---|---|
| P0 核心 | Message |
llm/types/message.rs |
核心 IR 类型,未来可能新增变体(MultiModal 扩展) |
ContentBlock |
llm/types/message.rs |
同上 | |
ContentBlockType |
llm/types/message.rs |
同上 | |
StreamEvent |
llm/types/response_v2.rs |
流式事件集,Provider 扩展可能新增事件 | |
HookEvent |
llm/hooks.rs |
生命周期钩子,框架扩展需要新增事件点 | |
| P0 Error | AgentError |
agent/error.rs |
顶层错误,下游 match 需保护 |
LlmError |
llm/error.rs |
LLM 调用错误 | |
ToolError |
tools/error.rs |
工具系统错误 | |
MemoryError |
memory/error.rs |
记忆系统错误 | |
PromptError |
prompt/error.rs |
提示词工程错误 | |
| P1 其他 | MemoryStrategy |
memory/conversation.rs |
对话策略,未来可扩展(如 Summarize) |
StepStatus |
agent/task.rs |
步骤状态机,可扩展(如 Cancelled) | |
ToolChoice |
llm/types/request.rs |
Provider 工具选择策略 | |
ResponseFormat |
llm/types/shared.rs |
响应格式枚举 |
明确不加的:
| 类别 | 枚举 | 原因 |
|---|---|---|
| 内部 wire-format | OpenaiChatMessage / OpenaiTool / OpenaiToolCall / ContentField / OpenaiContentPart / LegacyStreamEvent |
内部转换层,不构成公共 API 契约 |
| 语义稳定 | Role / ServiceTier / Modality / ImageDetail / AudioFormat / StopSequence |
语义已收敛,协议层无新增变体预期 |
| 使用面窄 | TemplateValue / Permission / McpTransport / ContentBlockBuilder / ExtraError |
内部实现细节或使用频率极低,下游不直接 match |
#[non_exhaustive]的不可逆性:一旦 v0.2.0-rc.1 发布,以下游代码可能依赖_ =>通配分支。在 v0.3+ 中移除#[non_exhaustive]将构成 semver breaking change(新增变体不再触发编译警告,下游 match 可能遗漏新变体),因此当前追加的标记应视为永久 API 契约。
3.1.2 StepStatus 迁移细节
// 变更前
#[allow(deprecated)]
pub enum StepStatus {
Completed(ChatResponse), // ChatResponse 已 #[deprecated]
...
}
// 变更后
#[non_exhaustive]
pub enum StepStatus {
Completed(MessageResponse),
...
}
字段映射差异:MessageResponse 不是 ChatResponse 的简单改名——两者结构不同,迁移需要做字段适配:
| ChatResponse 字段 | 类型 | MessageResponse 字段 | 类型 | 映射方式 |
|---|---|---|---|---|
message |
OpenaiChatMessage |
message |
Message |
类型替换:OpenaiChatMessage::assistant_text(t) → Message::Assistant { content: vec![ContentBlock::Text { text: t.into() }] } |
usage |
Usage |
usage |
Usage |
✅ 同类型,直接迁移 |
stop_reason |
Option<FinishReason> |
stop_reason |
StopReason |
类型替换:Some(FinishReason::Stop) → StopReason::Stop;无 Option 包裹 |
| — | — | id |
String |
新增必填字段,使用空字符串 "" 占位 |
| — | — | model |
String |
新增必填字段,使用 "mock" 或空字符串占位 |
| — | — | extra |
HashMap<String, Value> |
新增字段,使用 HashMap::new() 占位 |
迁移示例(task_agent_demo.rs 的构造代码):
// 旧代码(3 个废弃类型)
StepStatus::Completed(ChatResponse {
message: OpenaiChatMessage::assistant_text("天气:晴,22°C"),
usage: Usage::from_input_output(10, 5),
stop_reason: Some(FinishReason::Stop),
})
// 新代码(纯 MessageResponse)
StepStatus::Completed(MessageResponse {
id: String::new(),
model: "mock".into(),
message: Message::assistant("天气:晴,22°C"),
usage: Usage::from_input_output(10, 5),
stop_reason: StopReason::Stop,
extra: HashMap::new(),
})
涉及文件:
src/agent/task.rs:枚举定义 +#[allow(deprecated)]移除 +#[non_exhaustive]追加examples/task_agent_demo.rs:ChatResponse{...}→MessageResponse{...}构造替换,同时替换OpenaiChatMessage/FinishReason引用,移除#![allow(deprecated)]
3.2 Step 8.2 — Quick Start 示例
| 属性 | 值 |
|---|---|
| 文件 | examples/quick_start.rs |
| 规模 | ~36 行 |
| Provider | MockProvider(FIFO 单响应队列) |
| 工具 | EchoTool(回传 "收到: {input}",完整 JSON Schema 参数声明) |
| 执行 | submit_turn("你好") → 验证输出包含 "收到" |
| 验证 | cargo run --example quick_start exit 0 |
设计要点:
- 展示四层抽象:Agent trait / BaseTool 自定义 / AgentBuilder 装配 / AgentSession 执行
- 无外部依赖、无 API key、零配置
3.3 Step 8.3 — 端到端示例
| 属性 | 值 |
|---|---|
| 文件 | examples/end_to_end.rs |
| 规模 | ~160 行(最小可行边界:3 工具 + 3 轮 + 持久化验证,防止实施中进一步膨胀) |
| Provider | 自动检测 AG_LLM_* → from_env(),fallback 到 MockProvider |
| 工具组合 | EchoTool(回显)+ CalcTool(四则运算,本地执行)+ NoteTool(笔记,通过 MemoryStore trait 操作 SessionMemory) |
| 持久化 | tempfile::TempDir + SqliteStore,drop 后重建连接验证数据不丢 |
| 对话 | 3 轮:计算 → 记笔记 → 回忆 |
| 验证 | cargo run --example end_to_end exit 0(无需任何外部配置) |
真实 Provider 切换:示例在文件顶部注释中说明 "设置 AG_LLM_BASE_URL / AG_LLM_API_KEY / AG_LLM_MODEL 环境变量即可使用真实 LLM Provider(支持 OpenAI / Ollama 等);未设置时自动降级为 MockProvider,零配置可运行。"
from_env() 部分环境变量策略:from_env() 要求完整的三件套({prefix}_BASE_URL + {prefix}_API_KEY + {prefix}_MODEL)。当环境变量部分设置时,示例整体降级到 MockProvider——不在"半配置"状态下尝试部分初始化。日志输出形如 "AG_LLM_* 环境变量不完整(检测到: {found_vars}),回退到 MockProvider"。
架构亮点:
┌─────────────────────────┐
│ AgentSession │
│ (submit_turn × 3) │
└────┬──────┬──────┬──────┘
│ │ │
┌────┘ │ └──────┐
▼ ▼ ▼
┌──────────┐ ┌────────┐ ┌──────────┐
│ EchoTool │ │CalcTool│ │ NoteTool │
│ (回显) │ │(四则) │ │ (记忆) │
└──────────┘ └────────┘ └────┬─────┘
│
┌──────▼──────┐
│ SessionMemory│
│ (MemoryStore)│
└──────┬──────┘
│
┌──────▼──────┐
│ SqliteStore │
│ (temp dir) │
└─────────────┘
NoteTool 展示 MemoryStore trait 解耦能力:不绑定 SqliteStore,上层 AgentSession 通过 SessionMemory 操作,底层可互换。
4. 否决项记录
| 否决方案 | 否决原因 |
|---|---|
#[non_exhaustive] 仅加 5 个核心类型 |
全面覆盖 Error enums 为零运行时成本,对下游更友好。Error 枚举是下游 match 最密集的地方,漏标会在 v0.3 引入 breakage |
| StepStatus::Completed 留到 v0.3 再修 | rc.1 前清理 deprecated 类型污染最划算——越晚 migration cost 越高,且当前仅 1 个示例 + 1 个测试引用 |
| Quick Start 纯文本路线(不展示自定义工具) | 含 EchoTool 展示核心差异化,仅多 5 行代码但传递了"可以自定义工具"的关键信息 |
| 端到端仅 Echo + Calc(无 NoteTool) | NoteTool 展示 MemoryStore trait 解耦能力是架构亮点,跳过后新用户无法理解 memory 如何集成到 Agent 流程 |
| 持久化仅注释说明不实际运行(方案 Y) | 进程内实操验证(create → drop → reopen → assert)比注释更有说服力,增加约 15 行代码 |
5. 关键假设
- MockProvider FIFO 队列满足 auto-tool-loop 消费顺序:MockProvider 的
pop()按预设顺序弹出。当 LLM 返回多个 tool call 时队列消费顺序与预设一致,无需额外同步 - StepStatus 切换需做字段适配:
ChatResponse(3 字段) 到MessageResponse(6 字段) 存在字段类型差异(message类型不同、stop_reason类型 + Option 有无不同、id/model/extra为新增必填字段),消费者需按字段映射表提供占位值。但消费者仅 1 个(task_agent_demo.rs)+ 1 个内联测试,手动适配工作量极小。StepStatus的is_terminal()/is_pending()行为不受影响 - 所有 10 个示例零外部配置 exit 0:已有 8 个示例已验证,新增 2 个(quick_start + end_to_end)均使用 MockProvider fallback,无需 API key
#[non_exhaustive]× 14 不触发额外 clippy warning:当前无代码对以上枚举做 exhaustive match(不含_),追加#[non_exhaustive]是纯安全标记
6. 实施顺序与验证标准
6.1 提交顺序
Step 8.1 (4 commits)
→ commit 1: #[non_exhaustive] × 14
→ commit 2: StepStatus 修复(Completed(ChatResponse) → Completed(MessageResponse))
→ commit 3: CHANGELOG v0.2 + Cargo.toml version 0.2.0-rc.1 + README 更新
→ commit 4: 验证(test / clippy / doc 零告警)
Step 8.2
→ commit 5: examples/quick_start.rs(~36 行)
Step 8.3
→ commit 6: examples/end_to_end.rs(~160 行)
最终验证
→ cargo test --all-targets
→ cargo clippy --all-targets -- -D warnings
→ cargo doc --no-deps
→ git tag v0.2.0-rc.1
6.2 验收标准
| 指标 | 要求 |
|---|---|
cargo test --all-targets |
全绿 |
cargo clippy --all-targets -- -D warnings |
0 警告 |
cargo doc --no-deps |
0 warning |
| 所有 10 个示例 | cargo run --example <name> exit 0 |
| Cargo.toml version | 0.2.0-rc.1 |
| CHANGELOG | v0.2 条目完整(Added / Changed / Deprecated / Fixed / Removed 各节) |
| README | 示例列表 + 版本号更新 |
| git tag | v0.2.0-rc.1 |
7. 参考来源
- roadmap.md — Phase 8 原始定义(Step 8.1/8.2/8.3)、依赖关系(Phase 5/6/7 → Phase 8)
src/agent/task.rs—StepStatus当前实现,Completed(ChatResponse)类型src/llm/types/message.rs—Message/ContentBlock/ContentBlockType枚举定义src/llm/types/response_v2.rs—StreamEvent/StopReason枚举定义(StopReason 已有#[non_exhaustive])src/llm/types/shared.rs—ResponseFormat/Role/FinishReason等枚举(FinishReason 已有#[non_exhaustive])src/llm/types/request.rs—ToolChoice枚举定义src/llm/hooks.rs—HookEvent枚举定义src/llm/error.rs—LlmError枚举定义src/agent/error.rs—AgentError枚举定义src/tools/error.rs—ToolError枚举定义src/memory/error.rs—MemoryError枚举定义src/memory/conversation.rs—MemoryStrategy枚举定义src/prompt/error.rs—PromptError枚举定义examples/task_agent_demo.rs— 当前使用#[allow(deprecated)]+ChatResponse的示例
8. 实施计划
8.1 实施步骤
Step 8.1 — API 稳定性扫尾
拆为 4 个增量 commit,依次提交。
commit 1: #[non_exhaustive] × 14
| 属性 | 值 |
|---|---|
| 涉及文件 | 14 个枚举定义所在文件(见下方清单) |
| 前置依赖 | 无 |
| 预估工作量 | S(<1h) |
| 风险等级 | 低 |
在每个目标枚举定义处的 pub enum 之前加一行 #[non_exhaustive],纯文本属性追加,无逻辑变更。
| 目标枚举 | 文件路径 | 行号附近 |
|---|---|---|
Message |
src/llm/types/message.rs |
pub enum Message (L22) |
ContentBlock |
src/llm/types/message.rs |
pub enum ContentBlock (L99) |
ContentBlockType |
src/llm/types/message.rs |
pub enum ContentBlockType (L134) |
StreamEvent |
src/llm/types/response_v2.rs |
pub enum StreamEvent (L167) |
HookEvent |
src/llm/hooks.rs |
pub enum HookEvent (L9) |
AgentError |
src/agent/error.rs |
pub enum AgentError (L20) |
LlmError |
src/llm/error.rs |
pub enum LlmError (L10) |
ToolError |
src/tools/error.rs |
pub enum ToolError (L6) |
MemoryError |
src/memory/error.rs |
pub enum MemoryError (L8) |
PromptError |
src/prompt/error.rs |
pub enum PromptError (L3) |
MemoryStrategy |
src/memory/conversation.rs |
pub enum MemoryStrategy (L14) |
StepStatus |
src/agent/task.rs |
pub enum StepStatus (L59) |
ToolChoice |
src/llm/types/request.rs |
pub enum ToolChoice (L14) |
ResponseFormat |
src/llm/types/shared.rs |
pub enum ResponseFormat (L70) |
注意:
StepStatus在 commit 2 中会同时被修改(variant 类型替换 + 移除#[allow(deprecated)])。commit 1 仅追加#[non_exhaustive]属性,commit 2 再处理变体变更和清理。
验收条件:cargo build --all-targets 通过
commit 2: StepStatus 修复 + 废弃类型清理
| 属性 | 值 |
|---|---|
| 涉及文件 | src/agent/task.rs,examples/task_agent_demo.rs |
| 前置依赖 | commit 1(StepStatus 先标记 #[non_exhaustive],此处改 variant 时一并保留,无实际冲突) |
| 预估工作量 | S(<1h,约 20 行改动) |
| 风险等级 | 低 |
两步操作:
-
src/agent/task.rs(L59-L71):StepStatus::Completed(ChatResponse)→Completed(MessageResponse)- 移除
#[allow(deprecated)](第 13、59 行两处)
-
examples/task_agent_demo.rs:- 替换 3 个废弃类型:
ChatResponse→MessageResponse,OpenaiChatMessage::assistant_text(t)→Message::assistant(t),FinishReason::Stop→StopReason::Stop - 补充
id: String::new(),model: "mock".into(),extra: HashMap::new()占位字段 - 移除
# - 移除
use中的ChatResponse、OpenaiChatMessage、FinishReason - 添加
use std::collections::HashMap,use agcore::llm::types::{Message, MessageResponse, StopReason}(注意:Message::assistant_text(t)不存在,需使用Message::assistant(t))
- 替换 3 个废弃类型:
字段映射参见 §3.1.2 的字段映射表和迁移示例。
验收条件:cargo build --all-targets 通过,零 deprecated warning
commit 3: CHANGELOG + 版本号 + README
| 属性 | 值 |
|---|---|
| 涉及文件 | CHANGELOG.md,Cargo.toml,README.md |
| 前置依赖 | commit 1+2(CHANGELOG 需记录实际变更) |
| 预估工作量 | S(<1h) |
| 风险等级 | 低 |
-
CHANGELOG.md:新增[0.2.0-rc.1]条目,包含:- Added:SqliteStore 持久化 / OllamaProvider / ProviderConfig::from_env / ToolDef IR / Quick Start 和 end_to_end 示例
- Changed:MessageRequest.tools 切换 ToolDef / StepStatus::Completed 类型替换
- Deprecated:ChatResponse / with_system_prompt() / with_client()
- Non-exhaustive:14 个枚举标记清单
-
Cargo.toml:第 3 行version = "0.1.0"→version = "0.2.0-rc.1" -
README.md:更新示例列表从 7 个改为 10 个(含新增 2 个),版本号同步
验收条件:人工 review CHANGELOG + git diff 确认版本号
commit 4: 验证
| 属性 | 值 |
|---|---|
| 涉及文件 | 无代码改动 |
| 前置依赖 | commit 3 |
| 预估工作量 | S(<1h,主要等待编译) |
| 风险等级 | 低 |
运行三条命令:
cargo test --all-targets
cargo clippy --all-targets -- -D warnings
cargo doc --no-deps 2>&1 | grep "^warning:" && echo "WARNINGS FOUND" || echo "0 warnings"
验收条件:前两条 0 错误,第三条输出 0 warnings
Step 8.2 — Quick Start 示例
commit 5: examples/quick_start.rs
| 属性 | 值 |
|---|---|
| 涉及文件 | examples/quick_start.rs |
| 前置依赖 | 无(可从 Phase 7 独立创建) |
| 预估工作量 | S(<1h) |
| 风险等级 | 低 |
新文件 examples/quick_start.rs,~36 行,结构如下:
1- 6 use 块(agcore 类型 + Arrow/std 类型)
7- 8 struct Greeter + impl Agent(name / system_prompt)
9-14 struct EchoTool + #[async_trait] impl BaseTool(完整 JSON Schema 带 text 参数)
15-20 fn mock_response() -> MessageResponse 辅助函数(构造纯文本响应)
21-33 #[tokio::main] async fn main():
- ToolRegistry::new() + register EchoTool
- MockProvider 预设 1 条 mock_response
- AgentBuilder::new() + provider + tool_registry + hook_executor → build
- AgentSession::new + submit_turn("你好")
- println!("{}", response.text())
设计约束:
- EchoTool 的
parameters()返回完整 JSON Schema:{"type":"object","properties":{"text":{"type":"string"}},"required":["text"]} - 无外部依赖、无 API key、零配置
- 展示四层抽象:Agent trait / BaseTool 自定义 / AgentBuilder 装配 / AgentSession 执行
验收条件:cargo run --example quick_start exit 0,输出包含 "收到"
Step 8.3 — 端到端示例
commit 6: examples/end_to_end.rs
| 属性 | 值 |
|---|---|
| 涉及文件 | examples/end_to_end.rs |
| 前置依赖 | commit 5(示例编写模式已建立);SqliteStore(Phase 7 已完成) |
| 预估工作量 | M(1-4h) |
| 风险等级 | 中 |
新文件 examples/end_to_end.rs,~160 行,最小可行边界(3 工具 + 3 轮 + 持久化验证)。
Provider 初始化策略:
if env::var("AG_LLM_BASE_URL").is_ok() && env::var("AG_LLM_API_KEY").is_ok() {
// 使用真实 Provider(AG_LLM_MODEL 非必填,from_env 内部会处理默认值)
let provider: Arc<dyn LlmProvider> = Arc::from(create_provider(
ProviderType::OpenaiChat, ProviderConfig::from_env("AG_LLM").unwrap()
)?);
} else {
// MockProvider fallback,预设 4 条响应序列
let found = ["AG_LLM_BASE_URL", "AG_LLM_API_KEY"].iter()
.filter(|k| env::var(k).is_ok()).collect::<Vec<_>>();
eprintln!("AG_LLM_* 环境变量不完整(检测到: {:?}),回退到 MockProvider", found);
}
工具定义:
| 工具 | 功能 | 关键技术点 |
|---|---|---|
EchoTool |
回显输入 | 基础工具注册模式 |
CalcTool |
本地执行四则运算 | 手动解析算术表达式(ponytail:基础 +-*/ 运算无需引入 rhai 依赖) |
NoteTool |
通过 MemoryStore trait 读写笔记 | 直接持有 Arc<dyn MemoryStore>,key 前缀 "note:";save 用 MemoryStore::save(MemoryItem { id: "note:{key}", content, .. }),query 用 MemoryStore::list(MemoryFilter { prefix: Some("note:"), .. }) |
持久化验证:
let dir = tempfile::TempDir::new()?;
let db_path = dir.path().join("agcore.db");
let backend = Arc::new(SqliteStore::open(&db_path)?);
// ... 构建 RuntimeBundle + AgentSession,写入数据 ...
drop(bundle); // 释放所有对 backend 的 Arc 引用
drop(session);
// 此时 backend 无活跃引用,SQLite 连接自动关闭
let backend2 = Arc::new(SqliteStore::open(&db_path)?); // 重建连接
// assert 数据仍在
输出示范:
=== agcore 端到端演示 ===
🔄 Provider: MockProvider (离线回退模式)
💾 SqliteStore: /tmp/agcore_XXXXX/agcore.db
🔧 注册工具: echo, calc, note
第 1 轮 用户: 帮我算 25 * 4
→ 调用 calc(...) → 100
→ 回答: 25 * 4 = 100
第 2 轮 用户: 记下来:结果是 100
→ 调用 note(save, ...)
→ 回答: 已记录
第 3 轮 用户: 我刚才算了什么?
→ 调用 note(query)
→ 回答: 您刚才的计算结果是 100
📊 用量: prompt=XX, completion=XX
=== 持久化验证 ===
✓ 跨连接数据存活验证通过
✓ 端到端演示完成
设计约束:
- 文件顶部注释说明
AG_LLM_*环境变量切换真实 Provider - 零外部配置可运行(Mock fallback)
- 最小可行边界:3 工具 + 3 轮 + 持久化验证,不膨胀
验收条件:cargo run --example end_to_end exit 0(零外部配置)
8.2 并行机会
commit 1 和 commit 5 可以并行执行(零文件重叠)。commit 5 也可与 commit 2 并行。commit 6 实质上也仅依赖「代码库状态稳定」而非某个具体 commit。
| 并行组 | commit A | commit B | 前提 |
|---|---|---|---|
| 1 | commit 1(#[non_exhaustive]) | commit 5(Quick Start) | 零文件重叠 |
| 2 | commit 2(StepStatus 修复) | commit 5(Quick Start) | 零文件重叠 |
| 3 | commit 5(Quick Start) | commit 6(端到端) | 零文件重叠,但存在知识依赖——commit 6 需参考 commit 5 的 MessageResponse 构造、MockProvider 用法、AgentBuilder 装配模式。推荐 commit 5 先行或实施前同步这些模式 |
8.3 风险与应对
| 风险 | 影响 | 可能性 | 应对 |
|---|---|---|---|
| MockProvider 响应序列与 tool-loop 消费顺序不匹配 | commit 6 端到端示例不通过 | 中 | 按 §5 假设 1:设计响应队列时确保每条 Mock 响应的 stop_reason 与 ToolUse/Stop 匹配。出现不匹配时改用完整 MessageResponse 构造显式控制 |
| NoteTool 与 AgentSession 的数据传递路径需要扩展现有 API | commit 6 需要修改 session.rs |
低 | ponytail 方案:NoteTool 直接持有 Arc<dyn MemoryStore> 引用,在 execute 时直接操作 MemoryStore::save/get,绕过 AgentSession 的 session_memory 封装 |
#[non_exhaustive] 在某个 enum 上导致 crate 内 match 编译失败 |
commit 1 不通过 | 低 | 实施前先运行 `rg "match.*(Message |
8.4 测试策略
| commit | 测试 | 方式 |
|---|---|---|
| commit 1 | 编译测试 | cargo build --all-targets |
| commit 2 | 编译 + 单测 + 无 deprecated warning | cargo build --all-targets && cargo test |
| commit 3 | 人工 review | git diff |
| commit 4 | 全量自动化 | cargo test + clippy + doc |
| commit 5 | 示例运行 | cargo run --example quick_start |
| commit 6 | 示例运行 | cargo run --example end_to_end |
| 最终 | 全量回归 | 全部三项 + 所有 10 个示例 |