AgentArenaClickHouse Workshops

04 Release to production

Instructor notes for module 04 — timing, talk track, common failures, and reset steps.

Facilitator companion to the learner lesson 04 Release to production.

Timing

~15 minutes total.

  • 3 min — start the serving API (uvicorn serving.api:app --port 8100).
  • 2 min — a raw curl against /ask.
  • 4 min — start the web Chat tab and ask a question through the UI, click 👍/👎.
  • 6 min — tour LangFuse: Traces filtered by tag serving, Sessions, cost/latency, the user_feedback score.

Talk track

  • Open by naming the reuse, again: the serving API runs the exact same agents/ core and agents/sqlguard.py read-only sandbox as the benchmark harness. What Modules 01–02 measured is what's about to run live — there is no separate "eval harness" that quietly diverges from what ships.
  • Frame the shift in question this module represents: from "which config is best?" (a Module 01 question, answered once) to "is it still working, and for whom?" (an ongoing question this module hands off to).
  • The load-bearing sentence for this whole module: it's the same LangFuse project. Not a new observability stack — the Traces and Sessions views you're about to open are the same project connected in Module 00 and used to run the Arena in Module 01. Dev and production are two points in one continuous loop, not two different tools.
  • When you curl /ask, point out the response shape live: SQL, result rows, cost_usd, latency_ms, outcome, and a trace_id — say that trace_id is exactly what an annotation-queue reviewer would open in Module 03's loop.
  • In the Chat tab, click a 👍 and a 👎 live and then find both as user_feedback scores on their traces in LangFuse — this is the moment the audience sees the improvement loop's input actually being produced, not just described.
  • Close on the "what to watch for" list from the learner module — negative feedback clusters, cost/latency drift, error outcomes — and tie each one explicitly back to Module 03 (triage into the annotation queue) or Module 01 (re-run the Arena if pricing or the model roster changed).

Common failures

  • Placeholder OPENROUTER_API_KEY/ask calls fail with a 401 from OpenRouter, surfaced as a 500-ish outcome in the response rather than a clean error; this should have been caught in Module 00, but if it wasn't, this is where it becomes visible to end users.
  • Serving API not running / wrong port — the web Chat tab talks to VITE_SERVING_BASE (defaults to http://localhost:8100); if uvicorn serving.api:app isn't up, or is up on a different port than the UI expects, the Chat tab shows a network/fetch error, not a helpful message. Confirm the port matches on both sides.
  • CORSserving/api.py allows all origins by default, so CORS itself is unlikely to be the blocker; if the Chat tab still errors, look first at whether the serving process is actually running before chasing CORS.
  • Stale/invalid config_id/ask needs a config_id that matches <model>__<prompt> from Module 01's winner (e.g. claude-sonnet-5__P1_zeroshot); a typo'd or outdated config_id (from a different demo run) fails immediately.
  • ClickHouse not seeded/ask queries the v_* views through the read-only arena_ro user; if Module 00 didn't finish, questions return empty results or errors instead of real answers.
  • No LangFuse trace showing up — confirm .env's LANGFUSE_* vars are sourced in the same shell that started uvicorn; a missing key doesn't crash the server, it just silently drops tracing.

Reset steps

  • If ClickHouse or the local dashboard needs a clean base first: scripts/arena.sh up.
  • Restart the serving API: source .env && uvicorn serving.api:app --port 8100 (kill any prior instance on that port first if it's wedged).
  • Restart the web Chat tab: cd web && VITE_SERVING_BASE=http://localhost:8100 npm run dev.
  • Re-verify with a fresh curl: curl -s localhost:8100/ask -H 'content-type: application/json' -d '{"question":"How many customers are there?","config_id":"claude-sonnet-5__P1_zeroshot"}' — swap in whatever config_id Module 01 actually crowned for this room.
  • If the demo needs fresh Leaderboard/trace data to point at during the LangFuse tour, re-run a cheap subset first: python -m eval.harness --run-id demo2 --models qwen3.7-flash,gpt-5.6-luna --prompts P1_zeroshot,P3_dialect.

On this page