看到 Agent 在任务日志里一步一步执行到第 30 步是一种有点神奇的体验。一开始它只是在读文档接着调了一个 API然后根据返回值生成 SQL再接下来又去数据库中验证了一遍结果最后告诉你哪一项是异常的。整个过程没有人的介入它自己决定下一步做什么连续跑了十几分钟。但如果回到大模型本身你会发现一件奇怪的事任何一次模型请求都有 token 上限生成的文本量也是有限的。为什么一个 Agent 能连续跑几十步好像完全没有受到模型输出长度的限制答案在于Agent 的长任务执行从来不是靠“一次推理”完成的。它是一套由模型和运行时协同工作的架构。这里说的运行时指的是负责循环、状态管理、工具调用、上下文维护和异常处理的整套执行系统。模型在其中有贡献但并不是全部。这篇文章会从模型层讲到运行时讲清楚 Agent 连续跑几十步背后的完整机制以及当你想自己搭建、调试或排查这类系统时应该从哪里入手。我的核心判断是Agent 能连续跑几十步不是模型单点能力的外溢而是模型被嵌进了一个带状态、带循环、带记忆和带错误恢复的执行系统。模型只负责其中的“决策”其余部分由运行时负责。1. 先理解一件事Agent 不是“一次生成”而是“决策-执行”循环1.1 模型生成的局限让你无法用单次请求完成长任务任何大模型都有上下文窗口和输出 token 上限。一次请求能做的事情是有边界的可以写一段长文可以完成一个复杂问题的回答但很难一边调工具一边观察返回值再根据返回值调整策略。因为模型本质上是“输入到输出”的映射输入一旦固定输出就固定没有外部反馈也没有中间观察的机会。如果想让模型完成一个多步骤任务就必须打破“一次请求”这个单位。常见做法是把任务拆成多轮调用每一轮模型只生成一小段“下一步动作”的决策外部程序执行这个决策再把执行结果作为新输入的一部分返回给模型。模型看到反馈后再决定下一步做什么。这个过程看起来像是在“连续跑”但本质上是多次不连续模型调用的拼接。模型每一轮看到的上下文里既有原始目标也有前几步的历史摘要还有刚刚发生的工具结果。它并不需要在一个响应里输出完整个任务。1.2 这个循环才是 Agent 的核心骨架一个最基本的 Agent 循环至少包含四个环节生成决策模型读入当前任务和已有信息决定下一步动作。执行动作运行时调用工具、API、命令或检索拿到结果。观察反馈执行结果作为新的上下文传给模型。更新状态运行时不只把结果塞给模型还要记录步骤序号、任务进度、已完成与待办事项。只要这个循环能稳定运转理论上任务步数可以远大于模型单次生成限制。你看到的“几十步”是一次又一次循环的累积。“连续跑几十步”不是因为模型的输出没有长度限制而是因为循环结构允许它把每一段有限的输出拼接起来。还有一个容易被忽略的点循环的终止条件。如果一个 Agent 没有明确的结束机制它就会一直跑下去直到撞上迭代上限或 token 上限。所以在设计系统时不能只考虑“怎么跑”更要提前考虑“什么时候停”。我见过很多新手写 Agent先把精力全花在 prompt 上结果一跑长任务就出问题。其实更基础的问题在循环本身你有没有正确维护消息历史有没有设置迭代上限工具调用失败后要不要重试这些问题没解决prompt 写得再好也没用。2. 从模型到运行时长任务完整架构的五个关键层2.1 决策层模型负责“下一步做什么”不负责记忆和工作流模型层在 Agent 架构里的职责可以概括为“决策器”。它主要负责理解用户目标、拆分任务、选择工具、判断结果、修正错误。它不负责把过去所有步骤完整记在心里也不负责保证循环不崩、管理超时、处理并发。所以在架构设计上不要指望模型做一个“全能大脑”。模型更像一个决策 CPU需要其他组件为它保存状态、提供上下文和扩展能力。某些模型支持 function calling能在生成时输出结构化工具调用指令这对 Agent 特别有用因为它让“决策”和“执行”有了清晰的接口。但这并不意味着模型是万能的。模型也有幻觉、有理解偏差、有单次生成不稳定的问题。运行时设计得越健壮模型偶尔犯错的代价就越小。反过来说如果运行时很脆弱模型稍微出一次错整个任务可能就中断了。2.2 上下文管理层记忆不是把全部历史塞进窗口长任务里最容易遇到的问题就是上下文爆炸。如果把每一轮工具返回结果不加处理地全部塞进下一个请求最多跑十几步就会触发 token 上限或者让模型被大量噪音干扰难以提取关键信息。实际系统通常做三件事摘要压缩定期把前面步骤做一次摘要丢掉细节只保留任务进展和关键结论。关键信息抽取从工具结果中只保留与任务直接相关的字段。滚动窗口保留最近 N 轮完整会话更早的内容压缩或归档。有些模型支持长上下文但还是建议保持上下文精简。长上下文只是提供了更大的“存储空间”并不代表模型能有效利用其中所有信息。在长任务里重点不是“把多少信息塞进去”而是“怎么让模型每一步都看到最关键的少量信息”。上下文管理是运行时的重要职责。模型每回合看到的输入实际上是运行时为它组装好的而不是原始历史的一比一复制。这就像开选题会你不需要把完整剧本背下来只要记住上一幕的关键脉络就能继续推进下一幕。2.3 运行时控制层循环、停止条件和异常处理运行时控制层是整个架构里最像“基础设施”的部分它负责控制循环什么时候开始、什么时候停止、出错时怎么处理。具体要管的事情包括迭代上限防止无限循环。停止条件任务完成、用户中断、错误次数超限都可以终止。工具调用协议模型输出特定格式的动作描述运行时解析并执行。重试与回退API 调用失败时是换一个工具重新试还是直接放弃。任务队列在复杂工作流里可以维护一个待办任务列表模型每一步从中取一个任务。现在的 Agent 架构有一个很明显的趋势是把运行时和模型拆开。模型可以按需替换但运行时负责稳定执行。这样即使模型本身体感不强运行时也能通过重试、自检、人工审批等机制提高任务成功率。换句话说长任务能不能跑得远更多取决于运行时的“接盘能力”而不是模型单轮输出的聪明程度。2.4 工具执行层每多一个工具模型能做的事就多一类Agent 能跑几十步除了循环另一个关键是工具。工具层让模型不再局限于“文本进文本出”而是可以读文件、查数据库、调 API、执行命令、访问网页。工具执行层需要注意两件事工具返回值要结构化返回给模型的不能是一大坨原始网页 HTML最好是提炼过的 JSON 或纯文本。工具执行要安全可控执行命令前最好有审批或白名单读写的路径、调用的接口都要有边界。从架构上看工具层是模型和外部世界之间的桥。长任务能跑多远往往取决于工具层对返回结果的处理质量。如果工具返回的信息太琐碎模型就会在噪音里迷失任务看起来执行了很多步但质量很差。如果工具本身不稳定模型也会跟着倒霉。2.5 可观测性层你能看到“跑了多少步”不是魔法是日志和追踪为什么你能在界面上看到 Agent 执行到第 30 步这不是 Agent 自己有意识而是运行时在持续写日志、记录步骤、输出事件。一个生产级别的 Agent 运行时至少应该记录每步的输入和输出摘要。调用了哪个工具耗时多少结果如何。当前任务状态、已完成步骤、剩余步骤。当轮的 token 消耗、成本估算。异常时的堆栈和错误信息。可观测层不仅服务于用户界面更服务于开发者。Agent 跑飞了、循环了、一直调用同一个工具这些行为都必须能在日志里追踪出来。没有日志的长任务一旦出错排查成本会成倍增加。这五个层是互相配合的。模型层负责决策上下文层提供记忆运行时控制循环工具层扩展能力可观测层暴露问题。它们合在一起才构成了“能跑几十步”的长任务 Agent。如果你拿着这个分层去看任何一个开源框架会发现它们本质上都是在这个框架上做工程化。3. 一次长任务是如何“连续跑几十步”的从用户意图到步骤执行3.1 任务拆解与计划生成长任务开始前多数框架会让模型先生成一个计划。这一步很重要它给后面的循环提供了“停止条件”和“进度感知”。比如用户要求“启动后端服务并验证健康状态”模型可能把任务拆成几步确认后端代码路径与启动命令。执行启动。等待服务可用。调用健康检查接口。查看日志确认有没有异常。汇总结果给用户。这个计划会作为初始上下文放入循环。每一步执行完后模型读取当前计划和实际结果决定是继续、调整计划还是结束。没有计划的时候Agent 容易陷入“下一步做什么”的迷茫步数再少也可能原地转圈。3.2 多步循环内部的“观察-决策-执行”在运行时每一轮循环大概是这样的从消息历史中读取最新状态。交给模型生成下一步动作。解析模型输出判断动作类型。如果是工具调用则执行对应工具。把工具结果写回消息历史。更新任务进度和步骤计数。判断是否满足停止条件。关键点在于模型并不需要一次性知道所有细节它只需要在每一轮获取“当前目标 历史摘要 刚刚发生的工具结果”就能继续决策。这就是 Agent 能跑几十步却不需要一次性输出几十个动作的原因。3.3 一个极简的 Agent 循环示例下面给一个非常简化的 Python 伪代码用来理解循环结构。注意它不是完整实现只是说明核心骨架from some_llm_sdk import chat_completion max_steps 30 step 0 messages [ {role: system, content: 你是一个能调用工具完成任务的中文Agent。}, {role: user, content: 启动后端服务并验证健康状态} ] while step max_steps: response chat_completion(messages) action parse_action(response) if action[type] finish: print(任务完成) break if action[type] tool_call: result execute_tool(action) messages.append({ role: assistant, content: response }) messages.append({ role: tool, content: result, tool_call_id: action[tool_call_id] }) step 1 print(fstep {step} executed)这里的max_steps就是防御无限循环的护栏。execute_tool是运行时负责的工具调度入口。每步执行结束后只有把结果追加到messages模型才有依据决定下一步。要找的架构关键就在这个循环层而不是模型内部。实际框架会比这复杂很多比如支持并行工具调用、错误重试、人工中断、异步执行等。但核心骨架就是上面这段伪代码。理解了这一步再去看 LangChain、CrewAI 或别的框架你就能认出它们底层都是类似的循环。3.4 为什么“几十步”太多时会变慢变贵甚至失控长任务不会没有代价。每多一个步骤就多一次模型调用token 消耗和延迟都会线性上升。Agent 能连续跑几十步不代表它应该无限制地跑。从实践看步骤数越多失败概率也会叠加。某一步工具返回异常或者模型误解了结果后续步骤可能一起跑歪。这也是为什么我很建议生产系统设置明确的步骤边界。一些更具体的建议设置合理的max_iterations。不要为了让任务“显得厉害”而把它调得过大。在关键工具调用后增加校验节点。例如任务完成前让模型先回答“结果是否符合预期”再决定是否结束。不要让 Agent 在无人监督的情况下执行高影响操作。涉及文件删除、支付、权限变更等行为应该强制人工确认。4. 搭建长任务 Agent 时真正要调的不是 prompt而是这五个参数很多人让 Agent 跑长任务失败后第一反应是“再改一下 prompt”。这个方向不是完全错但它往往忽略了一个更基础的问题运行时参数没有设置对。下面是几个我认为最能决定长任务能不能稳定跑完的参数。4.1 最大迭代次数max iterations这个参数保护系统不在错误路径上无限循环。设置多少合适呢如果任务是 5 步以内的轻量任务可以设 10 步给模型一点重试空间。如果是复杂的多步骤任务30 步到 50 步比较常见。但最好不要盲目调大步数越往上单次任务成本越高。如果发现任务经常需要超过最大次数首先要检查的不是提高上限而是任务拆解是否合理。模型可能一直在原地打转没有真正推进。一个有效的判断标准是看日志里最近 10 步是否都在调用同一个工具或者反复生成相似的失败动作。4.2 温度与采样参数Agent 运行时的 temperature 通常要比聊天场景设置得更低一点比如 0 到 0.5 之间。因为 Agent 需要在每一步做出相对稳定、可执行的决策太高的随机性会让它频繁改变计划或者在一件事上反复横跳。不过这也和任务类型有关。如果是创意类任务温度可以高一些如果是工具执行、数据分析、代码修改低温度更安全。你可以在一个任务里开头用稍高温度生成计划后续执行阶段用低温度保证稳定但这通常需要在运行时做额外逻辑不是所有框架都直接支持。4.3 单次工具调用的超时时间长任务里最容易被忽视的参数就是工具超时。模型可能生成了一个工具调用但工具本身执行得很慢比如某个 API 30 秒还没响应。如果运行时没有超时控制整个 Agent 循环就像卡死一样。实践经验是给每一项工具调用设置一个合理的超时时间超过后要让模型知道当前工具不可用它可以换一种方式实现目标而不是永远等下去。超时时间应该按工具类型区分数据库查询可以长一些HTTP 请求可以短一些文件读写则要控制在几秒内。4.4 上下文压缩策略前面讲过上下文管理在生产环境里必须有压缩策略。常见做法是当最近消息数量超过阈值时触发一次摘要压缩把旧消息合并为一段“任务进行到哪一步、已经有哪些结论”然后清掉详细历史。这一步非常影响长任务步数上限。如果没有压缩策略即使模型本身支持长上下文长期运行时 token 费用也会高到让人不敢继续跑。而且过长的上下文会让模型注意力分散反而降低输出质量。一个朴素但有效的压缩规则是保留系统提示、用户最终目标、最近 3 到 5 轮完整对话其余部分压缩成一段 300 字以内的进展摘要。这样每一步模型要读的核心信息其实很少决策质量反而更可控。4.5 重试次数与失败处理策略当 Agent 执行到第 18 步工具调用突然报错系统应该怎么做退出重试还是换一个方法建议设置有限次数的重试。重试时要区分错误类型临时网络错误可以重试。工具参数错误重试意义不大应该让模型根据错误信息修改参数。权限或鉴权失败应该停止通知用户处理。工具不存在或超出白名单应该立即停止说明运行时配置有问题。把这些逻辑写进运行时比让模型自己“尝试处理”要可靠得多。因为模型对错误类型的判断不稳定运行时规则可以保证一致性。你也可以在给模型的工具描述里加上“如果遇到权限错误直接终止并报告用户”给模型一个明确的处理路径。5. 长任务跑飞了按照这个排查链路定位问题5.1 现象分类先看 Agent 在你面前表现出的外在现象。不同现象对应的排查重点完全不同。任务跑到一半自己停了。任务在某个循环里来回重复不推进。报错“达到输出 token 上限”回答被截断。每一步都很慢但步数很多。工具调用失败后Agent 放弃任务或者乱来。先不要急着改 prompt。先把现象定性再看是模型问题还是运行时问题。5.2 输入与目标边界接着检查任务输入。用户给的目标是否太模糊比如“帮我写一个完整项目”模型可能一直在构思计划永远不执行任何具体动作。给 Agent 的任务最好是明确可验证的。如果目标本身无法判断“完成”Agent 就可能一直执行下去。所以我在设计任务时通常会要求用户给出“结束条件”。例如“输出一个 JSON 文件包含所有关键字段”就比“帮我整理数据”清晰得多。5.3 运行时配置与日志再看运行时的状态。具体来说当前max_iterations是多少是不是被提前截断。是否触发过上下文压缩压缩策略是不是把关键信息丢了。工具调用记录里有没有同一个工具被反复调用。每次调用的耗时和 token 消耗是多少。这些信息都来自日志。所以我说日志是 Agent 系统的刚需。如果一个框架没有输出步骤级的日志调试长任务会非常痛苦。你可以自己埋点把每一步的输入摘要、输出摘要、工具调用、token 消耗写进结构化日志。5.4 模型输出与工具解析如果运行时配置正常问题可能在模型与工具之间的接口。模型输出的动作没有被正确解析是最常见的故障来源。比如模型本来想调用search_web工具但输出了一个 markdown 代码块而你的解析器只会读 JSON于是解析失败Agent 卡在这一步。判断方法也很简单把某一步的模型完整输出、解析后的动作、工具返回值以及写入消息历史的内容打印出来逐段对比。看到底是哪一层断了。5.5 一个简单排查优先级表现象优先检查项次要检查项中途停止迭代上限、停止条件模型输出格式无进展循环上下文压缩、目标是否明确温度过高输出被截断单次输出 token 上限上下文超限工具反复失败工具参数、鉴权重试策略速度很慢工具超时、并发度模型延迟这张表不是万能但大部分 Agent 长任务问题都能归到这几类里。按照“现象 → 输入 → 运行时配置 → 模型输出与工具解析”的顺序排查基本可以定位到具体层。6. Agent 长任务的适用边界不是所有任务都需要跑几十步6.1 适合长任务架构的场景长任务 Agent 适合那些需要多轮交互、多步验证、动态调整的任务。典型场景包括数据分析读取数据 → 清洗 → 建模 → 验证 → 生成报告。代码修改读代码 → 定位问题 → 修改 → 跑测试 → 根据报错再改。信息汇总或调研搜索 → 筛选 → 提取关键信息 → 结构化输出。这些任务的共同特点是一次请求无法完成需要观察中间结果而且中间结果会影响后续动作。模型只有在拿到上一步的真实反馈后才能做出相对可靠的下一步决策。6.2 不适合长任务架构的场景不是所有任务都适合让 Agent 自由跑几十步。高精度、强规则的定时任务应该用普通调度系统而不是 Agent。影响面很大的生产变更比如账号权限修改建议拆成短步骤每一步人工审批。任务目标本身不清晰的任务Agent 会变成“看起来在努力实际上不知道在干什么”。单次执行成本敏感的场景长任务会很容易把 token 费用打上去。如果任务可以拆成几次独立短任务反而更便宜、更可控。6.3 生产落地至少还需要补三块能力如果只是学习用现成框架的默认循环就能跑起来。但如果要放到生产环境至少要补三块能力。权限与安全边界。Agent 能访问哪些文件、执行哪些命令、调用哪些 API必须提前卡好。不要在运行时让模型自由选择系统命令。任务状态持久化。任务执行到一半程序崩了重启后还能不能接着跑记录任务状态和中间产物非常关键否则长任务会变成一次性碰运气。人工审批和干预入口。在关键步骤前允许人查看中间结果、修改参数、终止任务。这个不是降低效率而是给长任务兜底。一个跑了几十步的 Agent 任务中间一旦错了方向越往下跑损失越大。7. 把长任务当成可维护的系统而不是模型炫技有一次我在本地跑一个自动化数据整理任务前 20 步都顺理成章到第 21 步时模型决定调用一个根本不存在的模块。当时第一反应是“这个模型真笨”后来才意识到问题不在于模型不够聪明而在于我没有给运行时配置工具白名单也没有让工具层在调用前做校验。模型只是按已有上下文做决策真正允许它调用错误模块的是我写的运行时。这个经验放到今天依然适用。Agent 能连续跑几十步真正的前提是运行时足够稳。模型可以换prompt 可以调但循环、状态、日志、重试、压缩、终止条件这些东西才是长任务能不能落到实处的关键。如果你正在搭自己的 Agent我的建议是先别追着最新模型跑先把你自己的循环写清楚。用一条简单的、只有三四个工具的任务测试认真查看每一步的输出、日志和状态变化。等你把“决策-执行-观察-更新”这个循环弄得足够顺手再往里面加更复杂的任务Agent 跑几十步就不再是玄学而是一套你可以调试、可以维护、可以控制的工作流。