Build and deploy an agent¶
An agent in Kionga is a deployed record that points at an entry point
(module:function) in a runtime image, with an LLM backend, a list of registered
tools, per-replica resources, replica limits, and canary traffic. This guide
covers registering tools, deploying and chatting with an agent, connecting a real
LLM, monitoring usage, shifting traffic, and building your own agent.
Agents run on LangGraph, Agno, NOOA or your own adapter. LangGraph gets built-in checkpoints and Langfuse callbacks. For the other frameworks, see Run agents built with other frameworks.
To build visually, use the native Agent Designer, which tests, evaluates, publishes and deploys graphs, or a Langflow canvas. Saved Langflow flows can be captured as versioned Kionga snapshots, published as independent agents, and activated on a stable managed endpoint. The Langflow guide covers that workflow.
Before you begin¶
- To deploy, chat with and change agents: the
agentsservice for a normal user, or theengineer,operatororadminrole, and access to the agent's project. Viewers can see agents but cannot chat with or change them. - To register tools: the
catalogservice for a normal user, or theengineer,operatororadminrole. - Capacity: for a normal user, every agent counts against the compute grant at its maximum replicas (see Deploy an agent).
- For the API and SDK examples: export
MLAIOPS_URLand a personal API key with the needed scopes asMLAIOPS_TOKEN. See Authentication.
Register the agent's tools¶
An agent can name only tools that are registered in Kionga; the gateway rejects an agent that references an unregistered tool.
curl -s -X POST "$MLAIOPS_URL/api/v1/tools" \
-H "Authorization: Bearer $MLAIOPS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name": "kb_search", "version": "1.0.0",
"description": "Search the support knowledge base",
"input_schema": {"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"]},
"tags": ["support"]}'
The console lists registered tools under Catalog > Tools, but you register them through the API or the SDK.
Verify: mlaiops tool list includes the tool.
Deploy an agent¶
- Open Agents and click + Deploy agent.
- Optional: under Load a generated contract, paste the
the generated
agent.jsoncontract (in theplatformfolder) from aproduction-agentproject and click Load JSON. - Under Identity, choose the Project and enter the Agent name and Version. Disabled or unassigned projects are not listed.
- Under Runtime and capacity, enter the OCI image, preferably pinned
by digest, and the Graph module (
package.module:attribute). Choose the LLM backend and set the replicas, CPU and memory per replica, and any GPUs. - Under Tools, select registered tools.
- Click Deploy agent.
Example entrypoint fills in the graph module for LangGraph, Agno, NOOA or a custom adapter. It does not install or start a runtime.
curl -s -X POST "$MLAIOPS_URL/api/v1/agents" \
-H "Authorization: Bearer $MLAIOPS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"project_id": "prj-123",
"name": "incident-response",
"version": "1.0.0",
"image": "ghcr.io/acme/incident-response@sha256:<digest>",
"graph_module": "incident_response_agent.graph:build",
"llm_backend": "openai-compatible",
"autoscaling": {"min_replicas": 2, "max_replicas": 6},
"resources": {"cpu": "1", "memory": "2Gi", "gpu": 0},
"tools": ["runbook_search", "create_escalation"]
}'
Field rules:
llm_backendismock(default),openai,anthropic,openai-compatibleorself-hosted.- CPU and memory use Kubernetes quantities. They default to
500mand1Giper replica. - When
gpuis above zero,gpu_typedefaults tonvidia.com/gpu. Another type must be a domain-qualified Kubernetes extended resource, outside the Kubernetes-reserved domains, and not a native resource name such ascpu. max_replicasmust be at leastmin_replicasand at most 100.
For a normal user, Kionga counts every agent the user owns at its maximum replicas, plus the trace sidecar's CPU and memory for each possible pod. The total CPU, memory, GPUs and replica count must fit the user's grant, and a GPU type must match the grant. Administrators and operators skip the capacity check but not the field rules.
The agent becomes ready only when its runtime answers its health check.
Until then it is pending, and Chat stays disabled.
Verify: the agent card under Agents shows ready, and the summary counts
it as a ready runtime.
Chat with an agent¶
On a ready agent's card, click Chat, type a message and click Send. Each turn shows the reply, the token count and the latency.
For each turn, Kionga checks the runtime's health for up to 3 seconds and returns
503 agent_not_ready without sending the turn if it fails. The runtime then loads
the session's checkpoint, so conversation state carries across turns in a
session, runs the graph and its tools, calls the LLM, and reports the session's
turns, tokens and cost.
Verify: the reply appears, and the session shows under Live sessions.
On Compose, all agents share one runtime that serves the demo support agent,
agents.customer_support.graph:build, with the tools feature_store_lookup
and kb_search. Kionga creates no agent record for you; the
quickstart registers one.
On Kubernetes, each agent gets its own Deployment and Service.
Connect a real LLM provider¶
By default, agents use the mock backend, which replies with a [mock] prefix
and needs no key. To use a real provider on Compose:
-
Add the provider to
deploy/.env:# OpenAI, or any OpenAI-compatible server behind LLM_UPSTREAM_URL MLAIOPS_LLM_BACKEND=openai # or openai-compatible MLAIOPS_LLM_MODEL=gpt-4o OPENAI_API_KEY=sk-... # LLM_UPSTREAM_URL=https://api.openai.com # where the trace proxy forwards # or Anthropic # MLAIOPS_LLM_BACKEND=anthropic # MLAIOPS_LLM_MODEL=claude-sonnet-4-5 # ANTHROPIC_API_KEY=sk-ant-... -
Recreate the runtime:
With openai and openai-compatible, every call goes through the trace proxy,
which forwards it to the provider and publishes a trace record (agent, version,
session, status code and duration, not the prompt or response) to the Kafka
topic mlaiops.llm.traces. With anthropic, the runtime calls Anthropic directly, so
the trace proxy does not capture the call; Langfuse tracing and measured token
usage still work. Keys stay in the environment and are never written to traces,
logs or the store.
Verify: a chat reply no longer starts with [mock].
Monitor sessions, traces and cost¶
Open Agents. Live sessions lists each session with its agent, current
node, status, turns, tokens and cost. The Prompt Library panel lists your
Langfuse prompts. For full traces, open the Langfuse UI (on Compose,
http://localhost:3000).
| Route | Returns |
|---|---|
GET /api/v1/agents/{id}/sessions |
Live sessions with turns, node, tokens and cost |
GET /api/v1/agents/{id}/traces |
Trace records |
GET /api/v1/agents/{id}/usage |
Total tokens, cost and active sessions |
Token counts come from the model's usage metadata; Kionga never estimates them.
Cost uses the per-1,000-token rates in MLAIOPS_COST_PER_1K_INPUT and
MLAIOPS_COST_PER_1K_OUTPUT.
Shift canary traffic¶
- On the agent card, click Traffic.
- Set the Canary weight, the percentage of requests routed to the canary version, and click Update traffic.
Or call the API:
curl -s -X PUT "$MLAIOPS_URL/api/v1/agents/<agent-id>/traffic" \
-H "Authorization: Bearer $MLAIOPS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"canary_weight": 10}'
On Kubernetes, the operator turns the weight into a stable and canary traffic plan.
Verify: the agent card shows the new weight, for example 10% canary.
Build your own agent¶
Start from the production-agent template rather than an empty module. The
starter runs before you change it.
-
Create the project and copy its scaffold command:
-
Run the command in Jupyter or the IDE (see Scaffold a project). Add
--agent codex,--agent claudeor--agent customto let a coding agent extend the generated folder. - Write your graph. The entry point must be a
build(model, checkpointer)compatible callable that returns a compiled graph, aStateGraphor a factory. Define tools in code withmlaiops_sdk.register_tooland pass them to LangGraph withlangchain_tools([...]). Register the same tools with Kionga (see Register the agent's tools). - Build and push an image, pinned by digest, and
deploy it. The project's generated
agent.jsoncontract (in itsplatformfolder) fills in the deploy form.
Verify: the deployed agent reaches ready and answers in Chat.
Add memory¶
Short-term checkpoints and long-term memory are separate:
- Checkpoints keep one conversation's state across turns. They use the
PostgreSQL URL in
MLAIOPS_CHECKPOINT_DSN, orDATABASE_URLwhen that is not set. - Long-term memory uses
AgentMemoryClient, withrememberandrecallover a pgvector table in the same PostgreSQL, plusget_entity_featuresfor online features. Its default embedding function is deterministic, so memory tests run offline.
Keep artifacts and large context in object storage, not in prompts or queues.
On Kubernetes¶
Kionga derives one DNS name per agent ID, so different agents can reuse a human
name without overwriting each other. The operator creates the agent's
Deployment and Service, and reports the agent ready when at least
min_replicas pods are available. When max_replicas is above min_replicas,
it also creates a HorizontalPodAutoscaler that targets 70% average CPU, which
needs a working Kubernetes metrics API. On Compose, AGENT_RUNTIME_URL points
every agent at the shared runtime, so autoscaling does not apply.
Release checklist¶
Before you shift traffic to a new agent version:
- Run the deterministic graph and tool tests with the mock model.
- Run the golden evaluation cases and failure-path tests.
- Check tool schemas, timeouts, permissions and safe retries.
- Check that checkpoints and memory are isolated by agent and tenant.
- Inspect Langfuse traces for secrets and unexpected tool payloads.
- Deploy by image digest with a small canary weight.
- Compare quality, latency, tokens, cost and error rate.
- Promote the canary, or return traffic to the stable version.
Next steps¶
- Run agents built with Agno, NOOA or your own framework.
- Use the built-in feature store for agent lookups.
- Process real-time events with an agent.