XAgent ReACT 框架深度解析:实现细节、提示词设计与通用方案对比

XAgent ReACT 框架深度解析:实现细节、提示词设计与通用方案对比

本文聚焦 XAgent Inner Loop 中的 ReACTChainSearch,从源码级别拆解其「推理---行动---观察」闭环如何落地,完整收录 ToolAgent 提示词与 function schema,并与论文 ReACT、LangChain、OpenAI Agents 等通用方案做对照。适合已读过 task_handler.py 外层循环、希望深入理解单个子任务如何被 ReACT 驱动的工程师。


1. 背景:ReACT 在 XAgent 中的位置

1.1 双层循环

XAgent 把任务执行拆成两层:

text 复制代码
Outer Loop (task_handler.outer_loop)
  ├── PlanAgent 生成 / refine 计划树
  └── 对每个 TODO 子任务:
        Inner Loop (task_handler.inner_loop)
          └── ReACTChainSearch.generate_chain()
                └── 直到 subtask_submit 或步数耗尽

Outer Loop 管「做什么、顺序如何、失败后怎么改计划」;Inner Loop 管「当前这一个子任务怎么靠工具做完」。

1.2 入口代码

inner_loop 是 ReACT 的唯一入口:

python 复制代码
# XAgent/workflow/task_handler.py
search_method = ReACTChainSearch(xagent_core_components=self.xagent_core)

arguments = function_manager.get_function_schema('action_reasoning')['parameters']
search_method.run(
    config=self.config,
    agent=agent,  # ToolAgent,RequiredAbilities.tool_tree_search
    arguments=arguments,
    functions=self.function_handler.intrinsic_tools(self.config.enable_ask_human_for_help),
    task_id=task_ids_str,
    now_dealing_task=self.now_dealing_task,
    plan_agent=self.plan_agent,
)

执行完成后,now_dealing_task.process_node = search_method.get_finish_node(),submit 结果挂在 Plan 节点上,供 Outer Loop 的 posterior_processplan_refine_mode 使用。

1.3 命名与实现的落差

类名 ReACTChainSearchTaskSearchTree 暗示「树搜索」,但实现是 单链 ReACT

  • 每步只扩展一个子节点(make_father_relation
  • 无分支、无 backtracking、无 value-based 选优
  • max_try 默认为 1,几乎不重试整条链

准确说法:Chain-based ReACT,不是 MCTS 或 Best-of-N 搜索。


2. 核心类:ReACTChainSearch

文件:XAgent/inner_loop_search_algorithms/ReACT.py

2.1 类职责

成员 作用
tree_list 每次 generate_chain 追加一棵 TaskSearchTree(支持多次 attempt,默认只用 1 次)
finish_node 链终止时的 ToolNode(submit 节点或最后一步工具节点)
need_for_plan_refine subtask_submit 解析出的 refine 标志,供 Outer Loop 使用
status SUCCESS / FAIL / HAVE_AT_LEAST_ONE_ANSWER

2.2 run() vs generate_chain()

python 复制代码
def run(self, ...):
    for _attempt_id in range(max_try):  # 默认 max_try=1
        self.generate_chain(...)

    if self.status == SearchMethodStatusCode.HAVE_AT_LEAST_ONE_ANSWER:
        self.status = SearchMethodStatusCode.SUCCESS
    else:
        self.status = SearchMethodStatusCode.FAIL

run() 只做重试包装和最终状态归一;所有 ReACT 语义在 generate_chain() 的 while 循环里


3. generate_chain:逐步拆解

3.1 循环骨架

python 复制代码
def generate_chain(self, config, agent, arguments, functions, task_id, now_dealing_task, plan_agent):
    self.tree_list.append(TaskSearchTree())
    now_attempt_tree = self.tree_list[-1]
    now_node = now_attempt_tree.root  # 空 ToolNode,depth=0

    while now_node.get_depth() < config.max_subtask_chain_length:  # 默认 15
        # ① 可选:人工中断改写 thoughts
        # ② make_message:拼 Observation 历史
        # ③ 读 workspace 文件结构
        # ④ ToolAgent.parse:Reason + Act(一次 LLM 调用)
        # ⑤ message_to_tool_node
        # ⑥ FunctionHandler.handle_tool_call:执行
        # ⑦ 挂树、推 UI、now_node 下移
        # ⑧ submit 则 break

    self.finish_node = now_node

默认配置(assets/gpt-3.5-turbo_config.yml):

yaml 复制代码
max_subtask_chain_length: 15
max_retry_times: 3
enable_summary: true
enable_ask_human_for_help: False

3.2 单步数据流

sequenceDiagram participant GC as generate_chain participant MM as make_message participant TA as ToolAgent participant FH as FunctionHandler participant TS as ToolServer participant TN as ToolNode GC->>MM: now_node.process MM-->>GC: additional_messages GC->>TA: parse(placeholders, arguments, functions, additional_messages) TA-->>GC: message (thoughts + function_call) GC->>TA: message_to_tool_node TA-->>GC: new_tree_node GC->>FH: handle_tool_call(new_tree_node) alt 真工具 FH->>TS: execute_command_client TS-->>FH: command_result else subtask_submit FH->>FH: handle_subtask_submit end FH->>TN: node.data.tool_output = result GC->>GC: now_node = new_tree_node

4. Re / Act / Ob 在 XAgent 里分别是什么

这是理解 XAgent ReACT 的关键:三个字母都在,但形态与论文不同

4.1 Reason(Re)--- 同一次 function call 里的 schema 字段

模型被强制调用 subtask_handle(或最后一步的 subtask_submit),在 同一个 JSON 里必须先填:

字段 schema 描述 字数提示
plan 下一步宏观计划 array,约 30 词
thought 内部推理,从前步结果学习并纠错 约 50 词
reasoning 为什么给出该 thought 约 100 词
criticism 对当前 thought/plan 的 constructive 自我批评 无硬上限
tool_call 实际工具名 + 参数 ---

来源:XAgent/ai_functions/pure_functions/task_handle_functions.yml

此外,inner_loop 还把 action_reasoning 的 parameters merge 进 function schema(与 Plan refine 里 merge simple_thought 是同一套 BaseAgent.generate 机制)。在 OpenAI 路径下 ToolAgent.parse 会把 arguments=None,推理字段完全由 subtask_handle schema 承载。

日志输出(Re 的可视化)在 core.print_assistant_thoughts

python 复制代码
# THOUGHTS / REASONING / PLAN / CRITICISM 分别打印
assistant_thoughts = assistant_reply_json_valid.get("thoughts", {}).get("properties", {})

结论:Reason 不是单独一轮 LLM,而是 Act 之前的 mandatory structured fields。

4.2 Act(Act)--- tool_callsubtask_submit

ToolAgent.message_to_tool_node 拆分 message:

python 复制代码
new_node.data['thoughts']['properties'] = message["arguments"]       # Re 部分
new_node.data["command"]["properties"]["name"] = function_call["name"]   # Act 部分
new_node.data["command"]["properties"]["args"] = function_call["arguments"]

OpenAI 路径的特殊处理:真实外部工具不直接作为顶层 function,而是嵌在 subtask_handle.tool_call 里。ToolAgent.parse 会:

  1. functions 里滤掉 subtask_submitsubtask_handle
  2. 把可用工具 schema 追加进 system prompt 文本
  3. 只保留 [subtask_submit, subtask_handle] 两个顶层 function
  4. 解析后把 tool_call 拆出来 变成真正的 function_call

这是为兼容早期 OpenAI function calling 限制的 hack,也是 XAgent ReACT 与「标准 tool use」差异最大的地方之一。

FunctionHandler.handle_tool_call 路由:

command_name 行为
外部工具名 toolserver_interface.execute_command_client
subtask_submit 解析 success / refine 建议,不访问 ToolServer
ask_human_for_help interaction.ask_for_human_help
视为成功,无输出

4.3 Observe(Ob)--- 写入 ToolNode,下轮经 make_message 喂回

执行后:

python 复制代码
# function_handler.py
node.data["tool_output"] = command_result
node.data["tool_status_code"] = tool_output_status_code
node.history.add("system", f"Command {command_name} returned: {command_result}", "action_result")

下一轮,make_message 从当前节点沿父链收集历史:

python 复制代码
# node.py --- ToolNode.process
def process(self):
    data = []
    now_node = self
    while now_node.father != None:
        data = [now_node.data] + data
        now_node = now_node.father
    return data

make_message 生成两条 user 消息:

python 复制代码
# 消息 1:当前子任务完整描述
now_subtask_prompt = f'''Now you will perform the following subtask:\n"""\n{terminal_task_info}\n"""\n'''

# 消息 2:已执行步骤(含 tool_output 摘要)
user_prompt = f"""The following steps have been performed (you have already done the following and the current file contents are shown below):\n
{action_process}
"""

enable_summary=Trueaction_process = summarize_action(action_process, terminal_task_info),会对每一步调用 summarize_actionactions_reflection 等 LLM 摘要,再按 token 预算拼接 [return]

结论:Observation 不以 Observation: 文本标签出现,而是下一轮 prompt 里的 user 上下文注入。


5. 完整提示词(ToolAgent)

来源:XAgent/agent/tool_agent/prompt.py

Dispatcher 默认使用以下模板(占位符由 fill_in_placeholders 替换)。

5.1 SYSTEM_PROMPT(全文)

text 复制代码
You are an experimental cutting-edge super capable autonomous agent specialized in learning from environmental feeback and following rules to do correct and efficient actions.
Your decisions must always be made independently without seeking user assistance. 
You can interactive with real world through tools, all your tool call will be executed in a isolated docker container with root privilege. Don't worry about the security and try your best to handle the task.
As a Super Agent build with super powerful tools, you are capable of handling any given task, thus your capabilities are far above regular simple AI or LLM.

--- Your Workflow ---
1. You will first be given a task (query) together with a plan to handle it.
2. Then you will handle one of the subtasks. Steps:
  - Decide what action should be taken next:
    - If the action is something like text understanding, text classification, text analyzing, do it on your own and use FileSystem tools to write down your answer.
    - If not, try your best to use available tools to do it. Ask user for help when you face problems. Chat with former autonomous agent when you have problems or when you get confused about what other autonomous agent have done.
 - After decide the action, call functions to apply action.
3. After you reached all subtask goals, you must use FileSystemEnv to write a task report contains all information for goals before submit the subtask.
4. Finally, call `subtask_submit` to submit the subtask and give the detailed suggestions about the future planning.

--- Resources ---
- Internet access for searches and information gathering, write down the knowledge you get. 
- A FileSystemEnv to read and write files (text, code, markdown, latex...), always write down detailed content as it will help further actions. 
- A python notebook to execute python code. Always follow python coding rules. Contains libs like numpy, pandas, matplotlib, sklearn, etc.
- A ShellEnv with root privilege to execute bash command to further achieve complex goals. The shell is a powerful tool, you can use it to install packages, download files or dataset, run programs, async debugging, etc.
- Ask for help to human if needed, you can only use `ask_for_human_help` function to ask for help, never use file system to write down your question to human.

--- Maximum Your Performance ---
1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.
2. Constructively self-criticize your big-picture behavior constantly.
3. Reflect on past decisions and strategies to refine your approach.
4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.
5. When generating function call, please check the json format carefully. 
  5.1  Please remember to generate the function call field after the "criticism" field.
  5.2  Please check all content is in json format carefully.

*** Important Rules ***
- You must follow your workflow.
- You are more than a Large Language Model (LLM), you have the capability to do acutal things rather than simply give guidance or write text.
- With the help of tools, you can do nearly everything. You can not only write guides or code, but can also use the tools to actually do the task like setup service or develop complex program.
- If the task is something like text understanding, classification, analyzing, etc, do it on your own and use FileSystem tools to write down your answer, don't use external tools or execute codes.
- Do not use python notebook to process text, you can process text by yourself.
- You can only give up when the tools are insufficient.
- You must pass literal and concrete value to tools, do not use reference or pointer, labels.
- Always use a tool efficiently, reduce the number of steps as much as possible.
- File system struture is printed every time, do not print_filesystem_structure again.
- Submit the subtask immediately if no further actions needed.
- Run any program with the shell if you need, you have the full control of you docker container. You are not limited.
- You can doing any task with the help of given tools, even developing complex programs or configure complex develop environment.
- Only use ask_for_human_help to ask for help, do not use file system or any other tools to write down your question to human.

--- Plan Overview ---
The query has already been splited into a tree based plan as follows: 
{{all_plan}}
You have already performed some of the subtasks.

占位符 {{all_plan}} :每轮由 generate_chain 填入,来自 plan_agent.latest_plan.to_json(),可经 summarize_plan 压缩。

5.2 USER_PROMPT(全文)

text 复制代码
Now, it's your turn give the next function call (please output all the necessary parameters for the function call).
--- Status ---
Current Subtask: {{subtask_id}}
File System Structure: {{workspace_files}}

--- Available Operations ---
- Use tools to handle the subtask and interact with real world.
- Use "subtask_submit" only when you achieve all milestones of the current subtask or you make sure it's impossible with the given tools. Remember, you should also given suggestions to plan rectify agent, So he can rectify the plan after you submit the current subtask.

*** Important Notice ***
- You can at most use {{max_length}} steps of tool calls. After that you must use "subtask_submit". This is the {{step_num}}'th step now, watch out the budget.
- If milestone is too hard to achieve, you can use "subtask_submit" to give up the subtask and divide it into smaller subtasks.
- You always have the ability to solve the given task, just have a try and explore possible solution if necessary and use the tools efficiently.
{{human_help_prompt}}

Now show your super capability as a super agent that beyond regular AIs or LLMs!

运行时占位符:

占位符 来源
subtask_id now_dealing_task.get_subtask_id()
workspace_files FileSystemEnv_print_filesys_struture(截断 1000 token)
max_length config.max_subtask_chain_length
step_num now_node.get_depth() + 1
human_help_prompt 是否允许 ask_human_for_help

5.3 最终 messages 组装顺序

ToolAgent.parsePlanRefineAgent 相同:

python 复制代码
messages = prompt_messages[:additional_insert_index] + additional_messages + prompt_messages[additional_insert_index:]
# additional_insert_index = -1

实际顺序:

text 复制代码
[system]  SYSTEM_PROMPT(含 all_plan、OpenAI 路径下还追加 Available Tools JSON)
[user]    make_message 第 1 条:当前 subtask 描述
[user]    make_message 第 2 条:已执行步骤 + tool 返回
[user]    USER_PROMPT(含 subtask_id、workspace、步数预算)

OpenAI 路径还会在 messages[0]['content'] 末尾动态拼接:

text 复制代码
--- Avaliable Tools ---
You are allowed to use tools in the "subtask_handle.tool_call" function field.
Remember the "subtask_handle.tool_call.tool_input" field should always in JSON...
{tools JSON schema}

6. Function Schema 完整定义

6.1 subtask_handle(普通一步:Re + Act)

yaml 复制代码
# task_handle_functions.yml
- name: subtask_handle
  description: give some reason together with a tool call.
  parameters:
    properties:
      plan:
        type: array
        items:
          type: string
        description: "Max 1 items about what to do next. Around 30 words."
      thought:
        type: string
        description: "internal reasoning and thoughts, learn from the former results and correct your action. Around 50 words."
      reasoning:
        type: string
        description: "Why you give the `thought`. Around 100 words."
      criticism:
        type: string
        description: "constructive self-criticism of the current thought and plan on its weakness and strength."
      tool_call:
        type: object
        required: [tool_name]
        properties:
          tool_name:
            type: string
            enum: []   # 运行时由 change_subtask_handle_function_enum 填充
          tool_input:
            anyOf: [object, string]
    required: ["plan", "thought", "reasoning", "criticism", "tool_call"]

6.2 subtask_submit(终止一步:提交 + 驱动 Outer Loop)

yaml 复制代码
- name: subtask_submit
  parameters:
    properties:
      result:
        properties:
          conclusion: string  # ~400 words
          milestones: array[string]
          success: boolean
      submit_type:
        enum: [give_answer, give_up, max_tool_call, human_suggestion]
      suggestions_for_latter_subtasks_plan:
        properties:
          need_for_plan_refine: boolean
          reason: string  # ~50 words,给 PlanRefineAgent
    required: ["submit_type", "result", "suggestions_for_latter_subtasks_plan"]

subtask_submit 同时承担:

  • Inner Loop 退出信号
  • Outer Loop 状态更新(SUCCESS / FAIL)
  • need_for_plan_refine → 是否进入 plan_refine_mode

6.3 action_reasoning(merge 用,OpenAI 路径下被 bypass)

yaml 复制代码
# reasoning.yml --- inner_loop 传入 arguments,但 ToolAgent 在 openai 模式下置 arguments=None
required: ["plan", "thought", "reasoning", "criticism"]

7. 退出条件与强制策略

7.1 正常退出

python 复制代码
if tool_output_status_code == ToolCallStatusCode.SUBMIT_AS_SUCCESS:
    self.status = SearchMethodStatusCode.HAVE_AT_LEAST_ONE_ANSWER
    break
elif tool_output_status_code == ToolCallStatusCode.SUBMIT_AS_FAILED:
    break
  • SUBMIT_AS_SUCCESS:子任务标记 SUCCESS,可能触发 plan refine
  • SUBMIT_AS_FAILED:子任务标记 FAIL,同样可能 refine(例如请求 split)

7.2 步数耗尽强制 submit

python 复制代码
if now_node.get_depth() == config.max_subtask_chain_length - 1:
    function_call = {"name": "subtask_submit"}

倒数第二步(depth=13,max=15)起 只能 调用 subtask_submit,防止无限工具循环。

7.3 人工中断(可选)

python 复制代码
if now_node.father != None and interaction.interrupt:
    receive_data = interaction.receive(can_modify)
    data, rewrite_flag = self.rewrite_input_func(now_node.data, receive_data)
    now_node.data = data  # 改写 thought/reasoning/plan/criticism

根节点(depth=0)不检查 interrupt;从第二步起用户可注入建议改写当前步思考,但不直接改 tool 参数。


8. Observation 压缩:summarize_action

enable_summary=true(默认开启),历史 Observation 不是 raw tool_output 全量灌回,而是经 summarize_action 多级压缩:

  1. 逐步格式化:[thought][tool calling][return]
  2. 每步调用 LLM summarize_action 生成 summary + description
  3. 调用 actions_reflection 提取 key_actions 和 suggestions
  4. 按 token 预算(max_return_length: 8192)优先保留关键步的完整 return

这对长 ReACT 链至关重要:Observation 层本身又是一层 LLM 摘要系统,不是简单字符串拼接。


9. ToolNode 数据结构

python 复制代码
# node.py
self.data = {
    "content": "",
    "thoughts": {
        "properties": {
            "thought": "",
            "reasoning": "",
            "plan": "",
            "criticism": "",
        },
    },
    "command": {
        "properties": {
            "name": "",      # 工具名或 subtask_submit
            "args": "",
        },
    },
    "tool_output": "",
    "tool_status_code": ToolCallStatusCode.TOOL_CALL_SUCCESS,
}
self.history: MessageHistory = MessageHistory()

ReACT 链在 TaskSearchTree 上表现为:

text 复制代码
root (空节点, depth=0)
 └── step1 ToolNode (thoughts + command + tool_output)
      └── step2 ToolNode
           └── ...
                └── submit ToolNode (finish_node)

10. 与通用 ReACT 方案对比

10.1 对照总表

维度 论文 ReACT LangChain ReAct Agent OpenAI Assistants / Responses API XAgent ReACTChainSearch
输出格式 自由文本 Thought/Action/Observation 文本或 tool calls 原生 tools + tool_outputs 多轮 嵌套 subtask_handle function call
Reason 与 Act 分两行文本 通常同轮或分两轮 分轮:assistant tool_calls → tool role 同一次 JSON:thought + tool_call
Observation 回放 追加为 assistant/user 文本 Message history 官方 tool role message user 消息注入(make_message + summarize)
计划上下文 可选 AgentExecutor + planner 可选 instructions 强制 system 里嵌 full plan tree
终止 模型输出 Finish 自定义 stop 模型停止调 tool 强制 subtask_submit + 步数上限
失败后 同链继续 同链或重跑 同 thread 继续 submit → Outer Loop refine Plan
工具协议 文本 Action LangChain Tool OpenAI tools schema ToolServer HTTP + 嵌套 JSON
搜索 单链 单链为主 单链 名含 Search,实际单链

10.2 论文 ReACT(Yao et al.)

经典格式:

text 复制代码
Thought 1: ...
Action 1: Search[entity]
Observation 1: ...
Thought 2: ...

XAgent 差异:

  • 没有 Thought: / Action: / Observation: 文本标签
  • Reason 是 schema 字段,Act 是 tool_call,Ob 是下轮 user 上下文
  • 多了 plan tree、submit 协议、plan refine 闭环
  • 多了 Docker 沙箱、文件系统快照每轮注入

XAgent 优势: 结构化程度高,便于录制和 UI 展示;与 function calling 时代模型对齐。

XAgent 劣势: ReACT 语义被掩盖在 function call 里;Observation 非标准 chat 格式,对部分模型不一定最优。

10.3 LangChain create_react_agent

典型模式:

python 复制代码
# 概念示意
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, max_iterations=N)
executor.invoke({"input": task})

特点:

  • Tools 直接注册为 LangChain Tool 对象
  • Prompt 模板显式含 {tools}{tool_names}agent_scratchpad
  • agent_scratchpad 自动拼接 Thought/Action/Observation 或 tool messages

对比 XAgent:

LangChain XAgent
scratchpad 框架自动维护 手动 make_message + ToolNode.process
推理字段 通常只有 Thought thought + reasoning + plan + criticism 四字段
提交语义 无标准 subtask_submit submit 带 success/refine 建议,接 Outer Loop
工具层 进程内 Python 函数 远程 ToolServer Docker

XAgent 更像 带计划树的企业级 ReACT Runtime ,LangChain ReAct 更像 轻量单任务循环

10.4 OpenAI 现代 Tool Use(Chat Completions / Agents SDK)

标准多轮:

text 复制代码
user: 任务
assistant: tool_calls: [{name, arguments}]
tool: {tool_call_id, content: 结果}
assistant: tool_calls: [...] 或 最终回答

对比 XAgent:

  • OpenAI:tool 是独立 role,Observation 语义清晰
  • XAgent:Observation 塞进 additional_messages 的 user 文本;OpenAI 路径还把真实 tools 降级subtask_handle.tool_call 嵌套

XAgent 的嵌套是为解决「每轮既要推理字段又要调工具」且兼容旧 API 的折中;现代 API 可直接:

python 复制代码
response = client.chat.completions.create(
    messages=history,
    tools=[...],  # 每个工具顶层注册
)

或用 Structured Output 分离 reasoning JSON 与 tool calls。

10.5 Plan-and-Execute / LangGraph

Plan-and-Execute 典型拆法:

text 复制代码
Planner LLM → 静态步骤列表
For each step:
    Executor LLM + tools
Replanner(可选)→ 改计划

XAgent 等价映射:

Plan-and-Execute XAgent
Planner PlanGenerateAgent
Executor ReACTChainSearch + ToolAgent
Replanner PlanRefineAgent(仅改未来节点)
Step list Plan 树(中序遍历)

XAgent 的 ReACT 绑死在 Plan 节点上 :每轮 system prompt 带 整棵 plan 树,不是只给当前 step。上下文更重,但有利于避免 subtask 间目标漂移。

10.6 AutoGPT / BabyAGI 系

早期自主 Agent 常用:

text 复制代码
命令 JSON:{"command": "web_search", "args": {...}}
或文本:NEXT ACTION: ...

与 XAgent 相似点:structured command + 环境反馈循环。

差异:XAgent 有显式 Plan 树、submit/refine 协议、ToolServer 沙箱、录制回放;AutoGPT 系更扁平,计划常是内存里的 todo list。


11. XAgent ReACT 的设计取舍总结

11.1 做得好的地方

  1. Re + Act 合一:一步 LLM 调用拿齐推理与动作,latency 低于严格三步分离。
  2. 强制反思字段:schema 层保证每步有 thought/criticism,不是可选 CoT。
  3. Observation 摘要summarize_action 解决长链 context 爆炸。
  4. 硬边界:15 步 + 强制 submit,避免 runaway tool loop。
  5. 与 Outer Loop 协议化对接subtask_submit 是明确的 Inner/Outer 边界 API。
  6. ToolNode 树:轨迹结构化,便于 UI、recorder、posterior reflect。
  7. 每轮 workspace 快照:文件结构实时注入,减轻「忘了环境状态」。

11.2 偏旧或易混淆的地方

  1. 嵌套 tool_call:与 modern flat tools 不一致,维护成本高。
  2. Observation 非 tool role:多轮理解可能弱于标准 chat。
  3. 连续 user messages:system 后多条 user,非 canonical format。
  4. 名不副实:ChainSearch 无搜索。
  5. 根节点空跑:depth=0 的 root 不执行,第一步 depth=1 才真正调 LLM。
  6. summary 依赖额外 LLM 调用:Observation 压缩本身耗 token/成本。

12. 一步 ReACT 的完整生命周期(示例)

假设当前 subtask 为 1.2,已执行 2 步,第 3 步开始:

text 复制代码
1. make_message 生成:
   user: "Now you will perform subtask 1.2: ..."
   user: "The following steps have been performed: [0] ShellEnv(...); [1] FileSystemEnv(...); ..."

2. placeholders 填充 USER_PROMPT:
   subtask_id=1.2, step_num=3, max_length=15, workspace_files=...

3. ToolAgent.parse → LLM 返回 subtask_handle:
   {
     "plan": ["Read config and patch port"],
     "thought": "Previous shell output shows service on 8080, need to change config",
     "reasoning": "...",
     "criticism": "...",
     "tool_call": {"tool_name": "FileSystemEnv_read_file", "tool_input": {"filepath": "..."}}
   }

4. message_to_tool_node → 新 ToolNode

5. FunctionHandler → ToolServer 读文件 → tool_output 写入节点

6. interaction.insert_data → Web UI 展示 THOUGHTS / COMMAND / RESULT

7. now_node 指向新节点;若未 submit,回到 while 顶部

13. 若现代化 XAgent ReACT,建议方向

  1. 扁平 tools :外部工具顶层注册;reasoning 用 Structured Output 或单独字段,不再嵌套 subtask_handle.tool_call
  2. 标准 Observation :用 tool role message 或 assistant tool_calls + tool results 真多轮,替代 make_message 伪 user 历史。
  3. 保留 submit 协议subtask_submit 作为 structured terminal action 仍然有价值,是 Plan 层接口。
  4. 可选分离 Reason:高能力模型可用两次调用(cheap reason + action),低能力模型保持合并 schema。
  5. renameReACTChainSearchReACTChainExecutor,避免 Search 误导。

14. 关键代码索引

主题 路径
ReACT 主循环 XAgent/inner_loop_search_algorithms/ReACT.py
Inner Loop 入口 XAgent/workflow/task_handler.pyinner_loop
ToolAgent 提示词 XAgent/agent/tool_agent/prompt.py
ToolAgent 解析 / OpenAI hack XAgent/agent/tool_agent/agent.py
Function schema XAgent/ai_functions/pure_functions/task_handle_functions.yml
工具执行 / Observation 写回 XAgent/function_handler.py
ToolNode / process XAgent/data_structure/node.py
历史摘要 XAgent/agent/summarize.pysummarize_action
配置上限 assets/gpt-3.5-turbo_config.yml
思考日志 XAgent/core.pyprint_assistant_thoughts

15. 结论

XAgent 的 ReACT 不是论文里文本交替的 ReACT,而是:

在 Plan 节点约束下,用 subtask_handle 把 Reason 与 Act 压进一次 structured function call,用 ToolNode 链保存 Observation,用 make_message + summarize_action 把 Observation 注入下一轮 prompt,用 subtask_submit 关闭 Inner Loop 并 handoff 给 Outer Loop 的 Plan refine。

理解这套框架,需要同时看:提示词(workflow + 步数预算)、schema(四段推理 + tool_call)、generate_chain 循环、FunctionHandler 中介、Observation 摘要管道------缺一不可。

与通用方案比,XAgent 走的是 「重协议、重结构、重 Plan 上下文」 路线,适合长任务、可审计、需人机协作的场景;若只需短链路 tool agent,现代 flat tool use + 标准 message history 往往更简单。两种路线没有绝对优劣,取决于你要的是 Runtime 完整性 还是 集成简洁性

相关推荐
ch_09182 小时前
从0构建SDK第4节:实现 ReflectionAgent 的自我反思循环
typescript·agent·ai编程
米小虾15 小时前
AI Agent 安全实战指南:当智能体开始"不听话",开发者该如何应对?
人工智能·安全·agent
Databend19 小时前
2KB histogram 背后:Databend 如何低成本追踪长尾延迟
大数据·数据分析·agent
笃行35019 小时前
用 CodeBuddy “复活“《山海经》:异兽图鉴网站的诞生
agent
镜舟科技20 小时前
Databricks 再提 LTAP,AI 时代的数据底座为何重回大一统叙事?
数据库·架构·agent
轻口味20 小时前
别被模型宣传骗了,真实 Agent 任务一跑就知道
agent·ai编程
小星AI21 小时前
Kimi Code CLI 超详细教程,附源码
人工智能·agent
Databend21 小时前
从湖仓升级为 Agent 时代的数据控制面,Snowflake 和 Databricks 有哪些布局
大数据·数据库·agent