Codewhale Workflow 外部记忆(External Memory)设计边界:基于 v0.9.0 Cutline 的层划分、可见性与权限原则
2026/9/9 14:00:01 网站建设 项目流程

Codewhale Workflow 外部记忆(External Memory)设计边界:基于 v0.9.0 Cutline 的层划分、可见性与权限原则

【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale

本文解读 CodeWhale 开源仓库中的设计文档 docs/rfcs/WORKFLOW_EXTERNAL_MEMORY.md。该 RFC 回答了一个关键架构问题:当 Workflow(工作流)系统演化到 v0.9.0 之后,跨长时运行的外部记忆(External Memory)应该如何被引入。它是一份设计边界(design boundary)而非运行时实现——先划定"什么该做、什么绝不该做",再谈代码。读完本文,你将理解:外部记忆为何必须保持可选与显式、它与现有 User Memory / Repo Search / RLM Memo / TraceStore / Cached-main 五条记忆与回放层的边界划分、可见性与权限的硬性要求,以及未来实现应遵循的落地路线。

文档定位:原则优先的 Cutline

文档自注为"Principle-only cutline",状态标注日期 2026-07-15,并在 v0.9.0 依然有效。它开宗明义地划清了"已经存在"与"仅被提议"的边界:

  • 仓库中已经存在:用户记忆(/memory命令与remember工具)以及 RLM 会话(见 docs/MEMORY.md、docs/ARCHITECTURE.md);
  • 仅被提议、尚未进入代码树:层边界表格中出现的 TraceStore、ARMH/RLM memo store、cached-main overlay 等机制名称。

这一点提醒读者:本文引用到的多数分层表格属于未来的演进路线图,真正的落地必须逐个经过设计与评审,而不是一蹴而就。把"原则"与"现状"区分开,是理解该 RFC 的前提。

核心决策:外部记忆必须可选、显式、可审计

RFC 的Decision章节给出 v0.9.0 之后不可动摇的底线:

外部记忆应保持可选(optional)与显式(explicit)。CodeWhale 的正常运行不能依赖它,Workflow 不得为长时运行静默开启外部记忆。

在此基础上,未来版本中外部记忆只能以三种形态出现:

  1. 显式的工作流节点(explicit workflow node)——其输入、输出、作用域与权限都在类型化的 Workflow IR 中可见;
  2. 可选的插件或技能(skill)驱动的工具——由用户刻意启用;
  3. 有文档记录的实验(documented experiment)——其状态可被检查、清空与导出。

同时它被明确排除在三种角色之外:

  • 不能是隐藏的上下文基底(hidden context substrate)
  • 不能是仓库搜索的替代品
  • 不能是每次工作流运行的默认后备存储

为什么"显式节点"是一个硬约束:类型化 IR 佐证

"输入、输出、作用域与权限在类型化 Workflow IR 中可见"这一要求并非空话。Workflow 引擎的核心 crate crates/workflow/src/lib.rs 维护着 Rust 侧的类型化 IR 边界,其 crate 注释明确写道:运行时工具暴露、worktree 应用、回放与模型执行,只有在取消与证据(evidence)语义被证明之后,才允许叠加在其上(见crates/workflow/src/lib.rs顶部文档注释)。WorkflowSpec携带nodes: Vec<WorkflowNode>WorkflowNode枚举统一建模顺序、分支、循环、展开等各类节点,并有专门的校验函数把关节点形态。

也就是说:如果未来要引入外部记忆,就必须先把它提升为一等公民的 IR 节点,让validate_workflow_nodes之类的校验路径能看到它的存在——这与"隐藏检索(hidden retrieval)藏在普通 prompt 背后"的形态针锋相对。同样的思路也体现在实验性搜索模块 crates/workflow/src/experimental_search.rs 中:它自称是"authoring and freeze boundary,而非新的运行时或调度器",并强调 worker 自报结果永远不会被提升为硬门禁证据——防止把不可审计的隐式通道悄悄变成系统默认行为。

层边界:六层记忆与回放如何分工

RFC 的核心是一张层边界表,把外部记忆与既有/规划中的记忆和回放层彻底剥离开。这张表是全文的骨架,逐层说明如下(保留原始英文层名以便对照源码):

作用域v0.9.0 之后的规则
User memory(用户记忆)/memory呈现的小型持久化用户偏好与事实可选开启、归用户所有、不作为工作流证据
Repo search / codemap(仓库搜索/代码地图)从仓库派生的结构与搜索结果可由工作区重建;不是记忆日志
ARMH/RLM memo(会话内记忆)会话内工作记忆与精确上下文记忆化命中/未命中遥测可见;不构成持久回放证据
TraceStore记录工作流、分支、叶子与控制结果确定性回放的来源;回放期间不做实时模型调用
Cached-main overlay(缓存主分支覆盖层)经评审与回放后沉淀的经验可检查、可回退;绝不改写 Git main
External memory(外部记忆)常规上下文之外的本地或插件支撑的大数据仅限显式节点/插件;必须可见且可清空/导出

User memory:今日唯一的记忆实现

表格中的 User memory 是仓库中真实存在的部分。系统文档 docs/MEMORY.md 说明:自 v0.9.4 起,原生记忆存储(native memory store)是唯一的记忆系统——以 Markdown 文件为持久源、由 SQLite FTS5 做全文索引,完全离线,按仓库 git origin 的哈希划分作用域。

  • 启用方式:环境变量DEEPSEEK_MEMORY=on(真值:1/on/true/yes/y/enabled),或在~/.codewhale/config.toml写入[memory] enabled = true
  • 目录布局:~/.codewhale/memory/global/MEMORY.md(全局)+workspace/<id>/MEMORY.md(仓库级)+ 可重建的index.sqlite3FTS5 缓存;
  • 注入策略:启用后系统提示词携带**有边界、带出处(provenance)**的记忆块(最多 32 条 / 12,000 字符,global + 当前 workspace),并明确标记为"不可信用户数据"而非第二指令层;更深层检索通过memory_search/memory_get工具完成;
  • 写入方式:#前缀的 composer 输入、/memory native remember子命令、以及模型侧自动化的remember工具(JSON schema 见 docs/MEMORY.md)。

这与 RFC 中 User memory 的定位完全一致:"Opt-in、用户所有、不作为工作流证据"。它服务于跨会话的偏好与约定(如"本仓库用 4 空格缩进"),而不是被 Workflow 当作隐含证据源。

ARMH/RLM memo:可见的命中/未命中遥测

表格要求 ARMH/RLM memo(会话内工作记忆与精确上下文记忆化)提供可见的命中/未命中遥测,且不构成持久回放证据

"可见遥测"在 IR 中已有对应数据结构:crates/workflow/src/lib.rs中的WorkflowMemoUsage携带armh_hitsarmh_missesarmh_saved_estimated_tokens以及 provider prompt-cache 的命中/未命中计数(见crates/workflow/src/lib.rsWorkflowMemoUsage定义与add_assign聚合逻辑)。这些字段随LeafResult一起被记录,使得"某个叶子节点是否真的从记忆化中获益"可以量化——这正是 RFC 反复强调的可解释性在数据结构层面的落地。

另一方面,RLM 会话(persistent Recursive Language Model REPL 会话)今天已经存在于仓库中,docs/ARCHITECTURE.md 将其描述为"沙箱化 Python REPL,支持语义化辅助调用与var_handle输出"。RFC 的 status 注记特意澄清:目前树中只有 user memory 与 RLM 会话,ARMH/RLM memo store 本身仍是提案。

TraceStore:确定性回放的证据源

TraceStore 的规则是"记录工作流、分支、叶子与控制结果,作为确定性回放的来源;回放期间不进行实时模型调用"。

尽管 TraceStore 尚未进入代码树,但其回放契约在 crates/workflow/src/replay.rs 已有扎实的雏形:

  • WorkflowReplayTracetrace_idleaf_recordsReplayLeafRecord:叶子输入哈希 + 结果)与control_recordsReplayControlRecord:控制节点结果与生成节点)组成;
  • WorkflowReplayExecutor以这些记录为输入重放执行;
  • 关键选项ReplayOptions { allow_live_replay: bool }默认关闭(见crates/workflow/src/replay.rs),即默认不允许实时(live)回放——与 RFC"回放期间不做实时模型调用"互为表里:回放应当只依据已记录的证据复现结果,而不是重新烧钱调用模型。

Cached-main overlay:可回退、绝不写 main

该层承载"经评审与回放后沉淀的经验/教训",但要求可检查、可回退、绝不改写 Git main。它把"经验沉淀"与"真实仓库状态"彻底隔离:任何从运行中提炼出的改进,都要先落在这个可逆的 overlay 上,经人工/门禁评审后再走正常合入路径。

外部记忆:行尾的"新层"

外部记忆在表中是独立一行:作用域为"常规上下文之外的本地或插件支撑的大数据",v0.9.0 之后的规则是仅限显式节点/插件,必须可见且可清空/导出。把这一行放在表格末尾,语义很清楚:它是将来要加的第七层,而不是对既有六层的暗中替换。

可见性要求:把记忆做成"活动的上下文层"而非"直觉"

RFC 给出任何未来外部记忆实现都必须对外展示的六项信息:

  1. 何时处于激活状态
  2. 由哪个工作流节点或插件拥有它
  3. 状态存储在哪里
  4. 它能读取哪些仓库或运行作用域
  5. 它是否被纳入回放、导出或晋升(promotion)证据
  6. 如何检查、清空、固定(pin)与导出它

原文接着给出了一个判定准则,值得原样保留:

UI 应把外部记忆当作一个活动的上下文层来对待,而不是当作看不见的模型直觉。如果一次运行无法解释某条事实为何来自外部记忆,那么这个功能就没有准备好作为默认使用。

这条"解释性原则"是全文档最具操作性的验收标准:任何记忆引入,只要无法在运行结束时间答"这条事实从哪来",就应视为不成熟。它与前文 IR 中的memo_usage遥测、TraceStore 的ReplayLeafRecord输入哈希是一脉相承的——CodeWhale 的记忆哲学是用出处与可观测性取代"黑盒直觉"。

权限与隐私:继承最严格的相关作用域

外部记忆必须默认采用最严格的适用作用域,RFC 列出四条硬约束:

  1. 不得跨越仓库/工作区边界,除非获得显式批准——对应 docs/MEMORY.md 中已有实现的隐私设计:workspace 记忆以 git origin 的哈希为 key,一个仓库的笔记不会泄漏进另一个仓库的 prompt;
  2. 项目本地配置不得静默启用宽泛的外部记忆读取——防止仓库内一个.toml就把用户本机大范围数据卷进上下文;
  3. 回放必须把外部记忆输入记录为证据,或将回放标记为不可用/已分叉(diverged)——这与 replay.rs 中"依据输入哈希 + 记录结果重放"的模型一致:证据链缺失时宁可声明"回放不可用",也不能用猜测补齐;
  4. 导出必须让外部记忆的引用可见,但默认不得倾倒私有的原始状态——即"导出引用、遮蔽原始数据"。

推迟的工作与落地顺序

RFC 明确列出 v0.9.0 cutline 范围内不做的五件事,防止范围蔓延:

  • 默认开启的 Aleph 风格记忆(对所有 Workflow 运行);
  • 从外部记忆自动晋升进 cached-main overlay;
  • 在普通 prompt 背后做隐藏检索;
  • 托管式或共享式外部记忆服务;
  • 把外部记忆当作 TraceStore 回放的替代品。

最后,RFC 给出了明确的未来实施顺序建议

未来的实现应先从一个只读的类型化工作流节点与一个mock 回放夹具(mock replay fixture)开始,然后再加入任何插件支撑或实时检索路径。

这条路线与 Workflow crate 的现状高度吻合:目前 crates/workflow/src/lib.rs 中已经存在以 mock 叶子结果(leaf_outcomes映射等)驱动执行器的测试脚手架,而 crates/workflow/src/replay.rs 提供了类型化的 trace/record 结构——两者共同构成"先只读节点、先 mock、再谈真实检索"的天然试验台。此外,相关演进在根 CHANGELOG.md 的 v0.9.0 阶段记录中亦可见端倪(例如叶子/控制节点结果记录朝向 TraceStore 契约的方向,以及"外部记忆保持可选、显式、可见、可清空/导出,而不是成为隐藏的默认上下文基底"的表述)。

总结

WORKFLOW_EXTERNAL_MEMORY这份 RFC 的独特价值,在于它用最小的篇幅划定了一条最清晰的架构红线

  • 记忆要分层:User Memory 管用户偏好、Repo Search 管可重建事实、ARMH/RLM Memo 管会话内记忆化(带命中遥测)、TraceStore 管确定性回放、Cached-main 管可逆经验沉淀——各司其职,互不越界;
  • 外部记忆要显式:只能是类型化 IR 节点、用户刻意启用的插件/技能工具、或有完整可观测性的实验;
  • 一切要可审计:激活状态、属主、存储位置、作用域、证据参与、检查/清空/导出路径缺一不可;
  • 数据要守界:跨仓库需批准、本地配置不得静默放权、回放证据链断裂即声明不可用、导出不泄私密原始态。

对于希望参与 CodeWhale 演进(Issues / PRs 欢迎)的开发者,这份文档给出了进入门槛最低的起点:在真实代码库中先建立只读节点与 mock 回放验证,再谈任何插件或实时检索。对使用者而言,它也意味着一个稳定的承诺——无论未来记忆能力如何扩展,默认的、显式的、可解释的 CodeWhale 运行方式不会因为新增记忆层而悄悄改变。

【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询