快来看,n8n更新了!超越提示工程的长期运行智能体

内容来源:https://blog.n8n.io/long-running-agents-beyond-prompt-engineering/
内容总结:
AI代理可靠性危机:行业反思过度依赖大模型自评
近日,关于AI代理(AI Agent)设计方法的讨论在开发者社区引发热议。有技术专家指出,当前行业过度依赖提示词工程(Prompt Engineering)来引导大语言模型(LLM)自我审查和生成事实性信息,这种做法实则埋下了严重隐患。
核心问题:自我评估加剧“幻觉”风险
专家认为,越是使用LLM进行自我评估或执行分析任务,就越容易引入新的“幻觉”(Hallucination)和“漂移”(Drift)点。将文本生成器用于自动化任务时,开发者应将其视为普通软件组件,严谨设计其运行逻辑,而非依赖模型自身的“自觉”。
关键区分:模型与代理的本质差异
文章强调,模型(Model)仅负责文本输入输出,而代理(Agent)才是执行层。一个典型故障案例是:模型在生成JSON对象中途达到令牌上限,导致截断输出,最终引发代理层面的工具调用格式错误或状态写入损坏。
上下文管理:长期运行代理的生命线
由于每次向LLM发送提示词都会重新发送完整对话历史,长对话极易耗尽上下文窗口,导致模型偏离主题。专家建议采用四阶段管理策略:创建时确保上下文内容可见、压缩时删除语义无关令牌并摘要整合、存储时写入不可篡改的持久化账本、召回时通过账本重建“我在哪里”的状态认知。
持久执行:代理的“休眠-唤醒”机制
长期运行的代理并非持续运行,而是按需唤醒。其身份和状态可跨会话持久化,而内存变量、计时器等无需保留。唤醒源包括Webhook回调、轮询机制及自动化工作流引擎,确保代理在不活动期间不占用计算资源。
任务评估:用确定性验证替代“LLM法官”
针对代理是否偏离任务,行业通行做法是“让另一个LLM来评判”,但这被批评为“最不可靠的解决方案”。专家建议采用确定性验证门控,包括:API状态码检查、模式验证、跨字段一致性检查、状态差异查询及单元测试执行。此外,状态机解析、沙箱行为基线监控、异常检测(如递归循环、令牌激增)均为有效手段。
可接受的LLM评估场景
只有当任务意图在执行前被明确枚举(如工具白名单、步骤序列、数据源定义)时,评估才可简化为针对执行日志的是/否问题。LLM仅可用于“将此痕迹映射到分类学类别X”这类窄范围判断,作为“模糊编译器”而非自主评判者。
业内专家坦言,构建可靠的长时运行代理需要跨多产品协作和持续工程投入,任何宣称的“框架蓝图”都可能忽视确定性组件的核心价值。该讨论将推动行业从“提示工程”向“确定性系统工程”范式转变。
中文翻译:
你们过度依赖提示词来设计智能体了。不管你们把这叫做上下文工程还是该死的循环工程,你们仍然是在要求大语言模型确保自己只生成事实性信息,并且自己审查信息。
你越是让大语言模型自我评估或进行分析,你引入的幻觉点和漂移点就越多。
当你使用文本生成器来自动化那些你不想做的事情时,你仍然需要把它当作任何其他软件一样对待,并设计它的运行逻辑。
在讨论长期运行的智能体之前,先提醒自己以下几点:
- 使用短期运行的智能体完全没问题。用最简单的工具做最合适的活儿。
- 区分模型和智能体。模型接收文本输入并生成文本输出,但它不做其他任何事情。智能体是执行部分。智能体依赖模型,例如,模型在JSON对象中途达到令牌上限是一个模型级事件(输出截断),同时带来智能体级后果(工具调用格式错误、状态写入失败、账本记录损坏)。
这个系列讨论的是“操控框架”(harness)。一次大语言模型调用可以作为一个工具来使用(例如,把这40个工具结果总结成200字),但它应该是操控框架决定在它自己的时间表上、用它对输出的自有验证来执行的确定性函数调用的一部分。而不是智能体在任务中途自己决定“天哪,我现在真该压缩一下上下文了”。
第一部分:上下文与记忆
你发送给大语言模型的每一个提示词都会重新发送完整的对话历史。这种类似聊天的体验只是一个用户界面。一种用户幻觉™。这意味着在较长的对话中,你可能会用完上下文窗口,模型开始截断它,并且/或者你会遇到上下文腐化和漂移,导致模型偏离主题。
你总是发送完整对话这一事实,使得上下文管理变得更容易。这意味着你可以在窗口内对上下文进行整理,去掉“肩胛骨后面的结”,并使其在语义上尽可能紧凑。即使你有一个百万美元——抱歉,百万令牌的窗口,你仍然会遇到腐化和漂移。
这也意味着你可以从一个智能体那里获取上下文,将其转储到另一个智能体中,并继续该会话。因此,你可以去掉思考令牌和工具调用开销,只保留语义相关的部分。
上下文有自己的生命周期。你从系统提示词、工具定义、用户提示词、对话、推理、工具调用等开始。因此,在考虑为这些长时间运行的会话管理上下文时,我们应该考虑在生命周期的各个阶段该做什么。
创建(并理解)上下文
上下文是在你使用大语言模型时自然构建的。你需要刻意关注的是窗口内内容的可见性。Gumloop有一个很酷的上下文使用量仪表盘,可以实时显示对话期间大语言模型上下文窗口的使用量。它显示了按类别划分的令牌明细,例如:
- 系统
- AI指令
- 能力
- 工具
- 技能
- 子智能体
- 对话
在长期运行的智能体中,你会看到对话部分在增加,而系统提示词和工具定义保持稳定。
压缩上下文
随着上下文的积累,你可以修剪语义无关的令牌,并将较大的块总结成语义上等效的较小块。
谷歌的ADK上下文压缩功能通过总结智能体工作流事件历史中较旧的部分来减小上下文大小。它使用滑动窗口方法在会话中收集和总结智能体工作流事件数据。一旦当前会话中的工作流事件或调用次数达到特定阈值,它就会总结较旧事件的数据。
你不能靠不断总结之前的上下文来蒙混过关。在某个时刻,操控框架应该执行一次完整的上下文重置。这意味着它将拆除当前会话,并根据持久化工件重建下一个请求,这将在下一部分探讨。
存储上下文
大语言模型是无状态的,所以如果你的上下文是短暂的,你将失去整个智能体会话。但是,你可以将上下文写入持久化存储。如果能将这些存储架构设计为不可变账本,智能体可以写入和读取,但不能修改或删除,那就更好了。
这些存储服务必须由你(开发者)来配置,你可以确定性地定义权限。要求大语言模型“拜托永远不要更新账本”可不是软件工程。
存储中放什么由你决定。转储整个窗口,总结它,只写一级标题,等等。
在谷歌的EAP中,记忆生成功能将其中几个决策捆绑在一起。
- 提取仅从源数据中拉取最有意义的信息并持久化为记忆,而不是将所有内容都转储进去。
- 整合将新提取的信息与已有信息合并,让记忆随着新信息的摄入而演化。
- 生成在后台异步运行,因此智能体不必等待其完成。
- 事件摄入持续流式传输和管理对话事件,根据你配置的批处理规则自动触发生成。
- 提取是可定制的。你通过给记忆库提供特定主题和少样本示例来告诉它什么才算有意义。
召回上下文
有了存储的上下文,你可以将账本用作重建机制。在新的会话中,智能体可以读取持久化计划、进度说明以及关于已发生事件的仅追加记录,以重建“我在哪里”的状态,而无需重放完整的对话历史。
正如Cloudflare所说,你可以解雇20%的员工,用AI取代他们,并使用智能体的计划作为上下文。如果智能体有一个结构化的计划,那么计划本身就提供了足够的上下文:“我处于7个步骤中的第3步,这一步是‘等待制裁检查结果’,结果刚刚到达。”
再次以谷歌的EAP为例,托管存储和检索带来自有其功能集。
- 整合和检索按身份隔离,因此一个实体的记忆不会渗透到另一个实体中。
- 存储是持久的,可从多种环境访问:智能体运行时、你的本地环境或其他部署选项。检索可以使用限定在特定身份范围内的相似性搜索,只拉取相关内容,而不是所有内容。
- 可以设置生存时间(TTL),使过期信息自动失效,TTL应用于插入或生成的记忆。
- 自动维护修订版本,让你可以检查记忆在新信息摄入时如何转变。
- IAM条件限制哪些主体可以读取或写入给定范围的记忆。
身份作为上下文管理的一个关注点
你可以检索限定在特定用户身份范围内的所有记忆。记忆的范围在生成或创建时定义,并且不可变。
这使得身份限定的记忆对于给定用户或实体,可以跨独立作业和会话持久化。在谷歌的Agent Memory Bank中,记忆是通过大语言模型从会话事件中提取和整合的,限定在用户或智能体身份范围内,通过相似性搜索检索,并基于TTL过期和修订历史进行管理。
在Cloudflare中,身份是智能体的一个持久、可寻址的属性。Durable Object身份在休眠/重启后仍然存在,无需重新建立;这是崩溃后能再次找到任务状态和身份记忆的锚点。
这种持久性质量需要额外的机制来确保跨实例、跨故障点的连续性,我们将在下一部分讨论。
第二部分:持久化执行
作为上下文管理的一部分,你现在有了一些持久化存储。很好,如果你丢失了会话,你可以用它把上下文重新拉回智能体。
“嘿,Claude,检索这个,然后从这继续——”
不!
我们来看看在失败时确定性地恢复智能体的方法。
一个长期运行的智能体并不是持续运行很长时间的。它在需要时运行,跟踪任务、上下文和先前的上下文。预计智能体会等待很多时间。但正如我们在第一部分讨论的,大语言模型每次提示都会收到完整的对话请求,因此持久性的整个概念归结为“我如何有效地构建这些数据,使得大语言模型在任务间保持一致的行为”。
什么需要持久化,什么不需要
参考Cloudflare的文章,他们的长期运行智能体模式确保以下内容在调用间持久化:
- 智能体状态,即智能体继续会话所需的持久化数据
- 创建的所有SQLite表,包括在SQLite之上构建的抽象
- 定时任务,存储在SQLite中,触发告警以唤醒智能体
- 每个WebSocket客户端的连接状态
以下内容不需要保留:
- 内存变量
- 运行中的定时器
- 打开的HTTP调用
- 回调和Promise链
一个智能体有身份和持久状态。它不需要活跃的计算实例。它可以配置为在事件发生时唤醒,并在完成时重新休眠。唤醒源是智能体与外部世界的全部接口;你不需要一个常驻循环来让智能体“运行”数周。
要唤醒智能体,你可以使用webhook回调,智能体启动外部工作,注册自己的回调URL,然后休眠,仅在回调到达时唤醒。对于不支持回调的服务,你还可以定义带退避的重试轮询。智能体安排一次轮询,用递增的延迟重新安排它,并设置间隔上限。
最后,你可以定义广泛的自动化工作流,使用可独立重试的多步骤管道,并将其交给专用的工作流引擎,而不是在智能体内部管理步骤排序。
子智能体也按照自身条件获得同样的持久性。每个子智能体都有自己的状态、计划、持久化协程和生命周期,并将其数据存储在与父智能体相邻的位置。
持久性的关键属性是,父智能体在子智能体工作时不必保持活跃。它可以启动工作,休眠,然后在子智能体的计划或恢复检查触发时被唤醒。崩溃不会一下子摧毁整个“家族”;每个身份都可以独立恢复。
令牌和速率限制监控作为预测信号
通过按会话和按租户的令牌消耗监控,你可以在遇到速率限制或错误时定义继续和重试策略。如果累计使用轨迹预测在下一次检查点之前会达到速率限制,操控框架可以主动设置检查点、限流或切换模型/提供商。
恢复机制
在最粗粒度上,恢复可以是一个在启动时读取账本的会话。一个简单的“我在哪里”检查就可以恢复任务,即使没有更精细的策略。然后你可以为一项工作的持续时间持久化一行记录,在定义点存储中间状态,并在重启时从最后存储的状态恢复。
幂等性对于持久化接受至关重要,特别是对于webhook驱动的智能体,调用者会重试投递,必须避免重复的副作用。所有这一切之下的通用模式是事件溯源或基于日志的恢复:
我们描述了一个不可变的任务账本,包含智能体的计划:应该发生什么,按什么顺序发生,等等。你还需要一个单独的仅追加执行日志,记录实际发生的事情,包含每一次工具调用、每一次模型响应、每一次状态转换。它可以被确定性地重放以重建状态,无论哪个进程或容器恢复工作。
这是Restate的日志功能和DBOS的工作流/步骤注解背后的基本思想。
Restate在继续之前持久化每一步,并确定性地重放以重建崩溃前的状态,而DBOS则检查点到Postgres中。
这些工具还为需要撤销部分工作的智能体提供了补偿和回滚机制。当智能体执行多个操作但出现问题时,你需要系统地撤销更改以保持一致性。
持久化执行供应商格局
你可以通过评估DBOS、Restate、Inngest等供应商来了解不同的实现思路。一些通用例子包括:
- 外部事件上的挂起-恢复——将工作流暂停直到信号到达(webhook、审批、人工决策)并稍后恢复的一等原语,可能在重新部署后仍然有效,等待期间不占用计算资源。
- 流控制和并发限制——带每租户或每工作流并发上限和速率限制的持久化队列,使重试和扇出不会压垮下游系统。
- 在应用代码中表达的持久性与单独编排层的对比:有些使持久性对普通控制流透明(你所用语言中的一个库或注解),另一些则将其作为具有自身执行模型的托管平台原语提供。
你也可以在n8n中通过实现其确定性的基于工作流的功能来设计自己的持久化执行逻辑,定义重试、写入持久化存储、使用计划任务和webhook等确定性触发器。
身份作为持久化属性
在Cloudflare的模型中,智能体的名称是路由键,该身份跨越休眠、重启和重新部署而持续存在。凭据按智能体或子智能体身份限定范围。持久性的回报是可归因性:因为身份是持久的,执行日志中的每个条目都可以追溯到一个持久的智能体身份。
在平台层面,谷歌的Agent Identity和Registry是这一点的产品化版本,跟踪哪个身份、哪个版本正在运行哪个任务。
第三部分:任务推进与评估
你会注意到你的智能体慢慢陷入错误和幻觉中。为了在不询问智能体的情况下判断它是否仍在任务上,大多数AI工程师找到了完美的解决方案:询问另一个大语言模型。
呃……
大语言模型作为裁判是最简单的修复方法,也是最不可靠的。它是同一类模型,犯着同类错误,只是层级上移了一层。这篇文章是关于如何最大限度地减少进度验证对大语言模型判断的依赖,并且在大语言模型仍然有用的地方,将其限制在狭窄、可检查的角色中。
清单作为进度单位
在任务账本或清单中,每个条目都需要在智能体执行之前定义完成标准。在智能体开始之前写下完成条件,是影响最大的单一举措,正是因为它阻止了智能体在运行中途重新定义“完成”。
配套规则是每次只处理一个条目。每次只处理一个条目可以防止智能体试图一次性做完所有事情而把事情做一半,并且使验证变得易于处理,因为每次处理正好有一个声称的状态转换需要检查。
确定性验证门
“问模型是否完成”的替代方案是,对照执行日志或实时系统状态运行一个返回布尔值的检查,该检查不依赖任何模型调用。
门类型的一个分类,从最便宜/最可靠到更复杂:
- 状态/响应代码:API调用是否返回200,而不是4xx/5xx。
- 模式验证:响应是否解析为有效的JSON/XML,并匹配预期的结构(所需字段存在,类型正确)。
- 跨字段一致性检查:响应负载中的用户名是否与请求用户的身份匹配;返回的ID是否与请求的ID匹配。
- 状态差异检查:步骤声称创建/更新/删除的东西是否真的在目标系统中出现/改变/消失(操作后重新查询)。
- 测试执行:针对代码更改运行单元/集成测试。
验证活动的其他机制包括:
状态机用于有效进度 - 一种有限状态机方法用于语义解析,将状态定义为工具调用/步骤类型,将转换定义为它们之间允许的序列;在运行时通过FSM解析观察到的动作序列。状态机之外的状态是违规;意外的转换是异常。通过一小套固定的合法状态,每次转换都可以在执行日志中提交到账本之前进行验证。
沙箱和行为基线 - 你也可以先在受控环境(沙箱)中运行智能体,观察它实际做了什么:它调用了哪些工具,它移动了多少数据量,它到达了哪些目的地,它进行了哪些系统调用。然后你可以:
- 在观察到安全后,将特定操作加入生产环境,理想情况下作为确定性白名单条目,而不是重新调用智能体的判断;
- 使用该配置文件作为最小权限权限和偏差告警的参考基线。
智能体行为的非生成式检查 - 一些有用的检查根本不会生成文本。仅编码器的分类器(BERT系列模型,如DeBERTa、RoBERTa或ModernBERT)可以在标记的对齐/不对齐或良性/恶意示例上进行微调,并输出一个与阈值比较的标量,从而无需生成模型即可做出判断。
工具调用模式的异常检测 - 监控递归循环(重复调用同一工具,仅参数略作变化)、令牌数峰值、乱序执行,并在它们累积之前终止运行。
可接受的大语言模型作为裁判的使用方式
意图评估只有在意图在执行前被明确界定的情况下才可能进行。
“明确”意味着一个枚举的工具白名单,一个定义的任务必须循环经过的步骤或状态序列,定义的数据源,定义的基于规则生成子智能体的机制,以及定义的API端点和方法。
一旦这些存在,评估就简化为对照执行日志提出的一组是/否问题:这一步执行了吗,字段填写正确吗,调用返回了预期的代码吗,检索到的数据是否按照其模式进行了验证,等等。
即使在评估中使用了大语言模型,它也应该被限制在狭窄、可检查的判断中。例如“这个跟踪是否匹配分类法类别X”。这是可接受的,正是因为模型充当一个模糊编译器,将观察到的行为映射到确定性类别,而不是即时发明“好”的定义。
实施
本文描述的所有内容将跨越多个产品,并需要持续的工程投入。不要把这当作一个逐步的蓝图或框架来构建可靠的长运行智能体,而是探索那些被所有自称循环工程专家忽视的确定性组件。
我将继续探索这些主题以及它们如何应用于n8n和更广泛的市场。我欢迎改进、反馈和纠正,请通过LinkedIn联系我。
英文来源:
Y'all relying too much on prompting your way through agent design. Call it context engineering or god damn loop engineering, you still ask the LLM to make sure it only generates factual information and that it reviews information itself.
The more you use an LLM to evaluate itself or perform analysis, the more points of hallucination and drift you introduce.
When you use text generators to automate the stuff you don’t want to do, you still need to treat it as any other piece of software, and design its operating logic.
Before talking about long running agents, remind yourself of the following:
- It’s fine to use short-running agents. Use the simplest tool for the job.
- Differentiate between models and agents. A model takes a text input and generates a text output, but it does not do anything else. The agent is the execution part. Agents rely on models, for example a model hitting its token limit mid-JSON-object is a model-level event (truncated output) with an agent-level consequence (malformed tool call, broken state write, corrupted ledger entry).
This series is about the harness. An LLM call can be used as a tool (e.g., summarize these 40 tool results into 200 words) but it should be part of a deterministic function call the harness decides to make, on its own schedule, with its own validation of the output. It is not the agent deciding, mid-task "oh man, I should really compress my context now."
Part 1: Context and Memory
Every prompt you send to an LLM resends the full conversation history. The chat-like experience is a UI. A user illusion™. This means that in longer conversations, you can max out the context window and the model starts truncating it, and/or you experience context rot and drift where the model gets off-point.
The fact you always send the full conversation makes context management easier. It means you can massage the context inside the window to get rid of knots behind the shoulderblade and keep it as semantically packed as possible. Even if you get a one million dollar- sorry, token window, you will still experience rot and drift.
It also means that you can pick up the context from one agent and dump it into another and carry on the session. You can therefore get rid of the thinking tokens and tool call overhead to only keep what is semantically relevant.
Context has its own lifecycle. You start with the system prompt, tool definitions, user prompt, conversation, reasoning, tool calls, etc. So when thinking about managing context for these long-running sessions, we should think about what to do throughout the lifecycle.
Create (and understand) context
Context is built naturally as you use the LLM. What you need to be intentional about is visibility of what goes in the window. Gumloop has this cool Context Usage Meter that gives you real-time visibility into how much of the LLMs model’s context window is being used during a conversation. It shows token breakdown with categories like: - System
- AI Instructions
- Abilities
- Tools
- Skills
- Subagents
- Conversation
In long-running agents, you will see that conversation portion increases while the system prompt tool definitions remain stable.
Compress context
As context accrues, you can trim semantically irrelevant tokens and summarize larger chunks into semantically equivalent smaller chunks.
Google’s ADK Context Compaction reduces the size of context by summarizing older parts of the agent workflow event history. It uses a sliding window approach for collecting and summarizing agent workflow event data within a session. It summarizes data from older events once it reaches a threshold of a specific number of workflow events, or invocations, with the current session.
You can’t get away with constantly summarizing previous context. At some point, the harness should perform a full context reset. This means it will tear down the session and rebuild the next request from durable artifacts, explored in the next session.
Store context
LLMs are stateless, so if your context is ephemeral, you will lose the whole agent session. You can, however, write context in persistent storage. Bonus points for architecting these as immutable ledgers, where agents can write, and read, but not modify or delete.
These storage services must be provisioned by you, the developer, where you can define permissions deterministically. Asking the LLM “pls never update ledger pls” is not software engineering.
What goes in the storage is up to you. Dump the whole window, summarize it, write H1s only, etc.
In Google’s EAP, memory generation bundles several of these decisions together. - Extraction pulls only the most meaningful information out of the source data to persist as memories, rather than dumping everything in.
- Consolidation merges newly extracted information with what already exists, letting memories evolve as new information is ingested.
- Generation runs asynchronously in the background, so the agent doesn't have to wait for it to complete.
- Event ingestion streams and manages conversation events continuously, automatically triggering generation based on batching rules you configure.
- And extraction is customizable. You tell Memory Bank what counts as meaningful by giving it specific topics and few-shot examples.
Recall context
With stored context, you can use the ledger as a reconstruction mechanism. On a fresh session, an agent can read the durable plan, the progress notes, and the append-only record of what has already happened to reconstruct "where am I" without replaying the full conversation history.
As Cloudflare put it, you can fire 20% of your employees to replace them with AI and use the Agent’s plan as context. If the agent has a structured plan, the plan itself provides sufficient context: "I am on step 3 of 7, the step was 'await the sanctions-check result', and the result just arrived."
Once again in Google's EAP, managed storage and retrieval brings its own set of features. - Consolidation and retrieval are isolated per identity, so one entity's memories don't bleed into another's.
- Storage is persistent and accessible from multiple environments: Agent Runtime, your local environment, or other deployment options. Retrieval can use similarity search scoped to a specific identity, pulling only what's relevant rather than everything.
- A time-to-live can be set so stale information expires automatically, with the TTL applied to inserted or generated memories.
- Revisions are maintained automatically, letting you inspect how a memory transforms as new information is ingested.
- IAM conditions restrict which principals can read or write a given scope's memories.
Identity as a context-management concern
You can retrieve all the memories scoped to a particular user identity. A memory's scope is defined when the memory is generated or created and is immutable.
That makes identity-scoped memory durable across separate jobs and sessions for a given user or entity. In Google's Agent Memory Bank, memories are extracted and consolidated via an LLM from session events, scoped to a user or agent identity, retrieved via similarity search, and managed with TTL-based expiry and revision history.
In Cloudflare, Identity is a durable, addressable property of the agent. Durable Object identity persists across hibernation/restart without re-establishment; this is the anchor that lets task state and identity memory be found again after a crash.
This durability quality requires additional mechanism for ensuring continuity across instances and through failure points, which we address in the following part.
Part 2: Durable Execution
As part of your context management, you now have some persistent storage. Cool, you can use it to pull the context back into an agent if you lose the session.
“Hey Claude, retrieve this and pick up fro-”
No!
We look at deterministic ways of resuming agents in case of failure.
A long-running agent doesn’t run for long. It runs when needed, keeping track of tasks, context, and previous context. Expect the agent to wait quite a lot. But as we discussed in the first part, LLMs always get the whole conversation request with every prompt, so the whole concept of durability comes to “how do I structure this data effectively such that task-to-task the LLM behaves consistently”.
What persists, and what doesn’t need to
Referring back to Cloudflare’s piece, their long-running agent pattern ensures the following persists across calls: - Agent state, the persistent data the agent requires to continue a session
- All SQLite tables created, including abstractions built on SQLite
- Scheduled tasks, which are stored in SQLite, trigger alarms to wake the agent
- Connection states for each WebSocket client
The following don’t need to survive: - In-memory variables
- Running timers
- Open HTTP calls
- Callbacks and promise chains
An agent has an identity and persistent state. It does not need an active compute instance. It can be configured to wake on an event and go back to sleep upon completion. Wake sources are the agent's entire interface to the outside world; you don't need an always-on loop required to keep an agent "running" over weeks.
To wake an agent up, you can use a webhook callback, where the agent kicks off external work, registers its own callback URL, and hibernates, waking only when the callback arrives. You can also define polling with backoff for services that don't support callbacks. The agent schedules a poll, reschedules it with an increasing delay, and caps the interval.
Lastly, you can define wide automation workflows with, independently-retryable multi-step pipeline, and hand it to a dedicated workflow engine rather than managing the step sequencing inside the agent.
Sub-agents get this same durability on their own terms. Each child has its own state, schedules, durable fibers, and lifecycle, and stores its own data colocated under the parent.
The property that matters for durability is that the parent doesn't have to stay active while the child works. It can start the work, hibernate, and be woken when the child's schedule or recovery check fires. A crash doesn't take down the whole family at once; each identity is recoverable on its own.
Token and rate-limit monitoring as a predictive signal
With per-session and per-tenant token consumption monitoring, you can define continuation and retry policies when hitting rate-limits or errors. If cumulative usage trajectory projects a rate-limit hit before the next checkpoint, the harness can proactively checkpoint, throttle, or switch model/provider.
Recovery mechanics
Recovery at the coarsest level can be a session that reads the ledger on startup. A simple "where am I" check can resume the task even without finer policies. You can then persist a row for the duration of a piece of work, stash intermediate state at defined points, and recover from the last stash on restart.
Idempotency matters here for durable acceptance, particularly for webhook-driven agents where callers retry delivery and duplicate side effects must be avoided. The general pattern underneath all of this is event-sourcing or journal-based recovery:
We described an immutable task ledger consisting of the agent’s plan: what should happen, in what order, etc. You also need a separate append-only execution log containing what actually happened, containing every tool call, every model response, every state transition. It can be replayed deterministically to reconstruct the state, regardless of which process or container resumes the work.
This is the underlying idea in Restate's journal feature and DBOS's workflow/step annotations.
Restate persists every step before proceeding and replays deterministically to reconstruct pre-crash state, while DBOS checkpoints into Postgres.
These tools also offer compensation and rollback mechanisms for agents that need to undo partial work when failures occur. When agents perform multiple actions and something goes wrong, you need to systematically undo the changes to maintain consistency.
Durable execution vendor landscape
You can look at different implementation ideas by evaluating the vendors such as DBOS, Restate, Inngest. Some general examples include: - Suspend-and-resume on external events — first-class primitives for pausing a workflow until a signal arrives (a webhook, an approval, a human decision) and resuming it later, potentially across redeploys, without holding compute open while waiting.
- Flow control and concurrency limits — durable queues with per-tenant or per-workflow concurrency caps and rate limits, so retries and fan-out don't overwhelm downstream systems.
- Durability expressed in application code vs. a separate orchestration layer: some make durability transparent to ordinary control flow (a library or annotations in your language), others offer it as a managed platform primitive with its own execution model.
You can also design your own durable execution logic in n8n by implementing its deterministic workflow-based features to define retries, writing data in persistent storage, deterministic triggers such as schedules and webhooks.
Identity as a durability property
In Cloudflare's model the agent's name is the routing key, and that identity persists across hibernation, restart, and redeploy. Credentials are scoped per agent or sub-agent identity. The payoff for durability is attribution: because identity is durable, every entry in the execution log ties back to a persistent agent identity.
At the platform level, Google's Agent Identity and Registry are the productized version of this, tracking which identity, at which version, is running which task.
Part 3: Task Progression & Evaluation
You’ll notice your agent slowly slipping into mistakes and hallucinations. To determine whether the agent is still on task without asking it, most AI engineers found the perfect solution: ask another LLM.
Huh…
LLM-as-judge is the easiest fix and the least reliable one. It's the same model class making the same kind of error, one level removed. This article is about minimizing how much progress validation depends on any LLM's judgment at all, and where an LLM is still useful, constraining it to narrow, checkable roles.
The checklist as the unit of progress
In a task ledger or checklist, each entry needs a completion criterion defined before an agent executes against it. Writing down the done condition before the agent starts is the single highest-leverage move, precisely because it stops the agent from redefining "done" mid-run.
The companion rule is to work one entry at a time. Working a single entry per pass keeps the agent from trying to do everything at once and leaving things half-done, and it makes validation tractable, since each pass has exactly one claimed state transition to check.
Deterministic validation gates
The alternative to "ask the model if it's done" is to run a check against the execution log or live system state that returns a boolean, independent of any model call.
A taxonomy of gate types, from cheapest/most reliable to more involved: - Status/response codes: did the API call return 200, not 4xx/5xx.
- Schema validation: does the response parse as valid JSON/XML and match an expected shape (required fields present, correct types).
- Cross-field consistency checks: does the username in the response payload match the identity of the requesting user; does a returned ID match the one requested.
- State-diff checks: did the thing the step claimed to create/update/delete actually appear/change/disappear in the target system (re-query after the action).
- Test execution: unit/integration tests run against code changes.
Other mechanism for validating activities include:
State machines for valid progress - A Finite-state-machine approach to semantic parsing defines states as tool-call/step types and transitions as the allowable sequences between them; the observed action sequence is parsed through the FSM at runtime. States outside the machine are violations; unexpected transitions are anomalies. With a small fixed set of legal states, each transition can be validated against the execution log before it's committed to the ledger.
Sandboxing and behavioral baselines - you can also run the agent in a controlled environment first (the sandbox) and observe what it actually does: which tools it calls, what data volumes it moves, what destinations it reaches, what system calls it makes. You can then: - Graduate specific actions to production once observed-safe, ideally as deterministic allowlist entries rather than re-invoking an agent's judgment;
- Use the profile as the reference baseline for least-privilege permissions and deviation alerting.
Non-generative checks for agent behavior - Some useful checks don't generate text at all. Encoder-only classifiers (BERT-family models such as DeBERTa, RoBERTa, or ModernBERT) can be fine-tuned on labeled aligned/misaligned or benign/malicious examples and output a scalar against a threshold, giving you a verdict without a generative model in the loop.
Anomaly detection on tool-call patterns - monitoring recursive loops (same tool called repeatedly with minor argument variations), token count spikes, out-of-order executions and kills the run before they accrue.
Acceptable LLM-as-judge usage
Intent evaluation is only possible if intent was explicitly defined before execution
‘Explicit’ means an enumerated tool allowlist, a defined sequence of steps or states the task must cycle through, defined data sources, defined rules-based mechanisms for spawning sub-agents, and defined API endpoints and methods.
Once that exists, evaluation collapses into a set of Yes/No questions asked against the execution log: did this step execute, were the fields filled in correctly, did the call return the expected code, was the retrieved data validated against its schema, etc.
Where an LLM is used for evaluation at all, it should be constrained to a narrow, checkable judgment. For example "does this trace match taxonomy category X." That's acceptable precisely because the model is acting as a fuzzy compiler mapping observed behavior onto a deterministic category, not inventing "good" on the fly.
Implementation
Everything described in this article will span across multiple products and require ongoing engineering. Do not treat this as a step-by-step blueprint or framework for how to construct reliable long-running agents, but rather an exploration of the deterministic components which are overlooked by all self-titled loop engineering experts.
I will continue exploring these topics and how they apply for n8n and in the wide market. I welcome improvements, feedback and corrections, so please reach out to me on LinkedIn.
文章标题:快来看,n8n更新了!超越提示工程的长期运行智能体
文章链接:https://news.qimuai.cn/?post=4945
本站文章均为原创,未经授权请勿用于任何商业用途