Ir al contenido principal
Your AI Prompts Aren't Config. They're Production Code.

Your AI Prompts Aren't Config. They're Production Code.

AI Integration
5 min readPor Daily Miranda Pardo

Monday afternoon you change three words in the system prompt. "You are a billing assistant" becomes "You are an expert billing assistant." Sounds better. You test ten cases in staging — all pass. You deploy.

Thursday, the accounting team reports 47 invoices misclassified. You check the logs: no exceptions. The code is identical. Only three words changed.

This scenario plays out in 100% of teams that treat their prompts as configuration rather than code.

Why a System Prompt Is Production Code

Deterministic code has a clear contract: same input, same output. If you change parseDate(), tests fail or pass. You see it immediately.

A system prompt is not deterministic. It's an instruction the model interprets, and that interpretation shifts depending on context, the input document, and the exact model version. When you modify a prompt, you're not editing business logic. You're changing the statistical behavior of a system that decides what to do.

Three words of difference can mean the model, faced with an ambiguous document, makes different decisions. Not on the main case you always test — on the 5% of edge cases your clients encounter every week.

Teams that understand this manage their prompts with the same rigor as code: semantic versioning, controlled deployment, automatic rollback, audit log. Teams that don't do reactive hotfixes every time something breaks in production.

The Four Most Common Prompt Management Mistakes

1. The prompt lives in an environment variable or .env file

A .env has no history. You don't know who changed what or when. If something breaks in production, you can't correlate it to a specific prompt change. Prompts need to live in a system with explicit versioning.

2. The production prompt is changed directly

No staging for the prompt. No canary. No prior evals. The change goes live to 100% of traffic immediately. The first signal is a client complaint.

3. No audit log of changes

Who approved the current version? When was it deployed? How does it differ from the previous one? Without this log, debugging a production incident takes hours instead of minutes.

4. Versions aren't semantic

prompt_v2_final_DEFINITIVE is not versioning. v1.3.2 is: major for breaking behavior changes, minor for compatible improvements, patch for minor fixes.

Implementation: a Prompt Registry in TypeScript + Supabase

The most practical solution for mid-sized teams: a Supabase table that acts as a central prompt registry.

-- migration: create prompt_registry table
create table prompt_registry (
  id          uuid primary key default gen_random_uuid(),
  agent_id    text not null,       -- "invoice-extractor", "support-bot"
  version     text not null,       -- semver: "1.3.2"
  content     text not null,       -- the full system prompt
  traffic_pct integer default 100, -- % of traffic receiving this version
  is_active   boolean default false,
  deployed_by text,
  deployed_at timestamptz default now(),
  eval_score  numeric,             -- latest eval score (0–1)
  notes       text
);

create index idx_prompt_registry_active
  on prompt_registry(agent_id, is_active, traffic_pct);

The TypeScript client that loads the correct prompt:

import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_KEY!
);

export async function getActivePrompt(agentId: string): Promise<string> {
  const { data, error } = await supabase
    .from("prompt_registry")
    .select("version, content, traffic_pct")
    .eq("agent_id", agentId)
    .eq("is_active", true)
    .order("traffic_pct", { ascending: false });

  if (error || !data?.length) {
    throw new Error(`No active prompt found for agent: ${agentId}`);
  }

  // Two active versions = canary in flight, distribute traffic
  if (data.length === 2) {
    const rand = Math.random() * 100;
    return rand < data[1].traffic_pct
      ? data[1].content  // canary version
      : data[0].content; // stable version
  }

  return data[0].content;
}

This pattern allows two versions to be live simultaneously — stable at 90% traffic, canary at 10% — without any change to the agent's calling code.

Canary Deployment for Prompts

The controlled flow for a prompt change:

1. Create new version in registry (is_active: false)
2. Run evals against golden dataset → score ≥ 0.90
3. Activate with traffic_pct: 10 (canary)
4. Monitor 24h: eval_score, error_rate, latency
5. Score holds → scale to 50% → 100%
6. Score drops → automatic rollback (is_active: false)

The automatic rollback script, integrated in your monitoring job:

import Anthropic from "@anthropic-ai/sdk";

const anthropic = new Anthropic();

async function monitorCanary(agentId: string) {
  const score = await runEvalSuite(agentId, "canary");

  if (score < 0.90) {
    await supabase
      .from("prompt_registry")
      .update({ is_active: false })
      .eq("agent_id", agentId)
      .lt("traffic_pct", 100);

    console.error(
      `[ROLLBACK] ${agentId} canary score ${score} < 0.90 — reverted to stable`
    );
  }
}

This is exactly the kind of infrastructure we set up from day one in DAILYMP's AI agent projects — not as a patch after the first incident.

How This Connects to Your Evals

A prompt registry without evals is a versioning system with no quality criterion: you know what changed but not whether the change was good. If you don't yet have a golden dataset to evaluate your agents in production, start there.

The complete chain looks like:

evals define the quality threshold
→ prompt registry manages versions
→ canary controls exposure
→ automatic rollback if score drops
→ audit log explains what happened

Any missing link makes the system brittle. Many teams have agents running but none of these five in place.

What Separates a Prototype from a Maintainable System

An agent without prompt management is a system that works as long as nobody touches it. Every prompt change is a risk event with no safety net.

With a simple registry, explicit semver, and a 10% canary, every prompt change goes through the same rigor as a code deploy. Rollback takes seconds, not hours. The audit log answers "who changed this and when?" in a single SQL query.

The cost of building this infrastructure on a new project is measured in hours. The cost of adding it after the first serious incident is measured in days of reactive work — plus client trust.

If you have agents in production with uncontrolled prompt changes, we can audit the current state and build the right infrastructure:

Let's talk about your production agent →

Compartir artículo

LinkedInXWhatsApp

¿Procesos repetitivos en tu empresa?

Descarga gratis el Mapa de Automatización IA — los 5 procesos que más tiempo roban y cómo resolverlos.

Sin spam. Solo el PDF. Puedes darte de baja cuando quieras.

Escrito por Daily Miranda Pardo

Ayudo a empresas a automatizar procesos, crear agentes IA y conectar sistemas inteligentes.