Skip to Content

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 ───► output

Pattern

  1. Planner. ONE LLM call. Output is a JSON list of steps. Each step has shape:
    {"id": "E1", "tool": "<tool_name>", "args": {...}}
    Args may reference prior steps via {{En}} placeholders , {"args": {"url": "{{E1}}"}} will use E1’s output as the url argument.
  2. 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.
  3. 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.

Last updated on