首页 / 文章

打破人工智能代理无限循环的十一种方法

检测工具卡住的情况,添加停止条件,并通过检查点来恢复,而非使用更多令牌。

发布者:REACTAPP.TOP阅读约 11 分钟2555 词

来源: **Your AI Agent Is Stuck in a Loop. Here Are 11 Ways to Fix It**

Agent
  ↓
Tool
  ↓
Result
  ↓
Agent
  ↓
Same Tool
  ↓
Same Tool
  ↓
Same Tool
  ↓
💸

1. 为什么人工智能代理会陷入循环?

Search customer
→ Find customer
→ Check order
→ Check order again
→ Search customer again
→ Check order again
Bad tool selection
Ambiguous tool results
State not changing
Weak stopping conditions
Repeated failed attempts
Model choosing the same strategy again
track_package("12345")
Status: In transit
Estimated delivery: Tomorrow

2. 简单的代理循环

对于那些会花费资金或修改生产数据的操作,需要人工进行审批。编译时的连接方式并不等同于业务上的完整性。

while (!done) {
  const action = await model.decide(context);
  const result = await executeTool(action);
  context.push(result);
}
Model
 ↓
Tool
 ↓
Result
 ↓
Model
 ↓
Tool
 ↓
Result
 ↓
...

现实世界中的例子

以实际应用为例,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新执行该步骤,而无需猜测隐藏状态。 需同时记录正常流程与异常恢复路径。重试机制、人工审核环节以及错误处理都是产品不可或缺的部分,而非后续需要补充的功能。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。仅靠编译时的配置并不足以确保业务的完整性。 以实际应用为例,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新执行该步骤,而无需猜测隐藏状态。 应将此阶段视为输入与验证后输出之间的契约。为相关成果命名,明确成功判定标准,绝不允许出现无声无息的半完成状态。

get_refund_status()
Refund pending
get_refund_status()

3. 为智能体设定预算

在处理“3. 为智能体设定预算”这一环节时,首先需列出合同条款:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改有据可依。 在功能结果旁记录执行时间以及令牌或查询成本。提前明确成本有助于避免从演示环境过渡到共享环境时出现意外账单。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次收取相同的LLM调用费用。

const MAX_STEPS = 12;
const MAX_TOOL_CALLS = 20;
const MAX_RUNTIME_MS = 30_000;

为何要设置多个限制?

在研究“为何要使用多重限制?”这一主题时,首先需明确相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 应将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在耗时较高的步骤之后设置检查点。当操作人员重新执行后续节点时,恢复流程不应再次对同一次大型语言模型调用收费。

Steps        → reasoning budget
Tool calls   → external API budget
Time         → latency budget
Tokens       → model cost

示例

在处理示例时,首先需明确约定:所需的输入参数、成功标志以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 同时记录正常流程与异常恢复路径。重试机制、人工审核环节以及错误消息处理都是产品功能的一部分,而非后续需要补充的内容。 在耗时较高的步骤之后设置检查点。当操作员重新尝试某个节点时,恢复流程不应再次调用相同的大型语言模型接口。 在处理示例时,首先需明确约定:所需的输入参数、成功标志以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 将此阶段视为输入与验证后输出之间的契约。为相关成果命名,定义成功判定标准,并杜绝无声的半完成状态。

Search restaurant
→ Search restaurant
→ Search restaurant
→ Check table
→ Check table
→ Check table
→ Search restaurant again
Maximum 8 actions
Maximum 15 seconds
Maximum 5 reservation checks

4. 检测重复操作

  1. 将重复动作检测视为可度量的指标时效果最佳。在扩大范围之前,先记录一个成功的示例、一个失败案例以及回滚说明。在功能结果旁同时记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。要保持图结构简洁且类型明确,嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在出现中断后导致流程无法继续。
search_users(...)
search_users(...)
search_users(...)
const signature = `${toolName}:${JSON.stringify(args)}`;

if (seenActions.has(signature)) {
  throw new Error("Repeated tool invocation detected");
}
seenActions.add(signature);

但仅靠精确匹配是不够的

但仅靠精确匹配是不够的,将其视为可测量的结构才能发挥最佳效果。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。 将配置置于应用程序代码之外。环境文件、密钥存储和功能标志应集中存放于一处,这样操作人员无需查看整个结构就能进行审计。 保持数据结构的层次简单且类型明确。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致无法继续处理。

search("Node.js latency")
search("nodejs latency")
search("Node latency")

5. 检测进度缺失

  1. 将“检测进度缺失”视为可度量的指标时效果最佳。在扩大范围之前,需记录一份理想状态下的流程日志、一个故障案例以及回滚说明。同时将正常流程与恢复流程都记录下来。重试机制、人工审核环节以及错误处理都属于产品本身的功能,而非后续需要补充的内容。要保持数据结构的层次简单且类型明确,否则嵌套的数据结构会掩盖具体是哪个节点修改了哪个字段,还会在进程中断后导致无法继续执行。
  2. 将“检测进度缺失”视为可度量的指标时效果最佳。在扩大范围之前,需记录一份理想状态下的流程日志、一个故障案例以及回滚说明。应将此阶段视为输入与已验证输出之间的契约,为相关文档命名,明确成功标准,绝不允许出现无声无息的半完成状态。
Step 1 → Search customer
Step 2 → Search customer by email
Step 3 → Search customer by name
Step 4 → Search customer by phone
Step 1
Find customer → ✅
Step 2
Find order → ✅
Step 3
Check shipment → ✅
Step 4
Check shipment → same result
Step 5
Check shipment → same result

一种实用的心智模型

为建立有效的思维模型,在修改代码之前应明确输入参数、该步骤的负责人以及终止标准。操作人员应当能够从已知的检查点重新执行该步骤,而无需猜测隐藏状态。应在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。当下一步操作是编写代码或调用工具时,优先选择具有结构化格式且经过模式验证的输出,而非自由形式的文字描述。

How many actions did the agent take?
What changed after each action?

6. 不要盲目重试

对于第6点:不要盲目重试,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审核。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。

charge_card()
→ timeout

这一原则同样适用于智能体

对于智能体而言,同样适用这一原则:在修改代码之前需明确输入参数、该步骤的负责人以及终止条件。操作人员应能够从已知的检查点重新执行该步骤,而无需猜测隐藏状态。 需同时记录正常流程与异常恢复路径。重试机制、人工审核环节以及错误处理都是产品不可或缺的部分,而非后续需要补充的内容。 对于任何会耗费资金或修改生产数据的操作,都必须经过人工审批。仅靠编译时的配置并不足以保证业务的完整性。 对于智能体而言,同样适用这一原则:在修改代码之前需明确输入参数、该步骤的负责人以及终止条件。操作人员应能够从已知的检查点重新执行该步骤,而无需猜测隐藏状态。 应将这一阶段视为输入与经过验证的输出之间的契约。为相关成果命名,明确成功标准,绝不允许出现无声无息的半完成状态。

for (let i = 0; i < 10; i++) {
  await callTool();
}
Timeout
→ Retry may make sense

Invalid input
→ Retry with same arguments makes no sense
Permission denied
→ Try a different strategy
Same successful result
→ Stop

7. 为智能体制定恢复策略

在处理“7. 为智能体制定恢复策略”这一环节时,首先需写下相关合同条款:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及令牌或查询成本。提前明确成本信息,可避免在从演示环境过渡到共享环境时出现意外费用。 在耗时较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次收取相同的LLM调用费用。

search_invoices(customer_id)
→ No result
search_invoices(customer_id)
→ No result
→ search_invoices(customer_id)
→ No result
→ search_invoices(customer_id)
Search by customer ID
        ↓
No result
        ↓
Search by email
        ↓
Still no result
        ↓
Search archived invoices
if (isStuck(state)) {
  return replan({
    reason: "No progress detected",
    previousActions
  });
}

8. 明确“完成”的标准

在处理第8步时,要明确标注“已完成”的状态,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持透明。 将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在耗时较高的步骤之后设置检查点。当操作人员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。

I found an order.
Done.
Task:
Find latest order

Done when:
- customer identified
- orders retrieved
- orders sorted by date
- latest order selected
- result returned

现实世界类比

在运用现实世界类比进行设计时,首先需明确合同条款:所需输入、成功信号以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 同时记录正常流程与故障恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续的优化工作。 在成本较高的步骤之后设置检查点。当操作员重新尝试某个节点时,恢复流程不应再次调用相同的大型语言模型。 在运用现实世界类比进行设计时,首先需明确合同条款:所需输入、成功信号以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 将此阶段视为输入与验证后输出之间的契约。为相关成果命名,定义成功判定标准,并拒绝默许部分完成的情况。

Destination reached

9. 在需要之前就加入可观测性功能

  1. 在真正需要之前就建立可观测性,将其视为可度量的指标最为有效。在扩大范围之前,先记录一份典型的成功案例、一个故障实例以及回滚说明。 在功能结果旁同时记录执行时间以及令牌或查询成本。尽早了解成本情况,就能避免从演示环境过渡到共享环境时出现意外的费用支出。 保持图表状态简洁且类型明确。嵌套的数据结构会掩盖哪个节点修改了哪个字段的信息,还会在出现中断后导致无法继续处理。
run_id
step
tool
arguments
duration
result size
retry count
token usage
termination reason
Run: abc123

Step 1
search_users
210ms

Step 2
get_user
130ms

Step 3
get_orders
180ms

Step 4
get_orders
175ms

Step 5
get_orders
172ms

Step 6
LOOP DETECTED
Reason: No state change

10. 更安全的智能体循环

  1. 将更安全的代理循环视为可度量的对象来处理,效果最佳。在扩大范围之前,先记录一个成功的示例、一个失败案例以及回滚说明。 将配置置于应用程序代码之外。环境文件、密钥存储和功能标志应集中存放于一个位置,以便操作人员无需查看整个结构即可进行审计。 保持图结构的扁平化与类型化。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,且在中断后会导致无法继续执行。
while (!done) {
  if (steps >= MAX_STEPS) {
    return terminate("Step budget exceeded");
  }
  if (Date.now() - startTime > MAX_RUNTIME_MS) {
    return terminate("Time budget exceeded");
  }
  const action = await model.decide(context);
  if (isRepeated(action)) {
    return replan("Repeated action detected");
  }
  const previousState = snapshot(state);
  const result = await executeTool(action);
  state = updateState(state, result);
  if (!hasProgress(previousState, state)) {
    markNoProgress();
  }
  if (tooMuchNoProgress()) {
    return replan("No meaningful progress");
  }
  if (isComplete(state)) {
    done = true;
  }
}

11. 模型负责决策,框架负责执行。

  1. 模型负责决策,框架负责执行。将其视为可度量的界面时效果最佳。在扩大范围之前,需记录一份理想案例、一个故障案例以及回滚说明。 同时记录正常流程与恢复流程。重试机制、人工审核环节以及错误处理都是产品的一部分,而非后续需要补充的内容。 为每轮对话和每次会话设定token预算。智能工具会大量消耗上下文,设置上限可避免演示过程变成意外的费用账单。
  2. 模型负责决策,框架负责执行。将其视为可度量的界面时效果最佳。在扩大范围之前,需记录一份理想案例、一个故障案例以及回滚说明。 将此阶段视为输入与经过验证的输出之间的契约。为相关成果命名,明确成功标准,杜绝无声的半完成状态。
What should I do next?
How many times can you act?
How long can you run?
Have you repeated yourself?
Are you making progress?
Did the state change?
Are you allowed to call this tool?
When should execution stop?
Speed limiter
Brake system
Fuel gauge
Navigation system
Collision warning

目标并非消除循环

Write code
→ Run tests
→ See failure
→ Fix code
→ Run tests
→ See failure
→ Fix code
→ Tests pass
→ Stop
Did the agent loop?
Did the agent make progress?

制作检查清单

☑ Is there a maximum step count?
☑ Is there a runtime limit?
☑ Is there a tool-call budget?
☑ Can repeated actions be detected?
☑ Can we detect lack of progress?
☑ Are retries failure-aware?
☑ Can the agent re-plan?
☑ Is "done" explicitly defined?
☑ Can we see every tool call in production?
☑ Do we know why an agent terminated?

最后的话

感谢您成为社区的一员

操作检查清单

针对3372f6d9932d的改写标记1:用操作员用语重新表述相关内容,保持[[CODE_n]]占位符不变,避免重复原文句子。

针对3372f6d9932d的改写标记2:用操作员用语重新表述相关内容,保持[[CODE_n]]占位符不变,避免重复原文句子。

针对3372f6d9932d的改写标记3:用操作员用语重新表述相关内容,保持[[CODE_n]]占位符不变,避免重复原文句子。

为 3372f6d9932d 的标记 4 进行重写:用操作符语言重新表述周围的陈述,保持 [[CODE_n]] 占位符不变,避免重复源文本句子。

为 3372f6d9932d 的标记 5 进行重写:用操作符语言重新表述周围的陈述,保持 [[CODE_n]] 占位符不变,避免重复源文本句子。

为 3372f6d9932d 的标记 6 进行重写:用操作符语言重新表述周围的陈述,保持 [[CODE_n]] 占位符不变,避免重复源文本句子。

为 3372f6d9932d 的标记 7 进行重写:用操作符语言重新表述周围的陈述,保持 [[CODE_n]] 占位符不变,避免重复源文本句子。