Skip to main content
This guide builds a research agent end to end. The agent takes a research question, searches the web, reads sources, and produces a structured summary with citations. By the end you’ll have a working agent and a complete trace.

What we’re building

A research agent that:
  • Takes a topic or question.
  • Plans the research (what to search for).
  • Searches the web for primary sources.
  • Reads the most relevant pages.
  • Synthesizes a structured summary.
  • Returns the summary with citations.
The agent uses web_search, web_fetch, and a custom submit_research_report tool for the structured output.

Step 1 — Configure the agent

catalog/agents/researcher/agent.json:
catalog/agents/researcher/system-prompt.md:

Step 2 — Define the structured output tool

catalog/tools/submit_research_report.json:
The tool is implemented as a skill that just records the input — your application reads the structured payload from the tool_call.input. The researcher needs a web-search key:
Reload the Engine.

Step 4 — Send the first request

The stream:
Your application reads the submit_research_report tool’s input from the tool_call event — that’s your structured payload, ready to display or store.

Step 5 — Storing structured output

In your application:

Step 6 — Memory for follow-ups

When the user asks a follow-up question on the same topic, the agent should remember what it already found. The Engine handles this automatically:
  • Same task_id → conversation history includes the prior research.
  • Different task_id → the Learning Centre may have surfaced relevant episodes during retrieval.
You can also write episodes explicitly during the run by giving the agent a memory_episode_write tool. The agent records “during research on X, the most authoritative source was Y” — useful for next time.

Step 7 — Add evals

Custom scorers check that every key_points[i].source_url is a valid URL and that the structured output validates against your schema.

Improvements worth making

Citation verification

Add a verify_url tool that fetches the URL and confirms the cited text appears in the page. Catches the model hallucinating sources that sound plausible.

Multi-source corroboration

For high-stakes claims, require the agent to cite at least two independent sources. Adjust the system prompt:

Long-context Gemini for source-heavy queries

When the user’s question requires reading many long sources, route to Gemini 2.5 Pro instead of Sonnet:
  • Run two Engine instances.
  • Switch upstream based on query complexity.

Domain-specific search tools

For research within a specific domain (legal, medical, financial), swap web_search for a domain-specific search tool that hits authoritative databases. The agent’s flow stays the same; the inputs get better.

Pitfalls

  • Hallucinated citations. The model can confidently cite URLs that don’t exist. The verify_url tool above is the durable fix.
  • Search loops. The agent searches, doesn’t find what it wants, searches again with a slight variation. Cap iterations: “After 3 searches, commit to what you have or ask the user.”
  • One-shot summary masquerading as research. Without explicit instruction to call submit_research_report, the model will write the report as text. The system prompt must enforce the tool call.
  • Stale information. Search returns old pages. For time-sensitive questions, prefer searches with date filters or domain-specific tools.

See also