Skip to main content
A powerful pattern is to let an orchestrator LLM call the Responses API as a web_research function tool: the orchestrator decomposes the user’s problem and plans, and each tool call is delegated to Parallel as a full grounded-research answer. The orchestrator sees finished, synthesized answers — not raw search results — so its job reduces to planning sub-questions and reconciling what comes back.

The tool definition

The tool takes a single argument — a complete, self-contained question — and returns an answer:

Writing the tool description

The tool description is the contract that shapes how the orchestrator uses the tool — it is the highest-leverage text in this pattern. Best practices:
  • Say it returns a synthesized answer, not search results. Orchestrators trained on web_search-style tools will otherwise issue keyword queries and plan to read results themselves. Words like “answers a question” and “(not raw results)” flip it into asking full questions.
  • Demand the complete, self-contained question. The subagent has no conversation context — every constraint (dates, units, qualifiers, ambiguity resolution) must travel inside the one query string. Repeat this in both the tool description and the parameter description.
  • Bias toward one thorough call first. State that a single call already performs multi-hop research, so the orchestrator doesn’t pre-decompose a question the subagent could answer whole — decomposition should be reserved for genuinely independent parts or gaps left after the first answer. This is your main lever on cost and latency.
  • Keep one required parameter. A single query string is hard to misuse. If you want the orchestrator to control research depth, add an optional effort enum (low | medium | high) with guidance like “use high only for questions that require extensive research” — and default it to low in your handler.

Executing the tool

The handler is just a Responses API call:
Python

Full orchestrator loop

One client for the orchestrator (here OpenAI), one for the Parallel tool backend:
Python

Operational guidance

  • Execute independent tool calls concurrently. When a question has independent parts, the orchestrator should issue those web_research calls in the same turn and your handler should run them concurrently (e.g. asyncio.gather) — wall-clock stays close to a single call instead of the sum.
  • Pick the tier per call: low for cheap breadth across many sub-questions, high for the hardest single lookups.
  • Cap the tool budget and force a final answer when it is exhausted (as above), so a runaway orchestrator can’t loop indefinitely.
  • The same pattern works with any tool-calling orchestrator — see Anthropic Tool Calling and OpenAI Tool Calling for provider-specific wiring.

Next steps

  • Statefulness — an alternative to orchestration when all you need is follow-up questions on a prior answer