MemoryLake
返回全部文章
Tutorial2026 年 9 月 9 日·12 分钟阅读

如何将 Factory Droid 的 Spec Plan 移出用户主目录(2026 指南)

Spec Mode 是 Factory Droid 最出色的功能,它所生成的产物是你们团队在一周内创建的最有价值的文档。

想想其中包含什么。你描述一个目标及其约束条件。Droid 读取代码库——其官方文档称它会“调研代码库、读取相关文件并提出具体的实现方案”——同时明确不触碰任何内容,因为 Spec Mode “采用只读规划行为,然后调用 ExitSpecMode 请求批准”。接着,人类阅读该方案,进行讨论并予以批准。调研、权衡和人类判断,全部凝聚在一个文件中。

默认情况下,该文件会被写入 ~/.factory/specs

不是代码库。不是共享云盘。而是恰好运行该会话的用户的个人主目录。你们本周最优秀的推理成果仅存在于一台笔记本电脑上,脱离了版本控制,对于负责实现的队友以及会询问“为什么要这样做”的评审人员来说,完全是不可见的。

这只需要修改一行配置,然后做一个稍微大一点的决定。如果你还在迁移阶段,从 GitHub Copilot 迁移到 Factory Droid 介绍了指令文件方面的内容;而本文则关注 Droid 在你开始工作后所产出的内容。

为什么你产出的最佳推理会落在代码库之外

Factory 的设置文档中有一个名为“Spec mode settings”的章节。它包含一句描述和仅有的一个设置项。

“控制由 Spec Mode 创建的持久化 spec 存储。”

该设置项是 specSaveDir,它在参考表中的对应行写道:

“保存 spec 的写入目录。支持 ~ 路径展开。”

其默认值为 ~/.factory/specs

这值得坦率地说明:确实存在一个持久化的 spec 存储,它确实一个已记录的功能,并且它默认指向一个针对每个用户的本地位置。没有隐藏任何东西,也没有损坏任何东西。这个默认值只是将个人工具的默认设置应用到了团队产物上。

这也是一种一贯的设计风格,而不是疏忽。在同一个设置参考中,worktreeDirectory(使用 worktree 标志创建的 git 工作树的父目录)默认值为 ~/.factory/worktrees。Factory 将自己的脚手架放在你的用户主目录下,对于脚手架来说这是正确的直觉。但 spec 并不是脚手架。

随之而来的是两件事,第二件代价高昂。

方案无法传递。 Spec Mode 正是针对那些方案最为关键的工作而推荐的:

“Spec Mode 用于实现前的调研和规划。适用于架构变更、迁移、安全敏感型工作,或任何你希望在 Droid 编辑文件前评审方案的任务。”

这些都是需要多人协作、耗时数周的工作。负责实现第四步的人往往不是运行会话的人,而方案并不在他们能够阅读的地方。

该模式所强制执行的边界也值得引用,因为它解释了为什么输出结果足够可信、值得保留:

“在 Spec Mode 期间,Droid 不应编辑文件、更改配置、提交代码、启动服务或写入外部系统。它可以读取文件、搜索代码库、检查链接的产物并提出澄清问题。”

推理无法在任务结束后留存。 一个 spec 是针对特定时刻编写的:当前的代码库、当前的约束、当前的选项集。六个月后,实现代码已合并,而 spec 成了没人会打开的用户主目录里的一个过期文件。其中的决策——例如“由于重放成本,我们拒绝了事件溯源方案”、“我们接受了增加一张表以避免迁移”——依然成立且起着支撑作用,但它们没有被作为决策记录在任何地方,而只是作为过时方案中的一个段落存在。

这第二个问题是人们很晚才会发现的,通常是在有人离职时。这与在有人离职时保留 AI 上下文的情况如出一辙:知识确实被写下来了,但写在了个人的地方。

人们尝试的其他替代方案

手动将优秀的 spec 复制到代码库中。 这确实可行,前一两个 spec 往往会这样处理。但摩擦在于,文件位于你需要记住的路径中,且以会话命名而非以工作命名,因此这种手动复制很快就会停止。

将方案粘贴到 Pull Request(PR)描述中。 这种做法更好,因为它落在了可评审且永久留存的地方。但 PR 描述的范围仅限于单次 diff,而一个跨越四个 PR 的 spec 会被拆碎到四个描述中,每个描述都缺失了对其他部分至关重要的内容。

将方案放入工单(Ticket)中。 同样的权衡。方案现在对团队可见,并与一个最终会被关闭的工作项绑定。但没人会去已关闭的工单中寻找某张表存在的原因。

将 spec 转化为 AGENTS.md 的一部分。 这混淆了两种不同类型的内容。AGENTS.md 存放的是每次会话都会读取的常规指令;而 spec 是一次性的方案。将它们合并,你会得到一个超长的、每次都会加载的文件,里面描述着早在三月份就已经完成的工作。

保留默认设置并依赖会话记录(Transcript)。 这是最糟糕的选择,因为 Droid 自身的文档将子智能体(subagent)和会话行为描述为受限于会话本身,而记录只是日志,不是文档。Spec Mode 的全部意义就在于它能产出比记录更好的东西。

永久提交每一个 spec。 这属于过度矫正。不加思索地将存储指向代码库,你会得到几十个过期的方案文件,每个文件都提出了一个此后已经发生变化的实现方案,它们不仅会分散读者对实际文档的注意力,还会干扰智能体对实际指令文件的读取。

这六种尝试的共同模式是,人们要么将 spec 视为个人草稿文件,要么将其视为永久文档,而它两者都不是。它是一个包含少数永久事实的临时产物。解决方案必须兼顾这两个方面。

解决方案:将存储移入项目,然后提取决策

分为三个步骤。第一步是修改一行配置,第二步决定提交什么,第三步是让其持久生效。

步骤 1:将 specSaveDir 指向项目

在项目的 Factory 设置中,将 specSaveDir 设置为代码库中的一个目录,而不是接受默认的用户主目录。Factory 会读取用户级别的 ~/.factory/settings.json 以及项目 .factory/ 文件夹中的设置,因此请将此项放入项目文件中——spec 的位置是项目的属性,而不是你个人机器的属性。

在依赖它之前,请在首次运行时确认路径解析到了你期望的位置。关于该设置的文档说明指出它支持 ~ 路径展开,因此最好检查一下你选择的路径样式所获得的行为,而不是凭空假设。

在修改此文件时,还有两个相关的设置值得了解。第一个是 sessionDefaultSettings.interactionMode,其文档中描述的作用非常简单:

“设置新会话是在 Auto 还是 Spec Mode 下启动。”

如果你希望在某个代码库中将规划作为默认姿态,将其设置为 spec 会非常有用。第二个是 specModeModel,参考文档将其描述为对会话在 Spec Mode 下启动时所用模型的覆盖——这值得设置,因为规划和实现适用于不同的模型。另外请注意,.droid.yaml 在文档中被标记为较旧的配置界面;请使用 .factory/ 文件。

步骤 2:决定提交什么以及忽略什么

既然 spec 已经保存在代码库中,请深思熟虑地做出决定,因为“提交所有内容”的默认答案就是上面提到的过度矫正。

有用的划分方式是按生命周期。正在进行的工作的 spec 应该被提交——它是共享的方案,第二个 PR 的评审人员需要它。而已经发布的工作的 spec 已经完成了它的使命,继续保留它会误导别人去阅读一个不再描述当前系统的方案。

Factory 为你提供了针对机器特定部分的机制。你可以在任何 .factory/ 文件夹中的 settings.json 旁创建一个 settings.local.json,文档中描述的行为是:

“本地覆盖会合并到同级对应的 settings.json 之上,并遵循相同的层级优先级。如果你希望将特定于机器的偏好设置排除在版本控制之外,请将 settings.local.json 添加到 .gitignore 中。”

将该文件用于任何纯粹个人的设置,并保持共享的 settings.json 持有共享的 spec 路径。

步骤 3:在归档方案前提取决策

这是改变最终结果的步骤,每个 spec 大约需要两分钟。

当一个 spec 的工作合并后,最后阅读一次该方案,并提取出明年依然成立的句子。不是具体的实现步骤——那些现在已经在代码中了。而是决策:考虑了什么、拒绝了什么以及原因。一个 spec 通常包含三到四个这样的决策,埋在二十个段落的顺序描述中。

这三四句话是该文档全部的持久价值。将它们记录在方案文件之外的某个地方,这样方案文件就可以被归档或删除,而不会丢失任何信息。跳过这一步,你又会回到因为害怕丢失其中的内容而永远保留过期 spec 的状态——这正是导致人们一遍又一遍地向 AI 重新解释上下文的囤积症问题。

在 MemoryLake 中进行设置

MemoryLake 是存放提取出的决策的地方。它独立于代码库和任何单一智能体,通过 MCP 或 API 回答关于你项目决策的问题——因此,在方案文件消失后,任何人在任何工具上都可以获取来自 spec 的推理。你的 spec 仍保留在 Factory 写入它们的项目目录中;而共享层则保存着那四句值得保留的话。

步骤 1:创建 API 密钥

生成密钥并在大约三十秒内发送你的首次请求。在上述步骤 3 之前完成此操作,这样在你阅读方案时,就有地方存放每一个决策。

创建 MemoryLake API 密钥,使 spec 方案的决策比生成它们的机器寿命更长
创建 MemoryLake API 密钥,使 spec 方案的决策比生成它们的机器寿命更长

步骤 2:上传你的第一批记忆

梳理你现有的 spec——包括那些仍留在用户主目录中的 spec——并记录每个真实的决策,包括选择了什么、拒绝了什么以及原因。支持文档和文件也放在同一个地方;将项目文档转化为 AI 记忆介绍了如何在不重写的情况下批量完成此操作。

将从 Spec Mode 方案中提取的决策上传到共享的 MemoryLake 工作区
将从 Spec Mode 方案中提取的决策上传到共享的 MemoryLake 工作区

步骤 3:连接你的 AI 和智能体

让 Droid、Claude、Codex 以及你的其他智能体通过 MCP 或 API 进行访问。下一次 Spec Mode 会话启动时,就已经知道了前五个会话所做的决定,这就是“规划”与“重新规划”的区别。

通过 MCP 和 API 将 Factory Droid 及其他智能体连接到 MemoryLake
通过 MCP 和 API 将 Factory Droid 及其他智能体连接到 MemoryLake

这在实践中带来了什么改变

第一个改变是,方案可以被受其影响的人员评审。它存在于代码库中、分支上、diff 中。负责第四步的实现者无需向任何人索要文件即可阅读它。

第二个改变是 Spec Mode 获得了更好的输入。Droid 在提出方案前会调研代码库,因此,一个包含最近几个方案以及可查询的历史决策记录的代码库,比一个两者皆无的代码库能为它提供更多的参考依据。

第三个改变是 spec 不再堆积。一旦持久的内容被提取出来,删除已发布的方案就毫无负担,而进行中方案的目录可以保持足够小,以便人们阅读。

第四个改变是方案不再受限于笔记本电脑。用户主目录路径是针对单台机器的,这与 Claude Code 在不同机器间遗忘内容背后的不对称性是一样的——同样的解决方法也适用:将共享内容放在代码库或共享服务保存的地方,而不是单台机器保存的地方。

第五个改变是交接时间变短了。在会话之间共享上下文试图解决的一半问题,就是避免有人在别人看不到的文档中,重新推导一个已经经过深思熟虑做出的决策。

Spec Mode 产物的最佳实践

在项目设置中设置 specSaveDir,而不是在用户设置中。 Spec 的存放位置是项目的属性。用户级别的设置指向的路径在你要打开的下一个代码库中可能毫无意义。

在首次运行时验证路径。 关于该设置的文档说明涉及 ~ 路径展开。在依赖它之前,请检查你实际得到的路径。

提交进行中的 spec,停用已发布的 spec。 针对已合并工作的方案是对一个此后已发生变化的系统的描述。

在归档前提取决策。 每个 spec 提取三到四句话。这是全部的工作,也是让删除变得安全的原因。

不要将 spec 放入你的指令文件中。 AGENTS.md 在每次会话中都会加载。已完成的方案不应该出现在每次会话中。

使用 settings.local.json 存储特定于机器的偏好设置。 它会合并到同级共享文件之上,并且应该被加入 gitignore,从而保持共享的 spec 路径处于共享状态。

考虑将代码库默认设置为 Spec Mode。 将交互模式设置为 spec 可以使规划成为你期望的工作中的默认姿态。

停用 .droid.yaml 它在文档中被标记为较旧的配置界面,而 .factory/ 文件是当前的配置界面。

结论

Factory 的文档记录了一个由单个设置项 specSaveDir 控制的持久化 spec 存储,默认指向你用户主目录中的一个目录。Spec Mode 本身是一种只读规划,它会调研代码库并停下来等待人类批准,推荐用于架构变更、迁移和安全敏感型工作。将这两个事实结合起来,默认配置就会将你们团队最深思熟虑的推理文档写入你们团队唯一看不到的地方。

更改路径只需要一行代码。真正产生回报的是随之而来的习惯:提交描述进行中工作的方案,停用描述已发布工作的方案,并在停用之前,提取出其中在明年依然发挥作用的三四个决策。做到这一点,Spec Mode 就会变成它在纸面上所呈现的样子——一个为团队保留优秀决策的机器,而不是为一台笔记本电脑保留优秀决策的机器。

常见问题

默认情况下,Factory Droid 将 Spec Mode 方案保存在哪里?

保存到由 specSaveDir 设置指定的目录中,其文档记录的默认值为 ~/.factory/specs。Factory 的设置参考将该部分描述为控制由 Spec Mode 创建的持久化 spec 存储,而 specSaveDir 是其中唯一的设置项。

我可以更改 spec 的写入位置吗?

可以,这正是 specSaveDir 的用途。在项目的 Factory 设置中进行设置,以便该位置随代码库一起移动,而不是随你的机器移动。文档指出该设置支持 ~ 路径展开,因此请在首次运行时验证你选择的路径样式是否按预期解析。

我应该将 spec 提交到 git 吗?

提交描述进行中工作的 spec,因为它们是评审人员或后续实现者所需的共享方案。停用描述已发布工作的 spec,因为它们提出的实现方案在代码库中已经过时。在停用之前,提取其中包含的决策并将其记录在持久的地方。

Spec Mode 与 Normal Mode 到底有什么不同?

其文档将其描述为只读规划行为,随后调用 ExitSpecMode 请求批准。在 Spec Mode 期间,Droid 不应编辑文件、更改配置、提交代码、启动服务或写入外部系统;它可以读取文件、搜索代码库、检查链接的产物并提出澄清问题。

我可以将 Spec Mode 设置为代码库的默认模式吗?

可以。sessionDefaultSettings.interactionMode 设置接受 spec 以及 auto,并控制新会话是否在 Spec Mode 下启动。还有一个设置可以为 spec 会话固定特定模型,如果你在规划和实现时偏好不同的模型,这将非常有用。

.droid.yaml 仍然受支持吗?

Factory 的设置文档将 .droid.yaml 描述为较旧的项目配置界面,并引导你使用当前的 .factory/ 文件——即用户和项目级别的 settings.json,以及两级目录下可选的 settings.local.json,用于在同级合并特定于机器的覆盖设置。