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

31 KiB
Raw Permalink Blame History

AG Core Roadmap — v0.3.0

本文件聚焦 v0.3.0 版本 的规划与交付(Phase 1319)。Phase 13-19 全部完成,v0.3.0 交付完毕。 返回总入口:roadmap.md

v0.3.0 愿景

从"LLM 调用工具箱"升级为"能构建多 Agent 协作、RAG、长记忆 Agent 产品的基础系统"。补齐 LangChain 7 大组件中缺失的 Document 和 VectorStore 能力,落地笔记设计中的 ContextSlot fork/merge、摘要自动生成、知识图谱,建立 engine 引擎层(会话树 + time-travel Checkpointer + SubAgent Dispatch + Agent Switch),为即将开发的多 Agent 产品提供完整基础。

v0.3.0 总体范围

总体规模7 个增量 PhasePhase 1319),总新增代码约 2600 行,测试从 277 → 427。7 个 Phase 全部完成(M9-M15 已达成),v0.3.0 交付完毕。


v0.3.0 — 多 Agent 基础系统(Multi-Agent Foundation

目标:从"LLM 调用工具箱"升级为"能构建多 Agent 协作、RAG、长记忆 Agent 产品的基础系统"。补齐 LangChain 7 大组件中缺失的 Document 和 VectorStore 能力,落地笔记设计中的 ContextSlot fork/merge、摘要自动生成、知识图谱,建立 engine 引擎层(会话树 + time-travel Checkpointer + SubAgent Dispatch + Agent Switch),为即将开发的多 Agent 产品提供完整基础。

总体规模7 个增量 PhasePhase 13-19),总新增代码约 2600 行,测试从 277 → 427。

功能清单

P0 — 必须交付

# 功能 模块 方案要点
1 技术债清理(旧 types 文件) llm/types request.rs / response.rs / old_stream.rs 三个 Phase 0 旧文件删除;内部类型移入 provider/openai.rs
2 ContextSlot fork/merge agent/context fork(child_id, strategy) 别名 + merge(child, MergeStrategy) 三种策略(Append/Replace/Summarize
3 Document 系统 document/(新模块) Document 核心类型 + RecursiveCharacterSplitter(递归字符分割,支持 chunk_size/chunk_overlap/separators
4 Embedding 抽象 llm/embedding Embedding traitembed / dim+ MockEmbedding 测试实现
5 向量存储持久化 vector/(新模块) VectorStore trait + InMemoryVectorStore(读写)+ PersistentVectorStoreSqliteStore 后端)+ RagPipeline 组合器
6 摘要自动生成 agent / llm/hooks SummaryConfig 配置 + OnTurnEnd Hook 自动检测 token 水位 → 调 LLM 生成摘要 → SessionMemory::set("conversation_summary", ...)
7 SessionManager + 会话树 engine/(新模块) Session 工厂(create/create_child+ 按 ID 恢复(get+ 子树管理(children/parent/destroy_subtree+ 元数据持久化(MemoryStore
8 Time-travel Checkpointer engine/checkpointer checkpoint(session) 全量序列化 + rollback(session_id, ckpt_id) 回滚 + fork(session_id, ckpt_id, new_id) 分支 + list_checkpoints
9 Agent Switch engine/switch 热切换 session.agent(替换 Arc<dyn Agent>),slot 历史 / turn_index / session_memory 全保留
10 SubAgent Dispatch engine/sub_agent dispatch(parent, sub_agent, task, config) 单任务 + dispatch_all(parent, tasks, config) 并行派发(Semaphore 并发控制)+ 子 SessionMemory 继承 + SubTaskResult 结构化回传
11 知识图谱 memory/graph KnowledgeGraph traitadd_entity / add_relation / get_related / find_by_keywords+ InMemoryGraph 实现 + tag_index 标签管理
12 双通道检索 memory/retriever MemoryRetriever 扩展为双通道(KnowledgeStore + KnowledgeGraph+ RetrievalStrategy::Hybrid

实施计划 — 7 个增量 Phase

编号说明Phase 13-19 接续 v0.2 的 Phase 5-12,按开发顺序排列。

Phase 13: 热身清理 + ContextSlot fork/merge

目标:清除 Phase 0 遗留的旧 types 文件,交付超低价功能建立节奏。

Step 内容 文件范围 验证标准
13.1 OpenaiChatRequest 移入 provider/openai.rstypes/request.rs 删除 llm/types/request.rs + llm/provider/openai.rs cargo build --all-targets
13.2 OpenaiChatResponse/Chunk 移入 provider/openai.rstypes/response.rs 删除 llm/types/response.rs + llm/provider/openai.rs cargo build --all-targets
13.3 old_stream.rs 删除 + types/mod.rsChatResponse 删除 llm/types/old_stream.rs + llm/types/mod.rs cargo build + 确认 3 个旧文件不存在
13.4 ToolChoicerequest.rs 搬到 tool.rs llm/types/tool.rs + llm/types/request_v2.rs cargo test --all-targets 全绿
13.5 ContextSlot::fork(child_id, strategy) 别名 + merge(child, MergeStrategy) agent/context.rs 单元测试:fork → 子 slot 消息 = 父 slot 副本;merge(Append) → 消息按序追加

依赖:无 优先级P0 预估规模:约 200 行 状态 Phase 13 全部交付物已完成(2026-07-08)


Phase 14: Document 系统 + Embedding 抽象

目标:补齐 LangChain 7 大组件中最明显的缺口——Document 类型和分割器。不搞 Loader 框架,用户用 fs::read_to_string 自行加载。

交付物

  1. src/document.rs 新模块(Document 类型 + RecursiveCharacterSplitter
  2. src/llm/embedding.rsEmbedding trait + MockEmbedding

设计要点

  • Documentid / content / metadataHashMap<String, String>/ mime_type
  • RecursiveCharacterSplitterchunk_size(默认 1000/ chunk_overlap(默认 200/ separators["\n\n", "\n", "。", "", "", ".", " ", ""],含 CJK 标点)
  • 两阶段算法:按 separator 优先级递归分割(Phase 1+ 贪心合并 + overlap 滑动窗口(Phase 2
  • 所有长度比较以 Unicode 字符数为单位(chars_len()),非字节数
  • Embedding traitasync fn embed(&self, input: &[String]) -> Result<Vec<Vec<f32>>, LlmError> + fn dim()
  • 复用 LlmError 而非新错误类型
  • MockEmbedding:sin-hash 零依赖伪随机向量 + L2 归一化
  • 不引入 DocumentLoader trait(应用层职责)

实际新增2026-07-09 commit d4c4d8f,详见 docs/20-phase14-document-and-embedding.md):

  • 新增文件 3 个:
    • src/document.rs580 行)— Document 类型(4 字段 + new/from_raw 构造器,2 个 new 接受 impl Into<String> + RecursiveCharacterSplitter(两阶段算法:按 separator 优先级递归分割 + 贪心合并 overlap,所有长度比较 chars_len() 字符级,overlap 提取 chars().rev().take().rev() 字符级安全)+ 19 个内联测试
    • src/llm/embedding.rs183 行)— Embedding traitasync + LlmError+ MockEmbedding(sin-hash:字节和+长度做种子,f32::sin(seed + i) * 10000,L2 归一化到单位长度,零向量防除零)+ 6 个内联测试
    • examples/document_demo.rs(74 行)— 端到端演示 Document → RecursiveCharacterSplitter → MockEmbedding → InMemoryVectorRetriever → search
  • 修改文件 2 个:
    • src/lib.rs+3 行:pub mod document + pub use document::Document + 空行)
    • src/llm.rs+1 行:pub mod embedding
  • 关键设计:
    • 早返回守卫split_textchars_len(text) <= self.chunk_size 时直接返回 [text],避免短文本在 Phase 2 join("") 中丢失 separator 边界
    • Document::new 使用 impl Into<String>:接受 &strString,比规范示例的 String 更灵活
    • new() panic + try_new() Result 双路径:与 Rust 库惯例一致
    • CJK 分隔符扩展DEFAULT_SEPARATORS 包含 "。"/""/"",避免中文文本跳过句子级退化为空格分割
    • chunk_size = 0 校验:构造器拒绝零值,避免字符级兜底死循环
    • tracing 埋点split() 入口 tracing::debug! + 每文档/每 chunk tracing::trace!
    • debug_assert 溢出保护:单文档 chunk 数 < 10000 时 debug_assert!
    • Metadata 键覆盖文档化HashMap::insert() 静默覆盖 source_id/chunk_index/chunk_count 在 split() doc comment 注明
  • 测试:19 个 Document 测试(含 1 个 split_multibyte_utf8_boundary CJK 边界测试)+ 6 个 Embedding 测试,全量 286 → 313(+27 新测试,但部分测试覆盖范围重叠计算约 25 个净增)
  • 方案文档:docs/20-phase14-document-and-embedding.md(1417 行,含背景/调研/方案对比/实施计划(详细版)/3 轮审查修复记录),经过 3 轮 PM/SA 审查 + 1 轮实施后修复
  • clippy 0 警告,doc 0 warning
  • 无新增外部依赖(Cargo.toml 未修改)

实施后调整

  • 实施发现方案算法中 Phase 1 累加器设计与测试期望冲突("para1\n\npara2" 在 chunk_size=100 时 1 chunk 更合理),简化为"按 separator 切分 + Phase 2 合并"两阶段分工
  • 二次审查发现 split_text 缺少早返回守卫 + current_sep_count 虚增计数,全部已修复

依赖:无(纯数据结构 + 零新 crate 依赖) 优先级P0 预估规模:约 350 行 状态 Phase 14 全部交付物已完成(2026-07-09)


Phase 15: 向量存储持久化(SqliteStore 后端)

目标:实现 VectorStore 持久化,让语义检索支持进程重启后数据恢复。

设计决策:不用 pgvector。基于已有 SqliteStorerusqlite)做持久化包装——运行时全量加载到 InMemory 索引做余弦搜索,写时同步到 SqliteStore。

交付物

  1. 新增 src/memory/vector_store.rs937 行)—— VectorStore trait + InMemoryVectorStore + PersistentVectorStore + RagPipeline
  2. VectorStore traitadd(&[Document], &[Vec<f32>]) 批量 / search(query, k) 返回 (Document, f32) / remove(ids) 幂等
  3. PersistentVectorStore:构造时从 MemoryStore 全量加载已有索引;add 先写持久化后写内存(持久化失败时内存不污染,重启自动恢复);search 纯内存余弦搜索(快照 clone + 锁外计算)
  4. RagPipeline:组合器封装 split → embed → store.addingest)和 embed → store.searchretrieve)两条管线
  5. 存储格式:vec:{namespace}:{doc_id} → JSON {doc_id, content, metadata, embedding, created_at},通过 MemoryStore 通用接口读写
  6. src/memory/vector.rsVectorRetriever trait + InMemoryVectorRetriever 标注 #[deprecated(since = "0.3.0")],迁移路径指向 VectorStore / InMemoryVectorStore

实际新增2026-07-09 commit 32d886f):

  • 新增文件 1 个:src/memory/vector_store.rs937 行,含 19 个内联测试)
  • 修改文件 3 个:src/memory/vector.rs+4 行 deprecated 标注);src/memory.rs+pub mod vector_store + 4 个 pub use re-export);examples/document_demo.rs(迁移到 RagPipeline ingest+retrieve
  • 零新外部依赖(Cargo.toml 未修改)
  • 全量测试 313 → 335+22Phase 15 新增 19 测试 + 部分重叠计数 22 净增);clippy 0 警告,doc 0 warning
  • 设计文档:docs/21-phase15-vector-store-persistence.md(1570 行,经 3 轮审查 + 文档-代码不一致修复:search_orthogonal_vectors 返回 1 条 score≈0 而非空列表)

依赖Phase 14Document 类型 + Embedding trait 优先级P0 预估规模:约 400 行(实际约 937 行纯实现 + 测试) 状态 Phase 15 全部交付物已完成


Phase 16: 摘要自动生成

目标:闭环长对话能力。v0.2 的 inject_summary 消费端(FocusedConfig.summary_override)已就绪,缺的是生产端。

交付物

  1. SummaryConfig 结构体:trigger_token_ratio(默认 0.75 / max_context_tokens(默认 32_000/ summary_prompt(默认中文 DEFAULT_SUMMARY_PROMPT{messages} / debounce_turns(默认 3 / summary_model(默认 None 沿用主模型) / max_tool_result_chars(默认 500
  2. submit_turn / finalize_turn 中 OnTurnEnd 之后插入内联检查点(非 Hook 扩展):should_summarize(水位 + 防抖,首次不受防抖约束)→ generate_summary 关联函数(新 LlmCycle + submit_messages 无工具调用)→ 更新 FocusedConfig.summary_override + slot.save() 持久化 + SessionMemory::set("conversation_summary", summary) 全局快照
  3. AgentBuilder 扩展:.summary_config(cfg) 方法(不覆盖整个 AgentConfig
  4. 公开 APIget_conversation_summary() -> Result<Option<String>, AgentError>
  5. format_messages_as_text() 简洁版消息格式化(System/User/Assistant + [Tool: name] + Tool Result [id]: 截断到 max_tool_result_chars 字符)

设计决策:内联于 submit_turn 流程而非 Hook 扩展(因为 HookContext 无法携带 &mut self 引用更新 slot config,且流式路径的 finalize_turncycle 已销毁)。Option<SummaryConfig> 的 opt-in 机制已足够提供可插拔性,不改变 Hook 系统签名。流式路径中 submit_turn_stream 已将 turn_index 提前 ++1,检查点使用 saturating_sub(1) 修正。

依赖:无(submit_turn 流程 + CostTracker + SessionMemory + LlmProvider 均已就绪) 优先级P0 预估规模:约 220 行(实际约 250 行,含 11 个内联测试) 方案文档docs/22-phase16-summary-auto-generation.md471 行,经 PM/SA 审查 11 项修复 + 实施后第二轮审查 9 项修复全部完成) 状态 Phase 16 全部交付物已完成(含实施后 PM/SA/Code Reviewer 第二轮审查 PASS

实施后审查修复记录(共 9 项):

  • 🔴 B1generate_summary 调用 submit_messages(Vec::new(), vec![]) 发送空消息列表 → 移除 with_messages(),直接 submit_messages(vec![Message::user_text(prompt)], vec![])
  • 🟡 W4should_summarize 使用 self.turn_index 而非 current_turn 参数 → 改签名接收 current_turn,流式路径防抖准确
  • 🟡 W2summary_model 硬编码 unwrap_or("gpt-4o") → 改为条件赋值,None 时沿用 CycleConfig::default()
  • 🟡 W5Full 模式 slot.save() 无谓调用 → 移入 SlotMode::Focused 分支内
  • 🟡 W3format_messages_as_text 缺 30K 整体截断 → 新增 MAX_TOTAL_CHARS=30_000 + truncate_total_chars,优先保留最新
  • 🟡 W6:摘要成功无日志 → 添加 tracing::info!(turn, summary_len, "摘要自动生成成功")
  • 🟡 W1/W7:缺 3 个测试 → 新增 format_total_charset_truncation_keeps_recent / summary_written_to_focused_slot_config / summary_skipped_for_empty_messages / summary_not_generated_if_max_context_unreachable
  • 💭 context.rs:78 过时注释("v0.3 将支持 Hook 驱动")→ 更新为"v0.3 Phase 16 起 AgentBuilder 内联检查点自动生成摘要"

第二轮审查门禁PASS0 🔴 阻塞)。cargo test --all-targets 353 passed / 0 failedclippy 0 警告,doc 0 warning。


Phase 17: Agent 执行引擎(会话树 + Time-travel Checkpointer

目标:建立 engine/ 模块。解决 v0.2 中"session 在变量里、无法通过 ID 恢复、不支持父子关系"的空白。

方案文档docs/23-phase17-agent-execution-engine.md

交付物

  1. src/engine/ 新模块(session_manager.rs + checkpointer.rs + snapshot.rs + error.rs
  2. SessionManager
    • create(agent, bundle) -> Result<String, EngineError> — 创建根 sessionUUID v4 自动生成 ID
    • create_child(parent_id, agent) -> Result<String, EngineError> — 创建子 session(继承父 RuntimeBundleArc::clone 共享引用)
    • get(session_id) -> Result<Arc<Mutex<AgentSession>>, EngineError> — 按 ID 查找(仅查内存,不自动从存储恢复)
    • recover(session_id, agent, bundle) -> Result<Arc<Mutex<AgentSession>>, EngineError> — 从存储恢复 session
    • replace(session_id, session) -> Result<(), EngineError> — 替换已有 session 实例(用于 rollback 后切换)
    • children(parent_id) / parent(child_id) — 树形查询
    • destroy(id) — 生命周期管理(允许孤儿 session 存在,不递归删除子 session)
  3. Checkpointer
    • checkpoint(session) — 每个 submit_turn 末尾自动保存全量状态快照
    • rollback_load(session_id, ckpt_id) -> SessionSnapshot — 读取 checkpoint JSON 为 snapshot(不重建 AgentSession
    • list_checkpoints(session_id) — 列出 checkpoint 列表
    • delete_all(session_id) — 清理某 session 所有 checkpoint
    • fork() 推迟(底层可拆解为 rollback + create_child,作为高层 API 等价于约 30 行组合代码,已具备原始能力)
  4. SessionSnapshot 独立 struct(位于 engine/snapshot.rs)—— 避开 Arc<dyn Agent> 不可序列化的限制,通过 to_snapshot() / from_snapshot() 双向转换实现 AgentSession 快照持久化
    • to_snapshot()async,从 SessionMemory 读取完整数据)+ from_snapshot()(纯同步构造)+ restore_memory()async 写回持久层)
  5. EngineError 枚举(含 MemoryError 透传变体 与项目既有 AgentError 风格一致)

Checkpoint 存储格式ckpt:{session_id}:{ckpt_id}SessionSnapshot JSON(全量 session 状态,含所有 slot 消息列表)。Ponytail:全量 JSON 够用,等遇到存储效率问题时再改增量模式。

会话树持久化session:{session_id}:metaSessionMeta JSON{agent_name, parent_id, created_at, turn_count}

依赖Phase 10ContextSlot 持久化 — 消息由 slot 自己管,Checkpointer 管执行状态) 优先级P0 预估规模:约 700 行(5 新增文件 + 5 修改文件) 状态 Phase 17 全部交付物已完成


实际新增2026-07-153 commits + 实施审查修复一轮):

  • 新增 5 文件(src/engine/mod.rs19 行)+ error.rs43 行)+ snapshot.rs35 行)+ checkpointer.rs373 行)+ session_manager.rs910 行含测试)
  • 修改 5 文件
    • src/llm/types/usage.rsCostTrackerClone, Serialize, Deserialize3 行)
    • src/agent/context.rsContextSlot + MergeStrategySerialize, Deserialize4 行)
    • src/agent/session_memory.rs — 新增 list_entries() + set_with_meta() 方法
    • src/agent/session.rs — 新增 to_snapshot() (async) / from_snapshot() (sync) / restore_memory() (&mut self, async) / has_pending_memory_restore() + 公开 bundle() accessor
    • src/lib.rspub mod engine
  • 新增 1 示例examples/engine_demo.rs~210 行,端到端演示 create → submit_turn → checkpoint → list → rollback_load → from_snapshot → restore_memory → replace → destroy 全链路,含 rollback 一致性 assert
  • 依赖:零新外部依赖(ponytail:ckpt_id 用纳秒+计数器生成,session_id 同理)
  • 测试353 → 374+21 引擎内联测试:Checkpointer 6 个 + SessionManager 15 个)
  • 质量基线cargo test --all-targets 374 passed / 0 failedcargo clippy --all-targets -- -D warnings 0 警告;cargo doc --no-deps 0 warningcargo run --example engine_demo exit 0
  • 关键设计决策落地
    • SessionSnapshot 独立 struct(避开 Arc<dyn Agent> 不可序列化)
    • to_snapshot async + from_snapshot 纯同步 + restore_memory async 三段式分离
    • session_memory_data 改用 HashMap<String, SessionMemoryEntry>(保留 metadata/created_at
    • EngineError::Memory(#[from] MemoryError) 透传变体
    • EngineManager 锁契约:所有写操作先 HashMap 再 I/O(或反之,destroy 反向)
    • 自动 checkpoint 失败 tracing::error! 不阻断主流程(不提供强持久化保证)
    • ckpt_id 时间戳+纳秒+计数器无外部依赖(created_at_nanos 字段确保同秒内精确排序)
    • 孤儿策略:destroy() 不递归删除子 session;父被销毁后 parent() 返回 Ok(None)
  • 实施审查通过:经过 PM + SA + Code Reviewer 三方联合审查 → 1 轮修复 → 全部 🟡 警告关闭
  • M13 里程碑达成 — Phase 17 rc.1 标签可打(v0.3.0 第二个 Phase

Phase 18: Agent Switch + SubAgent Dispatch + Agent 间交互

目标:在 SessionManager 基础上,提供 Agent 角色热切换和子代理调度能力。

交付物

  1. engine/switch.rsswitch_agent(session_id, new_agent):替换 Arc<dyn Agent>slot 历史 / turn_index / session_memory 全保留
  2. engine/sub_agent.rs — SubAgent Dispatch 核心:
    • DispatchConfigmax_concurrency(默认 10/ inherit_session_memory(默认 true/ bridge_keys
    • dispatch(parent_id, sub_agent, task, config) -> SubTaskResult:创建子 session → 继承父 SessionMemory → submit_turn → 返回结构化结果
    • dispatch_stream(parent_id, sub_agent, task, config) -> SubTaskStream:流式版
    • dispatch_all(parent_id, tasks, config) -> Vec<SubTaskResult>:并行派发,tokio::sync::Semaphore 控制并发数
  3. SubTaskResultchild_id / response / usage / summary + child_memory(sm) 读取子 SessionMemory

Agent 间交互三层级

  • 父→子:继承 SessionMemory 快照 + bridge_keys 指定 key 强制注入 system prompt
  • 子→父:SubTaskResult 结构化回传 + SessionMemory["result_summary"] 结论摘要
  • 子↔子(间接):通过公共 MemoryStore namespaceshared:{parent_session_id})共享数据

依赖Phase 17SessionManager + 会话树) 优先级P0 预估规模:约 500 行

实际新增2026-07-15 commit 46de111,详见 docs/24-phase18-agent-switch-and-dispatch.md):

  • 方案文档:docs/24-phase18-agent-switch-and-dispatch.md700 行,含 Agent Switch 与 SubAgent Dispatch 的设计推演)
  • 新增文件 2 个:
    • src/engine/switch.rs222 行)— SessionManager::switch_agent() 热切换:替换 Arc<dyn Agent>slot 历史 / turn_index / session_memory / cost_so_far 全部保留,同步更新 SessionMeta.agent_name 到持久层
    • src/engine/sub_agent.rs1071 行)— SubAgent 调度完整实现:4 个公开方法 + 3 个公开类型
  • 修改文件 4 个:
    • src/engine/mod.rs+5 行:pub mod switch; pub mod sub_agent; + pub use sub_agent::{DispatchConfig, SubTaskResult, SubTaskStreamEvent};
    • src/engine/error.rs+1 变体:DispatchFailed(#[source] String)
    • src/engine/session_manager.rs+2 处可见性:save_session_meta / load_session_metapub(crate)switch.rs 使用)
    • src/llm/types/usage.rs+From<Usage> 实现供 SubTaskResult.usage 字段构造)
  • 新增 4 个示例:
    • examples/agent_switch_demo.rs(115 行)— Agent 热切换演示
    • examples/sub_agent_dispatch_demo.rs141 行)— dispatch / dispatch_all 并行派发演示
    • examples/bridge_keys_demo.rs197 行)— bridge_keys 过滤的 SessionMemory 继承演示
    • examples/dispatch_stream_demo.rs121 行)— dispatch_stream 流式派发演示
  • 关键设计:
    • switch_agent 锁契约:先 get session → 锁 Mutex 替换 agent 并读取 turn_index → 释放 Mutex → 读/写 SessionMeta(无锁 IO),最大限度减少锁竞争
    • SessionMeta 保留原则:切换 agent_name 字段,但 created_at / parent_id 保留原始(血缘不可变)
    • switch_agent 不自动 checkpoint:与 auto_checkpoint 语义一致(仅 submit_turn / finalize_turn 触发),避免每次角色切换产生冗余 checkpoint
    • inherit_session_memory 快照语义:捕获调用时刻的父 session_memory 快照,子 session 写回后即使父被并发写入也不传播(防止非确定性结果)
    • bridge_keys 三态语义None = 不继承任何(安全默认)/ Some(vec![]) = 继承全部 / Some(keys) = 仅继承指定 key
    • shared_namespace 约定式共享:纯约定字段,不触发自动注入逻辑,子 agent 显式 session.set_session_data("shared:{prefix}:{key}", value) 写入
    • dispatch_all 部分成功语义Vec<Result<SubTaskResult, EngineError>> 按输入顺序 indexed 收集,task panic 通过 DispatchFailed 哨兵占位(不破坏顺序一致性)
    • dispatch_stream 后台 finalizespawn task 内部调 finalize_turn() 落库,明确不参与 auto_checkpoint(避免与流式 checkpoint 重复)
    • SubTaskStreamEvent 事件序列ChildCreated { child_id }Stream(StreamEvent) × NCompleted(SubTaskResult)Error { child_id, error }
    • SUBTASK_NAMESPACE 防误注入:子 session 注入到 SessionManager 时使用 subtask: prefix 避免与 SessionMeta 的 session:{id}:meta 冲突
  • 测试:+17 内联测试(4 switch + 5 dispatch + 4 dispatch_all + 4 dispatch_stream),全量 374 → 391 passed / 0 failed+170 失败)
  • 质量基线:cargo test --all-targets 391 passed / 0 failedcargo clippy --all-targets -- -D warnings 0 警告;cargo doc --no-deps 0 warning4 个示例全部 exit 0
  • 零新外部依赖(ponytail:与 Phase 17 一致)

状态 Phase 18 全部交付物已完成


Phase 19: 知识图谱 + 双通道检索

目标:落地 docs/note-knowledge-graph-design.md 中记录的知识图谱设计,提供实体-关系图检索能力。扩展 MemoryRetriever 为双通道。

交付物

  1. src/memory/graph.rs(新文件):
    • GraphEntity / GraphRelation / ScoredEntity 核心类型
    • RelationDirection 枚举(Outgoing / Incoming / Both
    • KnowledgeGraph traitadd_entity / get_entity / remove_entity / add_relation / remove_relation / get_related / find_by_keywords / find_tags / set_entity_tags
    • InMemoryGraph 实现:HashMap<String, GraphEntity> + Vec<GraphRelation> + BFS 图遍历
    • TagConstraintsmax_tags_per_entity 默认 8
  2. src/memory/retriever.rs 扩展:
    • MemoryRetriever 增加 knowledge_graph 可选字段
    • RetrievalStrategy 枚举:Hybrid(默认)/ KnowledgeOnly / GraphOnly

与 Document 系统的关系:知识图谱提供实体级检索("这个实体和什么相关"),VectorStore 提供语义相似度检索("哪些文档最相似"),两者互补。

依赖MemoryStore 持久化(v0.1 Phase 3 优先级P0 预估规模:约 400 行(实际约 720 行核心 + 200 行测试) 方案文档docs/25-phase19-knowledge-graph-and-retrieval.md(652 行,经 PM/SA 双轮审查 PASS 状态 Phase 19 全部交付物已完成(2026-07-17)

实际新增2026-07-17):

  • 新增文件 2 个:
    • src/memory/graph.rs~580 行)- GraphEntityid/name/entity_type/description/tags/properties+ GraphRelation(无 id 字段,composite_key() 派生)+ RelationDirection#[derive(Default)] + #[default] Outgoing+ ScoredEntity(含 path 路径)+ TagConstraintsmax_tags_per_entity 默认 8+ KnowledgeGraph trait10 个 async 方法)+ InMemoryGraphMutex<GraphInner> 单一锁结构,避免嵌套锁死锁)+ BFS 图遍历(visited 防环 + 权重乘积衰减 + 多路径先到先得 + depth=0 返回空)+ 标签管理(tag_index 反向索引)+ 23 个内联测试
    • examples/knowledge_graph_demo.rs(~140 行)- 端到端演示:构建图谱 -> BFS 遍历 -> 标签管理 -> Hybrid/GraphOnly 双通道检索
  • 修改文件 3 个:
    • src/memory/retriever.rs - RetrievalStrategy 枚举(Hybrid 默认 / KnowledgeOnly / GraphOnly+ RetrievalItem enum(统一列表,score() 方法)+ RetrievalResult 新增 strategy 字段(反映实际执行策略)+ MemoryRetriever 双通道(with_knowledge_graph / with_strategy 链式构造)+ search_knowledge_store / search_graph 私有方法 + tokio::join! 并行 + 旧 ScoredItem 标注 #[deprecated] + RetrieverConfig 新增 graph_depth(默认 2+ 13 个内联测试
    • src/memory.rs - pub mod graph + 重导出 7 个图类型 + 更新 retriever 重导出
    • examples/knowledge_search_demo.rs - 适配新 APIRetrievalItem enum match + RetrieverConfig.graph_depth
  • 关键设计:
    • Mutex<GraphInner> 单一锁结构 - 避免 set_entity_tags 嵌套锁死锁风险(审查修复)
    • RetrievalResult.strategy 反映实际执行策略 - graph 未注入时退化为 KnowledgeOnly(审查修复)
    • GraphRelation 无 id 字段 + composite_key() 派生方法
    • BFSvisited 防环 + 权重乘积衰减 + 多路径先到先得 + depth=0 返回空
    • 零新外部依赖ponytail 风格)
  • 测试:391 -> 427 passed / 0 failed+36 新测试:23 graph + 13 retriever
  • 质量基线:cargo test --all-targets 427 passed / 0 failedcargo clippy --all-targets -- -D warnings 0 警告;cargo doc --no-deps 0 warningcargo run --example knowledge_graph_demo exit 0

v0.3.0 Phase 依赖关系图

graph BT
    P13["<b>Phase 13: 热身清理</b><br/>旧 types 文件删除<br/>ContextSlot fork/merge"]:::done
    P14["<b>Phase 14: Document + Embedding</b><br/>Document 类型<br/>RecursiveCharacterSplitter<br/>Embedding trait"]:::done
    P15["<b>Phase 15: 向量存储持久化</b><br/>VectorStore trait<br/>PersistentVectorStore<br/>RagPipeline<br/>19 新测试"]:::done
    P16["<b>Phase 16: 摘要自动生成</b><br/>SummaryConfig<br/>内联检查点<br/>首次防抖跳过<br/>18 新测试"]:::done
    P17["<b>Phase 17: 执行引擎</b><br/>SessionManager<br/>会话树<br/>Time-travel Checkpointer<br/>21 新测试"]:::done
    P18["<b>Phase 18: 切换与调度</b><br/>Agent Switch<br/>SubAgent Dispatch<br/>dispatch_all 并发控制<br/>17 新测试"]:::done
    P19["<b>Phase 19: 知识图谱</b><br/>KnowledgeGraph trait<br/>InMemoryGraph<br/>双通道检索"]:::done

    P15 --> P14
    P18 --> P17

    classDef done fill:#4ade80,stroke:#16a34a,color:#1a1a1a
    classDef pending fill:#fbbf24,stroke:#d97706,color:#1a1a1a

关键里程碑

里程碑 Phase 完成条件 可验证指标 状态
M9 Phase 13 旧 types 文件删除、cargo test --all-targets 全绿、fork/merge 测试通过 2026-07-08
M10 Phase 14 Document + RecursiveCharacterSplitter 分割结果验证、MockEmbedding 测试通过 2026-07-09
M11 Phase 15 PersistentVectorStore 持久化 roundtrip、RagPipeline::ingest → retrieve 端到端验证 2026-07-09
M12 Phase 16 多轮对话后摘要自动写入 SessionMemory、派生 slot 时摘要正确注入 + 第二轮实施审查 PASS 2026-07-10
M13 Phase 17 (rc.1) SessionManager 创建/recover/replace/子树/销毁集成测试通过、Checkpointer checkpoint/rollback/list_checkpoints 验证(fork 推迟,按需时引入) 2026-07-15
M14 Phase 18 switch_agent 热切换验证(slot / turn_index / session_memory 保留)、dispatch / dispatch_all 并行派发 + Semaphore 顺序、dispatch_stream 流事件序列验证 2026-07-15
M15 Phase 19 KnowledgeGraph 实体-关系 CRUD + get_related BFS 验证、双通道检索 Hybrid 策略验证 2026-07-17