Implémenter CAI dans des applications
Ajoutez des boucles de critique et de révision aux pipelines d’IA de production.
Implémenter CAI dans des applications est une leçon AI Prompt Engineering gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Prompt Engineering, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Prompt Engineering comprend 4 leçons au total.
CAI comme modèle au niveau de l'application
Le Constitutional AI était à l'origine une technique utilisée lors de l'entraînement, mais la même boucle de critique et de révision peut être implémentée au moment de l'inférence dans vos applications. Vous n'avez pas besoin d'entraîner votre propre modèle : vous utilisez des appels d'API pour implémenter la boucle.
Le CAI au niveau de l'application est utile pour les scénarios de sortie à enjeux élevés, lorsque vous souhaitez ajouter un filet de sécurité aux mécanismes de protection intégrés au modèle.
Les trois fonctions nécessaires
Une implémentation de CAI nécessite trois fonctions composables : generate(), critique() et revise(). Chacune correspond à un appel distinct à un LLM. Vous les reliez dans la logique de votre application.
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].textAssembler la boucle
La fonction principale de l'application appelle successivement generate, critique et revise. Une seule itération de CAI ajoute 2 appels supplémentaires à un LLM en plus de la génération initiale.
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)Choisir entre 1 itération et N itérations
Combien d'itérations de critique et de révision devez-vous exécuter ? Voici la règle générale :
- 1 itération : suffisante pour la plupart des cas de filtrage de sécurité et d'amélioration de la qualité
- 2 itérations : lorsque la première critique a détecté des problèmes importants qui justifient un second passage
- 3 itérations ou plus : rarement nécessaires — rendements décroissants, coût élevé et risque de surcorrection
Une approche pratique consiste à exécuter systématiquement 1 itération et à ne déclencher une seconde itération que si la première critique a signalé des problèmes graves.
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])Coût des boucles de CAI
Chaque itération d'une boucle de CAI ajoute 2 appels supplémentaires à un LLM (critique + revise). À grande échelle, cela multiplie le coût de vos jetons :
- 1 itération : 3 fois plus de jetons qu'une réponse directe
- 2 itérations : 5 fois plus de jetons
- 3 itérations : 7 fois plus de jetons
Pour limiter ce coût : utilisez un modèle plus petit pour la critique, mettez en cache les résultats des critiques et ne déclenchez le CAI que pour les catégories de demandes à haut risque.
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 revisedCréer un classificateur du risque des demandes
Appliquez le CAI de manière sélective en classifiant d'abord le risque des demandes. Les demandes à faible risque reçoivent des réponses directes ; les demandes à haut risque passent par la boucle de critique et de révision. Cela permet d'équilibrer sécurité, coût et latence.
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)Journalisation et surveillance des sorties de CAI
Les systèmes de CAI en production devraient journaliser les réponses initiales et finales. Cela vous permet de mesurer la fréquence à laquelle la critique déclenche des révisions, de repérer les schémas d'échec récurrents et de vérifier la conformité des réponses.
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 asynchrone pour augmenter le débit
Pour les applications à débit élevé, implémentez le CAI de manière asynchrone avec asyncio. Vous pouvez également exécuter en parallèle la critique et la génération suivante lors du traitement de plusieurs demandes.
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']))Tester un pipeline de CAI
Testez votre pipeline de CAI avec des entrées adversariales connues. Vérifiez que les demandes dangereuses sont révisées, que les demandes inoffensives ne sont pas révisées à l'excès et que la sortie finale est meilleure que la sortie initiale.
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.pyQuand le CAI n'est pas le bon outil
Les boucles de CAI ne sont pas toujours la bonne solution. Envisagez d'autres options lorsque :
- la latence est critique : 3 appels à un LLM ajoutent de 3 à 10 secondes
- le coût est limité : un coût multiplié par 3 pour les jetons peut être prohibitif à grande échelle
- le modèle gère déjà bien la sécurité : l'ajout du CAI peut entraîner une prudence excessive
- vous avez besoin d'une sécurité déterministe : utilisez des filtres par mots-clés ou des classificateurs, plutôt qu'une critique probabiliste par LLM
Utilisez le CAI pour la génération de contenu à enjeux élevés, les domaines sensibles à la conformité et les sorties pour lesquelles la qualité est essentielle.
Faire évoluer votre ensemble de principes
Vos principes de CAI devraient évoluer en fonction de ce que la critique détecte en production. Si la critique modifie rarement la réponse initiale, vos principes sont peut-être trop vagues. Si la critique signale toujours le même problème, mettez à jour l'étape de génération afin de l'éviter dès le départ.
Examinez chaque semaine les journaux de critique : recherchez les schémas récurrents, puis renforcez votre invite système de génération pour empêcher ces problèmes ou précisez le principe afin de mieux définir ce qui constitue un problème.
Vérification des connaissances : coût du CAI
Par rapport à une réponse directe d'un LLM obtenue en un seul appel, combien d'appels à un LLM une itération de CAI (generate → critique → revise) nécessite-t-elle ?
Récapitulatif : implémenter le CAI dans les applications
Le CAI au niveau de l'application implémente une boucle en trois étapes au moyen de trois fonctions : generate(), critique() et revise(). Une itération ajoute 2 appels supplémentaires à un LLM ; 2 itérations ou plus sont réservées aux situations à haut risque. Optimisez les coûts en utilisant un modèle plus petit pour la critique, en classifiant le risque des demandes afin d'appliquer le CAI de manière sélective et en exécutant les demandes de manière asynchrone. Journalisez les réponses initiales et finales pour mesurer la fréquence réelle des révisions. Appliquez le CAI aux domaines critiques pour la conformité et à enjeux élevés ; évitez-le pour les applications à faible risque et sensibles à la latence.
Questions Fréquemment Posées
La leçon « Implémenter CAI dans des applications » est-elle gratuite ?
Oui — le texte complet de « Implémenter CAI dans des applications » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Prompt Engineering, passe à CoddyKit PRO. Le cours AI Prompt Engineering comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Implémenter CAI dans des applications » ?
Ajoutez des boucles de critique et de révision aux pipelines d’IA de production. Tu pratiques AI Prompt Engineering avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Prompt Engineering ?
Aucune expérience préalable n'est requise. AI Prompt Engineering sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Implémenter CAI dans des applications » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Prompt Engineering ?
Oui. Chaque leçon AI Prompt Engineering inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Principes de CAI et prompts de critique
- Schémas d’autocritique et de révision
- Tension entre innocuité et utilité
- Implémenter CAI dans des applications