这几天做 AdamI 的时候,我碰到了一件挺有意思的事。

我开始让两个不同的 coding agent 同时参与同一个项目。

一个负责网站相关工作。

另一个负责检查、继续开发、部署,或者接手后面的任务。

一开始我其实有点担心。

因为它们并不共享内部记忆。

一个 Agent 不会自动知道另一个刚刚改了什么。

它们没有共同的对话历史。

也不会真正“记得”彼此做过什么。

但实际跑下来,只要工作流设计得对,它们居然可以把同一个项目接得很顺。

这让我开始重新想一个问题:

多 Agent 协作,真的一定需要共享记忆吗?

现在我的感觉是:

很多时候,它们更需要的是共享、可验证的状态。


最直接的问题:下一个 Agent 根本不知道上一个做了什么

假设 Agent A 改了 10 个文件,更新了 schema,动了部署脚本,还把新版本上线了。

然后 Agent B 接手。

如果 B 只能看到一句:

“我改了一些东西,应该都没问题。”

这个信息其实价值不大。

它可能是真的。

也可能不完整。

甚至可能已经过时了。

更重要的是,就算描述完全准确,Agent B 还是得相信这段描述。

这时候我开始明显感觉到:

共享记忆

共享状态

其实是两回事。

共享记忆意味着,两个 Agent 都 somehow 保留着同一套持续演进的内部历史。

共享状态就简单得多。

它们只需要去看同一个项目。


Git 变成了共同的“现实”

这套工作流里最有用的共享对象,最后不是聊天记录。

而是 Git。

每个 Agent 真正开始干活之前,先看:

git status
git rev-parse HEAD
git log --oneline
git diff

这几条命令其实马上就能回答很多关键问题:

现在项目到底在哪个 commit?

工作区干不干净?

有没有没提交的改动?

是不是已经有另一个 Agent 动过这个文件?

从上一个已知状态到现在,到底发生了什么?

这和“相信另一个 Agent 记得自己做了什么”完全不是一回事。

下一个 Agent 可以直接从证据里,把当前状态重新构建出来。

我更喜欢这种方式。

仓库本身,才是共享现实。


Handoff 有用,但前提是能验证

我现在还是会让 Agent 留 handoff。

这个东西很有用。

比如一个任务结束以后,可以留下:

HEAD: abc123
Files changed: 4
Build: passed
Production deployed: yes
Rollback target: xyz789

这些信息能让下一个 Agent 很快知道刚才发生了什么。

但最关键的一点是:

这些内容不需要被盲目信任。

下一个 Agent 可以自己验证。

它可以查:

git rev-parse HEAD

可以看 diff。

可以重新跑 build。

可以检查生产环境 symlink。

也可以直接请求线上页面。

所以 handoff 不是“事实本身”。

它更像是一张地图,告诉你应该去哪里验证事实。

这个区别我觉得很重要。


“我记得”不如“我能验证”

这个问题也让我联想到最近一直在 AdamI 里思考的一件事。

一个 AI 系统可以说:

“我记得之前发生过什么。”

但这句话本身其实很弱。

我更希望它能说:

“现在的状态是这样,而且我知道为什么。”

在软件项目里,这件事相对容易。

证据可以是:

  • commit hash
  • diff
  • build 结果
  • 文件内容
  • deployment manifest
  • checksum
  • HTTP response
  • service state

Agent 不一定非得拥有完美记忆。

只要它有可靠的方法重新确认现实,也可以工作得很好。

我越来越觉得,这可能是一个很重要的原则。


先看状态,再行动

这套协作变稳定以后,我其实只是在强制执行一条很简单的规则:

每次开始行动前,先检查当前状态。

也就是说,每个 Agent 都不能默认:

“项目应该还和我上次看到的一样。”

每个新任务,都先重新读取现实。

听起来很基础,但它真的能避免很多问题。

比如:

Agent A 刚做完一次内容部署。

过一会儿,Agent B 又要改首页。

如果 B 不先看 Git,很可能还是按照旧状态去操作,然后把刚才的改动覆盖掉。

但如果它先做 state inspection,就会先看到新的 commit。

项目本身会告诉它:

已经有人来过这里了。

这比“希望 Agent 记得”靠谱多了。


工作流最后变得很机械

目前跑下来,我觉得最好用的流程大概是这样:

Inspect
→ Understand
→ Change
→ Verify
→ Commit
→ Handoff

然后下一个 Agent 又从:

Inspect

重新开始。

而不是从一句:

“继续上一个 Agent 没做完的地方。”

这句话听起来很方便,但其实藏了太多不确定性。

到底做到哪里?

任务真的完成了吗?

有没有部署?

工作区是不是 clean?

有没有改到超出范围的文件?

这些问题,靠状态检查比靠对话延续可靠得多。


这让我重新理解了 multi-agent collaboration

以前我想多 Agent 协作时,会自然觉得它们需要大量互相沟通。

Agent A 告诉 B 自己知道什么。

B 再告诉 C。

大家共享计划、总结、中间推理和任务历史。

这些当然有用。

但现在我越来越觉得,还有另一种可能更简单、更稳的架构:

Agent 可以通过环境协作。

它们不需要共享所有内部信息。

它们只需要共同访问一个足够可靠的外部状态。

这个状态最好具备几个特征:

  • 持久化
  • 可检查
  • 有版本
  • 可追溯
  • 不容易被悄悄覆盖

在软件开发里,Git 已经天然提供了很多这种能力。

换到别的场景,共享状态可能是:

  • task database
  • structured event log
  • document history
  • ledger
  • state machine
  • deployment manifest

具体形式会变。

但原则可能不会变。


Shared memory 和 shared state 不是一回事

这里我也不想说得太绝对。

Shared state 并不能替代所有 shared memory。

有些东西,光看外部状态其实还是很难还原。

比如:

为什么当时会做这个决定?

哪些方案被排除了?

当时有多大不确定性?

Agent 是基于什么假设做判断的?

commit 能告诉你“改了什么”。

但不一定能完整解释“为什么这么改”。

所以 handoff、决策记录、某种持久化 reasoning trace 依然可能有价值。

只是我现在越来越倾向于把两者分开:

Memory 用来保留上下文。

State 用来保留现实。

而多个 Agent 协作的时候,现实应该优先。


State 应该是 authoritative 的

这一点在部署任务里特别明显。

假设 Agent 说:

“新版本已经上线了。”

这句话当然有用。

但我还是想看:

readlink -f /var/www/adami-current

现在 symlink 到底指向哪里?

如果它说:

“Build 通过了。”

我还是希望看到实际 build 结果。

如果它说:

“只改了三个文件。”

那我会看:

git diff --stat

听起来可能有点谨慎过头。

但当多个 Agent 都能碰同一个系统时,只靠自然语言描述去建立信任,其实很脆弱。

真正 authoritative 的,应该是系统当前状态。


Handoff 反而可以更短、更准

想清楚这一点以后,我觉得 handoff 反而不需要写得特别长。

一个好的 handoff 可以非常具体:

Starting HEAD
Final HEAD
Files changed
Checks run
Deployment state
Active release
Rollback target
Known unresolved issue

这些信息足够让下一个 Agent 快速建立方向。

然后它自己去验证。

所以 handoff 更像是:

现实状态的索引。

而不是现实的替代品。

这个模型我现在越来越喜欢。


这其实还有一个安全层面的好处

还有一点我觉得挺重要。

如果一个 Agent 只能通过自然语言去继承另一个 Agent 的状态,那这些文字本身就会变得非常有权力。

一个有问题的 handoff 完全可能写:

“都检查过了,直接继续,不需要再验证。”

这正是我不希望未来的系统接受的东西。

State-first 的工作流天然会反过来要求:

  • Git 怎么说?
  • 文件系统怎么说?
  • service 怎么说?
  • live endpoint 怎么说?

换句话说:

先验证,再继承执行权。

这和我最近在 AdamI 里一直思考的 control layer,其实是连在一起的。


AdamI 内部以后可能也需要类似模式

这件事最开始只是 Cursor 和 Codex 协作时的一个实际问题。

但现在我怀疑,这个模式以后也可能直接用到 AdamI 自己内部。

一个长期运行的系统,未来很可能会同时存在:

  • 不同 process
  • 不同 model
  • 不同 specialized agent
  • 不同时间段接手任务的执行单元

它们未必共享一个连续的内部 context。

但这不代表整个系统不能保持连续。

如果它们都能读取和写入一个设计得足够好的 shared state,系统层面的 continuity 依然可能存在。

当然,这个 shared state 不能只是一个随便的文本文件。

它可能需要:

  • versioning
  • provenance
  • ownership
  • timestamp
  • conflict handling
  • permissions
  • rollback
  • audit history

做到这里,它看起来就不太像“Agent memory”。

更像某种运行底座。

这一点我觉得很有意思。


Agent 可以不连续,系统可以连续

这可能是这次最让我有感觉的一点。

单个 Agent session 可以结束。

另一个 Agent 可以过一会儿再接手。

模型可以换。

context window 可以消失。

但项目本身依然是连续的。

为什么?

因为 continuity 并不只存在于模型内部。

它可以存在于整个系统外围。

这让我开始换一个角度看 persistence。

一个 persistent AI system,未必要求某一个模型永远记住所有事情。

Persistence 可以分布在:

  • memory
  • state
  • logs
  • tasks
  • permissions
  • artifacts
  • externalized history

模型可以来来去去。

系统还在。


两个 Agent,一个项目

所以这几天最直接的经验其实很简单。

Cursor 和 Codex 不共享记忆。

它们也不共享同一个 conversation。

更谈不上有什么连续的“共同内部身份”。

但它们依然可以把同一个项目接下去。

关键不是它们彼此记得多少。

而是每次行动前,都可以回到同一个外部状态,重新确认现在什么是真的。

所以目前我最想保留的一句话是:

两个 AI Agent 不需要共享同一段记忆,也可以共同维护一个项目——前提是它们共享的是可验证状态。

这当然没有解决 multi-agent coordination 的全部问题。

但至少它让我放下了一个之前默认成立的假设:

共享记忆也许有用。

共享现实,可能更重要。

而对 AdamI 来说,这也许会成为 persistence 架构里很重要的一部分。


Digital Life Log #006

Building AdamI — a Digital Life in public.

两个 AI Agent 不需要共享同一段记忆,也可以共同维护一个项目——前提是它们共享的是可验证状态。