Starphix
Agentic Engineering / Sources
The Lab / Sources / Agentic Engineering / Frameworks/AutoGen.md

AutoGen

Microsoft's multi-agent conversation framework. Designed for agent-to-agent collaboration.


Core Concepts

Agent Types

from autogen import (
    ConversableAgent,
    UserProxyAgent,
    AssistantAgent,
    GroupChat,
    GroupChatManager
)

# Basic agents
assistant = AssistantAgent(
    name="assistant",
    llm_config={"model": "gpt-4o"},
    system_message="You are a helpful assistant."
)

user_proxy = UserProxyAgent(
    name="user_proxy",
    human_input_mode="NEVER",  # ALWAYS, TERMINATE, NEVER
    code_execution_config={"work_dir": "coding", "use_docker": False},
)

# Group chat
agents = [assistant, user_proxy, coder, researcher]
groupchat = GroupChat(agents=agents, messages=[], max_round=20)
manager = GroupChatManager(groupchat=groupchat, llm_config=llm_config)

# Initiate
user_proxy.initiate_chat(manager, message="Build a web scraper")

Agent Classes

Class Purpose Key Features
ConversableAgent Base class LLM config, tools, memory, hooks
AssistantAgent LLM-driven System message, function calling
UserProxyAgent Human-in-loop Code execution, human input, termination
GroupChatManager Orchestration Speaker selection, round management
RetrieveUserProxyAgent RAG-enabled Vector DB integration

Conversation Patterns

1. Two-Agent (Assistant + User Proxy)

assistant = AssistantAgent("assistant", llm_config=config)
user_proxy = UserProxyAgent("user", human_input_mode="NEVER")

# User proxy executes code, assistant writes
user_proxy.initiate_chat(assistant, message="Plot sin(x)")

2. Group Chat (Multi-Agent)

coder = AssistantAgent("coder", system_message="Write Python code")
reviewer = AssistantAgent("reviewer", system_message="Review code for bugs")
tester = AssistantAgent("tester", system_message="Write unit tests")

groupchat = GroupChat(
    agents=[coder, reviewer, tester],
    messages=[],
    max_round=15,
    speaker_selection_method="auto"  # auto, round_robin, random
)

manager = GroupChatManager(groupchat=groupchat, llm_config=config)
user_proxy.initiate_chat(manager, message="Build a REST API")

3. Nested Chats (Hierarchical)

# Sub-chat for specific domain
coding_chat = GroupChat(agents=[coder, reviewer], messages=[], max_round=10)
coding_manager = GroupChatManager(groupchat=coding_chat, llm_config=config)

# Main chat delegates to sub-chat
main_agents = [planner, coding_manager, deployer]
main_chat = GroupChat(agents=main_agents, messages=[], max_round=20)

Speaker Selection

Method Description Best For
auto LLM chooses next speaker Dynamic, complex
round_robin Fixed order Predictable, fair
random Random Exploration
custom Function(state) -> agent Rule-based
def custom_speaker(last_speaker, agents):
    if last_speaker == "coder":
        return "reviewer"  # Always review after code
    return "coder"

groupchat = GroupChat(
    agents=[coder, reviewer],
    speaker_selection_method=custom_speaker
)

Tool Use

Function Calling

def get_weather(location: str) -> str:
    """Get current weather for a location."""
    return f"Sunny, 72°F in {location}"

assistant = AssistantAgent(
    name="weather_bot",
    llm_config={"model": "gpt-4o", "functions": [get_weather]},
    system_message="Use get_weather tool for weather queries."
)

Code Execution (UserProxyAgent)

user_proxy = UserProxyAgent(
    name="executor",
    code_execution_config={
        "work_dir": "workspace",
        "use_docker": True,  # Isolation
        "image": "python:3.11-slim",
        "timeout": 60
    },
    human_input_mode="NEVER"
)

# Agent writes code, user_proxy executes
assistant.initiate_chat(user_proxy, message="Create a dashboard")

Memory & Context

Built-in Memory

agent = AssistantAgent(
    name="memory_agent",
    llm_config=config,
    # Automatic conversation history
    # Max tokens managed by LLM config
)

External Memory (RetrieveUserProxyAgent)

from autogen import RetrieveUserProxyAgent

rag_agent = RetrieveUserProxyAgent(
    name="rag_user",
    retrieve_config={
        "task": "qa",
        "docs_path": ["./docs"],
        "chunk_token_size": 1000,
        "model": "text-embedding-3-small",
        "vector_db": "chromadb",
        "collection_name": "my_docs"
    }
)

Advanced Patterns

1. Teachable Agents

from autogen import TeachableAgent

teachable = TeachableAgent(
    name="learnable",
    llm_config=config,
    teach_config={
        "recall_threshold": 1.5,
        "token_limit": 2000
    }
)

# Teach via natural language
user_proxy.initiate_chat(teachable, message="Remember: API_KEY = 'secret'")
# Later...
user_proxy.initiate_chat(teachable, message="What's the API key?")

2. AgentEval (Auto Evaluation)

from autogen import AgentEval

evaluator = AgentEval(
    name="evaluator",
    llm_config=config,
    criteria={
        "correctness": "Does the answer solve the problem?",
        "completeness": "Are all parts addressed?",
        "clarity": "Is it well-explained?"
    }
)

score = evaluator.evaluate(task="Write a factorial function", response=code)

3. Magentic-One (Generalist Multi-Agent)

from autogen import MagenticOne

orchestrator = MagenticOne(
    llm_config=config,
    agents=["web_surfer", "file_surfer", "coder", "computer_terminal"]
)

result = orchestrator.run("Find and summarize the latest AI papers")

AutoGen Studio (No-Code UI)

pip install autogenstudio
autogenstudio ui --port 8081

Features: - Visual agent builder - Drag-and-drop workflows - Chat interface for testing - Session history - Export to Python code


Configuration

LLM Config

llm_config = {
    "model": "gpt-4o",
    "api_key": "sk-...",
    "temperature": 0.7,
    "top_p": 0.9,
    "max_tokens": 4096,
    "timeout": 120,
    "cache_seed": 42,  # Deterministic caching
    "functions": [tool1, tool2]  # For function calling
}

Agent Config

agent = AssistantAgent(
    name="specialist",
    llm_config=llm_config,
    system_message="You are a domain expert...",
    description="Use for technical questions",  # For speaker selection
    max_consecutive_auto_reply=3,  # Prevent loops
    human_input_mode="NEVER",
    is_termination_msg=lambda x: "TERMINATE" in x.get("content", "")
)

Multi-Agent Patterns

1. Sequential Pipeline

agents = [planner, researcher, writer, editor]
# Each passes output to next via group chat

2. Parallel with Aggregation

# Multiple researchers in parallel
researchers = [Researcher(f"researcher_{i}") for i in range(3)]
aggregator = AssistantAgent("aggregator", system_message="Synthesize findings")

groupchat = GroupChat(agents=researchers + [aggregator], ...)

3. Debate / Consensus

def consensus_speaker(last_speaker, agents):
    # Force debate: pro -> con -> pro -> con -> judge
    pass

debate_agents = [proponent, opponent, judge]
groupchat = GroupChat(agents=debate_agents, speaker_selection_method=consensus_speaker)

4. Hierarchical Delegation

manager = AssistantAgent("manager", system_message="Delegate to specialists")
specialists = [coder, researcher, designer, tester]

# Manager initiates sub-chats
def delegate(task, specialist):
    sub_chat = GroupChat(agents=[specialist, user_proxy], max_round=5)
    sub_manager = GroupChatManager(groupchat=sub_chat)
    user_proxy.initiate_chat(sub_manager, message=task)

Observability

Logging

import logging
logging.basicConfig(level=logging.INFO)
# Logs: agent messages, tool calls, code execution, speaker selection

AgentOps Integration

import agentops
agentops.init(api_key="...")

# Auto-traces: conversations, token usage, costs, errors

Custom Callbacks

agent = AssistantAgent(
    name="tracked",
    llm_config=config,
    # Hook into events
    on_message=lambda msg: log_to_analytics(msg),
    on_tool_call=lambda tool, args: track_tool(tool, args)
)

Deployment

Docker

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
# For code execution
RUN apt-get update && apt-get install -y docker.io
COPY . .
CMD ["python", "main.py"]

Kubernetes (Code Execution Isolation)

# Each UserProxyAgent gets its own pod for code execution
# Use KubeSpawner or similar for dynamic pods

Azure (Native)

# AutoGen integrates with Azure AI
llm_config = {
    "model": "gpt-4o",
    "api_type": "azure",
    "api_base": "https://myresource.openai.azure.com",
    "api_version": "2024-02-01"
}

Migration: AutoGen 0.2 → 0.4

0.2 0.4
autogen.agents autogen (flat)
UserProxyAgent UserProxyAgent (same)
GroupChat GroupChat (same)
llm_config dict LLMConfig dataclass
register_function @function_tool decorator
Conversation class Removed (use GroupChat)

Performance Tips

  1. Reuse agents — Don't recreate per task
  2. Limit rounds — max_round prevents infinite loops
  3. Cache LLM responses — cache_seed in config
  4. Batch tool calls — Parallel where possible
  5. Monitor token usage — AgentOps or custom tracking


Sources: AutoGen docs (microsoft.github.io/autogen), AutoGen GitHub, AutoGen Studio, AgentOps, Microsoft Research blog, AutoGen 0.4 migration guide, ArXiv: "AutoGen: Enabling Next-Gen LLM Applications" (Wu et al., 2023).

From the Agentic Engineering research vault · CC BY 4.0 · all notes · raw markdown