
做过大模型应用开发的朋友,大概率都踩过同一个坑:用 ReAct 架构搭智能体时,大模型“一边思考、一边调用工具、再根据结果接着想”,导致 Token 消耗像流水一样,响应速度慢得像老头乐。
为啥慢?因为它是同步串行的。大模型调用完工具 A,必须等工具 A 的返回结果喂进上下文,才能开始规划工具 B。如果中间夹杂了三次网页搜索和两次数据库查询,用户在前端屏幕前能盯着 loading 图发呆十秒钟。
今天咱们不玩虚的,直接拆解一种能把这个过程彻底拆开的提示词与架构方案——REWOO(Reasoning Without Observation)。
一、 传统 ReAct 的痛点与 REWOO 的破局逻辑
在传统的 ReAct(Reasoning and Acting)框架里,大模型的思维链(Chain-of-Thought)长这样:
`思考 1 -> 执行工具 1 -> 观察结果 1 -> 思考 2 -> 执行工具 2 -> 观察结果 2`
这种模式的致命弱点有三个:
1.上下文爆炸:每一步的中间结果和冗长的工具输出都会无条件塞进 Prompt,后面的 Token 计费呈指数级上升。
2.延迟叠加:网络延迟和模型推理时间串联累加,工具越多,速度越慢。
3.纠错能力差:一旦某一步的工具返回了脏数据,整个推理链条容易被带偏。
而 REWOO 的核心思想很简单粗暴:把“规划(Planning)”和“执行(Execution)”彻底解耦。
用大白话讲,就是让大模型学学人类的“项目经理”。项目经理在接到底层任务时,不会干一步想一步,而是先把整个项目的完整工序(Plan)一次性写出来,把需要调用的工具和参数占好位(比如 `#E1`、`#E2`),然后把这些任务一股脑丢给底层的异步执行器去跑。最后,把所有跑完的结果汇总,交由大模型做最终的综合输出。
来看一张对比表,直观感受两者的差异:
| 维度 | ReAct 架构 (传统同步) | REWOO 架构 (解耦异步) |
|---|---|---|
| 执行方式 | 串行:思考 $rightarrow$ 行动 $rightarrow$ 观察 $rightarrow$ 再思考 | 并行:一次性生成全量计划 $rightarrow$ 异步并发执行 $rightarrow$ 总结 |
| Token 消耗 | 随步骤线性或指数级增加,历史上下文冗余高 | 计划阶段固定,执行阶段按需注入,成本可控 |
| 耗时与延迟 | $T_{total} = sum (T_{llm} + T_{tool})$ | $T_{total} = T_{llm(plan)} + max(T_{tool}) + T_{llm(solver)}$ |
| 适用场景 | 简单、单步或强依赖前一步输出的动态任务 | 复杂多源信息检索、多工具组合的高并发任务 |
二、 实战拆解:REWOO 的三阶段工作流
实现 REWOO 不需要改动底层模型权重,完全可以通过提示词工程(Prompt Engineering)来约束大模型的行为。整个工作流分为三个明确的阶段:
1.Planner(规划器):分析用户意图,不看任何工具的实际返回结果,一口气写出所有的执行步骤和占位符。
2.Worker(执行器):解析 Planner 的输出,提取工具名和参数,利用代码(如 Python 的 `asyncio`)进行并发调用。
3.Solver(求解器):将原始问题、Planner 的计划以及 Worker 跑出来的执行结果(Evidence)结合起来,给出最终答案。
我们以“查询特斯拉和苹果最近一季度的财报营收,并计算两者的增长差”为例,来看看具体的提示词应该怎么写。
三、 核心提示词模板与编写细节
要把 REWOO 落地,关键在于约束大模型输出严格遵循特定格式的计划,方便后续的代码正则解析。
1. Planner 阶段提示词
这里的核心是让大模型使用 `#E1`, `#E2` 这样的变量来指代未来才会出现的工具结果。
你是一个资深的任务规划专家。请针对用户提出的问题,制定一个完整的执行计划。
你目前无法获取任何外部工具的实际返回结果,因此所有需要通过工具获取的信息,必须用占位符表示。
可用工具列表:
- GoogleSearch(query: str): 用于检索互联网公开信息。
- FinancialAPI(ticker: str, period: str): 用于查询上市公司财报数据。
输出格式必须严格遵守以下规范,不要输出多余的废话:
Plan: [步骤简述]
Tool: [工具名称](参数1="...", 参数2="...")
#E1 = [占位符名称]
Plan: [步骤简述]
Tool: [工具名称](参数1="#E1", ...)
#E2 = [占位符名称]
用户问题:{input_query}
2. Worker 阶段的代码实现(Python 异步并发)
当大模型吐出上面的计划后,我们需要写一小段 Python 逻辑去解析它,并丢给异步线程池或 `asyncio` 去跑。
import re
import asyncio
async def run_tool(tool_name, tool_args):
# 模拟异步调用外部 API 或搜索工具
await asyncio.sleep(1)
return f"Result of {tool_name} with {tool_args}"
async def execute_plan(plan_text):
# 正则提取 Plan, Tool 和 占位符
pattern = r"Plan:s*(.*?)nTool:s*(.*?)n(#Ed+)"
matches = re.findall(pattern, plan_text)
tasks = []
evidence = {}
for plan, tool, placeholder in matches:
# 实际开发中,这里需要处理占位符替换逻辑(如果后续步骤依赖前面步骤的结果)
tool_name, tool_args = tool.split("(", 1)
tool_args = tool_args.rstrip(")")
# 异步并发执行
tasks.append((placeholder, run_tool(tool_name, tool_args)))
results = await asyncio.gather(*(t[1] for t in tasks))
for i, (placeholder, _) in enumerate(tasks):
evidence[placeholder] = results[i]
return evidence
3. Solver 阶段提示词
当所有 Worker 把 `evidence` 跑出来后,把它们打包喂给 Solver 模型,完成最后一步的整合。
你是一个专业的分析师。请根据用户的原始问题、你之前制定的执行计划,以及工具实际返回的证据(Evidence),给出最终的准确回答。
原始问题:{input_query}
执行计划与证据:
{plan_and_evidence_combined}
要求:
1. 忽略执行过程中的中间噪音。
2. 逻辑严密,直接给出结论和计算过程。
四、 参数调优与避坑指南
在真实业务场景中落地 REWOO,有几个细节参数和常见陷阱必须注意:
1.大模型选型建议:
•Planner 阶段:建议使用指令遵循能力极强的模型,如 GPT-4o 或 Claude 3.5 Sonnet。如果模型对格式的遵守度不够,经常把 `#E1` 写错或者漏掉括号,整个异步流就会崩塌。
•Solver 阶段:可以使用性价比更高、推理速度更快的模型(如 GPT-4o-mini 或 Claude 3 Haiku),因为此时计算逻辑已经收敛,主要是文字整合。
2.核心超参数设置:
•Temperature(温度):在 Planner 阶段必须设置为 `0` 或极低值(如 `0.1`)。规划任务不需要大模型的“发散性创造力”,我们要的是绝对稳定的格式输出。
•Top_P:建议保持默认(`1.0`)或适当调低(`0.9`),减少长尾低概率词导致的格式错乱。
3.四大常见翻车陷阱:
•依赖链死锁:如果步骤 `#E3` 强依赖 `#E1` 和 `#E2` 的共同输出,而你在解析时没有做好拓扑排序,会导致参数传递为空。应对方案:在 Planner 提示词中明确要求“后置步骤必须显式引用前置占位符”。
•正则解析崩溃:大模型有时会在 `Tool:` 后面多加空格或 Markdown 标记(比如 “`python)。应对方案:在解析前使用清洗函数,去掉所有 Markdown 代码块符号,或者直接让模型输出 JSON 格式(使用 `response_format={“type”: “json_object”}`)。
•Token 浪费在长文本回传:如果 Worker 调用的工具返回了几万字的网页源码,全塞给 Solver 依然会爆上下文。应对方案:在 Worker 节点增加一层摘要过滤(Extractor),只把核心 Key-Value 传给证据池。
把 REWOO 的“规划-并发执行-求解”链路跑通后,你会发现智能体的响应速度能提升 3 到 5 倍,同时因为减少了多轮对话的上下文冗余,API 调用的整体 Token 成本能直接砍掉一半以上。动手写几行异步解析代码,把这个架构塞进你的 Agent 里,性能提升是立竿见影的。

评论前必须登录!
立即登录 注册