1. 为什么会这样:Agent 总在关键节点“停下来”
先说一个我自己的真实经历。有段时间我在调一个批量文档处理的 Agent,逻辑很简单:读取文件、提取关键字段、按规则重命名、归档到对应目录。整个流程跑通之后,我把它挂在后台准备让它自己干完一百多个文件。结果十分钟后回来看,它处理了三个文件就停住了,在等什么?在等我确认“是否继续处理下一个文件”。
那一刻我就明白了,标题里这个“停下来”的问题,是所有做 Agent 开发的人迟早会撞上的墙。模型不是能力不够,而是在提示词里没有被明确告知“你可以一直做下去”。它会默认把每次工具调用的结果当作一个阶段终点,然后停下来向用户汇报、等待指令。这在单轮问答里完全没问题,但放在 Agent 场景里就是灾难——自动化任务变成了半自动任务,而且是最低效的那种:需要你一直盯着,像个保姆一样不断告诉它“继续”。
为什么会这样?我拆成三个层面来讲。
第一层是模型训练的习惯。大模型在预训练和指令微调阶段,见过大量的“用户问一句、模型答一句”的样本。这种范式下,模型天然习惯在生成完一段内容后就主动收尾,因为它不需要也不被期待去发起下一轮行动。当你用 Agent 框架把工具调用、结果反馈、再调用这样的循环包起来之后,模型依然会带着这种“回答完毕就停止”的惯性。
第二层是任务描述的不确定性。也就是看你的提示词是怎么写的。
如果提示词只写了“处理这些文件”,模型并不知道“处理完一个文件之后应该干嘛”,于是它选择最安全的行为:停下来问。模型的这种“不确定就确认”倾向,在安全对齐做得越好的模型上越明显,因为谨慎是被刻意强化过的。我见过不少团队的失败案例,问题都不是出在模型能力上,而是出在提示词给了模型一个“可以随时刹车”的理由。
第三层是工具调用边界不清晰。Agent 每一步工具调用的输入输出、错误处理、下一步该接着做什么,如果在提示词或框架配置中没有指定,模型就会倾向于在边界处暂停。
这个问题的普遍性,比我一开始想的要严重。后来我在和各种做 Agent 开发的朋友交流时发现,不管是基于主流大模型 API 直接手写循环,还是用成熟一点的 Agent 框架,都会遇到。只是表现形式不同:有的模型是每跑完一步就问“是否继续”,有的是做完一个子任务就开始总结汇报、把决定权交还给你,还有的会在中途停下来反思自己“是否完成了所有需求”,然后告诉你“我可以继续”。这就是典型的需要靠提示词去纠正的行为偏差。
所以在进入实操之前,我先把这句话写在最前面:在 Agent 提示词设计里,“停下来”必须是一个显式的、由异常条件触发的动作,而不是模型的默认行为。如果你不把“不要停”写入规则,那模型一定会停。
2. 停下来的代价:两个真实场景的血泪教训
很多人可能觉得,Agent 停下来问一句“是否继续”只是多了一次交互而已,多点一下鼠标的事。但如果你把任务规模和时间维度拉长,就知道这事耽误事到什么程度。
场景一,批量文档处理。我上面提到的那个项目,一百多个 PDF 文件,每个文件需要提取信息、校验格式、重命名、归档。如果 Agent 每处理一个文件就停下来要确认,你需要手动点击一百多次“继续”。就算每次确认只要三秒钟,光点击确认就花了将近十分钟,而且这期间你不能走开。更要命的是,如果某一次确认后 Agent 进入了新的上下文轮次,有些对话框架会把之前的状态压缩或者遗忘,导致行为不一致。我遇到过的情况是:前五个文件处理得好好的,第六个文件开始突然换了一种重命名格式,就是因为上下文太长、状态信息丢失,而模型又在一次新的“确认轮次”里重新理解了任务。这不是模型笨,而是这种停下来再继续的模式,本身就容易破坏 Agent 的连续性。
场景二,数据爬取与整理类的 Agent。这个项目要抓取一批公开页面上的信息,把结果整理成结构化表格。任务特别适合全自动跑:抓取、解析、清洗、入库,一个流程下来几十个链接。但因为我在提示词里加了一句“每一步执行完后向用户汇报结果”,Agent 每次抓到几条数据之后就开始输出“已完成,是否继续抓取下一批”。整个任务变成了人工值守的伪自动化。最讽刺的是,等到我半夜醒来看了一眼日志,发现它早就停在第三个批次了,后面四十多个链接一个都没抓——这个任务本该二十分钟跑完的。
这两个场景的共同点是什么?任务的执行者(Agent)和任务的推进者(你)之间,没有建立起明确的权限边界。Agent 以为自己只是你的助手,每做一件事都要你的批准,而你以为你给了它完整的任务授权。这种认知偏差,只能靠提示词来纠正。
从这里也能反推出一个结论:不是所有任务都需要让 Agent “不要停”。如果你做的是一个内容创作辅助工具,用户希望每生成一段就确认一下,那“停下来”就是必要的。但在自动化执行的场景里——批处理、数据采集、报告生成、运维巡检——Agent 的执行连续性是刚需。判断标准很简单:任务中间有没有需要人类提供新信息的决策点?如果有,那就该停;如果没有,那就不该停,停了就是失败。
3. 提示词层的解药:把“推进”写进 Agent 的行为准则
现在进入正题。怎么通过提示词让 Agent 明白“不要在用户希望你推进时停下来”?我把方法分成四个层次,从粗到细。
3.1 角色设定:给 Agent 一个“执行者”的身份
第一层是角色设定。
不要用“你是我的助手”这种空泛的设定,要用“你是任务执行器”这种带有持续推进暗示的设定。角色设定的作用,是在一开始就给模型注入一个行为预期的框架。如果你的角色描述是“一个耐心细致的助理”,模型会倾向于多确认;如果你的角色描述是“一个独立完成任务的自动化执行引擎”,模型会更倾向于连续行动。
我常用的写法是这样:
你是一个自动化的任务执行引擎。你的职责是接收任务描述后,独立、连续地完成整套流程。在任务完成之前,你不需要也不应该向用户请求确认或征求许可。只有在遇到无法解决的问题时,你才需要停止并汇报。这一段的核心是“在任务完成之前……不需要也不应该向用户请求确认”。它能压住模型“每一步都确认”的倾向。我试过不同写法,直接把“不要问用户”写进角色设定,比在后面的规则里反复强调更有效,因为这个设定会贯穿整个生成过程。
3.2 流程规则:明确“怎么做完一步接一步”
第二层是流程规则,也就是告诉模型:做完一步之后下一步是什么,以及什么时候才算全部完成。
只告诉模型“不要停”是不够的,因为模型不知道该不该停的时候,它会倾向于停下来。正确的做法是给出一张清晰的“流程图”——不是代码流程图,而是文字描述的任务推进规则。
拿文档批处理举例,我在提示词里写的是:
处理流程如下: 1. 读取当前目录下的下一个待处理文件。 2. 提取文件中的关键字段,按既定规则校验。 3. 按规则重命名文件,并移动到对应归档目录。 4. 记录处理日志。 5. 循环执行以上步骤,直到没有待处理文件为止。 6. 全部完成后,输出汇总报告。这里最重要的句子是第五句:“循环执行以上步骤,直到没有待处理文件为止。”这句话等于明确告诉模型:不要停下来,直到条件不满足为止。而第六句又告诉它:做完所有事之后,你要输出一个报告,而不是问“还要做什么”。这样模型就有了一个清晰的目标导向,它知道什么情况下可以停——就是“没有待处理文件”——以及停的时候该做什么——就是输出汇总报告。
3.3 异常处理:只有这些情况你才需要停下来
第三层是异常处理规则。
“不要停”不等于“永远不会停”。真正好的提示词会给 Agent 开一个明确的“停止条件清单”,告诉它:哪些情况触发停止,哪些情况自己处理就好。这样反而是给了 Agent 更大的自由度,因为边界清晰了,它就不用在每个决策点上都纠结“我现在该不该停”。
我在提示词里通常会写这么一段:
在以下情况下,你必须停止并等待用户指示: - 遇到无法解析的文件或数据格式,且没有明确的备选处理方案。 - 发现处理结果违反了预设的校验规则,且无法自动修正。 - 任务执行过程中缺少必要的权限或凭据,无法继续。 - 检测到明显的安全风险或数据异常,需要人工确认。 除上述情况外,你应该自行推进任务流程,不要向用户请求不必要的确认。这个段落的价值在于:它把“停下来”从一个默认行为改写成了一个异常处理分支。模型默认会走“继续执行”的主路径,只有在匹配到特定的异常条件时,它才进入“停止并汇报”的分支。我发现这个思路对几乎所有主流大模型都有效,因为它本质上是在模仿一个优秀的人类员工:正常情况下自动工作,遇到解决不了的问题才向上级汇报。
3.4 终极兜底:一条硬性指令
第四层是一个很短的兜底指令,放在提示词的末尾区域,用来做最后的强化。
严格禁止在任务尚未完成时向用户提出类似“是否继续”、“是否确认”、“我应该继续进行吗”的询问。如果你发现自己想提出这类问题,请重新检查任务状态,然后继续执行未完成的步骤。这句话有一种很妙的副作用:它等于把“停下来问问题”这个动作本身定义成了一个错误行为。模型在生成文本时,会尽量减少犯错的可能,所以当你明确告诉它“询问是否继续”是禁止项时,它在生成过程中会自动规避这类输出。这个兜底指令配合前三层使用,效果叠加得很明显。
我建议把以上四层写法整合到一段完整的提示词里,顺序是:角色设定 → 流程规则 → 异常处理 → 兜底指令。有了这个框架,不管底层模型是谁,行为表现都会比其他写法稳定得多。
4. 光有提示词还不够:配套工程手段才是稳的
提示词能解决大部分问题,但别把所有希望都寄托在提示词上。Agent 能不能持续推进,工程侧的设计同样关键,甚至在某些情况下比提示词更关键。我来说几个我在实操中用了之后明显改善的工程手段。
4.1 参数调优:temperature 和 max_turns
先说 temperature,这个参数控制的是模型输出的随机性。在 Agent 执行任务时,如果 temperature 设得过高,模型容易偏离主线,甚至会自己给自己找不必要的“停下来确认”的理由;设得太低,模型会缺乏灵活性,遇到稍微有些变化的情况就容易短路。
我的经验值是:纯执行类的 Agent 任务,temperature 设在 0 到 0.3 之间是最稳的。如果这个 Agent 还涉及一些创意生成类的内容,比如帮你写营销文案,那可以稍微调高到 0.5 左右。但记住一个原则:Agent 任务越接近“执行”,temperature 越要低。我给自己的项目里就是统一的 0.1,基本没有因为“发散”出过问题,倒是低温度带来的稳定性和一致性让我省了不少事。
再说 max_turns。这个参数控制 Agent 最多可以执行多少轮工具调用。很多 Agent 框架里都有这个配置,默认值往往偏低(比如 5 轮或 10 轮)。如果你的任务流程是“读取 → 处理 → 保存 → 记录 → 循环”,一次循环就要好几轮工具调用,默认值很快就会被耗尽。模型一旦达到 max_turns 上限,不管任务有没有完成都会被迫停下来,这就由不得它了,是代码让它停的。所以务必检查一下你用的框架里这个参数是多少,根据任务复杂度酌情调大。我一般会设为 50 以上,如果任务复杂度高,设到 100 也不夸张。
当然,也不能完全依赖调大上限,这背后还要配合循环设计和中断条件。模型不会像人一样觉得“这个循环已经跑了八百次了该歇歇了”,它没有这种直觉,上限设得太高但缺少终止条件,反而可能导致死循环。所以下面的内容才是重点。
4.2 工具调用设计:给 Agent 一个“继续按钮”
有一部分 Agent 停下来,是因为它手上没有“继续做下去”的工具。看起来很奇怪对吧,但这种情况真的会发生。
举个例子:你给 Agent 配了一个“读取文件”的工具、一个“提取字段”的工具、一个“重命名”的工具。它处理完一个文件后,确实想继续处理下一个文件,但问题来了——它没有“列出目录里还有哪些文件”的工具,也没有“进入下一个循环”的入口。它能怎么办?它只能停下来告诉你“处理完一个了”,等着你给它下一个任务。
这就是工具设计的问题。如果想让 Agent 自主推进,你得给它一个能够驱动它继续的工具。这个工具可以是一个简单的“扫描目录获取待处理文件列表”的函数,Agent 调用完“处理文件”之后,会再调用一次“扫描目录”,发现还有文件,就继续处理;发现没有了,就结束任务。整个过程不需要用户介入,Agent 自己就能闭环。
所以在设计 Agent 的工具时,我总是会问自己一个问题:在整个任务流程里,Agent 在完成一个单元之后,有没有手段去获取“是否还有下一个”的信息?如果没有,就补一个工具。这一步看似简单,但对 Agent 的自主性影响极大。
4.3 循环控制:不是简单的 repeat,而是“条件推进”
这一点和第 3 节里的流程规则类似,但在工程上要说得更明确一些。在 Agent 开发中,如果你的框架支持自定义工作流,那循环控制逻辑不建议让模型自己凭空想,而是建议在框架层面给它一个显式的循环指令。
比如,用代码控制逻辑判断“是否还有未完成任务”,如果有就直接把下一步任务重新注入给模型,而不是等待模型自己提出“下一步做什么”。这种做法的好处是:即使模型的提示词写得不够完美,也不会轻易出现中断。
这里要提醒的是,循环推进的判断条件不要全交给模型。模型对“是否完成”的判断本身就可能出错,比如它可能误以为任务完成了,然后输出一个总结就收工。在工程上,这类问题可以通过校验“输出是否满足预设格式”来判断是否真的完成了,不满足就自动回到循环里重新让模型处理。这就是所谓的“外部校验 + 循环兜底”,和提示词配合起来,基本能把“中途停车”的概率压到极低。
5. 进阶技巧与避坑实录
说了这么多,最后来点更实操的。下面这几条是我在实际项目中一点点积累出来的经验和踩坑记录,每一条都对应着真实发生过的案例。
5.1 提示词对照:会停下来的写法 vs 不停下来的写法
我整理了一份简单的对照表,演示同一语义下两种写法的区别。做 Agent 开发的同学可以直接对照检查自己的提示词。
| 场景 | 容易导致停下来的写法 | 推荐写法 |
|---|---|---|
| 任务开始时 | “请帮我处理这些文件” | “请依次处理所有文件,无需在每步之间确认” |
| 处理完一个单元时 | “已完成第一个文件,是否继续?” | “继续处理下一个文件,若已无剩余文件则结束” |
| 遇到异常时 | “遇到了一个问题,请问该怎么处理?” | “遇到以下异常时,先尝试三种解决策略:重试、跳过并记录、使用备选方案” |
| 任务结束时 | “所有文件处理完毕,请问还需要做什么吗?” | “输出完整的结果报告,包含成功项、失败项及原因分析” |
可以看到,关键差异在于每一句话都给了 Agent 一个明确的行为指令,而不是把决策权交还给用户。我自己在做提示词 review 的时候,就是拿这个对照表来逐条检查的,效率很高。
5.2 常见问题排查表
如果你的 Agent 已经在跑了,但还是会出现非预期的停下来,按下面的表排查,一般都能找到原因。
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| 每完成一个子任务就停下来汇报 | 提示词给了模型随时确认的空间 | 加入“无需在每步之间确认”的明确禁令 |
| 跑了几轮之后停下来说“已完成”,但实际没完成 | max_turns 耗尽,或任务“完成判断”没有定义清楚 | 调大 max_turns,并在提示词中明确“完成”的具体标准 |
| 工具执行报错后停下来等待指令 | 异常处理策略缺失 | 在提示词中预设重试/跳过/换方案三种策略,只有三种都失败才停下来 |
| 循环了几十次停不下来 | 缺少循环终止条件,或终止条件由模型主观判断 | 在工程层加入外部校验,统计处理数量与清单数量做对比 |
表格里列出的这四类问题,覆盖了我实际遇到过的九成以上的“停下来”场景。尤其是第二类,特别常见——不是 Agent 不想干活,而是框架设定的轮数上限到了,它被迫停了。很多新手做 Agent,一遇到这种情况以为是提示词的问题,改了半天提示词没用,最后发现是 max_turns 不够。
5.3 另一个容易被忽视的问题:上下文长度
还有一个容易被忽视的隐性因素,就是上下文长度。Agent 跑了很多轮之后,对话历史会越来越长。模型在处理超过一定长度的上下文时,对早期指令的遵循度会下降,对最新内容的注意力会增强。这时候最糟糕的后果是:模型忘了最开始你给它设定的“不要停下来”规则,然后在中后期开始频繁地停下来问你。
解决这个问题有两条路。一条是工程侧的上下文压缩:定期总结中间结果,把对话历史中的早期内容替换成精简版本,保留核心任务指令和进度信息。另一条是提示词侧的:在任务的每一步工具调用结果返回时,顺手带上“任务未完成,继续执行”这样的短提示,让模型在每个循环节点上都能看到提醒,而不只是依赖最早的设定。
我实际项目中是两条路一起走。每次工具调用结束,返回给模型的内容里都会附一行“continue if task not complete”,并且在每三轮工具调用后做一次中间状态的摘要,替换掉旧的历史。实测下来,跑长任务时的稳定性提高了一截。
5.4 一个行业共识:越少让模型“想”要不要继续,效果越好
最后分享一个我摸索出来的通用原则:在设计 Agent 提示词时,尽量减少模型做“判断题”的机会。你给它的流程越明确、分支越清晰,它就越不容易在自己不确定的时候停下来。
模型天生是一个“填词器”而不是“决策器”,你让它自己决定“要不要停”,它就会基于概率来填这个决定,而概率上“停下来确认”通常是更安全的输出。反过来,如果你把流程设计成“执行完一步自动进入下一步”的直线结构,它不需要做判断题,只需要沿着流程走下去,自然就不会停。
这个原则也解释了为什么那些做得好的 Agent 项目,看起来流程都特别“死板”:每一步做什么、做完去哪、出错了怎么办、什么情况下收工,全都写得清清楚楚。表面上看是给模型上了很多约束,实际上是帮它卸下了“下一步该干嘛”的决策负担。当模型不需要思考这个问题的时候,它自然就不会停下来问你。
我在实际开发中,把这一条作为 Agent 提示词设计的总体纲领,配合前面说的角色设定、流程规则、异常处理和工程侧的配套手段,基本上把“Agent 中途停下来”这个问题的发生率降到了可以忽略的水平。当然,这不代表从此一劳永逸,每一次接新的任务类型、换新的模型,都还是要重新检查和微调。但有了这套思路和方法,你至少不用再一遍遍被“是否继续”这种问题折磨了。