AI 代理执行循环怎样设置工具调用最大轮数
来源:17golang原创
时间:2026-11-14 04:39:35 253浏览 收藏
我在给工具型代理加预算时,最容易混淆的是“调用了几次工具”和“模型循环了几轮”。更稳妥的做法是把 max_turns 当作代理运行的硬上限,再单独记录工具错误率、延迟和成本。OpenAI Agents SDK 的 Runner 会在最终输出、handoff 或工具结果之间继续循环;达到上限时抛出 MaxTurnsExceeded,也可以用错误处理器转成受控结果。
官方地址:https://openai.github.io/openai-agents-python/
如果任务通常 2~3 轮就能完成,可以先设 5 轮作为保护线;不要用“取消上限”解决未收敛问题,而要让上限触发后留下可观测、可解释的退出结果。
先把工具调用循环拆成可计数的回合
一个 turn 是一次模型调用,它可能在同一回合里产生一个或多个函数工具调用。工具执行完成后,结果会回到下一次模型调用;因此工具调用次数不一定等于 turn 数。把这几个量拆开,后面才知道上限到底保护了什么。

from agents import Agent, Runner
agent = Agent(
name="资料整理员",
instructions="先调用工具收集资料,再给出简短结论。",
tools=[search_docs],
)
result = await Runner.run(
agent,
"整理这份接口变更的影响范围。",
max_turns=5, # 限制模型回合数,不是把工具调用数直接设为 5
)
print(result.final_output) # 只在代理正常产生最终输出时读取结果
上面的 5 是循环保护线,不是质量分数。一次回合内如果模型并行请求多个工具,工具执行并发还受 max_function_tool_concurrency 等设置影响,这个并发限制与 max_turns 是两件事。
在上限触发时给出受控退出
只设置上限而不处理异常,用户看到的通常是一次失败。生产代码更适合把“没在预算内完成”转成明确状态,让调用方决定是否缩小问题、转人工或异步重试。
from agents import Agent, Runner, RunErrorHandlerInput, RunErrorHandlerResult
def on_max_turns(_data: RunErrorHandlerInput[None]) -> RunErrorHandlerResult:
# 明确告诉调用方:预算耗尽,不把同一任务偷偷重跑
return RunErrorHandlerResult(
final_output="本次任务超过工具调用预算,请缩小范围后再试。",
include_in_history=False, # 避免把兜底文案当成正常答案历史
)
result = await Runner.run(
agent,
"检查一组变更记录并归纳风险。",
max_turns=5, # 先给一个可观测的硬边界
error_handlers={"max_turns": on_max_turns}, # 将异常变成受控输出
)
print(result.final_output) # 调用方可以据此转入人工或缩小任务
这里的退出文案不应伪装成完整答案。它只说明代理没有在预算内完成,调用方还需要保存本次轮数、最后一个工具错误和任务标识。
用指标选择 max_turns,而不是凭感觉
我通常先在固定任务集上观察四个数字:成功任务的平均轮数、P95 轮数、工具错误率和达到上限的比例。若大多数成功样本在 3 轮内结束,直接把上限设成 20 往往只是延迟和成本的隐形放大器;若很多任务在 5 轮时刚好被截断,则应先检查工具返回是否过长、参数是否不完整,而不是盲目把上限加倍。

| 观察信号 | 更合理的动作 |
|---|---|
| 平均轮数低、上限触发少 | 保留小幅余量,例如从 3 调到 5 |
| 工具错误率随轮数上升 | 先修工具契约、参数校验和错误提示 |
| 上限触发集中在长任务 | 拆分任务或改成异步,不只提高上限 |
| 轮数稳定但成本波动大 | 另算输入输出 token、工具延迟和并发,不把 max_turns 当总预算 |
并发工具和嵌套代理要单独设预算
max_turns 约束的是某次代理运行的模型回合。它不等于单回合可以同时执行多少个本地工具,也不自动替子代理设定同样的上限。父代理调用一个 agent-as-tool 时,应给嵌套运行单独的 max_turns,并在业务层再加总延迟和成本预算。
from agents import Agent, ModelSettings, RunConfig, ToolExecutionConfig
agent = Agent(
name="资料整理员",
instructions="只调用必要工具,遇到不完整数据就说明缺口。",
model_settings=ModelSettings(
parallel_tool_calls=False, # 需要严格单工具节奏时关闭模型并行请求
),
)
run_config = RunConfig(
tool_execution=ToolExecutionConfig(
max_function_tool_concurrency=2, # 限制本地工具同时执行的数量
),
)
result = await Runner.run(
agent,
"只整理已提供的资料。",
max_turns=5, # 仍然只代表模型回合上限
run_config=run_config,
)
最后记住三个边界:max_turns 防止循环失控,工具并发限制保护本地执行资源,业务预算则负责限制总延迟和花费。三者分开记录,代理才会既能完成任务,也能在失败时及时停下来。
相关问题
max_turns 设为 None 可以吗?
可以表示不启用 SDK 的轮数上限,但仍建议在业务层保留超时、取消和成本预算。无限轮数不等于代理会自动收敛。
工具调用次数能直接用 max_turns 代替吗?
不能。一次模型回合可能产生多个工具调用,多个回合也可能重复调用同一个工具;需要单独统计工具调用事件。
-
207 收藏
-
284 收藏
-
387 收藏
-
328 收藏
-
426 收藏
-
351 收藏
-
308 收藏
-
科技周边 · 人工智能 | 27分钟前 | 缓存 · 人工智能 · mcp · 工具调用 · MCP JSON Schema tools/list tools/list_changed tools/call AI 工具调用320 收藏
-
414 收藏
-
271 收藏
-
212 收藏
-
324 收藏
-
346 收藏
-
139 收藏
-
459 收藏
-
318 收藏
-
科技周边 · 人工智能 | 13小时前 | python · dataset Hugging Face Datasets DatasetDict save_to_disk load_from_disk 离线加载365 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习