Tutorial: Canary a new agent version
This tutorial walks the full lifecycle of shipping a new agent version behind an alias: put a stable handle in front of your current agent, clone it, send a small slice of real traffic to the copy, widen the rollout, promote the winner, and retire the old version. Callers change nothing along the way.
By the end you will have run a canary rollout end to end and be able to repeat it for any agent.
For the routing model, see Agent aliases. For the patterns behind each step, see Alias workflows and best practices.
Before you begin
You need:
- A Vectara account. Sign up free for a 30-day trial.
VECTARA_API_KEYset as an environment variable.- The
agent_developeroragent_administratorrole, or an account role ofadministratororowner. - An existing agent to roll out. This tutorial uses
support-v1. Substitute your own key.
Step 1: Put an alias in front of your agent
Create an alias whose policy sends every session to support-v1. This is a
single catch-all rule, so behavior is identical to calling the agent directly,
but callers now have a stable name to address.
curl -X POST https://api.vectara.io/v2/agent_aliases \
-H "x-api-key: $VECTARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"key": "support",
"name": "Customer Support",
"description": "Stable handle for the support agent",
"policy": {
"type": "routed",
"rules": [
{ "targets": { "type": "single", "agent_key": "support-v1" } }
]
}
}'
Point your application at support instead of support-v1. This is the only
integration change you make in the whole tutorial.
Step 2: Confirm the alias resolves
Create a session through the alias and check which agent owns it.
curl -X POST https://api.vectara.io/v2/agent_aliases/support/sessions \
-H "x-api-key: $VECTARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Smoke test", "metadata": { "account_id": "acme" } }'
The response carries the resolved agent_key and the alias_key it came through:
{
"key": "ase_smoke_test_1c2e",
"agent_key": "support-v1",
"alias_key": "support",
"metadata": { "account_id": "acme" },
"enabled": true,
"created_at": "2026-06-02T10:35:44.637Z"
}
Step 3: Clone the agent and improve the copy
Create a second agent, support-v2, from a copy of support-v1. There is no
one-click clone: read the current definition with GET /v2/agents/support-v1,
then recreate it under the new key with POST /v2/agents, changing what you want
to test — the system prompt, the model, or the tools. Nothing routes to it yet,
so experiment freely. Verify it directly before exposing it:
curl -X POST https://api.vectara.io/v2/agents/support-v2/sessions \
-H "x-api-key: $VECTARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Direct check of v2" }'
Step 4: Send a canary slice to v2
Replace the alias policy with a weighted split that sends about 10 percent of
traffic to support-v2. Partition by account_id so each account stays on one
version while you evaluate, rather than flipping between versions per session.
curl -X PUT https://api.vectara.io/v2/agent_aliases/support/policy \
-H "x-api-key: $VECTARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"policy": {
"type": "routed",
"rules": [
{
"targets": {
"type": "weighted",
"partition_by": "get('"'"'$.session.metadata.account_id'"'"', '"'"''"'"')",
"options": [
{ "agent_key": "support-v1", "weight": 90 },
{ "agent_key": "support-v2", "weight": 10 }
]
}
}
]
}
}'
Callers still call POST /v2/agent_aliases/support/sessions exactly as before.
Step 5: Observe the split
Create sessions with different account_id values and watch which agent each
resolves to. Because the split is a deterministic hash of account_id, a given
account always lands on the same version.
for acct in acme globex initech umbrella soylent; do
curl -s -X POST https://api.vectara.io/v2/agent_aliases/support/sessions \
-H "x-api-key: $VECTARA_API_KEY" \
-H "Content-Type: application/json" \
-d "{ \"name\": \"probe\", \"metadata\": { \"account_id\": \"$acct\" } }" \
| grep -o '"agent_key": *"[^"]*"'
done
Most accounts resolve to support-v1, a minority to support-v2, and re-running
the loop returns the same assignment each time. Watch the support-v2 cohort in
your agent traces to judge the new version.
Step 6: Widen the rollout
When the canary looks healthy, replace the policy again with larger weights. Repeat as your confidence grows.
# 50/50
curl -X PUT https://api.vectara.io/v2/agent_aliases/support/policy \
-H "x-api-key: $VECTARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"policy": {
"type": "routed",
"rules": [
{
"targets": {
"type": "weighted",
"partition_by": "get('"'"'$.session.metadata.account_id'"'"', '"'"''"'"')",
"options": [
{ "agent_key": "support-v1", "weight": 50 },
{ "agent_key": "support-v2", "weight": 50 }
]
}
}
]
}
}'
Each change is atomic and affects only new sessions. If anything looks wrong,
roll back by replacing the policy with a single target on support-v1. Rollback
is instant and callers never notice.
Step 7: Promote v2
Once support-v2 should carry everything, replace the policy with a single
target. This removes the split and makes the intent explicit.
curl -X PUT https://api.vectara.io/v2/agent_aliases/support/policy \
-H "x-api-key: $VECTARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"policy": {
"type": "routed",
"rules": [
{ "targets": { "type": "single", "agent_key": "support-v2" } }
]
}
}'
Step 8: Retire v1
Before deleting support-v1, confirm no alias still routes to it.
curl "https://api.vectara.io/v2/agent_aliases?aliased_agent_key=support-v1" \
-H "x-api-key: $VECTARA_API_KEY"
If the list is empty, nothing depends on support-v1 and you can delete it. If
it is not, update those aliases first. An agent that is still referenced by an
alias cannot be deleted until the reference is removed.
What you built
- A stable
supportalias your callers address instead of a specific agent. - A canary rollout that moved traffic from
support-v1tosupport-v2in controlled steps, with each account held on one version. - A promotion and a clean retirement, all as policy changes, with no change to callers at any point.
Repeat this loop every time you improve the agent. The alias is the constant. The agents behind it are free to change.