无人值守的AI Agent为何重复劳动?LangGraph的上下文陷阱

无人值守Agent重做已完成节点,根因是已完成内容持续占据上下文、争夺模型注意力,而非模型漂移。
一位开发者发现其LangGraph构建的AI Agent在无人值守运行时,无报错地重做了已标记为"完成"的节点,并用不同命名规范覆盖了正确输出。经分析,问题根源并非模型漂移,而是两个层面的缺失:其一,交互式会话中人类会隐式提供任务边界信号(通过下一条消息暗示"这步做完了"),而自主运行的Agent没有这一外部参照;其二,即便节点状态被标记为done,其完整推理细节若仍留在上下文窗口中,就会持续与当前步骤争夺模型注意力,在长任务中随历史累积而愈发严重。有效解法是将"完成"从一个被动的布尔标志,变为主动触发上下文坍缩的动作——把已完成节点的输出压缩为简短摘要,让其从"活跃的注意力竞争者"降级为"沉淀的事实"。
一位开发者在Reddit上分享了一个值得深思的真实案例:他用LangGraph构建的AI Agent在夜间无人值守地执行代码重构任务,结果却把几小时前已经正确完成的两个节点重新处理了一遍——而且第二次处理用了与首次不同的命名规范,把正确的输出覆盖成了更差的版本。
没有崩溃,没有报错,没有重试记录。Agent只是径直绕回那些状态标记为"done"的节点,重新加工了它们。这个看似诡异的现象背后,隐藏着无人值守Agent与交互式会话之间一个根本性的差异。
现象:状态标记为"完成"却被重做
按常理推断,既然节点状态已经是"done",Agent不应该再去碰它。但这位开发者观察到的情况恰恰相反——Agent无视了这个状态标志,重新执行了已完成的工作。
他最初怀疑是模型漂移(model drift),但很快发现这个解释站不住脚。他指出:"同样的模型在交互式会话中跑同样长的时间,通常不会这么频繁地出这种错。"换句话说,问题不在模型本身,而在于运行模式。相同的模型、相似的任务时长,交互式使用和无人值守运行却呈现出截然不同的失败率,这才是真正需要解释的地方。
模型漂移(Model Drift) 通常指同一模型在长时间运行或多次调用后,因温度参数(temperature)引入的随机性、上下文窗口内容的累积变化,或底层模型版本的静默更新,导致输出结果逐渐偏离预期的现象。它是长程Agent任务中一个真实存在的干扰因素,因此开发者将其列为首要嫌疑有一定合理性。然而模型漂移的特征是输出质量的渐进式退化,而非对已完成节点的定向重访——后者具有明显的"选择性",更像是上下文驱动的决策错误,而非随机噪声。这一区分是定位问题根因的关键第一步。
真正的差异:人类在交互中默默扮演的角色
这位开发者给出的分析相当精彩。他认为交互式会话之所以更稳定,是因为人类在其中悄悄承担了一份"没人分配给他的工作"。
在人机交互中,人类会自然地注意到某个子任务已经完成,然后转向下一步。而发出的下一条消息,会隐式地传递这种"状态切换"的信号——哪怕从不明说。这种隐性的边界管理,是人类下意识完成的。
而一个无人值守、跑着长任务清单的图(graph),默认情况下没有任何角色来扮演这个职能。没有人在旁边说"这步做完了,往下走",Agent便失去了判断任务边界的外部参照。
根因:已完成节点的上下文仍在争夺注意力
这里是整个分析最关键的技术洞察。开发者指出:即便逐节点追踪了状态,如果已完成节点的"完整工作细节"仍然留在喂给下一步的上下文里,它就不是作为一个"已成定局的事实"安静地待着,而是在持续与当前真正要处理的步骤争夺模型的注意力。
更糟的是,在长时间运行中,这些已完成节点的细节会以和任务本身相同的速率不断累积。任务越长,无关的历史细节堆积得越多,当前步骤被淹没的风险就越大。于是模型在某个时刻"回头"去重做一个它以为还没完成的节点,也就不足为奇了。
这揭示了一个传统软件工程直觉容易忽略的点:在LLM驱动的Agent里,"状态标志"和"上下文内容"是两回事。一个布尔值标记为done并不能阻止模型被相关的历史文本重新激活——如果那些文本还在上下文窗口里。
这里涉及Transformer架构的一个核心机制:注意力机制(Attention) 对上下文窗口内的所有Token一视同仁地进行计算,并不天然区分"已完结的历史信息"与"当前需要处理的指令"。一段详尽的已完成节点推理过程,在Token数量上可能与当前任务指令相当,从而在注意力分配中占据可观的权重。这与传统软件中读取一个布尔状态位(几乎零开销)的直觉截然不同——在LLM中,"已完成"的内容只要还在上下文窗口里,其Token就持续参与每一次前向计算,并可能将模型的"关注焦点"拉回到已完结的工作上。这也解释了为什么仅靠状态标志无法解决问题:标志是程序逻辑层面的约束,而注意力竞争发生在模型推理层面,两者并不互通。
解法:把"完成"变成主动收缩上下文的动作
针对这个问题,这位开发者分享了两条实际有效的做法:
第一,在已完成节点的输出进入下游上下文之前,主动将其坍缩(collapse)成一段简短的完成摘要,而不是把完整的推理链条一路携带下去。这样下游步骤拿到的是"这件事做完了,结果是X"的精炼结论,而非一大段可能引发二次加工的详细过程。
第二,把节点的"done"状态当作一个会主动缩小其上下文贡献的信号,而不是一个没人读的状态位。换句话说,"完成"不应只是一个被动的标志,而应触发实际的上下文裁剪动作。
这两条建议的核心思想一致:对无人值守的Agent而言,上下文管理必须显式地替代人类在交互中默默提供的"边界感"。既然没有人来标记任务切换,系统就必须自己把已完成的工作从"活跃的注意力竞争者"降级为"沉淀的事实"。
上下文坍缩(Context Collapse) 是一种在Agent工程中逐渐获得认可的实践模式,其思路与检索增强生成(RAG)中的"压缩检索结果"以及思维链(Chain-of-Thought)推理后的"结论提取"有相通之处。具体实现上,可以在节点状态转为done时,调用一次轻量级的摘要调用(summary call),将该节点的完整推理过程替换为一条结构化的完成记录,例如{node: 'A', status: 'done', result: '...'} 。LangGraph本身支持在状态更新时自定义reducer函数,这为在图的数据流层面实现自动坍缩提供了原生切入点,无需在每个下游节点中手动过滤历史内容。
对Agent工程的启示
这个案例对正在构建生产级Agent系统的开发者有普遍参考价值。随着AI Agent被越来越多地部署到长时间、无人值守的任务场景中,上下文窗口里累积的历史信息不再是免费的"记忆",而是一种会主动干扰决策的噪声源。
设计Agent工作流时,值得把"上下文的主动收缩"视为与"状态追踪"同等重要的一等公民。单纯依赖状态标志而让完整历史自由堆积,在短任务里或许无伤大雅,但在长程、自主运行的场景下,就可能像这个案例一样,让Agent悄无声息地覆盖掉自己之前正确的成果。
原作者在Medium上写了更详细的版本:《Unattended AI Agents Have a Context Problem Humans Never Had》。
需要说明的是,这是单一开发者基于自身实践分享的观察与经验,相关结论尚未经过大规模验证,但其提出的问题视角对Agent开发者具有切实的参考意义。
相关推荐

OpenAI与Shield合作:Astra智能体如何革新IT故障修复
OpenAI与Shield合作推出Astra智能体,可自动登录电脑和遗留系统,实时修复IT故障,比传统模型快35%到40%,仅在需要人类判断时引入人工。

iPhone Duo续航实测:一天一充跑不掉,大屏是耗电元凶
iPhone Duo续航实测:重度使用一天需至少充电一次,6.5小时亮屏约剩30%电量。大屏展开频率是耗电关键,MagSafe电池背夹可救场,长期衰减同样值得关注。

Kimi K3.1 Pro开源发布:2.8万亿参数逼近Opus
Moonshot发布开源MoE模型Kimi K3.1 Pro,2.8万亿总参数、1040亿激活参数,Terminal Bench 4.0仅落后Opus 5.5不到1分,单任务成本约三分之一,API价格减半,开源权重11月4日开放。