LangGraphMulti-AgentPython

How I built a multi-agent system that critiques its own output

July 1, 2026·6 min read

Most AI pipelines work like this: you send a prompt, you get a response, you're done. That works fine for simple tasks. But if you want a researched, structured report on a complex topic — the first draft is rarely good enough.

I wanted to build something that knew that. A system that would write a report, read it back critically, and decide whether to revise or ship it.

The architecture

Four agents, one state machine:

- **Supervisor** — reads the current state and decides which agent runs next - **Researcher** — pulls live web data via Tavily Search - **Writer** — synthesises research into a structured 900–1400 word report - **Critiquer** — scores the draft across five dimensions and returns structured feedback

The loop runs until the Critiquer approves the output or three revision cycles complete — whichever comes first.

Why LangGraph

The key insight is that this isn't a chain — it's a graph with cycles. The Writer can run multiple times. The Supervisor can route back to the Researcher if the draft reveals gaps in the research.

LangGraph models this as a `StateGraph` where each agent is a node and routing is handled by conditional edges off the Supervisor. There's no hardcoded sequencing anywhere. The Supervisor just reads the state and decides.

def supervisor_node(state: ResearchState) -> dict:
    if not state.get("research"):
        return {"next": "researcher"}
    if not state.get("draft"):
        return {"next": "writer"}
    if state.get("critique") and state["critique"]["approved"]:
        return {"next": END}
    if state.get("revision_count", 0) >= 3:
        return {"next": END}
    return {"next": "writer"}

Simple. The complexity lives in the agents, not the routing.

The critique loop

The Critiquer scores the draft across five dimensions: coverage, evidence quality, structure, clarity, and actionability. Each gets a score out of 10. If the average is below 7, it returns specific feedback and the Writer gets another pass.

This is where it gets interesting. The Writer receives not just the original research but the full critique — what was weak, why, and what a better version would do differently. The rewrites are genuinely better.

What I'd do differently

The Researcher runs once. In a better version, the Critiquer's feedback would trigger targeted follow-up research — "the evidence for this claim is thin, go find more." That's the next thing I'm building.

The code is on GitHub if you want to dig in.