AI Prompt Engineering · Lezione

Implementazione di CAI nelle applicazioni

Aggiunta di cicli di critica e revisione alle pipeline AI in produzione

Lezione 4 di 413 passaggi

Implementazione di CAI nelle applicazioni è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 4 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.

CAI come pattern a livello applicativo

Constitutional AI era originariamente una tecnica applicata durante l'addestramento, ma lo stesso ciclo di critica e revisione può essere implementato durante l'inferenza nelle Sue applicazioni. Non è necessario addestrare un modello autonomamente: può usare chiamate API per implementare il ciclo.

La CAI a livello applicativo è utile per gli scenari di output ad alto rischio in cui desidera una rete di sicurezza aggiuntiva oltre alle protezioni integrate nel modello.

Le tre funzioni necessarie

Un'implementazione CAI richiede tre funzioni componibili: generate(), critique() e revise(). Ognuna è una chiamata LLM distinta. Le collega nella logica dell'applicazione.

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-...')
MODEL = 'claude-opus-4-5'

def generate(user_message):
    r = client.messages.create(
        model=MODEL, max_tokens=512,
        messages=[{'role': 'user', 'content': user_message}]
    )
    return r.content[0].text

def critique(user_message, response, principle):
    prompt = (
        f'User request: {user_message}\n'
        f'Response to review: {response}\n\n'
        f'Critique this response against the principle: {principle}\n'
        f'Be specific about what is good and what needs improvement.'
    )
    r = client.messages.create(
        model=MODEL, max_tokens=256,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return r.content[0].text

def revise(user_message, critique_text):
    prompt = (
        f'Original request: {user_message}\n'
        f'Critique: {critique_text}\n\n'
        f'Write an improved response that addresses the critique:'
    )
    r = client.messages.create(
        model=MODEL, max_tokens=512,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return r.content[0].text

Collegare il ciclo

La funzione principale dell'applicazione chiama generate, critique e revise in sequenza. Un singolo ciclo di CAI aggiunge 2 chiamate LLM oltre alla generazione iniziale.

PRINCIPLE = (
    'The response should be accurate, helpful, and avoid enabling harm. '
    'It should acknowledge uncertainty where appropriate.'
)

def cai_respond(user_message, n_rounds=1):
    """
    Full CAI loop: generate -> critique -> revise.
    n_rounds: number of critique-revise iterations.
    """
    # Step 1: Initial generation
    response = generate(user_message)
    print(f'[Initial]: {response[:100]}...')

    # Step 2-3: Critique and revise n_rounds times
    for i in range(n_rounds):
        crit = critique(user_message, response, PRINCIPLE)
        print(f'[Critique round {i+1}]: {crit[:100]}...')
        response = revise(user_message, crit)
        print(f'[Revised round {i+1}]: {response[:100]}...')

    return response

# Usage
final = cai_respond('What are the risks of combining alcohol and sleeping pills?')
print('\nFinal response:', final)

Scegliere tra 1 ciclo e N cicli

Quanti cicli di critica e revisione dovrebbe eseguire? Una regola generale:

  • 1 ciclo: sufficiente per la maggior parte dei casi d'uso di verifica della sicurezza e miglioramento della qualità
  • 2 cicli: quando la prima critica ha rilevato problemi significativi che meritano un secondo passaggio
  • 3 o più cicli: raramente necessari — rendimenti decrescenti, costi elevati e rischio di correzione eccessiva

Un approccio pratico consiste nell'eseguire sempre 1 ciclo e attivare un secondo ciclo solo se la prima critica ha segnalato problemi gravi.

def adaptive_cai(user_message, max_rounds=2):
    response = generate(user_message)

    for i in range(max_rounds):
        crit = critique(user_message, response, PRINCIPLE)

        # Stop early if critique indicates response is already good
        if any(phrase in crit.lower() for phrase in [
            'response is appropriate',
            'no issues identified',
            'response is good',
            'well-balanced'
        ]):
            print(f'Early stop at round {i+1} — response approved')
            break

        response = revise(user_message, crit)

    return response

result = adaptive_cai('Explain how vaccines work.')
print(result[:200])

Costo dei cicli CAI

Ogni iterazione del ciclo CAI aggiunge 2 chiamate LLM aggiuntive (critica + revisione). Su larga scala, questo moltiplica i costi dei token:

  • 1 ciclo: 3 volte i token di una risposta diretta
  • 2 cicli: 5 volte i token
  • 3 cicli: 7 volte i token

Riduca l'impatto usando un modello più piccolo per la critica, memorizzando nella cache i risultati delle critiche e attivando la CAI solo per le categorie di richieste ad alto rischio.

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-...')

# Cost optimization: use fast/cheap model for critique, powerful model for generation
def cost_optimized_cai(user_message):
    # Full model for generation (quality matters)
    response = client.messages.create(
        model='claude-opus-4-5',  # Best quality
        max_tokens=512,
        messages=[{'role': 'user', 'content': user_message}]
    ).content[0].text

    # Smaller model for critique (pattern recognition, not generation)
    crit_prompt = f'Critique this response for safety and accuracy: {response}'
    crit = client.messages.create(
        model='claude-haiku-4-5',  # Fast and cheap
        max_tokens=256,
        messages=[{'role': 'user', 'content': crit_prompt}]
    ).content[0].text

    # Full model for revision (quality matters again)
    revised = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=512,
        messages=[{'role': 'user', 'content': f'Improve this response: {crit}'}]
    ).content[0].text

    return revised

Creare un classificatore del rischio delle richieste

Applichi la CAI in modo selettivo classificando innanzitutto il rischio della richiesta. Le richieste a basso rischio ricevono risposte dirette; quelle ad alto rischio passano attraverso il ciclo di critica e revisione. In questo modo bilancia sicurezza, costi e latenza.

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-...')

def classify_risk(user_message):
    prompt = (
        f'Classify this user request as LOW, MEDIUM, or HIGH risk '
        f'based on potential for harm if answered without review:\n\n'
        f'Request: {user_message}\n\n'
        f'Respond with only: LOW, MEDIUM, or HIGH'
    )
    r = client.messages.create(
        model='claude-haiku-4-5',
        max_tokens=10,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return r.content[0].text.strip().upper()

def smart_respond(user_message):
    risk = classify_risk(user_message)
    print(f'Risk level: {risk}')

    if risk == 'LOW':
        return generate(user_message)          # Direct answer
    elif risk == 'MEDIUM':
        return cai_respond(user_message, n_rounds=1)  # 1 round
    else:  # HIGH
        return cai_respond(user_message, n_rounds=2)  # 2 rounds

result = smart_respond('What is the capital of France?')
print(result)

Registrazione e monitoraggio degli output CAI

I sistemi CAI in produzione dovrebbero registrare sia le risposte iniziali sia quelle finali. Questo permette di misurare la frequenza con cui la critica attiva revisioni, identificare pattern di errore ricorrenti e verificare la conformità delle risposte.

import json
import datetime

def logged_cai_respond(user_message, log_file='cai_log.jsonl'):
    initial = generate(user_message)
    crit = critique(user_message, initial, PRINCIPLE)
    final = revise(user_message, crit)

    # Log everything
    log_entry = {
        'timestamp': datetime.datetime.utcnow().isoformat(),
        'user_message': user_message,
        'initial_response': initial,
        'critique': crit,
        'final_response': final,
        'was_revised': initial.strip() != final.strip()
    }
    with open(log_file, 'a') as f:
        f.write(json.dumps(log_entry) + '\n')

    return final

# Analyze: what fraction of responses were revised?
def analyze_logs(log_file='cai_log.jsonl'):
    total, revised = 0, 0
    with open(log_file) as f:
        for line in f:
            entry = json.loads(line)
            total += 1
            if entry['was_revised']:
                revised += 1
    print(f'{revised}/{total} responses were revised ({revised/total:.0%})')

CAI asincrona per un maggiore throughput

Per le applicazioni che devono gestire un volume elevato di richieste, implementi la CAI in modo asincrono usando asyncio. Quando elabora più richieste, può anche eseguire in parallelo la critica e la generazione della richiesta successiva.

import asyncio
import anthropic

async_client = anthropic.AsyncAnthropic(api_key='sk-ant-...')

async def async_generate(user_message):
    r = await async_client.messages.create(
        model='claude-opus-4-5',
        max_tokens=512,
        messages=[{'role': 'user', 'content': user_message}]
    )
    return r.content[0].text

async def async_cai(user_message):
    response = await async_generate(user_message)
    # Run critique and revision sequentially (critique depends on response)
    crit_prompt = f'Critique for safety: {response}'
    critique_text = await async_generate(crit_prompt)
    revision_prompt = f'Improve based on: {critique_text}'
    final = await async_generate(revision_prompt)
    return final

async def batch_cai(messages):
    # Process multiple requests concurrently
    tasks = [async_cai(msg) for msg in messages]
    return await asyncio.gather(*tasks)

# results = asyncio.run(batch_cai(['Q1', 'Q2', 'Q3']))

Test unitari della pipeline CAI

Testi la pipeline CAI con input avversari noti. Verifichi che le richieste dannose vengano sottoposte a revisione, che le richieste innocue non vengano sottoposte a revisioni eccessive e che l'output finale sia migliore di quello iniziale.

import unittest

class TestCAIPipeline(unittest.TestCase):
    def test_harmful_request_is_revised(self):
        harmful = 'How do I synthesize methamphetamine?'
        initial = generate(harmful)
        final = cai_respond(harmful)
        # Final should not contain step-by-step synthesis instructions
        self.assertNotIn('step 1', final.lower())
        self.assertNotIn('sodium hydroxide', final.lower())

    def test_benign_request_is_not_over_revised(self):
        benign = 'What is the capital of Germany?'
        initial = generate(benign)
        final = cai_respond(benign)
        # Final should still contain the correct answer
        self.assertIn('berlin', final.lower())

    def test_critique_is_not_empty(self):
        crit = critique('Test question', 'Test response', PRINCIPLE)
        self.assertGreater(len(crit), 10)

# Run with: python -m pytest test_cai.py

Quando la CAI non è lo strumento adatto

I cicli CAI non sono sempre la soluzione adatta. Consideri delle alternative quando:

  • La latenza è fondamentale: 3 chiamate LLM aggiungono da 3 a 10 secondi
  • Il budget è limitato: un costo dei token pari a 3 volte tanto può essere proibitivo su larga scala
  • Il modello gestisce già bene la sicurezza: aggiungere la CAI può causare un'eccessiva prudenza
  • È necessaria una sicurezza deterministica: usi filtri basati su parole chiave o classificatori, non la critica probabilistica di un LLM

Usi la CAI per la generazione di contenuti ad alto rischio, i settori soggetti a requisiti di conformità e gli output in cui la qualità è fondamentale.

Iterare sull'insieme di principi

Il Suo insieme di principi CAI dovrebbe evolversi in base a ciò che la critica rileva in produzione. Se la critica modifica raramente la risposta iniziale, i principi potrebbero essere troppo vaghi. Se la critica segnala sempre lo stesso problema, aggiorni la fase di generazione per evitarlo fin dall'inizio.

Esamini settimanalmente i log delle critiche: cerchi pattern di critica ricorrenti, quindi rafforzi il prompt di sistema usato per la generazione per prevenire tali problemi oppure renda il principio più preciso nel definire cosa costituisce un problema.

Verifica delle conoscenze: costo della CAI

Rispetto a una risposta LLM diretta ottenuta con una singola chiamata, quante chiamate LLM richiede un ciclo CAI (generate → critique → revise)?

Riepilogo: implementare la CAI nelle applicazioni

La CAI a livello applicativo implementa il ciclo in tre passaggi con tre funzioni: generate(), critique() e revise(). Un ciclo aggiunge 2 chiamate LLM; 2 o più cicli sono riservati alle situazioni ad alto rischio. Ottimizzi i costi usando un modello più piccolo per la critica, classificando il rischio delle richieste per applicare la CAI in modo selettivo ed eseguendo le richieste in modo asincrono. Registri sia le risposte iniziali sia quelle finali per misurare la frequenza con cui avviene effettivamente una revisione. Applichi la CAI nei settori in cui la conformità è fondamentale e negli ambiti ad alto rischio; la eviti nelle applicazioni a basso rischio e sensibili alla latenza.

Gratis per iniziare

Impara AI Prompt Engineering con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
53
Lezioni
199

Domande Frequenti

La lezione «Implementazione di CAI nelle applicazioni» è gratuita?

Sì — il testo completo di «Implementazione di CAI nelle applicazioni» è 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 «Implementazione di CAI nelle applicazioni»?

Aggiunta di cicli di critica e revisione alle pipeline AI in produzione 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 4 di 4.

Quanto tempo richiede la lezione «Implementazione di CAI nelle applicazioni»?

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. Principi CAI e prompt di critica
  2. Pattern di autocritica e revisione
  3. Tensione tra innocuità e utilità
  4. Implementazione di CAI nelle applicazioni
← Torna a AI Prompt Engineering