Building a coding agent that can actually execute Python is straightforward with AutoGen, but wiring the AssistantAgent to a code executor correctly takes care. This autogen assistantagent code executor tutorial walks through a minimal, reproducible setup you can run locally and extend to production, covering install, LLM config, agent definitions, and the execution loop.
Step 1: Install AutoGen and supporting packages
Use Python 3.10 or newer. Create a virtual environment to avoid polluting global site-packages.
python -m venv .venv
source .venv/bin/activate
pip install pyautogen matplotlib
pyautogen is the package name for AutoGen 0.2.x; the import is still autogen. Matplotlib is only needed for the plot example; skip it if your tasks are pure computation.
If you choose Docker isolation (recommended for anything beyond local experiments), confirm the daemon is up:
docker ps
A running daemon returns an empty table without errors.
Step 2: Configure the LLM client
AutoGen speaks the OpenAI chat-completions protocol. You supply a config_list of model entries. The simplest entry points at OpenAI, but you can also target an OpenAI-compatible gateway. For instance, n4n.ai exposes one OpenAI-compatible endpoint that addresses 240+ models and applies automatic fallback when a provider is rate-limited or degraded, so a single base URL covers many backends.
import os
from autogen import AssistantAgent, UserProxyAgent
llm_config = {
"config_list": [{
"model": "openai/gpt-4o",
"base_url": "https://api.n4n.ai/v1",
"api_key": os.environ["N4N_API_KEY"],
}],
"temperature": 0,
"timeout": 60,
}
Set the key beforehand: export N4N_API_KEY=.... If you use OpenAI directly, change base_url to https://api.openai.com/v1 and model to gpt-4o. The timeout prevents hung requests from blocking the agent loop. You can list multiple entries in config_list for client-side failover, but a gateway that already handles fallback keeps the config flat.
Step 3: Define the AssistantAgent
The AssistantAgent wraps the LLM and system prompt. It does not execute code; it only generates messages and code blocks. Write a system message that forces executable output:
assistant = AssistantAgent(
name="coding_assistant",
llm_config=llm_config,
system_message=(
"You are a senior Python engineer. "
"Respond with short explanations and fenced Python code blocks. "
"Always write code that can run standalone. "
"When producing a file, use relative paths inside the working directory."
),
)
The name coding_assistant appears in chat logs; keep it unique if you later add more agents. A low temperature (set in llm_config) keeps generated code deterministic across runs.
Step 4: Add a code-executing agent
AutoGen’s UserProxyAgent acts as the bridge to the local runtime. Enable code execution via code_execution_config. On a trusted dev box, use_docker=False runs code in the current Python process’s environment. For any untrusted prompt, set use_docker=True.
user_proxy = UserProxyAgent(
name="executor",
code_execution_config={
"use_docker": False,
"work_dir": "coding_output",
"timeout": 30,
},
human_input_mode="NEVER",
)
work_dir is created automatically. timeout kills runaway scripts after 30 seconds. human_input_mode="NEVER" lets the agent run autonomously; set it to "TERMINATE" to require a keypress before each code block executes. Only the proxy holds code_execution_config—the assistant never touches the filesystem directly.
Step 5: Run a multi-turn coding task
Initiate the chat from the proxy. The assistant replies with code, the proxy executes it, and stdout/stderr are fed back as new messages. The call returns a ChatResult when max_round is hit or a termination string is seen.
task = "Plot y=sin(x) for x in [0, 2π] and save as sine.png."
chat_result = user_proxy.initiate_chat(assistant, message=task)
Verify success by checking the artifact:
import os
path = os.path.join("coding_output", "sine.png")
assert os.path.exists(path) and os.path.getsize(path) > 0, "Plot not generated"
print("Verified:", path)
If the assertion passes, your autogen assistantagent code executor tutorial pipeline is working. You should also see the PNG file in coding_output/. The proxy writes each attempted script to that directory, which is handy for post-hoc debugging.
Step 6: Observe the correction loop
Real tasks rarely succeed on the first try. Remove the output directory and send a vague request:
user_proxy.initiate_chat(assistant, message="Show a bar chart of [3,7,2].")
AutoGen prints each code block and its result. A typical failure looks like this in the log:
assistant (coding_assistant): ```python
import matplotlib.pyplot as plt
plt.bar([1,2,3],[3,7,2]); plt.savefig("bar.png")
executor: ModuleNotFoundError: No module named ‘matplotlib’ assistant (coding_assistant): ```python !pip install matplotlib import matplotlib.pyplot as plt plt.bar([1,2,3],[3,7,2]); plt.savefig(“bar.png”)
executor: Code executed successfully.
The assistant sees the ModuleNotFoundError and retries. This self-healing loop is the core value of the autogen assistantagent code executor tutorial approach: the LLM gets execution feedback exactly as a human would.
Step 7: Constrain and secure the executor
For shared deployments, harden the executor:
- Use Docker with a pinned image:
"use_docker": Trueplus"docker_image": "python:3.11-slim". - Set
timeoutto bound resource use. - Mount
work_diras a tmpfs to avoid disk persistence. - Drop network caps at the container level if tasks don’t need egress.
user_proxy = UserProxyAgent(
name="executor",
code_execution_config={
"use_docker": True,
"docker_image": "python:3.11-slim",
"timeout": 30,
"work_dir": "coding_output",
},
human_input_mode="NEVER",
)
Never grant the executor broad filesystem access. The agent pattern is safe only when the runtime sandbox is tight.
Step 8: Track usage and costs
After a chat, chat_result.cost reports the estimated token cost (based on the model’s listed pricing). When you route through a gateway such as n4n.ai, per-token usage metering is forwarded, and client-side cache-control hints are passed to providers, so repeated system prompts hit cache. No agent code changes are needed.
print("Estimated cost (USD):", chat_result.cost)
If cost is None, the configured model lacks pricing metadata. Inspect coding_output/*.py to see each attempted script; this is useful for debugging prompt drift or unexpected imports.
Step 9: Extend to multi-agent workflows
Wrap the two agents in a GroupChat to add a reviewer. Only the executor keeps code_execution_config; others are pure LLM.
from autogen import GroupChat, GroupChatManager
reviewer = AssistantAgent(
name="reviewer",
llm_config=llm_config,
system_message="Check code for correctness and security. Do not write code.",
)
group = GroupChat(agents=[assistant, user_proxy, reviewer], messages=[], max_round=12)
manager = GroupChatManager(group=group, llm_config=llm_config)
assistant.initiate_chat(manager, message="Compute fib(10) and plot growth.")
This modular design keeps the autogen assistantagent code executor tutorial pattern clean: generation, execution, and review are separate concerns. You can swap the assistant model or the executor sandbox without touching the chat topology.
Verifying the full setup
A successful run produces coding_output/sine.png (or bar.png) and prints a cost estimate. If the assertion in Step 5 fails, open coding_output for the last .py file and run it manually with python to see the error. The executor logs every attempt, so you can iterate on the system prompt rather than the agent code.
That is the complete autogen assistantagent code executor tutorial: from install to hardened multi-agent loop.