这篇想说什么
最近三个礼拜,我在做一个有点”不着调”的工具:把 Claude Code 变成一个有记忆、有人格、能自我进化的智能管家。开源在了 github.com/wennroy/swarm-agent(如果你看到的时候还不存在,就当作是我的私人实验就好)。
这篇不是教学贴。我更想讲它为什么会被做成这样,我做了哪些让自己都觉得意外的决定,以及——一个写错路径的 bug 是怎么让我重新思考”AI agent”这个概念的。
一句话剧透:有用,有趣,但不会让你觉得惊艳到爆。和大部分”AI 工具”一样,60% 是工程,30% 是品味,剩下 10% 是运气。
为什么想做这个
之前用 Claude Code 帮我干活,遇到一个反复出现的体验问题——它非常聪明,但每次开机都像第一次认识我。
- 我得重新告诉它我喜欢简洁、不要”好的我来帮你”开场白
- 重复的工程决策(”这个项目的 convention 是 X”)每次都要重新说一遍
- 上次合作时它帮我修了一个
next.config.js的坑,这次它又得重新发现一次
这其实和”雇佣一个非常聪明但每天早上失忆的同事”差不多。你会愿意和这样的同事一起做事吗?
我想试一件事:能不能给 agent 装上”长期记忆”和”自我进化”两个东西,让它从陌生人变成”老搭档”。
三件核心组件
整个 Swarm Agent 装进了三个互补的能力:
1. 长期记忆(memory-management.md)
一个三层目录结构,按需读取,不浪费上下文:
.remember/
├── now.md # 当前会话的即时记忆(缓冲层)
├── today-2026-08-10.md # 今日事件(工作层)
├── core-memories.md # 关键时刻和长期偏好(持久层)
├── recent.md # 最近 7 天的索引(自动加载)
└── archive.md # 旧记忆的压缩存档
每条记忆有分类:
| 分类 | 例子 | 放在哪 |
|---|---|---|
| 用户画像 | “后端工程师,习惯先写测试” | core-memories.md |
| 事实知识 | “这个项目用 PostgreSQL” | core-memories.md |
| 今日事件 | “今天重构了 XX 模块” | today-*.md |
| 反馈纠正 | “不要这样写注释” | core-memories.md |
最关键的几条规则:
– 主动保存 — 发现有意义的信息就存,不需要你说”记住这个”
– 读后再写 — 永远先读取再覆盖
– 脱敏 — 密码、token 一律不进记忆(用 *** 替代)
不难想到的限制:纯文本文件检索,没向量索引,没知识图谱。先做到 80%。
2. 自我进化(skill-management.md)
agent 不是一成不变的。每次对话都是一次学习机会。但学太快会有副作用——我曾经被一个 agent 改得”过于殷勤”,差点被我重置。
所以我加了一个阈值:连续 3 次同类信号 才触发一次进化。
信号类型:
1. 执行失败 — 命令报错、API 中断、权限拒绝
2. 用户纠正 — “不要这样”、”应该那样”
3. 用户确认 — “对,就这样”、”以后都这么做”
3 次同类 → 累计成”模式” → 给出改进建议 → 等用户拍板才合并。
signals = [
{"type": "user_correction", "context": "...", "timestamp": "..."},
{"type": "user_correction", "context": "...", "timestamp": "..."},
{"type": "user_correction", "context": "...", "timestamp": "..."},
]
if count_same_type(signals, "user_correction") >= 3:
propose_skill_improvement(signals)
这个设计后来救了我好几次。一周以后我回头看,发现很多”进化触发器”其实只是我那一两天情绪化的判断。
3. 团队协作(team-orchestration.md)
Claude Code 自带 Agent tool 可以 spawn subagent,但subagent 之间没有原生通信。我用文件系统作为通信介质,把 subagent 组成一个小团队:
Leader (主 agent)
├── Teammate A (写代码)
├── Teammate B (审查)
└── Evolver (提改进)
每个 role 有自己的 prompt、自己的 tools、自己的 model。比如 Reviewer 只读不写,Evolver 只在 Reviewer 标记为”需要改进”时才动。
一个三阶段 demo(生成 README → 审查 → 改进)在 Sonnet 上花了约 $1.5,跑通后产出了一份有用的反馈循环:
| Phase | 角色 | 成本 |
|---|---|---|
| 1. 生成 README | Writer (Sonnet) | $0.76 |
| 2. 审查 | Reviewer (Sonnet) | $0.43 |
| 3. 改进 | Improver (Sonnet) | $0.35 |
这个 demo 让我第一次相信”多 agent 团队协作”在 Claude Code 环境下是真的能跑通的,不是 PPT 上好看的东西。
一个把项目写到错误路径的 bug
但接下来就要讲真问题了。我设计了一个对比实验,让有/没有 swarm skill 的 Claude Code 同时做一个旅行 Dashboard 全栈项目(React + FastAPI + SQLite)。
相同 prompt,唯一区别是有没有 swarm skill。
跑了三次。前两次都被各自的 bug 卡住了——
Run 1: swarm 写到了 ~/travel-dashboard/
我的 prompt 没指定”在当前工作目录下创建”。swarm agent 自行脑补了一个路径。它写到了 /Users/wennroy/travel-dashboard/,而不是我期望的 experiment/baseline/。我一开始以为 swarm 完全失败了。
实际上它写了 35 个文件,代码质量还不错(SQLAlchemy 2.0 风格,类型完整,8 个页面 vs baseline 的 4 个)。只是写到错误位置而已。
Run 2: 还是路径 bug + API 502
移除了 max_turns=50,加了”在当前工作目录下创建”的指示,结果:
- baseline:API 502 中断前写了 16 个文件(后端完整)
- swarm:API 502 中断前写了 0 个文件,8 次 Write 全部失败(路径又错了,跑到
/home/user/travel-dashboard/)
两次实验里路径都不一样(~/ 和 /home/user/),证明这不是 prompt 问题,是 swarm skill 自己的指令在诱导 agent 选错路径。
看 swarm 的 transcript 可以发现,它在前 10 个 turn 里完全没有写代码,反而在 TaskCreate / TaskUpdate / 阻塞依赖管理上花了大量 turn。对于一个”单兵全栈”任务来说,这种开销完全不划算。
Run 3: 终于修好了
第三次,加了 CLAUDE.md 显式约束路径,并且让两边都不限 max_turns。这才得到一份真正能比较的数据:
| 指标 | Baseline | Swarm | 优胜 |
|---|---|---|---|
| 耗时 | 694s | 560s | Swarm (-19%) |
| 源文件数 | 30 | 37 | Swarm |
tsc 编译 |
✓ | ✓ | 平 |
| Vite build | ✓ | ✓ | 平 |
| 后端启动 | ✓ | ✓ | 平 |
| 8 维总分 | 22.0 / 31 | 27.5 / 31 | Swarm +5.5 |
最大差异在哪?
- 架构合理性:swarm 3.0 → 5.0。Baseline 把所有逻辑塞进
pages/,components/和hooks/是空的;swarm 搞了 7 个可复用组件 + 2 个自定义 hooks - 任务分解:swarm 2.0 → 4.0。Baseline 完全没有 TaskCreate
- 自我审查:swarm 2.0 → 4.0。Swarm 做了 7 次显式的 verify/test/build 检查
但 Baseline 在一个维度赢:功能完整性。swarm 的 PhotoWallPage.tsx 有一个 bug —— allPhotos 总是空数组,因为它假设了 TripListItem 含 photos[],结果 photo wall 只能显示每条 trip 一张缩略图。
简单说:swarm 会做出更好结构的代码,但偶尔漏掉一个边界 case。Baseline 更朴实但更稳定。
三周下来的一些非显然结论
跑完这一轮实验和几次真实使用后,几个我觉得不直觉的发现:
1. 阈值进化比实时进化好得多
我第一版想的是”实时检测 + 自动进化”,发现这会让 agent 天天改自己的”人格”,每次开会都有点陌生感。改成”3 次信号才触发”后,稳定多了。
2. 文件系统比 WebSocket / ZMQ 更适合 subagent 通信
网上很多多 agent 框架喜欢用消息队列、共享内存之类的”重武器”。在 Claude Code 环境下,subagent 之间没有原生通信,但它们能读写同一个文件系统。.swarm/ 目录就是我的”团队会议室”。简单,可观测,可重放。
3. Swarm 不是对所有任务都加分
对单兵全栈任务(一个人要做前后端),TaskCreate + TaskUpdate 的开销反而拖慢节奏。我现在在 prompt 里加了”任务超过 3 步才用 TaskCreate”,少了很多噪音。
4. 路径 bug 暴露了一个真实的设计问题
agent “帮用户做决定”的边界在哪?当 prompt 没指定路径时,agent 是应该问、还是应该选一个合理默认、还是该报错?我现在的答案是:显式失败胜过默默犯错。swarm 第三次跑加了路径校验,agent 在 prompt 含糊时会先 pwd 然后确认。
5. 最终最有用的不是”智能”,是”礼貌”
这是给我的最大教训。一个对用户偏好敏感(不要开场白、不要 emoji、不要 markdown 列表里夹代码)的 agent,比一个聪明的 agent 每天节省的时间和精力多得多。礼貌是个 1% 的改进,乘以每天 50 个交互,累积效应巨大。
还差很远的地方
诚实地说说 swarm agent 现在还没解决的:
- 记忆检索是纯文本 grep。对于上百条
core-memories的用户来说太慢了。需要 embedding 或 LLM-based 检索,但这又会消耗 token - 自我进化的 rollback 没有做。如果一次错误的进化合并进去了,目前需要手动 revert
- 跨项目的 agent 身份一致 — 现在每个项目有自己的
.remember/,没法跨项目共享同一份”人格” - subagent 之间的”上下文传染” 没有机制。比如 Reviewer 看到的和 Writer 看到的不一致时,目前 leader 是最后合稿的”唯一裁判”
这些都没解决,每个都是一篇博客主题。
写在最后
如果说三个礼拜学到了一件事,那就是:让 AI 真正的”工具化”,比”让它更聪明”重要得多。
聪明到能解 Leetcode Hard 是一回事。能每天节省我 10 分钟的认知负担,是另一回事。后者更难,但回报也更大。
如果你也在做类似的事情,欢迎交流。无论是扫一眼 swarm-agent 仓库,还是告诉我你遇到的同样困扰。
—— wennroy
2026.08.10
附录:几个具体数字
如果你对”具体投入”感兴趣:
- 总代码量:约 1500 行(含注释),分布在 5 个核心 md 文件 + 2 个 python 脚本
- demo 总成本:~$1.5(3 阶段子任务,Sonnet)
- 实验对比成本:~$7 / 3 轮 = $2.3 一轮(每次跑全栈项目)
- 总实验耗时:约 28 小时(含调试、被 API 中断、等待)
- 碰到最大的外部 blocker:Anthropic API 502(两次)
相关文章
- #666 HDBSCAN — 之前写的聚类算法介绍
- #657 Clustering is always Complicated — 聚类的本质困难
- #685 l2 normalization vs Cosine Similarity — 度量选择的实践
如果之后有相关更新(特别是路径 bug 类的修复),我会回来更新这个 post。