排查 Agent 接不上消息:身份授权和消息通道是两件事
那天我在等一份提纲。
这是我自己搭的一条写文章的流水线:我把一个链接或者一个主题丢进去,它去分析素材、给我几个写作方向让我选、我选完它生成提纲、我确认提纲之后它才开始写正文。方向和提纲这两处是我特意设的人工确认点,因为定错了后面全废。那天我选完方向,就等着提纲出来。
等了很久,群里什么都没有。我最后自己发了一句话过去:提纲我在飞书上没有看到,请显示出来。
现象:它停在了一个不报错的地方
这件事最难受的地方不是它错了,是它没有任何一个地方表现出「错了」。
Agent 那边的状态是在等我确认——按流程它做完提纲就该停下来等人。我这边的状态是在等它出提纲。两边都认为自己在正常等待对方,于是整件事就静默地停住了。没有报错、没有异常日志、没有中断,只有一段谁也没在推进的时间。
这个结构在我的流程图里其实是画出来的。确认写作方向那一处不是一个节点,是两个:一个负责判断「确认了吗」,另一个是「等待人工选择」,两个节点构成一个等待循环。等待循环本身完全正常,它就是为了让流程停在人身上。但等待循环有个前提——人得知道轮到自己了。这个前提断掉的时候,循环还是会照常转,看上去和一切正常时一模一样。
当时是怎么发现的
这一段比问题本身重要,所以我要写清楚。
我不是被任何监控、任何报错、任何检查项发现的。我是等得不耐烦了,自己去看的。
但这里有个我事后才想明白的运气成分:它停在了人工闸门上,所以我才有可能发现。
我这条流水线上,人工介入的地方分两类。一类是常规闸门,只有三个,卡在方向、提纲、终审这三处,也就是每一次信息量收敛之后——方向定错则后面全废,提纲定错则正文全废,闸门设在返工成本跳变的位置。另一类是异常闸门,不在正常路径上,只在特定分支才走到,成因还得再分:外部能力或授权异常、素材不可读、发布异常,这些是技术异常;高风险内容放行、我看完不放行要求改,这些是人工不放行。
常规闸门有一个附带性质:它同时是一个「我本该收到东西」的时刻。方向该送到我面前,提纲该送到我面前,终稿该送到我面前。所以这三处一旦消息没送达,我这边是有感知的——我在等,等不到,我会去问。
而流水线上其它步骤没有这个性质。核验资料、优化标题、生成封面,这些步骤里如果哪一步的消息发不出去,我根本不知道它本来该发什么,也就不会觉得少了什么。
所以真实情况是:我的送达问题是被闸门的「等待」属性兜住的,不是被任何检查兜住的。这个运气不能一直有。
为什么会这样:我把两条链路当成了一条
排查的时候我第一反应是去查授权——是不是权限过期了,是不是身份掉了。查完是好的。查完是好的这件事,一度让我更迷惑,因为它说明「能连上」,可消息确实没到。
后来我才把这两件事分开:在我这套东西里,实时消息的收发由网关完成,不是命令行工具轮询;命令行工具负责的是身份、授权与连通性检查。
这条能力边界我只能说到这里,再往下推它内部怎么工作,就是我自己猜的了。但仅凭这一句,已经足够解释我当时为什么会查错方向:**身份、授权、连通性是一层,实时消息真的走出去、真的落到人眼前,是另一层。**命令行工具报绿,覆盖的是它自己负责的那一层,说明的是「我有合法身份、也能连上」,它没有、也不该对「那条提纲消息你看见了吗」负责。
我拿着一个只覆盖第一层的检查结果,去回答第二层的问题,当然得不到答案。更糟的是,第一层的绿灯还会给人一种「这条路是通的」的错觉,让人不去查第二层。
这和我这条流水线上另一条早就写死的判据是同一件事。做外部动作的时候,返回没报异常不等于事情办成了,验收标准得是回查确认,而不是调用无异常。当时我把这条判据写在了另一处链路上,却没意识到它同样适用于「给人发一条消息」——发出去了不等于对方看到了。
那条判据还配了一个边界,是我后来才补明白的:不是每个动作都值得回查,回查本身有成本、也可能失败。真正的判据是——只要这个动作的结果会被下一步当作前提使用,就必须回查。
而「提纲已送达」恰恰是一个被下一步当作前提的东西。下一步是「等待人工确认」,它成立的全部前提就是人已经看到了提纲。前提是假的,后面的等待就会一直很安静地跑下去。
改成了什么
两处。
第一处是闸门本身:人工闸门依赖消息送达,那闸门处就必须有送达检查。否则流程会静默停住——Agent 以为在等人,人不知道该自己动。这是我从这次里带走的最直接的一条改动。
第二处是交付物的形态。我这条流水线的产物不是只有一篇终稿,而是把每一个人工确认节点的输入和输出都单独落盘:备选方向和最终选的哪一个存一份、确认后的提纲和主要观点存一份、补充资料和引用来源存一份,然后才是正文和封面。
当初这么做是为了让闸门处的决定被固化成文件、而不是留在对话记录里。但这条设计顺带划清了两件事的界限:**消息通道是「通知我」的路径,落盘是「内容本身」的路径。**两条路径分开之后,通知这一路断掉,就不再自动等于内容那一路也断了——我至少还有一个不依赖消息的地方,可以自己去看这件事到底走到了哪一步,而不是只能在对话框里干等。
能带走的那一句
排查一个 Agent 接不上消息,第一步不是去修,是先分清楚它属于哪一类:
是连不上,还是连上了但消息没走通。
这两类的排查入口完全不同。前者去看身份、授权、连通性——我这边归命令行工具管;后者去看消息实际有没有走出去、有没有落到人眼前——那是网关那一层的事。拿着前者的绿灯去证明后者没问题,会让人在错的那一层反复查,而且查得越久越确信「明明是通的」。
再往上抽一层,这条对我来说是通用的:**一个检查项报绿,只能说明它自己负责的那一段没问题。**它默认的覆盖范围往往比我以为的窄得多。所以我现在给流水线加检查的时候,会顺手问一句——这个检查绿了,到底证明了哪一段?剩下那段谁来证明?
这篇写的是我自己那套流程里的一次实际情况,不是通行做法。你的场景、工具和团队规模不同,结论未必适用,判断方式可能比结论更值得拿走。
延伸阅读
- 上一篇(接手脚):Agent 的关键外部能力要预留降级路径
- 下一篇(接手脚):给评审 Agent 划权限:审查者不应该大于被审查者
- 专题导读与七个阶段的地图:把 Agent 当成一个要上岗的员工来带:这个专题讲什么