0Pricing
AI Prompt Engineering · Lezione

Architettura di un prompt registry

Memorizzazione dei prompt come artifact versionati con metadati e tag

Architettura di un prompt registry è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Prompt Engineering, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Prompt Engineering include 4 lezioni in totale.

Perché un registro dei prompt?

Senza un registro, i prompt sono sparsi nel codice, nei file di configurazione e nella memoria degli sviluppatori. Un registro dei prompt è un archivio centralizzato che tratta ogni prompt come un artefatto versionato e tracciabile, proprio come il codice software.

I vantaggi includono riproducibilità, auditabilità, possibilità di rollback e collaborazione tra team.

Campi fondamentali di un artefatto prompt

Ogni artefatto prompt dovrebbe contenere questi campi:

  • prompt_id — identificatore univoco e stabile (ad esempio summarize-article)
  • version — stringa di versione semantica (ad esempio 2.1.0)
  • template — il testo effettivo del prompt con segnaposto {variable}
  • metadata — autore, tag, modello target, created_at, descrizione

Progettazione dello schema del database

Uno schema relazionale per un registro dei prompt memorizza i prompt e la relativa cronologia delle versioni in tabelle separate, consentendo ricerche e audit efficienti.

-- prompts table: one row per unique prompt identity
CREATE TABLE prompts (
  prompt_id   VARCHAR(100) PRIMARY KEY,
  description TEXT,
  created_at  TIMESTAMP DEFAULT NOW()
);

-- prompt_versions table: one row per versioned artifact
CREATE TABLE prompt_versions (
  id          SERIAL PRIMARY KEY,
  prompt_id   VARCHAR(100) REFERENCES prompts(prompt_id),
  version     VARCHAR(20)  NOT NULL,
  template    TEXT         NOT NULL,
  author      VARCHAR(100),
  tags        TEXT[],
  model       VARCHAR(50),
  is_active   BOOLEAN DEFAULT FALSE,
  created_at  TIMESTAMP DEFAULT NOW(),
  UNIQUE(prompt_id, version)
);

Progettazione di un registro basato su file

Per i team più piccoli, un registro basato su file utilizza una struttura di directory organizzata. Ogni prompt ha una propria cartella; ogni versione è un file YAML o JSON al suo interno.

# Directory structure
prompts/
  summarize-article/
    1.0.0.yaml
    1.1.0.yaml
    latest -> 1.1.0.yaml  # symlink
  classify-sentiment/
    1.0.0.yaml

# Example: summarize-article/1.1.0.yaml
prompt_id: summarize-article
version: '1.1.0'
model: gpt-4o-mini
author: alice@company.com
tags: [summarization, articles, english]
created_at: '2024-06-01T10:00:00Z'
template: |
  Summarize the following article in {num_sentences} sentences.
  Focus on: {focus_area}.

  Article:
  {article_text}

Classe Python PromptRegistry

Una semplice classe Python incapsula l'accesso al database ed espone metodi chiari: register(), get_active() e list_versions().

import psycopg2
import json
from datetime import datetime

class PromptRegistry:
    def __init__(self, dsn):
        self.conn = psycopg2.connect(dsn)

    def register(self, prompt_id, version, template, author, tags, model):
        with self.conn.cursor() as cur:
            # Ensure prompt identity exists
            cur.execute(
                'INSERT INTO prompts (prompt_id) VALUES (%s) ON CONFLICT DO NOTHING',
                (prompt_id,)
            )
            cur.execute(
                '''INSERT INTO prompt_versions
                   (prompt_id, version, template, author, tags, model)
                   VALUES (%s, %s, %s, %s, %s, %s)''',
                (prompt_id, version, template, author, tags, model)
            )
        self.conn.commit()
        print(f'Registered {prompt_id}@{version}')

    def get_active(self, prompt_id):
        with self.conn.cursor() as cur:
            cur.execute(
                'SELECT template, version FROM prompt_versions '
                'WHERE prompt_id=%s AND is_active=TRUE LIMIT 1',
                (prompt_id,)
            )
            row = cur.fetchone()
        if not row:
            raise ValueError(f'No active version for {prompt_id}')
        return {'template': row[0], 'version': row[1]}

Analisi approfondita dello schema dei metadati

Metadati dettagliati rendono il registro utile non solo per la semplice memorizzazione. Campi chiave dei metadati:

  • author — responsabilità e punto di contatto
  • tags — etichette ricercabili come ['production', 'summarization', 'v2']
  • model — modello target (il prompt potrebbe non essere indipendente dal modello)
  • changelog — descrizione leggibile delle modifiche apportate
  • test_suite — collegamento al dataset di valutazione per questo prompt
# Extended metadata example
prompt_metadata = {
    'prompt_id': 'extract-key-dates',
    'version': '2.0.0',
    'author': 'bob@company.com',
    'tags': ['extraction', 'dates', 'contracts', 'production'],
    'model': 'gpt-4o',
    'changelog': 'Added support for relative dates (next quarter, end of year)',
    'test_suite': 's3://company-evals/extract-key-dates/v2-testset.jsonl',
    'created_at': '2024-07-15T09:30:00Z',
    'is_active': True
}

Rendering dei template con variabili

I template dei prompt utilizzano una sintassi con segnaposto. Il registro genera il prompt finale sostituendo nel template le variabili disponibili a runtime. L'utilizzo di str.format_map() di Python è sicuro e semplice.

class PromptRegistry:
    # ... (previous methods)

    def render(self, prompt_id, variables: dict) -> str:
        artifact = self.get_active(prompt_id)
        template = artifact['template']
        try:
            rendered = template.format_map(variables)
        except KeyError as e:
            raise ValueError(f'Missing variable {e} for prompt {prompt_id}')
        return rendered

# Usage
registry = PromptRegistry(dsn='postgresql://...')
prompt = registry.render(
    'summarize-article',
    {
        'num_sentences': 3,
        'focus_area': 'financial impact',
        'article_text': 'Apple reported record revenue of $119B...'
    }
)
print(prompt)
# Output: Summarize the following article in 3 sentences.
# Focus on: financial impact. ...

Attivazione di una versione

In produzione dovrebbe essere attiva una sola versione di ciascun prompt alla volta. L'attivazione deve essere atomica: disattivare quella corrente e attivare quella nuova, tutto in un'unica transazione, per evitare intervalli senza una versione attiva.

def activate_version(self, prompt_id, version):
    with self.conn.cursor() as cur:
        # Deactivate all current versions
        cur.execute(
            'UPDATE prompt_versions SET is_active=FALSE '
            'WHERE prompt_id=%s AND is_active=TRUE',
            (prompt_id,)
        )
        # Activate target version
        cur.execute(
            'UPDATE prompt_versions SET is_active=TRUE '
            'WHERE prompt_id=%s AND version=%s',
            (prompt_id, version)
        )
        if cur.rowcount == 0:
            self.conn.rollback()
            raise ValueError(f'Version {version} not found for {prompt_id}')
    self.conn.commit()
    print(f'Activated {prompt_id}@{version}')

Elencare e cercare i prompt

Un registro è utile solo se è possibile individuarne i contenuti. Supporti la ricerca basata sui tag ed elenchi tutte le versioni di un determinato prompt.

def list_versions(self, prompt_id):
    with self.conn.cursor() as cur:
        cur.execute(
            'SELECT version, author, is_active, created_at '
            'FROM prompt_versions WHERE prompt_id=%s '
            'ORDER BY created_at DESC',
            (prompt_id,)
        )
        return cur.fetchall()

def search_by_tag(self, tag):
    with self.conn.cursor() as cur:
        cur.execute(
            'SELECT prompt_id, version, tags FROM prompt_versions '
            'WHERE %s = ANY(tags)',
            (tag,)
        )
        return cur.fetchall()

# Usage
for v in registry.list_versions('summarize-article'):
    print(v)  # ('1.1.0', 'alice', True, datetime(...))

for p in registry.search_by_tag('production'):
    print(p)  # ('summarize-article', '1.1.0', ['production', 'summarization'])

Endpoint API del registro

Esponga il registro come API REST, in modo che tutti i servizi (backend, pipeline ML e strumenti di valutazione) condividano un'unica fonte autorevole. Endpoint fondamentali:

  • POST /prompts/{id}/versions — registra una nuova versione
  • GET /prompts/{id}/active — recupera il template attivo
  • PUT /prompts/{id}/activate/{version} — attiva una versione
  • GET /prompts — elenca tutti i prompt con i relativi metadati
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()
registry = PromptRegistry(dsn='postgresql://user:pass@localhost/prompts')

class VersionPayload(BaseModel):
    version: str
    template: str
    author: str
    tags: list
    model: str

@app.post('/prompts/{prompt_id}/versions')
def register_version(prompt_id: str, payload: VersionPayload):
    registry.register(
        prompt_id, payload.version, payload.template,
        payload.author, payload.tags, payload.model
    )
    return {'status': 'registered'}

@app.get('/prompts/{prompt_id}/active')
def get_active(prompt_id: str):
    try:
        return registry.get_active(prompt_id)
    except ValueError as e:
        raise HTTPException(404, str(e))

@app.put('/prompts/{prompt_id}/activate/{version}')
def activate(prompt_id: str, version: str):
    registry.activate_version(prompt_id, version)
    return {'status': 'activated'}

Registro di audit e cronologia delle modifiche

Ogni evento di attivazione, disattivazione e registrazione dovrebbe essere registrato con un timestamp e l'autore dell'azione. Questa traccia di audit è essenziale per il debug degli incidenti in produzione e per soddisfare i requisiti di conformità.

CREATE TABLE prompt_audit_log (
  id          SERIAL PRIMARY KEY,
  prompt_id   VARCHAR(100),
  version     VARCHAR(20),
  action      VARCHAR(50),  -- 'registered', 'activated', 'deactivated'
  actor       VARCHAR(100), -- user or service that performed the action
  reason      TEXT,
  created_at  TIMESTAMP DEFAULT NOW()
);

-- Trigger to auto-log activations
CREATE OR REPLACE FUNCTION log_activation()
RETURNS TRIGGER AS $func$
BEGIN
  IF NEW.is_active != OLD.is_active THEN
    INSERT INTO prompt_audit_log (prompt_id, version, action)
    VALUES (NEW.prompt_id, NEW.version,
            CASE WHEN NEW.is_active THEN 'activated' ELSE 'deactivated' END);
  END IF;
  RETURN NEW;
END;
$func$ LANGUAGE plpgsql;

CREATE TRIGGER trg_activation
AFTER UPDATE ON prompt_versions
FOR EACH ROW EXECUTE FUNCTION log_activation();

Verifica rapida

In uno schema di database per un registro dei prompt, quale campo garantisce che, in un dato momento, venga fornita in produzione una sola versione di ciascun prompt?

Riepilogo dell'architettura del registro

Un registro dei prompt centralizza la gestione dei prompt trattandoli come artefatti versionati. Decisioni progettuali fondamentali:

  • Separare la tabella delle identità (prompt_id) dalla tabella delle versioni (version, template, metadata)
  • Un singolo flag is_active con scambi atomici previene i bug causati da due versioni attive contemporaneamente
  • Metadati dettagliati (autore, tag, modello, changelog) supportano l'individuazione e l'audit
  • Il livello API REST rende il registro accessibile a tutti i servizi
  • Il registro di audit supporta la conformità e il debug degli incidenti

I registri basati su file sono adatti ai team piccoli; per i sistemi di produzione multi-team ad alta disponibilità sono preferibili registri basati su database.

Domande Frequenti

La lezione «Architettura di un prompt registry» è gratuita?

Sì — il testo completo di «Architettura di un prompt registry» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Prompt Engineering, passa a CoddyKit PRO. Il corso AI Prompt Engineering include 4 lezioni in totale.

Cosa imparerò in «Architettura di un prompt registry»?

Memorizzazione dei prompt come artifact versionati con metadati e tag Eserciti AI Prompt Engineering con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Prompt Engineering?

Non è richiesta alcuna esperienza precedente. AI Prompt Engineering su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Architettura di un prompt registry»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Prompt Engineering?

Sì. Ogni lezione AI Prompt Engineering include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Architettura di un prompt registry
  2. Controllo versione dei prompt
  3. Strategie di deployment e rollback
  4. Monitoraggio delle prestazioni dei prompt in produzione
← Torna a AI Prompt Engineering