ReWOO
Reasoning WithOut Observation. Xu et al. 2023 , ReWOO: Decoupling Reasoning from Observations for Efficient Augmented Language Models.
The cost-saving sibling of Plan-and-Execute.
Each step in the plan is a real tool call, with {{En}}
placeholder substitution to reference prior step outputs. Independent
steps run in parallel.
Total cost: 2 LLM calls + N tool calls. ReAct on the same task needs roughly N+1 LLM calls (one per turn). For tool-heavy workloads where the planner can predict the call sequence upfront, ReWOO is 30–50% cheaper.
prompt ───► planner ───► [search({{E1}}), fetch({{E2}}=search.url)]
│
▼
parallel tool dispatch
(independent steps run concurrently;
dependent steps wait for {{En}})
│
▼
synthesizer ───► outputPattern
- Planner. ONE LLM call. Output is a JSON list of steps. Each
step has shape:
Args may reference prior steps via
{"id": "E1", "tool": "<tool_name>", "args": {...}}{{En}}placeholders ,{"args": {"url": "{{E1}}"}}will use E1’s output as theurlargument. - Executor. Walk the plan. Steps with no
{{En}}references (or only references to already-completed steps) run in parallel. Dependent steps wait for their referenced step to finish. - Synthesizer. ONE LLM call combining the original prompt + the tool results into the final answer.
Usage
from loomflow import Agent, tool
from loomflow.architecture import ReWOO
@tool
async def search(query: str) -> str:
"""Web search."""
...
@tool
async def fetch(url: str) -> str:
"""Fetch a URL."""
...
agent = Agent(
"Research the topic and produce a summary with citations.",
model="claude-opus-4-7",
architecture=ReWOO(),
tools=[search, fetch],
)
result = await agent.run("Recent advances in agent harnesses.")Or by string:
agent = Agent("...", model="...", architecture="rewoo", tools=[search, fetch])When ReWOO pays off
- Tool-heavy workloads (search / fetch / DB / API calls) where the planner can list the calls upfront.
- Independent steps. Multiple searches that can run in parallel.
- Cost matters. You save the per-turn LLM call ReAct would make between every tool result.
When ReAct is still better
- The plan depends on tool output you can’t predict. If the search result reshapes the next call, ReAct’s “think between each tool call” loop is needed.
- Failure recovery. ReWOO commits to the plan; a failed tool call doesn’t trigger replanning. ReAct re-thinks every turn.
Placeholders are textual substitution. {{E1}} is replaced with
E1’s tool result string before the dependent tool runs. For complex
data flows (extract a URL out of a JSON blob), have the model produce
a more structured plan upfront, or fall back to ReAct.