Building code executing autogen agents n4n.ai turns a multi-agent coding prototype into a production-ready system backed by a single OpenAI-compatible endpoint that fronts 240+ models with automatic fallback. This tutorial walks through a working setup where a UserProxyAgent executes generated Python locally while the AssistantAgent pulls completions from the gateway.
Step 1: Install dependencies and prepare credentials
AutoGen’s pyautogen package ships the agent primitives and the OpenAI-compatible client wrapper. You only need Python 3.9+ and a sandboxed working directory.
pip install pyautogen python-dotenv
mkdir coding_workspace
Export your gateway key and base URL. The inference gateway exposes an OpenAI-compatible chat route at https://api.n4n.ai/v1, so any client that speaks the OpenAI protocol works without modification.
export N4N_API_KEY="sk-..."
export N4N_BASE_URL="https://api.n4n.ai/v1"
Keep the key out of source control. A .env file loaded via python-dotenv is sufficient for local runs; in CI use secret injection.
Step 2: Configure the LLM client for AutoGen
AutoGen expects a config_list of model entries. Each entry maps to one model route on the gateway. Because the endpoint is OpenAI-compatible, set api_type to openai and point base_url at the gateway.
import os
from autogen import AssistantAgent, UserProxyAgent
llm_config = {
"config_list": [
{
"model": "anthropic/claude-3.5-sonnet",
"api_key": os.environ["N4N_API_KEY"],
"base_url": os.environ["N4N_BASE_URL"],
"api_type": "openai",
}
],
"timeout": 60,
"cache_seed": None, # disable prompt caching for deterministic code gen
}
The model field accepts any of the 240+ identifiers the gateway routes. If you omit base_url, AutoGen hits OpenAI directly; the gateway URL is what gives you fallback and unified metering. No price fields are required—the gateway returns usage in the standard usage object.
Step 3: Define the code-executing agent group
A minimal code-executing pair needs an AssistantAgent to generate code and a UserProxyAgent to run it. The proxy’s code_execution_config controls where files land and whether execution is dockerized.
assistant = AssistantAgent(
name="coder",
llm_config=llm_config,
system_message=(
"You are a senior Python engineer. "
"Respond with only the code needed to solve the task, "
"wrapped in a single python block. No prose."
),
)
user_proxy = UserProxyAgent(
name="executor",
code_execution_config={
"work_dir": "coding_workspace",
"use_docker": False, # True recommended for untrusted input
"timeout": 30,
},
human_input_mode="NEVER",
)
human_input_mode="NEVER" lets the agent run autonomously. For interactive debugging, switch to "TERMINATE" so it stops on a sentinel. If use_docker is True, AutoGen pulls a Python image and runs each cell isolated; locally it calls the interpreter directly.
Step 4: Run a coding task end to end
Initiate a chat with a concrete, verifiable request. The assistant returns a code block; the proxy writes it to coding_workspace/xxx.py and executes it, feeding stdout back into the conversation.
task = (
"Compute the first 10 Fibonacci numbers. "
"Save them to fib.json and generate a bar chart named fib.png."
)
user_proxy.initiate_chat(assistant, message=task)
Expected flow:
coderemits apythonfenced block.executorwrites the file, runs it, captures output.- If the script errors, the proxy returns the traceback; the assistant can self-correct on the next turn.
Step 5: Verify successful execution and metering
Verification is threefold:
Filesystem. Check the work directory:
ls coding_workspace
# expect: fib.json, fib.png, and a .py source file
cat coding_workspace/fib.json
# expect: [0,1,1,2,3,5,8,13,21,34] (or similar)
Console. AutoGen prints the execution result inline. A clean run shows exitcode: 0 and no exception. If you see exitcode: 1, the assistant’s code failed and the loop will retry if max turns allow.
Token usage. The gateway returns per-token usage in the OpenAI-compatible usage field. AutoGen aggregates this in assistant.client.total_usage after the chat. You can inspect it:
print(assistant.client.total_usage)
# Example output: CompletionTokens(...) with prompt/completion counts
Because the gateway performs per-token metering, the same numbers appear in your usage dashboard without extra instrumentation.
Step 6: Harden for production
Running generated code locally is fine for trusted tasks; for anything user-facing, enable Docker:
user_proxy = UserProxyAgent(
name="executor",
code_execution_config={
"work_dir": "coding_workspace",
"use_docker": True,
"docker_image": "python:3.11-slim",
},
human_input_mode="NEVER",
)
The gateway’s automatic fallback means a rate limit or degradation on anthropic/claude-3.5-sonnet silently reroutes to an equivalent model that satisfies the same capability profile—your AutoGen loop does not need retry logic for provider errors. If you want to pin a routing directive (e.g., prefer a specific provider region), pass it via the extra_headers field in the config entry; the gateway forwards cache-control hints and honors those headers.
{
"model": "anthropic/claude-3.5-sonnet",
"api_key": os.environ["N4N_API_KEY"],
"base_url": os.environ["N4N_BASE_URL"],
"api_type": "openai",
"extra_headers": {"x-n4n-cache": "max-age=300"},
}
Troubleshooting
Module not found in local execution. The proxy uses your current Python environment. Install required packages (pip install matplotlib) or switch to Docker with a custom image that prebakes dependencies.
Assistant writes prose instead of code. Tighten the system message and set max_consecutive_auto_reply=1 on the proxy to force a single code emission per turn.
Timeout on long computations. Raise timeout in code_execution_config and the timeout in llm_config for slower model responses.
Unexpected cost spikes. Set cache_seed to a fixed integer to enable AutoGen’s prompt caching, and rely on the gateway’s cache-control forwarding to avoid recomputing identical prefixes.
Closing notes
The pattern above is the minimal viable spine for code executing autogen agents: one assistant that writes, one proxy that runs, and a gateway that abstracts model routing. From here you can add a critic agent, swap the executor to a remote sandbox, or chain multiple code steps with inter-agent handoffs. The execution semantics stay the same—only the topology grows.