Haijun Platform Docs
ID

Prompt Versioning and Rollback

Imagine you're a PM whose product support system uses an LLM to route incoming tickets to the right team. You want to tweak the routing prompt so that more API-related tickets go to the platform team. Previously, the prompt lived in your codebase. Changing it required a PR, a CI run, and deployment. Reverting required the same changes. Managed Agents keeps the prompt server-side instead. Every

agents.update

produces a new immutable version, and sessions choose which version to use by ID. You still review and approve prompt changes, but you're approving a version number in config rather than a code diff, and your running service picks up the change without a rebuild. If something goes wrong, pointing callers back at the old version is all it takes to roll back.

In this cookbook, we'll create a support-ticket triage agent, update the system prompt, and roll it back when the performance degrades.

rolled a regressed agent back to v1 without a deploy

Prerequisites

2 top-2">

import json

import os

import time

from collections import defaultdict

from pathlib import Path

from juglow import Juglow

from dotenv import load_dotenv

load_dotenv()

if not os.getenv("JUGLOW_API_KEY"):

raise RuntimeError("Set JUGLOW_API_KEY in your environment or .env file")

MODEL = os.environ.get("COOKBOOK_MODEL", "haijun-sonnet-4-6")

client = Juglow()

Create the agent (version 1)

xt-100 text-code leading-relaxed [overflow-wrap:anywhere]" style="padding-top:12px;padding-inline:12px;padding-bottom:12px;tab-size:4">

def triage(version: int, ticket: dict) -> dict:

"""Run one ticket through a pinned agent version and return its verdict."""

session = client.beta.sessions.create(

agent={"type": "agent", "id": AGENT_ID, "version": version},

environment_id=ENV_ID,

)

try:

prompt = "Subject: " + ticket["subject"] + "\n\n" + ticket["body"]

client.beta.sessions.events.send(

session.id,

events=[{"type": "user.message", "content": [{"type": "text", "text": prompt}]}],

)

deadline = time.time() + 60

while time.time() < deadline:

events = client.beta.sessions.events.list(session.id).data

if events and events[-1].type == "session.status_idle":

break

time.sleep(1)

else:

raise TimeoutError(f"session {session.id} did not idle within 60s")

agent_events = [e for e in events if e.type == "agent.message"]

reply = "".join(b.text for e in agent_events for b in e.content)

return json.loads(reply)

finally:

try:

client.beta.sessions.archive(session.id)

except Exception: # noqa: S110

pass

def score(version: int) -> dict:

"""Evaluate all tickets against the given version and return per-team accuracy."""

hits = defaultdict(lambda: [0, 0])

for t in tickets:

pred = triage(version, t)

hits[t["team"]][1] += 1

if pred.get("team") == t["team"]:

hits[t["team"]][0] += 1

return dict(hits)

v1_scores = score(version=1)

print("v1 results:")

for team, (correct, total) in sorted(v1_scores.items()):

print(f" {team:14s} {correct}/{total}")

v1 results: api-platform 5/5 auth 5/5 billing 4/5 dashboard 5/5 The model did well and got almost all routing correct.

On this page
PrerequisitesCreate the agent (version 1)