如何设计一个自动提示智能体的循环系统?完整指南
你有没有遇到过这样的情况:让AI帮你写代码,它给出了一段代码,但运行报错;你把错误贴回去,它修改了,但又有新问题;你反复手动粘贴、提问、再粘贴……几轮下来,你累得够呛,时间也花了不少。
其实,这种“来回拉扯”的操作,完全可以交给一个自动循环系统来处理。今天我们就来聊聊,如何设计一个能自己提示自己、反复执行任务直到完成的智能体循环。
什么是“循环”?为什么单个提示不够用?
很多人以为,使用AI智能体就是写一个很棒的问题,然后得到答案,就结束了。这确实适用于快速问答。但对于真正的多步骤任务,比如“写代码 → 运行测试 → 测试失败 → 读取错误 → 修复代码 → 再运行测试”这样的流程,一个提示远远不够。
想象一下棋类游戏。一个提示就像走一步棋。你看一眼棋盘,走一步,然后轮到对手。如果你只走一步,永远赢不了一整局比赛。
而循环完全不同。它是一套策略——决定每一步怎么走,每步之后检查局面,直到赢了为止。
提示是单次走棋,循环是整套策略。
我们不再手动输入每一步提示,而是设计一套规则,让智能体自己按规则执行。规则只设一次,然后让智能体自己跑完整局。
那么,这套规则怎么设计呢?
循环的五个核心部分
一个能自动提示智能体的循环,由五个部分组成。我们逐一来看。
| 部分 | 作用 |
|---|---|
| 定义“完成” | 告诉循环何时停止的检查机制 |
| 构建上下文 | 每轮喂给智能体的最新信息 |
| 行动与捕获 | 执行步骤并抓取结果 |
| 用反馈闭环 | 把结果转化为下一轮的提示 |
| 设置停止条件 | 保证循环安全的防护栏 |
下面这张图展示了五个部分如何协同工作:
+--------------------------------------------------+
| The Loop |
| |
| Build Context ---> +-------+ |
| | Agent | |
| +-------+ |
| | |
| | acts |
| v |
| Capture Result |
| | |
| v |
| Check "Done"? ----- Yes ---> Stop
| | |
| | No (feedback) |
| | |
| +---------------------+
| (next turn) |
+--------------------------------------------------+
Stop conditions wrap the whole loop
我们构建上下文 → 智能体行动 → 捕获结果 → 检查是否完成。如果完成就停止;如果没完成,就把结果作为下一轮的提示,继续循环。停止条件像护栏一样包围整个过程。
接下来,我们详细拆解每一步。
第一步:先定义“完成”的标准
在任何事情运行之前,必须回答一个问题:循环怎么知道自己做完了?
这是第一步,也是最重要的一步。如果连“完成”都描述不清,智能体就没有方向。它要么永远跑下去,要么太早就停止。
所以,在写其他代码之前,先写好完成检查。这个检查必须写在代码里,不能只存在脑子里。
举例来说,如果我们要构建一个修复Bug的智能体,那么“完成”就意味着测试通过。其他场景的例子:
-
测试全部通过 -
输出符合某个数据格式 -
某个评分超过阈值
下面是一个简单的函数示例:
def is_done(result):
# 完成意味着所有测试都通过
return result.tests_passed
这个函数返回 True 表示工作完成,返回 False 表示还没完。循环会在每一轮后调用这个函数。
这个检查就像是循环的心跳。每一轮循环都会测一下心跳。如果心跳说“完成了”,循环就停止;如果说“还没好”,循环就再来一轮。
因此,必须从这里开始。循环里的其他所有部分都建立在它之上。
第二步:构建上下文,而不是手动写指令
这是最容易出错的地方。很多人仍然手动喂给智能体信息——每次手动输入新的指令,自己复制粘贴文件和错误日志。
我们必须停止这种做法。与其手动写指令,不如让系统自动构建上下文。
“上下文”在这里指什么?它指智能体本轮做出正确决策所需的一切:
-
它正在处理的文件 -
它能使用的工具 -
上次运行产生的错误日志 -
它已经尝试过的历史操作
换句话说,提示不再是手动敲出来的,而是由系统的当前状态自动拼装而成。
来看代码示例:
def build_prompt(state):
return f"""
目标:{state.goal}
文件:{state.files}
上一个错误:{state.last_error}
历史尝试:{state.past_attempts}
请决定下一步操作并执行修改。
"""
这里可以看到,提示是从状态(state)构建出来的。我们不需要手动输入错误信息——直接从状态里读取,自动放进提示中。状态变了,提示也跟着变。这就是核心思想。
循环每轮的结构都一样,只有上下文会变化。同一个 build_prompt 函数每次给出的提示都不同,因为背后的状态在不断推进。
第三步:让智能体行动,并捕获所有结果
现在执行这一步。我们把构建好的提示发给智能体,智能体完成它的工作——写代码、调用工具、修改文件等。
但行动只完成了一半工作。另一半是捕获所有输出结果:
-
修改的差异(diff) -
运行代码的标准输出 -
失败时的错误信息 -
系统的新状态
看代码:
def act_and_capture(prompt, state):
output = agent.run(prompt) # 智能体执行工作
result = run_checks(output) # 运行测试、抓取日志、获取diff
return result
这里我们运行了智能体,然后捕获了结果。结果包含了修改差异、输出信息以及检查是否通过。
关键思想是:这个输出不是终点。它会成为下一轮提示的原材料。我们刚捕获的失败信息,正好可以喂回给智能体,让它修复问题。所以必须捕获全部信息,不能丢弃。
第四步:用反馈形成闭环
我们现在有了一个结果。接下来要把这个结果喂回给第一步的“完成”检查。正是这一步,让整个过程成为循环,而不仅仅是单次动作。
只有两条路径:
-
通过?停止。任务完成。 -
失败?自动把失败转化为下一轮的提示。
第二条路径是精髓所在。当工作失败时,我们不放弃,而是把失败信息转化为下一步指令。类似:“测试失败了,错误信息是XXX,请修复。”
智能体利用刚刚发生的事情,自己重新提示自己。我们没有手动输入新提示——循环自动从失败中构建出来了。
看代码示例:
def loop(state):
while True:
prompt = build_prompt(state) # 第二步:构建上下文
result = act_and_capture(prompt, state) # 第三步:行动并捕获
if is_done(result): # 第一步:检查完成
return result # 通过了,停止
# 失败了,把失败转化为下一轮的提示
state.last_error = result.error
state.past_attempts.append(result)
这里可以看到循环自己闭合。如果完成就返回并停止;如果没完成,就把错误保存到状态中。下一轮 build_prompt 会自动包含这个错误。智能体利用失败来重新提示自己。循环自我驱动。
第五步:设置停止条件(安全护栏)
没有出口的循环不是系统,而是无底洞。如果智能体持续失败而循环不停,它就会无限消耗时间和金钱。所以必须设计护栏。
我们一次性设置好停止条件,然后让循环安全运行。几个重要的护栏:
-
限制重试次数:即使任务没完成,达到固定轮数后也停止。 -
监控成本:超过时间或费用预算就停止。 -
加入人工确认点:对于重要操作,暂停并让人确认后再执行。
把这些护栏加到循环中:
def loop(state, max_turns=10, max_cost=5.0):
turns = 0
cost = 0.0
while turns < max_turns and cost < max_cost:
turns += 1
prompt = build_prompt(state)
result = act_and_capture(prompt, state)
cost += result.cost
if is_done(result):
return result # 成功
state.last_error = result.error
state.past_attempts.append(result)
return "已停止:触及安全护栏" # 安全退出
这里我们用了两个护栏:重试次数上限和成本上限。循环在任务完成、或轮次用尽、或超预算时停止。永远有退出路径。循环不会无限运行。
特别注意:人工确认点对于难以撤销的操作尤其重要。删除文件、发送资金、推送到生产环境等都是典型例子。对于这些操作,必须暂停循环,让人确认后再让智能体执行。
完整循环代码
把五个部分合在一起:
# 第一步:定义完成
def is_done(result):
return result.tests_passed
# 第二步:从状态构建上下文
def build_prompt(state):
return f"""
目标:{state.goal}
文件:{state.files}
上一个错误:{state.last_error}
历史尝试:{state.past_attempts}
请决定下一步操作并执行修改。
"""
# 第三步:行动并捕获
def act_and_capture(prompt, state):
output = agent.run(prompt)
return run_checks(output)
# 第四、五步:用反馈闭环,加上护栏
def loop(state, max_turns=10, max_cost=5.0):
turns = 0
cost = 0.0
while turns < max_turns and cost < max_cost:
turns += 1
prompt = build_prompt(state)
result = act_and_capture(prompt, state)
cost += result.cost
if is_done(result):
return result
state.last_error = result.error
state.past_attempts.append(result)
return "已停止:触及安全护栏"
五个部分协同工作:定义完成、构建上下文、智能体行动、捕获结果、反馈闭环、护栏保护。我们只写一次,然后智能体就能自己完成多步骤任务。
一次完整运行示例
让我们用一个具体例子走一遍。假设目标是“修复登录失败的Bug”。
第一轮:状态中包含目标代码文件,但还没有错误信息。我们构建提示并发送。智能体修改了代码。我们捕获结果。测试仍然失败,错误信息为“密码为空时验证返回true”。还没完成,所以把这个错误保存到状态中。
第二轮:现在 build_prompt 自动包含了第一轮的错误。智能体读到“密码为空时验证返回true”,并修复了那行代码。我们捕获结果。测试通过了。
第三轮:没有第三轮。因为第二轮中 is_done 检查返回了 True,循环自己停止了。
注意最关键的一点:在这整个过程中,我们没有手动输入任何一条提示。第一轮的失败自动成为了第二轮的提示。循环帮我们提示了智能体,并且在任务完成那一刻自行停止。
运行循环的成本
有一点可能会让人意外:写代码很便宜,但让循环一遍又一遍运行代码并不便宜。
模型几秒钟就能写出一段代码,成本很低。但循环会一次又一次地运行模型,轮次接轮次,有时持续数小时。每一轮都有一点成本。一个跑通宵的循环可能执行数千轮。所以真实成本不在于生成一次代码,而在于循环为了达到目标所经历的所有轮次。
这就是为什么第五步的停止条件如此重要。一个不会停止的循环不仅仅是Bug——它在你睡觉时还在持续产生费用。
因此,我们最重要的任务变了:不再是写一个聪明的提示,而是确保循环能够停止。必须限制轮次、监控成本、任务完成立刻停止。
可复用的技能模块
从长远来看,循环本身只是线路,真正的价值在于它所调用的技能。
什么是“技能”?技能是一个小巧、可复用的工具,专门做好一件事。与其让模型每一轮都从头解决同一个问题,不如把那些重复的工作提取出来,变成一个命名工具,让循环直接调用。
基本原则是:当你发现自己反复做同一个步骤时,就把它提取出来做成技能。当你解决了一个棘手的问题时,也把它保存为技能。之后,循环在后续运行中几乎零成本就能获得它。
一个没有任何技能的循环,会让模型每一轮都从头重新解决相同的问题。而一个调用了若干经过验证的技能集合的循环,每增加一个技能就变得更强。这就是让循环随着时间推移越来越有价值、而不是单纯烧钱的原因。
常见错误与避免方法
在实际设计循环时,大部分人容易犯以下错误:
错误一:没有“完成”检查
如果不把完成条件写在代码里,循环永远不知道何时停止。始终先写第一步。
错误二:手动喂提示
如果你还在手动输入每一条提示,那根本不是循环——只是你自己在干活。必须从状态中自动构建提示。
错误三:丢弃输出结果
失败信息就是下一轮的提示。如果不捕获它,就没有东西可以反馈回去。
错误四:没有停止条件
没有出口的循环会无限运行并持续产生费用。始终限制重试次数并监控成本。
错误五:对一次性任务强行使用循环
循环只有在任务可重复且可检查时才值得。对于一次性任务,普通提示更合适。
错误六:循环内没有技能
如果循环每一轮都从头解决相同问题,会浪费时间和token。把重复工作变成可复用的技能。
常见问题解答
问:循环提示系统适合什么样的任务?
答:适合那些需要多步骤、可以自动检验是否完成的任务,比如代码修复、测试驱动开发、文档生成、数据清洗等。对于一次性问答或创意写作,单次提示就够用了。
问:怎么判断一个任务是否值得用循环?
答:可以问自己三个问题:这个任务需要两步以上才能完成吗?我能写一个自动判断“完成”的检查吗?我是否要反复执行类似的任务?如果三个答案都是“是”,那么循环就是合适的选择。
问:循环失败了怎么办?会不会一直卡住?
答:不会,因为我们设计了停止条件(最大轮次、成本上限)。此外你还可以加入人工确认点。循环永远有安全出口。
问:如何控制循环的成本?
答:主要方法有三个:设置最大轮次数、设置成本预算(比如5美元)、优化技能库以减少不必要的推理。另外,选择合适大小的模型也很重要——不是所有任务都需要最大的模型。
问:一个循环里可以嵌套另一个循环吗?
答:可以。复杂任务往往需要多级循环。例如,外层循环负责整体任务规划,内层循环负责具体某个子任务的执行。但要注意控制总成本和复杂度。
问:循环提示系统和大语言模型的关系是什么?
答:循环系统是调度框架,大语言模型是执行引擎。循环负责任务分解、状态管理和流程控制,模型负责每轮的具体推理和行动。两者分工明确。
问:我该如何开始实践?
答:从一个极简版本开始。先写一个 is_done 检查(比如检查某个文件是否存在某行代码),然后写一个 build_prompt 函数,最后加上 max_turns=3 的简单循环。跑通后再逐步增加技能和护栏。
总结
我们不再手动一步一步地操作。我们设计一次循环,给它自我检查的能力和停止机制,然后让它自己跑起来。
-
提示是单次动作,循环是完整策略 -
五个部分缺一不可:完成定义、上下文构建、行动捕获、反馈闭环、停止条件 -
先写“完成”检查,再写其他部分 -
让状态自动构建提示,绝不手动输入 -
捕获全部输出,失败就是下一轮的原材料 -
必须有护栏:限制轮次、监控成本、必要时人工确认 -
提炼可复用的技能,让循环的价值随时间增长
这就是设计一个能自动提示智能体的循环系统的完整方法。用它来解决真实的、多步骤的问题,让智能体真正为你工作,而不是你为它打工。

