n4nAI

Route AutoGen code execution to GPT-5.1 via n4n.ai

Route AutoGen code-executing agents to GPT-5.1 through n4n.ai with automatic fallback and per-token metering.

n4n Team4 min read922 words

Audio narration

Coming soon — every post will get a voice note here.

AutoGen’s code-executing agents become significantly more useful when you can swap the underlying model without rewriting agent logic. This tutorial shows how to route autogen code execution gpt-5.1 n4n.ai calls through a single OpenAI-compatible endpoint that handles fallback, metering, and provider cache hints automatically. You’ll end up with a drop-in replacement for openai.ChatCompletion that your existing AutoGen configuration can use unchanged.

Step 1: Install dependencies

Use Python 3.10 or newer. Create a virtual environment and install the current AutoGen release plus the OpenAI client library.

python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install "pyautogen>=0.2.30" openai python-dotenv

Verify the imports work:

import autogen
from openai import OpenAI
print(autogen.__version__)

You should see a version string like 0.2.30 or newer.

Step 2: Configure the n4n.ai endpoint

n4n.ai exposes an OpenAI-compatible base URL. Set it alongside your API key in a .env file so you never hardcode credentials.

cat > .env <<'EOF'
N4N_API_KEY=sk-your-n4n-key
N4N_BASE_URL=https://api.n4n.ai/v1
EOF

Load these values in your application bootstrap:

import os
from dotenv import load_dotenv

load_dotenv()

N4N_API_KEY = os.getenv("N4N_API_KEY")
N4N_BASE_URL = os.getenv("N4N_BASE_URL")

if not N4N_API_KEY or not N4N_BASE_URL:
    raise RuntimeError("Missing N4N_API_KEY or N4N_BASE_URL in environment")

Step 3: Create a shared OpenAI client pointed at n4n.ai

AutoGen agents accept an llm_config dictionary that ultimately gets passed to the OpenAI client. Construct a single client instance and reuse it across agents to benefit from connection pooling and consistent headers.

from openai import OpenAI

n4n_client = OpenAI(
    api_key=N4N_API_KEY,
    base_url=N4N_BASE_URL,
    default_headers={
        "HTTP-Referer": "https://your-domain.example",  # optional, for provider analytics
        "X-Title": "autogen-code-execution-demo",
    },
)

The default_headers are optional but recommended; some upstream providers use them for routing and abuse prevention.

Step 4: Define the model routing directive

n4n.ai honors a model field that can be a specific provider model slug or a routing directive. For GPT-5.1, use the canonical slug openai/gpt-5.1. You can also request automatic fallback by omitting the provider prefix, but explicit routing makes behavior predictable.

MODEL = "openai/gpt-5.1"

If you want n4n.ai to choose the best available model in the same capability tier, use gpt-5.1 without the provider prefix. The gateway will respect cache-control hints returned by the upstream provider and surface them in the response headers.

Step 5: Build the llm_config for AutoGen

AutoGen expects an llm_config with at least model, api_key, base_url, and optionally client if you want to inject your pre-configured client. Passing the client directly avoids duplicate HTTP connection pools.

llm_config = {
    "model": MODEL,
    "api_key": N4N_API_KEY,
    "base_url": N4N_BASE_URL,
    "client": n4n_client,
    "temperature": 0.2,
    "timeout": 120,
    "cache_seed": 42,  # enables AutoGen's built-in response caching
}

cache_seed activates AutoGen’s in-memory cache keyed by request payload. This is separate from provider-level caching but complements it.

Step 6: Create a code-executing user proxy agent

AutoGen’s UserProxyAgent with code_execution_config runs code in a sandbox. Point it at the same llm_config so the LLM calls that drive code generation also route through n4n.ai.

from autogen import UserProxyAgent

user_proxy = UserProxyAgent(
    name="user_proxy",
    human_input_mode="NEVER",
    max_consecutive_auto_reply=3,
    code_execution_config={
        "work_dir": "coding",
        "use_docker": False,  # set True if you have Docker and want isolation
        "timeout": 60,
    },
    llm_config=llm_config,
)

use_docker=False runs code in a local subprocess. For production workloads, set use_docker=True and provide a Docker image with your required dependencies.

Step 7: Create an assistant agent that writes code

The assistant agent receives the task, asks the LLM for code, and the user proxy executes it. Both agents share the same llm_config so every model call — planning, coding, debugging — goes through the gateway.

from autogen import AssistantAgent

assistant = AssistantAgent(
    name="assistant",
    system_message=(
        "You are a Python developer. Write clean, well-commented code to solve the user's task. "
        "Prefer standard library modules. Return only the code block, no markdown formatting."
    ),
    llm_config=llm_config,
)

Step 8: Register a termination condition

AutoGen conversations need a way to stop. A simple heuristic: terminate when the user proxy sees a result printed to stdout or when the assistant emits a final answer marker.

def is_termination_msg(msg: dict) -> bool:
    content = msg.get("content", "")
    return "TERMINATE" in content or "result:" in content.lower()

user_proxy.register_reply(
    trigger=AssistantAgent,
    reply_func=lambda *args, **kwargs: None,  # no-op, we just want the termination check
    config={"termination_check": is_termination_msg},
)

Step 9: Run a sample task

Kick off a conversation with a task that requires code execution — for example, computing a Fibonacci sequence with memoization and printing the 30th value.

task = (
    "Write a Python function that computes the nth Fibonacci number using memoization. "
    "Print the 30th Fibonacci number and the execution time in milliseconds. "
    "End your response with 'TERMINATE'."
)

chat_result = user_proxy.initiate_chat(assistant, message=task)

Run the script:

python run_autogen.py

Step 10: Verify success

You should see output similar to:

user_proxy (to assistant):
Write a Python function that computes the nth Fibonacci number using memoization. Print the 30th Fibonacci number and the execution time in milliseconds. End your response with 'TERMINATE'.

assistant (to user_proxy):
import time
from functools import lru_cache

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

start = time.perf_counter()
result = fib(30)
elapsed_ms = (time.perf_counter() - start) * 1000
print(f"fib(30) = {result}")
print(f"elapsed = {elapsed_ms:.3f} ms")
TERMINATE

user_proxy (to assistant):
exitcode: 0
stdout:
fib(30) = 832040
elapsed = 0.042 ms
TERMINATE

Key verification points:

  1. Exit code 0 — the sandbox executed without error.
  2. Correct resultfib(30) = 832040 matches the known value.
  3. TERMINATE marker — the conversation ended cleanly.
  4. Latency — the round-trip through n4n.ai to GPT-5.1 and back should be under a few seconds for this prompt size.

Step 11: Inspect gateway metadata (optional)

n4n.ai returns provider metadata in response headers. You can access them via the OpenAI client’s with_raw_response wrapper if you need to log which upstream model actually served the request, cache status, or token counts.

from openai import OpenAI

raw = n4n_client.chat.completions.with_raw_response.create(
    model=MODEL,
    messages=[{"role": "user", "content": "ping"}],
    max_tokens=5,
)

print(raw.headers.get("x-provider"))        # e.g., "openai"
print(raw.headers.get("x-cache-status"))    # e.g., "HIT" or "MISS"
print(raw.headers.get("x-tokens-used"))     # total tokens for the request

This is useful for observability pipelines but not required for basic operation.

Step 12: Enable automatic fallback for resilience

If you want the gateway to fail over to another provider when GPT-5.1 is rate-limited or degraded, remove the provider prefix from the model string and let n4n.ai handle routing.

# Fallback-enabled model string
MODEL_FALLBACK = "gpt-5.1"

llm_config_fallback = {
    **llm_config,
    "model": MODEL_FALLBACK,
}

The gateway will select an available model in the same tier (e.g., Claude 3.5 Sonnet, Gemini 1.5 Pro) and surface the actual provider in x-provider response headers. Your AutoGen agents require no code changes — only the model string differs.

Step 13: Meter per-token usage in your application

n4n.ai meters usage per token and exposes cumulative counters via the admin API. For in-process tracking, accumulate usage fields from each response.

total_prompt_tokens = 0
total_completion_tokens = 0

def track_usage(response):
    global total_prompt_tokens, total_completion_tokens
    usage = response.usage
    if usage:
        total_prompt_tokens += usage.prompt_tokens
        total_completion_tokens += usage.completion_tokens

# Monkey-patch the client create method for automatic tracking
original_create = n4n_client.chat.completions.create

def tracking_create(*args, **kwargs):
    resp = original_create(*args, **kwargs)
    track_usage(resp)
    return resp

n4n_client.chat.completions.create = tracking_create

After a batch of tasks, print the totals:

print(f"Prompt tokens: {total_prompt_tokens}")
print(f"Completion tokens: {total_completion_tokens}")

These numbers match what you’ll see in the n4n.ai dashboard, making cost allocation straightforward.

Step 14: Package as a reusable module

Extract the configuration into a module your team can import. This avoids copy-paste drift across notebooks and services.

# autogen_n4n.py
import os
from dotenv import load_dotenv
from openai import OpenAI
from autogen import UserProxyAgent, AssistantAgent

load_dotenv()

N4N_API_KEY = os.getenv("N4N_API_KEY")
N4N_BASE_URL = os.getenv("N4N_BASE_URL")
MODEL = os.getenv("N4N_MODEL", "openai/gpt-5.1")

if not N4N_API_KEY or not N4N_BASE_URL:
    raise RuntimeError("Set N4N_API_KEY and N4N_BASE_URL in environment")

n4n_client = OpenAI(
    api_key=N4N_API_KEY,
    base_url=N4N_BASE_URL,
    default_headers={"X-Title": "autogen-shared"},
)

llm_config = {
    "model": MODEL,
    "api_key": N4N_API_KEY,
    "base_url": N4N_BASE_URL,
    "client": n4n_client,
    "temperature": 0.2,
    "timeout": 120,
    "cache_seed": 42,
}

def make_agents(work_dir: str = "coding"):
    user_proxy = UserProxyAgent(
        name="user_proxy",
        human_input_mode="NEVER",
        max_consecutive_auto_reply=3,
        code_execution_config={"work_dir": work_dir, "use_docker": False, "timeout": 60},
        llm_config=llm_config,
    )
    assistant = AssistantAgent(
        name="assistant",
        system_message="Write clean Python code. Return only the code block. End with TERMINATE.",
        llm_config=llm_config,
    )
    return user_proxy, assistant

Now any script can do:

from autogen_n4n import make_agents

user_proxy, assistant = make_agents()
user_proxy.initiate_chat(assistant, message="Compute factorial of 20. TERMINATE")

Step 15: Run in a CI/CD pipeline

For automated testing, run the same script in a headless environment. Ensure the sandbox directory is writable and the API key is injected via secrets.

# .github/workflows/autogen-test.yml
name: autogen-code-execution
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: pip install -r requirements.txt
      - env:
          N4N_API_KEY: ${{ secrets.N4N_API_KEY }}
          N4N_BASE_URL: ${{ secrets.N4N_BASE_URL }}
        run: python -m pytest tests/test_autogen.py -v

A minimal test:

# tests/test_autogen.py
from autogen_n4n import make_agents

def test_fibonacci():
    user_proxy, assistant = make_agents(work_dir="/tmp/autogen_test")
    result = user_proxy.initiate_chat(
        assistant,
        message="Print fib(10). TERMINATE",
    )
    assert "55" in result.chat_history[-1]["content"]

Troubleshooting common issues

Symptom Cause Fix
401 Unauthorized Invalid or missing N4N_API_KEY Verify key in dashboard, check .env loading
404 Not Found Wrong N4N_BASE_URL Must be https://api.n4n.ai/v1 (trailing /v1)
503 Service Unavailable Upstream provider down Use fallback model string gpt-5.1 without provider prefix
Code execution timeout timeout too low in code_execution_config Increase to 120s for heavy computations
Docker permission denied use_docker=True without docker group Run usermod -aG docker $USER or use use_docker=False

Next steps

  • Add structured logging around initiate_chat to capture latency percentiles per task type.
  • Integrate the x-cache-status header into your observability stack to measure cache hit rates.
  • Experiment with temperature=0 for deterministic code generation when reproducibility matters.
  • For multi-agent workflows, share a single n4n_client instance across all agents to reuse HTTP/2 connections.

You now have a production-ready path from AutoGen code-executing agents to GPT-5.1 via n4n.ai, with fallback, metering, and caching handled at the gateway layer.

Tagsautogencode-executiongpt-5-1n4n-ai

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All autogen code-executing agents posts →