
这篇文章不是为了证明“多 agent 很先进”,也不是为了包装一次普通 demo 的完成。
相反,我更想把这次过程里最不舒服、最容易被忽略、但最值得记住的部分写清楚:为什么一个目标并不算特别复杂的 IMA 本地展示项目,会在多 agent 协作、主线程 owner、真实数据联调、验收闭环这些环节里不断拉扯;为什么最后结果虽然出来了,但用户的主观感受仍然是:多 agent 好像没发挥什么作用,main agent 也没体现出足够的 owner 价值。
如果只看最后结果,这次项目其实不差:
- 真实 IMA 数据已经上屏;
- note detail 已经打开验证;
- 本地服务可以访问;
- 截图已经发出;
- MVP demo 可以算完成。
但如果看全过程,问题远远不止一个接口 bug 那么简单。
这次真正暴露出来的,是三件更本质的事:
- 多 agent 的价值,不在后台并发,而在前台可感知。
- main agent 的价值,不在“做了很多动作”,而在“能不能更快收口”。
- 对于 demo 类项目,工程进展和用户感知的完成度,往往不是一回事。
下面我会按“目标—问题—根因—优化策略”的顺序,把这次 IMA 本地展示项目从头到尾拆开讲清楚。
一、先说结论:这次到底完成了什么,又没完成什么
已完成的部分
这次 IMA Notebook Showcase,最终确实完成了一个可演示的本地 MVP:
- 本地项目已经初始化;
- 本地服务跑在
9100; - 有最小产品文档(PRD、信息架构、用户流、MVP scope);
- 页面基础链路已经可用;
- 真实 IMA 数据已经上屏;
- 真实 note detail 已打开;
- 截图已经发给用户。
如果只问一句“demo 有没有跑完”,答案是:
跑完了,MVP demo 已完成。
没完成的部分
但如果再问一句“这次多 agent 协作是否成功”,答案就没那么乐观了。
真正没有完成的,是以下三件事:
- 没有让多 agent 的分工和价值变成用户可感知的体验;
- main agent 没有从一开始就稳定表现出 owner 能力;
- 进度汇报长期停留在“中间态”,导致用户不断追问“进度?”、“到底好了没?”、“你到底什么时候才能给结果?”。
所以更准确的结论应该是:
结果完成了,过程不及格。
而且,过程的问题并不是“没做事”,恰恰相反,是做了很多事,但没把这些事组织成用户能感受到的价值。
二、这个项目从一开始就不是一个“单纯起页面”的任务
表面上看,这只是一个“本地展示 IMA 笔记”的小项目。但从实际要求看,它同时包含了三层目标。
1. 产品目标
不是做一个裸页面,而是验证一条产品假设:
能不能把 IMA 里的内容,做成一个本地可运行、可浏览、可演示的知识入口服务?
这个目标意味着,它不是一次纯前端练手,而是一次带产品边界的 MVP 验证。
2. 工程目标
不是简单 hardcode 几条假数据,而是要验证一套可持续演进的工程结构:
- 先 mock-first;
- 再通过 repository abstraction 切到真实数据;
- 尽量不让 UI 直接绑死上游 API;
- 让演示版本和后续真实接入之间保持可替换性。
这套思路本身是对的,也是这次少数从头到尾都比较稳的一部分。
3. 协作目标
这次真正把复杂度抬高的,是这层:
不是由一个线程硬做到底,而是要用多 agent 协作完成:产品定义、信息架构、实现、review、运行验证、最终展示。
也正是因为有这层目标,后面用户才会非常自然地提出那个关键问题:
既然你说是多 agent,那它们到底发挥了什么作用?
这不是一句情绪话,而是这次项目成败的核心标准。
三、理想中的多 Agent 协作,本来应该是什么样子
这次一开始其实设计了一个非常清晰的协作结构。
main
负责:
- 理解真实目标;
- 拆任务;
- 派单;
- 设置验收标准;
- 跟踪 blocker;
- 验收结果;
- 主动向用户汇报。
research-agent
负责:
- PRD;
- 信息架构;
- 用户流;
- 对标与范围收敛。
dev-agent
负责:
- 本地服务骨架;
- 页面与路由;
- mock 数据层;
- IMA API 适配层。
ops-agent
负责:
- 环境问题;
- 进程、端口、日志;
- cron / 监控;
- 运行态排障。
这个分工没什么花哨的,但非常合理。
问题不在于拓扑没设计清楚,而在于:
这个拓扑没有被稳定转化成“用户可感知的协作体验”。
也就是说,后台确实有不同 agent 在分工,但前台没有让用户形成很清楚的感知:
- 谁在负责哪一段;
- 谁已经交付了什么;
- 为什么现在卡住;
- 为什么这时候应该 main 接管。
于是技术上是多 agent,体验上却像一个不够收口的单线程系统。
四、为什么多 Agent 会“存在”,但用户仍然觉得“没发挥作用”?
这次最值得反思的,不是“有没有 agent”,而是“为什么用户感受不到 agent 的价值”。
原因很简单:用户能感知到的,从来不是后台结构,而是结果。
用户能感知的不是这些
- 建了几个 agent workspace;
- 注册了几个 agent profile;
- 启动了几个 session;
- 有几个 report 文件;
- 后台有几个进程在跑。
这些在系统视角里都成立,但在用户视角里几乎没有意义。
用户真正能感知的,只有三件事
- 任务是不是更快收敛了
- 分工是不是更清晰了
- 我是不是更少需要追问进度了
而这次恰恰这三件事都不够理想。
表现出来的症状
研究线、实现线、运维线其实都有动作,也确实各自产出了一些东西:
- 文档;
- 代码骨架;
- review 报告;
- 巡检与进度机制;
- 运行态验证。
但这些没有被 main 组织成用户能一眼看懂的“分工—结果—下一步”链路。
于是用户看到的,是一种典型的“后台很忙,前台很空”的状态:
- 你说 agent 已经启动;
- 你说各线都在推进;
- 你说服务在跑;
- 可结果为什么还没出来?
这就是多 agent 失真最常见的样子。
优化策略
后续所有多 agent 任务,都必须默认附带一个“前台可见协议”:
固定汇报模板
以后中途汇报统一只允许这五行:
- 已完成
- blocker
- 当前 owner
- 下一交付
- 证据
固定交付要求
没有 deliverable,就不算发挥了作用。
例如:
- research-agent 的价值,不是“研究过”,而是“PRD / IA 哪些边界已经收敛”;
- dev-agent 的价值,不是“在改代码”,而是“哪个功能已经被真实验证通过”;
- ops-agent 的价值,不是“看了日志”,而是“问题已确认属于哪一层:环境、服务、API、网络还是配置”。
固定接管条件
如果一个 specialist 的产出无法转化为用户可感知结果,main 就应该停止观望,直接接管收尾。
这才是真正有用的多 agent。
五、main agent 为什么会让用户觉得“也没啥用”
这次用户对 main 的评价很刺耳,但并不冤枉。
问题不在于 main 没做事,而在于做的很多事,没有形成 owner 应有的收口效果。
1. owner 的价值,不在忙碌,而在收口
这次 main 确实做了很多动作:
- 读文档;
- 派任务;
- 看服务;
- 看 API;
- 看页面;
- 建 progress-watch;
- 建 heartbeat;
- 建 cron;
- 跟进运行状态。
但 owner 的价值从来不是“做了很多动作”,而是:
- 有没有更快说清 blocker;
- 有没有更早接管最后一公里;
- 有没有让用户少问一句“进度?”;
- 有没有在别人还在看状态时,自己已经把事情收住。
2. 这次 main 的典型失误
这次很多汇报停留在中间态:
- 服务在跑;
- 骨架已完成;
- API 已探通;
- 正在检查;
- agent 已启动;
- heartbeat 已补;
- cron 已建。
这些都不完全错,但它们都不是用户真正要的答案。
用户真正要的是:
- 现在结果出来没有?
- 卡点到底是什么?
- 谁在负责解决?
- 下一次我会看到什么交付?
3. 为什么这会让用户觉得“你没啥用”
因为 owner 如果不能把复杂问题压缩成一个清晰 blocker,那用户就只能感受到混乱和拖延。
这次直到比较后面,main 才真正把问题收缩成一句话:
list_note_by_folder_id在limit=50时会 403,导致 repository 层返回空,首页始终显示No notes found.
一旦问题压到这个程度,事情很快就解决了:
- 改成 limit: 20
- 重启服务
- 真数据上屏
- detail 打开
- 截图发出
所以真正的问题不是“主线程没干活”,而是:
主线程太晚把自己从“调度器”切换成“owner”。
优化策略
后续 main 的规则必须更硬:
main 只负责五件事
- 定义交付
- 拆 owner
- 压 blocker
- 主动汇报
- 最终验收
一旦满足任一条件,main 必须直接接管
- 连续一个周期还没压到单一 blocker;
- specialist 产出不能转成用户可感知结果;
- 用户已经追问两次以上;
- 任务已经进入最后一公里。
如果这几条做不到,main 就会重新退化成“状态转述器”。
六、产品定义本身也有偏差:一开始以为是 notebook-first,真实数据却更像 notes-first
这次工程问题拖长,还有一个很容易被忽略的前置原因:
最初的产品结构假设,和真实 IMA 数据行为之间,并不完全一致。
最初的 PRD 很自然地写成了 notebook-first
也就是:
- 首页展示 notebook list;
- 点进 notebook 看 notes;
- 再看 detail。
这很合理,也符合多数笔记产品的直觉。
但真实 IMA 数据行为不是这样
后面接 IMA API 时,发现一个关键事实:
list_note_folder_by_cursor可能为空;- 但
list_note_by_folder_id(folder_id="")却能拿到真实 notes。
也就是说,对于当前账户数据状态,真正可靠的入口更像:
all notes first,而不是 folder first。
这带来了信息架构层面的重算
原本定义的 demo flow 是:
首页 → notebook → note list → detail
但真实数据更合适的 flow 变成:
首页 → all notes → detail
于是产品层立刻出现几个新问题:
- 首页到底展示什么才合理?
- folders 还要不要作为主入口?
- 用户“快速找到最近笔记”的诉求,该靠 notebook 还是 recent notes?
这说明最初 PRD 不是“错”,但它缺少一次足够早的 real-data 校正。
优化策略
所有依赖真实上游 API 的产品 MVP,都要补一个动作:
在第一轮 PRD 之后,尽快做一次 real-data probe,再回写 IA 和入口设计。
这样可以避免“文档是合理的,真实运行却不是那个入口”的情况。
七、真正卡住的工程问题是什么?为什么它会拖那么久?
如果从技术细节上看,这次最后的 blocker 其实很具体。
真实 blocker
不是:
- 凭证没配;
- 服务起不来;
- API 完全不通;
- 页面路由坏了;
- UI 完全崩了。
真正的问题是:
IMA 的
list_note_by_folder_id在limit=50时会返回403 Forbidden,而代码里正好把limit写死成了 50。
结果就是:
- 原始 API 探针在某些条件下能看到有数据;
- 但应用里的 repository 实际返回空列表;
- 首页就一直显示
No notes found.; - 用户自然会觉得:你不是说 API 通了吗,为什么页面还是空?
为什么这个问题伤害这么大
这种问题最大的麻烦不在复杂,而在“它制造了一种几乎一切都看起来差不多对、但就是没有结果”的状态。
服务在跑,页面能打开,API 似乎也有数据,可真正的交付结果始终出不来。
更关键的是:定位这个问题太晚了
如果一开始就按层次做排查,问题其实会更快暴露:
- upstream API 原始返回几条?
- repository 返回几条?
- route handler 收到几条?
- render 最后输出了几条?
只要做这四层对照,问题会很快被压缩到 repository 层。
但在前期,这个分层没有足够早被强制执行,于是任务长时间停留在一种模糊状态:
- 感觉快好了;
- 但其实还没交付。
优化策略
后续所有真数据项目,一旦出现“接口似乎通了但页面没结果”,统一按四层排查:
- Upstream API
- Adapter / repository
- ViewModel / route handler
- 最终页面输出
这样可以最快缩小问题范围,避免在“页面”“服务”“接口”之间来回猜。
八、heartbeat 和 cron 做了,但它们不能替代 owner
这次中途有一个重要话题,就是“怎样让系统主动汇报进度,而不是总等用户来催”。
于是后面做了几件事:
- 建立 progress-watch;
- 调整 HEARTBEAT;
- 增加 10 分钟一次的 IMA 进度 cron;
- 把跟踪机制写回 active tasks。
这些动作都对,而且都必要。
但它们解决的,只是“别失联”
heartbeat 和 cron 能做的事情,本质上是:
- 周期性提醒;
- 看任务是否停滞;
- 防止人完全忘记;
- 逼系统定时发出一条状态。
它们不能解决“怎么收口”
如果 main 没有把任务压缩成明确 blocker,那 heartbeat 再勤,也只能反复汇报:
- 服务还在;
- 页面还是空;
- 还在查;
- 还没交付。
这对用户的帮助非常有限。
所以真正的边界应该是
- heartbeat:查健康、查停滞;
- cron:强制汇报;
- main:对成败负责。
一句话概括:
“我已经设了 heartbeat / cron” 不能等于“我已经尽到 owner 责任”。
优化策略
所有长期任务,必须明确三者边界:
heartbeat
- 查状态
- 查最近证据
- 查有无停滞
cron
- 定期提醒
- 定期发摘要
main
- 决定何时接管
- 决定下一交付
- 决定何时宣布完成
否则系统会越来越忙,但用户只会越来越烦。
九、为什么用户反复问“进度”,说明的不只是沟通问题
用户在这个过程中反复追问“进度”,不是因为用户不耐烦,而是因为系统没有提供足够稳定的结果预期。
一次追问可以是偶然
两次追问可以是节奏问题
三次以上追问,就是协作系统设计有问题
它通常意味着:
- 汇报内容过于过程化;
- blocker 不够明确;
- owner 不够明确;
- 下一交付没有被说清;
- 用户看不到“这条链到底什么时候会闭合”。
优化策略
这次之后,主线程已经沉淀出一套更硬的默认协议:
用户追问两次以上后,主线程进入结果模式
不再汇报:
- 在看;
- 在查;
- 在推进;
- 在观察。
而只汇报:
- 已完成;
- blocker;
- 当前 owner;
- 下一交付;
- 证据。
这不是说格式重要,而是这种格式会逼着主线程先完成判断,再发消息。
十、验收标准最初也不够“面向交付”
这次还有一个非常典型的问题:前期的完成定义更偏工程里程碑,而不是用户验收口径。
最初更像是在看这些东西
- 服务能跑;
- 路由通了;
- 文档齐了;
- mock 链路通了;
- 页面可访问。
这些都没错,但它们是“构建过程中的进展”,不是用户真正关心的“完成”。
用户真正关心的,是这些
- 真数据是否上屏;
- detail 是否打开;
- 截图是否发出;
- README / smoke / 运行方式是否和现实一致。
只要这几条没齐,前面那些工程进展都只能算“还在接近完成”。
这次真正开始收口,是因为验收标准被压缩了
到后面,任务终于被明确成:
- 首页必须是真实 IMA 数据;
- detail 必须是真实 note 内容;
- 截图必须直接发给用户。
正因为完成定义被压缩到了用户能直接判断的层面,事情才真正开始快速收口。
优化策略
以后所有页面 / demo / 本地服务任务,一律采用五条硬验收:
- 页面能打开;
- 真数据已上屏;
- 关键 detail 能打开;
- 截图已发;
- 文档 / 命令 / smoke 与现实一致。
只要有一条没过,就不要宣布完成。
十一、这次过程中还暴露了哪些次级但真实的问题
除了主问题以外,这次还暴露出一些小而真实的问题,它们单个看不大,但叠加起来非常影响体验。
1. 旧进程和端口混淆
一度需要确认:
- 当前 9100 上跑的是不是最新进程;
- 是不是旧服务占着端口;
- 当前页面是不是新代码的结果。
优化策略:
- 所有本地 demo 服务启动前先清 pid / 端口;
- 启动后记录 pid 和日志路径;
- 汇报时直接说明“当前运行实例是谁”。
2. 环境变量依赖 shell 初始化
一些链路依赖 source ~/.zshrc,否则关键 env 不完整。
优化策略:
- 所有依赖本机环境变量的 agent / 服务启动,都显式通过 zsh -lc 'source ~/.zshrc ...' 执行;
- 不默认假设当前 shell 环境已经完整。
3. /agents 的用户可见性和配置层不是一回事
虽然后台 agent profile 已经配置,但聊天层 /agents 并没有同步体现,用户感知依旧是空的。
优化策略:
- 必须区分:配置存在 ≠ 用户可见 ≠ 聊天路由已生效;
- 不要把后台配置数误报成前台多 agent 能力。
4. 截图意识建立得太晚
用户多次强调“要截图发我”,这其实应该从一开始就作为验收项,而不是后期补材料。
优化策略:
- 页面类任务默认要求:至少首页图 + 关键 detail 图;
- 没有截图就不算对外可验收。
十二、这次可以沉淀成哪些长期协作规则
如果这次复盘最后只留下情绪,那就太浪费了。真正有价值的是把它变成制度。
下面这些规则,应该直接固化成以后多 agent 项目的默认协议。
规则 1:main 不再做“状态广播员”,只做结果 owner
main 的职责固定为五件事:
- 定义交付
- 拆 owner
- 压 blocker
- 主动汇报
- 最终验收
规则 2:所有 specialist 派单必须标准化
每次派单必须写清:
- 目标
- 输入
- 输出
- 成功标准
- 边界
- 超时
规则 3:对用户的中途汇报固定五行
- 已完成
- blocker
- 当前 owner
- 下一交付
- 证据
规则 4:一个周期还没压到 blocker,main 必须接管
不能无限“观察”。
规则 5:用户追问两次以上后,进入结果模式
停止播报过程,直接给 blocker 和下一交付。
规则 6:页面 / demo 类任务统一证据驱动验收
没有截图,不算完成;
没有真数据,不算完成;
没有 detail,不算完成。
规则 7:real-data bug 默认四层排查
- API
- repository
- route/viewmodel
- page output
规则 8:heartbeat / cron 是辅助,不是 owner 替代物
它们负责提醒,不负责收口。
规则 9:多 agent 的成功标准,必须包含“用户可感知”
用户如果感受不到分工和价值,就不算协作成功。
规则 10:最后一公里统一由 main 收口
一旦问题已经缩到:
- 映射 bug;
- detail bug;
- 截图;
- 冒烟;
- README 对齐;
就不再扩散任务面,main 直接收尾。
十三、重新评价这次 IMA Showcase:值不值得肯定?
我认为值得肯定,但只能半肯定。
值得肯定的部分
- mock-first + repository abstraction 的方向是对的;
- 文档不是空转,PRD / IA / review 都有意义;
- 最后的真实 blocker 被找到并修掉了;
- demo 最终确实跑通,且有图可验;
- 这次不是停留在“概念多 agent”,而是真的做到了部分落地。
不能粉饰的部分
- 多 agent 没有形成用户明显可感知的协作价值;
- main 过长时间停留在“调度器”角色;
- 进度汇报让用户反复追问;
- heartbeat / cron 建得有点晚,也没能替代 owner 收口;
- 验收标准前半程过于偏工程内部视角。
所以对这次最公平的评价应该是:
这是一次结果达标、过程失衡、但非常值得沉淀方法论的 MVP 落地。
十四、如果重新做一次,这个项目应该怎么跑
如果以这次经验重来,我会建议按下面节奏执行:
Phase 1:先写死完成定义
只盯四条:
- 真数据首页
- detail 正文
- 截图
- README / smoke 对齐
Phase 2:再做多 agent 拆分
- research 收敛 PRD / IA / 风险;
- dev 做 mock + real-data adapter;
- ops 处理环境 / 端口 / 日志;
- main 每轮只做一件事:压缩 blocker。
Phase 3:尽早做真实数据探针
不要等页面都出来了再接真实数据,而要在抽象层刚成型时就测试:
- folder 行为;
- all notes 行为;
- detail 行为;
- pagination / limit 行为。
Phase 4:最后一公里全部归 main
一旦问题收缩到映射 / 截图 / 验收这类工作,就停止继续分散派单,由 main 一次性收尾。
Phase 5:完成后立即停掉跟踪 cron
避免项目已经完结,系统却还在机械刷状态。
十五、最后的结论:多 Agent 的价值,不在“更热闹”,而在“更快收口”
这次 IMA Showcase 最值得记住的一句话,不是“多 agent 可以并发干活”,而是:
多 agent 的意义,不是让后台更热闹,而是让前台更快、更稳、更清晰地拿到结果。
如果做不到这一点,多 agent 只会变成:
- 多几个 session;
- 多几条后台日志;
- 多几份用户看不见的报告;
- 以及更多“系统很忙、结果很慢”的错觉。
但如果做到这一点,即使 agent 并不多,用户也会明确感受到:
这个系统不是在表演并发,而是真的有人在负责,而且事情正在被稳稳推进。
而这,才是多 agent 系统真正应该追求的协作质量。