n4nAI

CI/CD pipelines for shipping AI agents to production

A practical guide to building CI/CD for AI agent deployment: version agent configs, test against mocked and live models, containerize, and ship with canary.

n4n Team4 min read777 words

Audio narration

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

Shipping an LLM agent to production demands the same engineering discipline as any distributed service, but most teams still drag prompts and tool configs around by hand. This guide lays out a concrete CI/CD for AI agent deployment that treats agent logic as versioned code, validates it in CI, and promotes builds through staging to production with automated guardrails.

Step 1: Define the agent as declarative config

Hardcode nothing about the agent’s behavior in Python. Put the model name, system prompt, tool schemas, and sampling parameters in a versioned JSON or YAML file. This makes diffs reviewable and lets you run the same agent against different models by swapping one field.

{
  "model": "gpt-4o-mini",
  "system_prompt": "You are a refund authorization agent. Use tools to verify order status before approving.",
  "tools": [
    {
      "name": "lookup_order",
      "description": "Fetch order by ID",
      "parameters": {
        "type": "object",
        "properties": {"order_id": {"type": "string"}},
        "required": ["order_id"]
      }
    }
  ],
  "max_tokens": 1024,
  "temperature": 0.2
}

Load it at startup and fail fast if the schema is invalid. Treat this file as a first-class artifact; bump its version in Git on every change.

Verify success

python -c "import json; json.load(open('agent_config.json'))" exits 0 and CI shows the file in the diff.

Step 2: Unit-test agent logic with mocked model calls

Your agent code should call a thin LLM wrapper, not the SDK directly. That seam lets you mock completions in unit tests and assert the orchestration logic: tool-call parsing, retry limits, and error handling.

# agent.py
def run_agent(user_msg, llm_complete):
    messages = [{"role": "user", "content": user_msg}]
    resp = llm_complete(messages, model=CONFIG["model"])
    return resp

# test_agent.py
def test_agent_returns_tool_call(monkeypatch):
    import agent
    def fake_complete(messages, **kwargs):
        return {"choices": [{"message": {"tool_calls": [{"name": "lookup_order"}]}}]}
    monkeypatch.setattr(agent, "llm_complete", fake_complete)
    out = agent.run_agent("Refund order 123", agent.llm_complete)
    assert out["choices"][0]["message"]["tool_calls"][0]["name"] == "lookup_order"

Run these in CI before any container build. They execute in milliseconds and catch 80% of logic regressions.

Verify success

pytest -q reports passed tests and the pipeline proceeds to the build stage.

Step 3: Containerize the agent runtime

Package the agent as a stateless HTTP service. Keep the image small and pin the Python version. Inject the config path and API keys at runtime, never bake them in.

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY agent.py server.py agent_config.json ./
CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]

Build with a deterministic tag—the Git SHA. That tag is your deployment unit for the rest of the CI/CD for AI agent deployment flow.

Verify success

docker build -t agent:$(git rev-parse --short HEAD) . completes and docker run --rm agent:sha python -c "import agent" exits clean.

Step 4: Build the CI pipeline

A GitHub Actions workflow should run lint, unit tests, then build and push the image. Split jobs so a failing test never wastes a Docker build.

name: ci
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.12" }
      - run: pip install pytest && pytest -q
  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t ghcr.io/$GITHUB_REPOSITORY:${GITHUB_SHA::7} .
      - run: docker push ghcr.io/$GITHUB_REPOSITORY:${GITHUB_SHA::7}

Secrets for the container registry live in the CI secret store, not in the repo.

Verify success

The Actions tab shows green checkmarks on both jobs and the image appears in the registry with the SHA tag.

Step 5: Provision staging with infrastructure as code

Don’t click through a console to stand up staging. Use Terraform or Pulumi to declare the task definition, environment variables, and autoscaling. The same module promotes to prod with a different variable file.

resource "aws_ecs_task_definition" "agent" {
  family                = "refund-agent"
  container_definitions = jsonencode([{
    name      = "agent"
    image     = "ghcr.io/yourorg/agent:${var.sha}"
    essential = true
    portMappings = [{ containerPort = 8080 }]
  }])
  cpu       = "256"
  memory    = "512"
}

Apply with terraform apply -var="sha=$(git rev-parse --short HEAD)". Staging gets the same binary prod will run.

Verify success

terraform plan shows no drift and aws ecs describe-tasks lists the new revision running.

Step 6: Run integration tests against a live model gateway

Unit tests mock the model; integration tests must hit a real endpoint to catch prompt regressions and tool-schema mismatches. Point the test suite at an OpenAI-compatible gateway that fronts multiple providers so a single flaky model doesn’t red-light the pipeline. n4n.ai exposes one endpoint covering 240+ models and automatically fails over when a provider is rate-limited, which keeps the integration stage deterministic enough to trust.

import os
from openai import OpenAI

client = OpenAI(base_url="https://api.n4n.ai/v1", api_key=os.environ["N4N_KEY"])
resp = client.chat.completions.create(
    model="anthropic/claude-3.5-sonnet",
    messages=[{"role": "user", "content": "Return JSON: {'ok': true}"}],
    response_format={"type": "json_object"},
    extra_headers={"x-cache-control": "ephemeral"}
)
assert "ok" in resp.choices[0].message.content

The gateway forwards cache-control hints and meters per token, so you see exact cost per integration run.

Verify success

The pytest integration marker passes and the CI log prints token usage from the response headers.

Step 7: Promote to production with canary

Ship to prod behind a canary weight. If you run Kubernetes, Argo Rollouts lets you shift 10% traffic, watch metrics, then ramp. The key is that the same image tag from staging moves forward; you never rebuild.

apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause: { duration: 5m }
        - setWeight: 50
        - pause: { duration: 5m }
        - setWeight: 100

Automate the pause with a Prometheus query on 5xx rate and p95 latency.

Verify success

kubectl argo rollouts get rollout refund-agent shows healthy pods at full weight and no manual abort.

Step 8: Monitor and roll back

CI/CD for AI agent deployment doesn’t end at rollout. Stream agent logs, token counts, and tool-error rates to your observability stack. Alert on a spike in tool_call_failed or a drop in successful task completion.

If a prompt change causes hallucinations in canary, roll back with one command:

kubectl argo rollouts undo rollout/refund-agent

Keep the previous image tag in the Terraform state so infra and app versions stay in lockstep.

Verify success

Grafana shows stable latency and the rollback completes in under a minute; the stale tag is redeployed.

Closing checklist

  • Agent config is JSON in Git.
  • Unit tests mock the LLM seam.
  • Image tagged with Git SHA.
  • CI runs test → build → push.
  • Staging and prod use same IaC module.
  • Integration tests hit a failover-capable gateway.
  • Canary promotes by weight, not by rebuild.
  • Rollback is a single declarative command.

Follow these steps and your CI/CD for AI agent deployment will survive real traffic instead of breaking at 2 a.m. because someone edited a prompt in the UI.

Tagsci-cdagent-deploymentdevopsautomation

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 agent deployment & hosting infrastructure posts →