This autogen n4n.ai getting started tutorial shows how to point Microsoft’s AutoGen framework at a single OpenAI-compatible endpoint that fronts 240+ models, then run a multi-agent conversation without juggling provider SDKs. You’ll configure one client, define two agents, and watch token usage accrue against a unified meter.
Prerequisites
- Python 3.10 or newer. AutoGen’s synchronous
pyautogenpackage relies onasynciointernals that stabilized in 3.10. - A virtual environment (recommended):
python -m venv .venv && source .venv/bin/activate. pip install pyautogen==0.2.32. The 0.2.x line exposesAssistantAgentandUserProxyAgentused below. (The newerautogen-agentchatsplit changes the API; this guide sticks to the battle-tested classic.)- An API key from the gateway, exported as
N4N_API_KEY. The key authenticates against the OpenAI-compatible base URL. - No prior AutoGen experience, but you should know how to read a Python traceback.
Install and configure the client
Install the package and set the environment variable:
pip install pyautogen==0.2.32
export N4N_API_KEY="sk-your-actual-key"
AutoGen expects an OpenAI-style configuration dictionary. The only non-default fields are base_url and api_key. The model field accepts any identifier from the gateway catalog—string formats follow <provider>/<model> or sometimes bare model names.
import os
from autogen import AssistantAgent, UserProxyAgent
config_list = [{
"model": "anthropic/claude-3-haiku",
"base_url": "https://api.n4n.ai/v1",
"api_key": os.environ["N4N_API_KEY"],
"temperature": 0.2,
# price is optional; used only for AutoGen's local cost estimate.
# The gateway performs actual per-token metering independent of this.
"price": [0.00025, 0.0005],
}]
If you omit price, AutoGen skips cost printing but usage tracking still works. The base_url override is the critical line: it redirects the underlying openai SDK from api.openai.com to the gateway, which then routes to the appropriate backend.
Define agents
AutoGen’s agent abstraction is simple. AssistantAgent wraps an LLM call; UserProxyAgent simulates the human (or executes code). For a safe first run, disable code execution and auto-forward human input.
assistant = AssistantAgent(
name="planner",
llm_config={"config_list": config_list},
system_message="You are a concise planning agent. Reply with bullet points only.",
)
user_proxy = UserProxyAgent(
name="user",
human_input_mode="NEVER",
max_consecutive_auto_reply=2,
code_execution_config=False,
)
max_consecutive_auto_reply caps the conversation depth so a misbehaving agent can’t loop forever. code_execution_config=False prevents the proxy from running generated Python locally—important when you don’t control the prompt source.
Run your first multi-agent task
Kick off the chat from the proxy:
chat_result = user_proxy.initiate_chat(
assistant,
message="List three ways to reduce cold start latency in serverless functions.",
)
AutoGen prints each turn to stdout by default. The chat_result object exposes summary, chat_history, and cost.
Expected output
You’ll see a formatted transcript:
user (to planner):
List three ways to reduce cold start latency in serverless functions.
--------------------------------------------------------------------------------
planner (to user):
- Use provisioned concurrency or warm pools to keep instances ready.
- Minimize deployment package size and trim unused dependencies.
- Choose a lightweight runtime (e.g., Node.js or Python with lazy imports).
--------------------------------------------------------------------------------
The exact wording varies by model. If you see a RateLimitError immediately, verify the key and that the model ID exists in the catalog.
Using model routing and fallback
The gateway honors client routing directives and forwards provider cache-control hints. In the autogen n4n.ai getting started setup, you get automatic fallback when a provider is rate-limited or degraded, so a single model ID is enough for most workloads. You don’t need to write retry logic that swaps openai for anthropic—the gateway returns a successful completion from a healthy provider.
If you need to pin a provider or set cache behavior, pass headers through the underlying OpenAI client. AutoGen accepts a prebuilt client in llm_config via the client key (version-dependent), or you can rely on the gateway’s default routing. Example of a custom client with a routing hint:
from openai import OpenAI
client = OpenAI(
base_url="https://api.n4n.ai/v1",
api_key=os.environ["N4N_API_KEY"],
# default_headers={"x-routing": "provider=openai"} # gateway-specific directive
)
# llm_config={"config_list": config_list, "client": client}
Because the gateway meters per-token usage across all backends, the usage object returned by any call matches what you’ll be billed, regardless of which provider actually served the token.
Tracking token usage
AutoGen attaches an usage dict to each message when the LLM responds. After the chat, inspect it:
last_msg = assistant.last_message()
print(last_msg.get("usage"))
Output matches the OpenAI shape:
{
"prompt_tokens": 42,
"completion_tokens": 38,
"total_tokens": 80
}
To aggregate across a multi-agent session, walk the chat history:
total = 0
for msg in chat_result.chat_history:
if "usage" in msg:
total += msg["usage"]["total_tokens"]
print(f"Session total tokens: {total}")
The gateway’s per-token metering means this client-side sum should equal the metered total on your invoice, even if some turns were served by different providers due to fallback.
A two-agent critique loop
Replace the user proxy with a second assistant to build a reviewer pattern without human involvement:
reviewer = AssistantAgent(
name="reviewer",
llm_config={"config_list": config_list, "temperature": 0.0},
system_message="Critique the plan for feasibility. One tight paragraph.",
)
chat_result = reviewer.initiate_chat(
assistant,
message="Propose a plan for caching LLM responses at the edge.",
)
AutoGen alternates messages between the two agents until max_consecutive_auto_reply on the initiating agent stops the loop. For three or more agents, use GroupChat and GroupChatManager; the same config_list works unchanged.
Expected output snippet
reviewer (to planner):
Your edge cache plan ignores invalidation on model weight updates. Add a versioned key derived from the model ID and a short TTL.
--------------------------------------------------------------------------------
planner (to reviewer):
Revised: cache key includes model ID + prompt hash; TTL 60s; purge on deploy webhook.
Error handling and backoff
The gateway’s fallback reduces rate-limit errors but doesn’t eliminate them under sustained load. Wrap initiation in a backoff loop:
import time
from openai import RateLimitError
for attempt in range(3):
try:
user_proxy.initiate_chat(
assistant,
message="Summarize quantum computing in two sentences.",
)
break
except RateLimitError:
time.sleep(2 ** attempt)
Also set a request timeout on the client if you build one manually: OpenAI(timeout=30). AutoGen’s default timeout is 60s, often too long for interactive apps.
Production considerations
- Model selection: Swap
"model"inconfig_listto any of the 240+ IDs without code changes. Keep a small allowlist to avoid typos. - Cache control: When the backing provider supports prompt caching, the gateway forwards cache-control hints. You can embed them in the system message payload if using the raw client; AutoGen’s string messages don’t expose the field directly, so use
client.chat.completions.createfor fine-grained caching. - Logging: Enable
autogen.runtime_logging.set_logger_level("INFO")to capture LLM calls. Ship usage totals to your metrics pipeline. - Concurrency: AutoGen agents are not thread-safe. Use one agent instance per conversation or serialize access.
Complete script
import os
from autogen import AssistantAgent, UserProxyAgent
config_list = [{
"model": "anthropic/claude-3-haiku",
"base_url": "https://api.n4n.ai/v1",
"api_key": os.environ["N4N_API_KEY"],
"temperature": 0.2,
}]
assistant = AssistantAgent(
name="planner",
llm_config={"config_list": config_list},
system_message="You are a concise planning agent. Bullet points only.",
)
user_proxy = UserProxyAgent(
name="user",
human_input_mode="NEVER",
max_consecutive_auto_reply=2,
code_execution_config=False,
)
user_proxy.initiate_chat(
assistant,
message="List three ways to reduce cold start latency in serverless functions.",
)
Run it: python main.py. You have a working AutoGen loop against a unified endpoint. Change the model field, watch the token meter, and scale to group chats when needed.