Skip to slide
Chapter 15 · Deep Research Agents and How They Are Trained
118 / 142

CHAPTER 15 · Deep Research Agents and How They Are Trained · 8 / 10

Code MVP: a deep research loop

"""
chapter 15: a deep research loop with planning, retrieval, and review.
Plan subtasks -> retrieve for each (with sources) -> review: keep only claims
backed by >= 2 independent sources -> produce a cited answer.
The review step is the fact-checking / anti-hallucination contract for facts.
"""
from collections import defaultdict

# --- fake retrieval: returns (claim, source) pairs for a subquery ---
FAKE_WEB = {
    "100m final time": [("final at 21:50", "olympics.com"),
                        ("final at 21:50", "bbc.com")],
    "eurostar last train": [("last Eurostar 21:13", "eurostar.com")],
    "west end show time": [("show at 19:30", "lwtheatres.co.uk"),
                          ("show at 19:30", "westend.com")],
}

def plan_subqueries(question: str) -> list:
    """Planning-only strategy (Chapter 15 taxonomy): decompose directly."""
    return ["100m final time", "eurostar last train", "west end show time"]

def retrieve(subquery: str) -> list:
    return FAKE_WEB.get(subquery, [])

def review(findings: list, min_sources: int = 2) -> dict:
    """ReviewAgent / fact-check: keep claims confirmed by >= min_sources
    independent sources; flag single-source claims as unverified."""
    by_claim = defaultdict(set)
    for claim, source in findings:
        by_claim[claim].add(source)
    verified = {c: sorted(s) for c, s in by_claim.items() if len(s) >= min_sources}
    unverified = {c: sorted(s) for c, s in by_claim.items() if len(s) < min_sources}
    return {"verified": verified, "unverified": unverified}

def deep_research(question: str) -> dict:
    findings = []
    for sub in plan_subqueries(question):          # MasterAgent plans
        findings.extend(retrieve(sub))             # SubAgents retrieve
    reviewed = review(findings)                     # ReviewAgent cross-checks
    answer = "; ".join(f"{c} [{', '.join(srcs)}]"
                       for c, srcs in reviewed["verified"].items())
    return {"answer": answer,
            "needs_more_research": list(reviewed["unverified"].keys())}

if __name__ == "__main__":
    from pprint import pprint
    pprint(deep_research("Can I watch the 100m final and still catch the West End show?"))

Run it: the loop plans three subqueries, retrieves claims with sources, and the review step keeps only the claims backed by at least two independent sources while flagging the single-source Eurostar time as needing more research. Every kept claim ships with its citations. That structure, plan then retrieve then cross-check then cite, is the spine of every production DR agent.

← → arrow keys work too