Skip to main content
Multi-agent research team that produces structured reports.

Code

"""AG2 (formerly AutoGen) multi-agent research team wrapped with Bindu.

Three specialized agents collaborate under GroupChat with LLM-driven
speaker selection to produce structured research reports. The team is
exposed as a single Bindu agent, callable via A2A protocol.

Architecture:
    User (via Bindu A2A) → handler → AG2 GroupChat
        ├── researcher — gathers information
        ├── analyst   — evaluates findings
        └── writer    — produces the final report
"""

import os
from autogen import ConversableAgent, LLMConfig
from autogen.agentchat import initiate_group_chat
from autogen.agentchat.group.patterns import AutoPattern
from bindu.penguin import bindufy
from dotenv import load_dotenv

load_dotenv()

llm_config = LLMConfig(
    {
        "model": os.getenv("LLM_MODEL", "openai/gpt-4o-mini"),
        "api_key": os.environ.get("OPENROUTER_API_KEY", ""),
        "base_url": "https://openrouter.ai/api/v1",
    }
)

config = {
    "author": "ag2-community",
    "name": "ag2-research-team",
    "description": (
        "A multi-agent research team powered by AG2 (formerly "
        "AutoGen). Three specialists — researcher, analyst, and "
        "writer — collaborate to produce structured reports on "
        "any topic."
    ),
    "deployment": {
        "url": "http://localhost:3773",
        "expose": True,
        "cors_origins": ["http://localhost:5173"],
    },
    "skills": ["skills/question-answering"],
}

def handler(messages: list[dict[str, str]]):
    """Run the AG2 research team and return the final report."""
    if not messages:
        return [{"role": "assistant", "content": "No input provided."}]
    user_input = messages[-1].get("content", "")
    if not user_input:
        return [{"role": "assistant", "content": "Empty message."}]

    # Fresh agents per request to avoid state leakage
    researcher = ConversableAgent(
        name="researcher",
        system_message=(
            "You are a research specialist. Investigate the "
            "given topic thoroughly. Present key facts, data "
            "points, and sources in a structured format."
        ),
        llm_config=llm_config,
    )

    analyst = ConversableAgent(
        name="analyst",
        system_message=(
            "You are an analyst. Review the researcher's "
            "findings. Identify trends, implications, risks, "
            "and opportunities. Be quantitative where possible."
        ),
        llm_config=llm_config,
    )

    writer = ConversableAgent(
        name="writer",
        system_message=(
            "You are a report writer. Once the researcher and "
            "analyst have contributed, synthesize their work "
            "into a structured report with: Executive Summary, "
            "Key Findings, Analysis, and Recommendations. "
            "Keep it under 500 words. End with TERMINATE."
        ),
        llm_config=llm_config,
    )

    user = ConversableAgent(
        name="user", human_input_mode="NEVER"
    )

    pattern = AutoPattern(
        initial_agent=researcher,
        agents=[researcher, analyst, writer],
        user_agent=user,
        group_manager_args={"llm_config": llm_config},
    )

    result, ctx, last = initiate_group_chat(
        pattern=pattern,
        messages=f"Research and produce a report on: {user_input}",
        max_rounds=10,
    )

    # Extract the last substantive message
    for msg in reversed(result.chat_history):
        content = msg.get("content", "")
        if content and "TERMINATE" not in content:
            return [{"role": "assistant", "content": content}]

    return [{"role": "assistant", "content": "Research complete."}]

if __name__ == "__main__":
    bindufy(config, handler)

How It Works

Multi-Agent Architecture
  • Three specialized agents collaborate in GroupChat
  • Researcher gathers information and data
  • Analyst evaluates findings and identifies trends
  • Writer synthesizes into structured reports
Agent Roles
  • researcher: Investigates topics thoroughly with facts and sources
  • analyst: Reviews findings, identifies risks and opportunities
  • writer: Creates structured reports with executive summary
Coordination
  • AutoPattern manages agent selection and conversation flow
  • LLM-driven speaker selection for optimal collaboration
  • Fresh agent instances per request prevent state leakage
Report Generation
  • Structured format: Executive Summary, Key Findings, Analysis, Recommendations
  • 500-word limit for concise reports
  • Automatic termination and content extraction

Run

uv run examples/advanced/ag2-research-team.py
Try: “Research the impact of AI on job markets in 2024” Go to frontend and run npm run dev Open http://localhost:5173 and try to chat with the AG2 research team