A deep research agent pursues a long-horizon goal through repeated searching, reading, planning, and synthesis. Its loop updates state and plans outside the agent, then stops when defined termination conditions are met. section 9.2
Design the loop around a few practical controls:
- Track state explicitly, including the goal, iteration count, follow-up questions, findings, and research-plan status. section 9.2 section 9.2.5
- Set termination conditions and iteration limits so the system converges instead of consuming tokens indefinitely. section 9.2 section 9.2.5
- Connect retrieval tools through a managed server context, and shut the server down when the loop exits. section 9.2.5
- Choose breadth-first or depth-first exploration by removing follow-up questions from the front or end of the queue. section 9.2.5
- Control context growth by passing only recent findings while synthesizing earlier information into later results. section 9.2.5
Planner with specialist workers
A research planner can delegate web search, extraction, analysis, criticism, and writing to tool-like workers. For a request to compare three open RAG rerankers, it searches for evidence, tracks sources, checks contradictions and coverage, then streams a cited brief. section 11.4
Figure 9.4 The external component/code sections that control a deep research agent and how the code works through each external step of the agentic loop
Trace how goal, state, plan, tools, and decisions move through the external steps of the research loop. section 9.2
Listing 11.7 08_deep_research_agent_tips.py
import asyncio
from agents import Agent, Runner
from openai.types.responses import ResponseTextDeltaEvent
web_search_tool = ... #1
extract_tool = ... #2
analyze_tool = ... #2
critic = Agent(name="Critic", instructions="Check completeness, bias, contradictions.")
writer = Agent(
name="Writer", instructions="Synthesize into a concise brief with citations."
) #3
researcher = Agent(
name="ResearchPlanner",
instructions=(
"Break down the research goal. Always use web/doc tools for facts. "
"Track sources and avoid unsupported claims."
),
tools=[
web_search_tool,
extract_tool,
analyze_tool,
critic.as_tool(),
writer.as_tool(),
],
)
# Stream results to your UI
stream = Runner.run_streamed(
researcher, "Map the 3 best open RAG rerankers and compare."
) #D
async def main():
result = Runner.run_streamed(
researcher, input="Map the 3 best open RAG rerankers and compare."
)
async for event in result.stream_events(): #4
if event.type == "raw_response_event" and isinstance(
event.data, ResponseTextDeltaEvent
):
print(event.data.delta, end="", flush=True)
if __name__ == "__main__":
asyncio.run(main())
Inspect a compact implementation of planner, search, extraction, analysis, criticism, writing, and streamed output. section 11.4
