五月写《我为什么开始给自己做一个“自进化个人 Agent”》时,我已经知道自己不缺另一个聊天窗口。我每天在 Codex、Claude Code、文档和各种项目之间切换,最累的是隔几天回来,又得亲自解释一遍:这个目标现在是什么、上次做到哪里、哪件事还等我决定。
那时我给自己的答案是“把工作链接起来”。四个月后,做个人工作站让我发现,这句话说起来容易,真正难的是接起来之后,谁有资格说一件事已经成为我的目标。
我犯的第一个错:把发现当成决定#
早期的本机会话同步,只要发现一个工作目录,就倾向于给它建一个项目。表面上很聪明:不用手工整理,打开工作站就有项目列表。但一次临时试验、一个下载目录、已经结束的旧会话,也会因此进入“正在做的项目”。系统只是看到了线索,却替我宣布了投入。
后来我把这条路拆成三步:先保存来源;再把它作为候选给我看;最后由我选“认领为新项目”“并入已有项目”或“只保留会话”。第三种不是删除。以后改主意,还能从原始会话重新认领。
这次修改还逼我面对一个不那么显眼的问题:旧版本已经自动建出来的空项目怎么办?若它没有计划、也没有实际工作项,直接删掉会抹去历史;什么都不做,又会继续污染列表。我选了归档,保留它从哪里来的证据。认领时,项目、目录关联和旧裁决要在同一笔数据库事务里成功;中途失败就一起回退。这里的验证不是“按钮能点”,而是真实 SQLite 失败注入、重试和重开后的状态核对。
那一轮我把“意外建项目”“认领后重试”“事务中途失败”等路径交给集成测试验证,9 个用例通过。这个数字只说明这些边界按预期工作,不能证明系统已经能自动判断我未来的所有项目。它反而让我更愿意把不确定性留在界面上,让我亲自决定候选来源的归属。
第二个错:把任务清单当成了目标#
目录不乱建之后,我又发现任务仍会散。一件事可能先在一段对话里讨论,过两天在另一个 Agent 里做实现,再从文档里补充约束。如果工作站只存“某个任务完成了”,我回来依然不知道长期目标有没有变。
于是我开始把用户明确批准的原话、计划和目标版本单独记账。这里有一条边界:原话属于人,系统从 PR、文档或聊天记录里抽出的建议只是候选。近期、明确、归属唯一的修订可以追加新版本;含糊、跨多个目标、引用他人材料的句子必须留给我核对。它还要告诉下一个 Agent:当前版本是什么,哪一步已验证,缺的证据在哪里。
做这部分时我也犯过很具体的实现错误。最初的句子切分会在逗号处截断一条完整目标;跨会话粘贴的资料也曾被错误地当成新的用户决定。代码审查发现后,我收窄了自动入账条件,并用真实数据库的重开、乱序和重复事件测试去钉边界。所谓“懂我”,如果连我是不是在下决定都分不清,只会更快地把项目搞乱。
后来围绕目标版本的 12 项测试,还专门放进了跨线程续接、重复事件和引用句。比如我说“之前有人建议把 X 作为目标”,工作站不能因为句子里有“目标”两个字就当成我现在批准了 X。这个区分很不起眼,却决定下一位 Agent 拿到的是我的真实意图,还是系统加工出来的误会。
现在的个人 Agent,离我想要的还有多远#
目前工作站已经能接住部分原生会话、项目事项、目标版本和每日反馈;一些连接器、跨 Agent 续办与自动收口仍在建设。我不想把“有一张看板”写成“它已经替我管好了所有工作”。
我现在更愿意这样描述它:各个 Agent 负责执行,工作站负责把来源、目标、进展、待确认、结果证据留在同一条线上。它应该在我不需要出现的时候安静地记录,在确实需要我裁决时把问题和依据拿出来,而不是因为抓到一点线索就替我宣布新项目、因为看到一句“完成”就替我验收。
这也是我对“个人 Agent”的理解变化。五月我想解决的是跨工具失忆;到了九月,我更在意它会不会擅自替我做决定。让系统记得更多只是第一步,记得准确、能改错、知道什么时候停下来,才是它值得长期使用的原因。