Article · 2025-07-24

AutoGen Multi-Agent System Practice Reflection: From Heavy-Weight Contextual Programming to Lightweight AI Assistant

My core objective was to address a key pain point of current AI code assistants: they are often "one-shot" and lack a continuous focus on code quality and subsequent optimization. I wanted my system to simulate a miniature development team.

1. System Design: A Trinity of AI Developers

1.1 The Concept

I designed three highly specialized agents:

  1. CoderAgent: Responsible for generating the initial Python code based on user requirements. Its core duty is to implement functionality quickly.
  2. QualityAnalyzerAgent: Responsible for reviewing the code generated by CoderAgent. It uses static analysis tools (like pylint) to check for style issues, potential errors, and non-standard practices, then provides specific modification suggestions.
  3. OptimizerAgent: After the code is functionally correct and meets quality standards, this agent examines it from a higher level, suggesting improvements related to algorithmic efficiency, code structure, and readability.

1.2 Technical Implementation

To enable these three agents to collaborate intelligently, I chose AutoGen's GroupChat mode with speaker_selection_method="auto". I expected the system to act like a project manager, automatically selecting the most appropriate agent to speak based on conversation context.

Here is the core code snippet for the system setup:

import autogen

# Configure the LLM
config_list = autogen.config_list_from_json(...) 
llm_config = {"config_list": config_list}

# 1. Define the agents
coder = autogen.AssistantAgent(
    name="CoderAgent",
    system_message="You are a helpful AI assistant that writes Python code to solve tasks. Return the code in a markdown code block.",
    llm_config=llm_config,
)

quality_analyzer = autogen.AssistantAgent(
    name="QualityAnalyzerAgent",
    system_message="You are a quality assurance expert. You review the given Python code for style, errors, and best practices. Suggest specific improvements.",
    llm_config=llm_config,
)

optimizer = autogen.AssistantAgent(
    name="OptimizerAgent",
    system_message="You are a performance optimization expert. You analyze the Python code for performance bottlenecks and suggest refactoring for better efficiency and readability.",
    llm_config=llm_config,
)

user_proxy = autogen.UserProxyAgent(
    name="UserProxy",
    human_input_mode="TERMINATE",
    code_execution_config={"work_dir": "coding"},
)

# 2. Set up the GroupChat with automatic speaker selection
# Using "auto" mode lets the LLM decide the next speaker
groupchat = autogen.GroupChat(
    agents=[user_proxy, coder, quality_analyzer, optimizer],
    messages=[],
    max_round=15,
    speaker_selection_method="auto" 
)

manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=llm_config)

# 3. Initiate the task
user_proxy.initiate_chat(
    manager,
    message="Write a Python function to find the nth Fibonacci number, then analyze and optimize it."
)

With this setting, my ideal workflow was: UserProxyCoderAgentQualityAnalyzerAgentOptimizerAgentUserProxy. It looked perfect. Reality delivered a different lesson.

2. The "Heaviness" in Practice: When Idealism Meets Reality

Once running, I felt a persistent sense of "heaviness"—not from any single issue, but from several compounding factors.

2.1 Interaction Latency and the Efficiency Black Hole

For a simple Fibonacci function, the entire process took several minutes. Each handoff between agents is a complete LLM call. The GroupChat's process for deciding the next speaker also requires an LLM inference. Completing one simple task involved 5–10 or more LLM calls.

In daily development work, I need code completions and suggestions in seconds, not the result of an AI team "holding a meeting" that requires waiting with a cup of coffee. This latency is fatal for high-frequency, real-time development assistance scenarios.

2.2 Uncontrollable "Emergent Intelligence"

speaker_selection_method="auto" is a double-edged sword. It introduced intelligence but also chaos. Several typical problems emerged:

This unpredictability transformed a tool meant to boost efficiency into a "black box" requiring careful guidance and observation.

2.3 Complex State Management and Context Passing

The 'state' in a multi-agent system is the piece of code being iterated on. Ideally, QualityAnalyzerAgent should analyze the latest code from CoderAgent.

But GroupChat state is maintained through an ever-growing message history. As conversation rounds increase, the context window expands rapidly. This increases token costs and causes subsequent agents to "lose focus" due to information overload, ignoring critical code versions or modification suggestions. I had to meticulously craft prompts, repeatedly reminding agents to "please focus on the code in the previous message," which itself became a burden.

2.4 High Configuration and Debugging Costs

Building this system required substantial investment in meta-work:

These upfront and ongoing costs are disproportionate to solving "write a Fibonacci function."

3. Reflection: Which Scenarios Truly Require "Heavy Artillery"?

This failed attempt clarified the nature and boundaries of multi-agent systems.

Multi-agent systems excel at:

Scenarios that benefit from multi-agent systems:

  1. Exploratory and Research Tasks: For example, "Investigate the latest advancements in autonomous driving technology and generate a comprehensive analysis report including technical summary, key players, and future trends." Such tasks lack a fixed process, require multiple complex steps like information gathering, integration, and analysis, and benefit from creative output synthesis.
  2. End-to-End Automation Projects: For example, "Automatically generate a project skeleton, write core code, and configure deployment scripts based on a user requirements document." These long-cycle, multi-step tasks run asynchronously. A multi-agent system functions like an autonomous project team working silently in the background.
  3. Complex Decision-Making and Simulation: For example, simulating a market environment where 'Consumer Agents,' 'Competitor Agents,' and 'Marketing Agents' interact to predict marketing strategy effectiveness.

Scenarios that demand a lightweight approach:

4. Returning to Simplicity: A Blueprint for Lightweight AI Assistants

Since the heavyweight multi-agent system didn't fit my daily development needs, what works better? The answer is returning to simplicity, leveraging other AutoGen patterns or shifting mindset.

4.1 Solution 1: Sequential Pipeline

If your process is deterministic, like "code first, then review," organize agents sequentially. AutoGen's register_nested_chats feature is perfect for this.

# This is a conceptual example to demonstrate how to build a sequential pipeline.
# After the CoderAgent completes its task, its result is automatically passed 
# as input to the QualityAnalyzerAgent.

# Assuming CoderAgent and QualityAnalyzerAgent are already defined

# Nested chat setup
review_chat = autogen.GroupChat(
    agents=[quality_analyzer, user_proxy],
    messages=[],
    max_round=2,
    speaker_selection_method="manual" # Or another controllable method
)

# Register the nested chat to form a pipeline
coder.register_nested_chats(
    [{"recipient": quality_analyzer, "message": "Please review the following code.", "summary_method": "last_msg"}],
    trigger=user_proxy,
)

user_proxy.initiate_chat(coder, message="Write a Python function for quick sort.")

This pattern maintains deterministic control flow: User → Coder → QualityAnalyzer. It preserves agent specialization while eliminating unpredictability and high coordination costs of auto-selecting GroupChat.

4.2 Solution 2: Single Agent with Tools

This is the mainstream, practical paradigm for building AI assistants today—aligned with OpenAI's Function Calling/Tool Use pattern.

The core idea: Instead of multiple agents conversing, create one capable AssistantAgent and encapsulate capabilities like 'quality analysis' and 'code optimization' as tools it can call.

import pylint.lint
import io
from pylint.reporters.text import TextReporter

# 1. Define the tool function
def lint_code(code: str) -> str:
    """Runs pylint on the given Python code and returns the report."""
    pylint_opts = ['--disable=all', '--enable=E,W']
    reporter = TextReporter(io.StringIO())
    pylint.lint.Run([io.StringIO(code)], reporter=reporter, exit=False, args=pylint_opts)
    return reporter.out.getvalue()

# 2. Create an agent with tool-calling capabilities
super_assistant = autogen.AssistantAgent(
    name="SuperAssistant",
    system_message="You are a super-assistant for Python development. You can write code and use tools to check its quality.",
    llm_config=llm_config,
)

# 3. Create a UserProxyAgent and register the tool
user_proxy = autogen.UserProxyAgent(
    name="UserProxy",
    human_input_mode="TERMINATE",
    code_execution_config=False, # We aren't executing code, just calling tools
)

user_proxy.register_function(
    function_map={
        "lint_code": lint_code
    }
)

# 4. Let the agent use the tool
# In the LLM's prompt, it will be informed that the lint_code tool is available.
# The LLM will decide when it's appropriate to generate a request to call this tool.

The advantages are decisive:

Conclusion

My journey from ambitious design to pragmatic retreat taught me a clear lesson: technology selection must always prioritize fitness for purpose. Multi-agent systems are powerful and fascinating, but they're not a universal solution. Chasing a "cool-looking" architecture while ignoring real-world efficiency, cost, and controllability is technical self-indulgence.

When building AI applications, the goal isn't the most complex system, but the one that best solves the actual problem. Within a framework like AutoGen, GroupChat is one of many tools. Learning to choose wisely between multi-agent collaboration, sequential pipelines, and single-agent-plus-tools based on task characteristics marks a mature AI engineer.

Collaboration between humans and AI, and between AI systems, will deepen. The challenge is maintaining clarity amid emerging technologies to find the balance between technical sophistication and practical value.

© 2026 Yuxu Ge ·