🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
đŸ’ŧ Servicesâ„šī¸ Aboutâœ‰ī¸ ContactView Pricing Plansfrom $10

Multi-Agent Research Team

LLM FrameworksLangGraphđŸŸĸ Free Lesson

Advertisement

Multi-Agent Systems

Multi-Agent Research Team — Specialized Agents Working Together

Build a team of specialized AI agents that collaborate on research tasks: a planner that breaks down questions, a researcher that finds information, a writer that synthesizes findings, and a critic that ensures quality.

  • Specialized Roles — Each agent excels at one task
  • Supervisor Pattern — A coordinator routes work between agents
  • Iterative Improvement — Critic loops back to writer until quality is met
  • Production Ready — Streaming, checkpointing, human-in-the-loop

"The best teams aren't made of generalists — they're made of specialists who communicate well."

Multi-Agent Research Team

Single agents struggle with complex tasks that require diverse expertise. This project builds a multi-agent system where specialized agents collaborate to produce high-quality research reports.

Team Architecture

Multi-Agent Research TeamSupervisorRoutes tasks to agentsPlanResearchWritePlanner AgentDecompose questionsCreate research planResearcher AgentSearch & extract infoUse tools & APIsWriter AgentSynthesize findingsDraft reportCritic AgentReview qualityRequest revisionsReviewRevise loopFinal ReportPublished outputIf quality >= 0.8-> Final ReportElse -> Revise

Complete Implementation

from typing import TypedDict, Annotated, List, Literal
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessage
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import MemorySaver

# --- State ---
class ResearchState(TypedDict):
    messages: Annotated[List[BaseMessage], add_messages]
    topic: str
    research_plan: list[str]
    research_findings: list[str]
    draft: str
    critique: str
    quality_score: float
    iteration: int
    phase: str

# --- Tools ---
@tool
def web_search(query: str) -> str:
    """Search the web for information."""
    return f"Search results for '{query}': [Simulated results about {query}]"

@tool
def read_document(url: str) -> str:
    """Read content from a URL."""
    return f"Content from {url}: [Simulated document content]"

tools = [web_search, read_document]

# --- LLM ---
llm = ChatOpenAI(model="gpt-4o", temperature=0)

# --- Agent Nodes ---
def planner_agent(state: ResearchState):
    """Create a research plan."""
    prompt = [
        SystemMessage(content="""You are a research planner. Given a topic, create a step-by-step research plan.
Return ONLY a numbered list of research steps."""),
        HumanMessage(content=f"Create a research plan for: {state['topic']}")
    ]
    response = llm.invoke(prompt)
    plan = [line.strip() for line in response.content.split("\n") if line.strip()]
    return {"research_plan": plan, "phase": "planning"}

def researcher_agent(state: ResearchState):
    """Execute research using tools."""
    tools_with_search = ToolNode(tools)
    
    prompt = [
        SystemMessage(content="""You are a researcher. Search for information on the topic.
Use the web_search tool to find relevant information.
Return your findings as bullet points."""),
        HumanMessage(content=f"Research topic: {state['topic']}\nPlan: {state['research_plan']}")
    ]
    
    response = llm.bind_tools(tools).invoke(prompt)
    
    # Simulate findings
    findings = [
        f"Key finding 1 about {state['topic']}",
        f"Key finding 2 about {state['topic']}",
        f"Key finding 3 about {state['topic']}",
    ]
    
    return {"research_findings": findings, "phase": "research"}

def writer_agent(state: ResearchState):
    """Write a comprehensive report."""
    prompt = [
        SystemMessage(content="""You are a technical writer. Write a comprehensive report based on the research findings.
Include: introduction, key findings, analysis, and conclusion."""),
        HumanMessage(content=f"""Write a report on: {state['topic']}

Research findings:
{chr(10).join(state['research_findings'])}

Previous draft (if any): {state.get('draft', 'None')}
Critique (if any): {state.get('critique', 'None')}""")
    ]
    response = llm.invoke(prompt)
    return {"draft": response.content, "phase": "writing"}

def critic_agent(state: ResearchState):
    """Review the draft and provide feedback."""
    prompt = [
        SystemMessage(content="""You are a quality critic. Review the draft and provide:
1. Quality score (0.0 to 1.0)
2. Specific feedback for improvement
3. Whether the draft is ready (score >= 0.8 = ready)"""),
        HumanMessage(content=f"""Review this draft:

{state['draft']}""")
    ]
    response = llm.invoke(prompt)
    
    # Extract score (simplified)
    score = 0.9 if "excellent" in response.content.lower() else 0.6
    
    return {
        "critique": response.content,
        "quality_score": score,
        "iteration": state.get("iteration", 0) + 1,
        "phase": "review"
    }

def supervisor_router(state: ResearchState) -> Literal["planner", "researcher", "writer", "critic", "end"]:
    """Route to the right agent based on current phase."""
    phase = state.get("phase", "")
    iteration = state.get("iteration", 0)
    
    if phase == "" or phase == "start":
        return "planner"
    elif phase == "planning":
        return "researcher"
    elif phase == "research":
        return "writer"
    elif phase == "writing":
        return "critic"
    elif phase == "review":
        if state.get("quality_score", 0) >= 0.8 or iteration >= 3:
            return "end"
        return "writer"  # Revise
    return "end"

# --- Build Graph ---
workflow = StateGraph(ResearchState)

# Add all agent nodes
workflow.add_node("planner", planner_agent)
workflow.add_node("researcher", researcher_agent)
workflow.add_node("writer", writer_agent)
workflow.add_node("critic", critic_agent)

# Entry point
workflow.set_entry_point("planner")

# Add conditional routing
workflow.add_conditional_edges(
    "planner",
    lambda s: "researcher" if s.get("research_plan") else "end",
    {"researcher": "researcher", "end": END}
)
workflow.add_conditional_edges(
    "researcher",
    lambda s: "writer" if s.get("research_findings") else "end",
    {"writer": "writer", "end": END}
)
workflow.add_conditional_edges(
    "writer",
    lambda s: "critic",
    {"critic": "critic"}
)
workflow.add_conditional_edges(
    "critic",
    lambda s: "end" if s.get("quality_score", 0) >= 0.8 or s.get("iteration", 0) >= 3 else "writer",
    {"end": END, "writer": "writer"}
)

# Compile with checkpointing
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)

# --- Run ---
config = {"configurable": {"thread_id": "research-1"}}
result = app.invoke(
    {"messages": [HumanMessage(content="Research the impact of AI on healthcare")], "topic": "AI in Healthcare", "phase": "start"},
    config
)

print("Final Report:")
print(result["draft"])
print(f"\nQuality Score: {result['quality_score']}")
print(f"Iterations: {result['iteration']}")

Interview Prep

Q: What is the supervisor pattern in multi-agent systems?

Answer: The supervisor pattern uses a central coordinator (supervisor) that:

  1. Receives the user request
  2. Decides which agent should handle it
  3. Routes the task to the appropriate agent
  4. Collects results and decides next step
  5. Loops until the task is complete

Benefits: Clear control flow, easy to debug, simple to add new agents. Drawbacks: Bottleneck at supervisor, single point of failure.

Q: How do agents communicate in LangGraph?

Answer: Agents communicate through shared state:

  • Each agent reads from and writes to the same state dictionary
  • Messages are appended to a shared message list
  • State fields like research_findings are passed between nodes
  • No direct agent-to-agent communication (all through state)

Q: When would you use multi-agent vs single agent?

Answer:

  • Single agent: Simple tasks, few tools, straightforward reasoning
  • Multi-agent: Tasks requiring diverse expertise, complex workflows, or quality assurance
  • Rule of thumb: If your prompt exceeds 1000 tokens or you need 5+ tools, consider multi-agent

Q: How do you debug multi-agent systems?

Answer:

  1. LangSmith tracing: Visualize the full agent graph execution
  2. State inspection: Log state at each node
  3. Human-in-the-loop: Pause and inspect state at critical points
  4. Deterministic testing: Mock LLMs for reproducible tests
  5. Incremental building: Add one agent at a time, verify, then add more

Need Expert LLM Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement