Skip to content

工具运行流程(Tool Loop)

适用版本:v4.0.8.2

Tool.async_plan_and_execute()v4.0.8.2 中不是一个简单 while 循环,而是一个由 TriggerFlow 驱动的标准化回路。

1. 总体流程

如何阅读这张图

  • PLANEXECUTE 不是文档概念,而是 runtime 内部的显式阶段。
  • 这让 Tool Loop 和普通 TriggerFlow 一样可以维护状态、做超时控制,也能被更稳定地调试。

2. 回合状态长什么样

text
round_state = {
  "done_plans": [...],          # 累积到当前轮为止的全部执行记录
  "last_round_records": [...],  # 仅上一轮的记录
  "round_index": 0,             # 当前轮数
}

架构思路

  • done_plans 负责提供全局上下文,避免模型忘记已经做过什么。
  • last_round_records 负责给规划器提供最近一轮的直接反馈,尤其适合失败重试和 follow-up。
  • round_index 是硬边界,防止回路无限转。

3. 规划阶段:plan_step

默认规划器会创建一个独立 ModelRequest,并读取这些上下文:

  • input.user_input
  • input.user_extra_requirement
  • input.available_tools
  • info.done_plans
  • info.last_round_result
  • info.round_index
  • info.max_rounds

输出结构被约束为:

python
{
    "next_action": "execute" | "response",
    "execution_commands": [
        {
            "purpose": str,
            "tool_name": str,
            "tool_kwargs": dict,
            "todo_suggestion": str,
        }
    ],
}

兼容归一化规则:

  • 传回 tool_commands 也会被收敛成 execution_commands
  • 传回单个 tool_command 也会被提升为列表
  • 缺失 next_action 时,框架会根据是否存在命令自动推断

4. instant 短路

默认规划器会监听流式结构化输出里的 next_action

若在 instant 流里尽早确认:

  • next_action=response

则会直接关闭规划流并返回,不再等待完整结果体。这一点对“无需调用工具的请求”很重要。

5. 执行阶段:execute_step

执行器收到的是一组归一化后的 ToolCommand

python
{
    "purpose": str,
    "tool_name": str,
    "tool_kwargs": dict,
    "todo_suggestion": str,
    "next": str,  # 与 todo_suggestion 对齐后的兼容字段
}

默认执行器会:

  1. 读取 tool.loop.concurrency
  2. 并发调用 async_call_tool(tool_name, tool_kwargs)
  3. 把结果规范化成 ToolExecutionRecord

规范化后的执行记录:

python
{
    "purpose": str,
    "tool_name": str,
    "kwargs": dict,
    "todo_suggestion": str,
    "next": str,
    "success": bool,
    "result": Any,
    "error": str,
}

6. 何时停止

以下任一条件满足时,Tool Loop 会结束:

  • next_action != "execute"
  • use_tool 被归一化为 False
  • 没有可执行命令
  • 达到 max_rounds

7. 收敛与注入

循环结束后,如果 done_plans 非空,框架会:

  • to_action_results(done_plans) -> prompt.action_results
  • 注入 extra_instruction
  • 把原始记录附加到 extra.tool_logs

如果没有任何执行记录,则不注入工具结果。