Реализация CAI в приложениях
Добавляйте циклы критики и доработки в рабочие конвейеры искусственного интеллекта.
«Реализация CAI в приложениях» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Prompt Engineering, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Prompt Engineering содержит 4 уроков всего.
CAI как шаблон на уровне приложения
Изначально Конституциональный ИИ был методикой, применяемой на этапе обучения, но тот же цикл критики и доработки можно реализовать на этапе вывода в собственных приложениях. Вам не нужно обучать собственную модель — для реализации цикла достаточно использовать вызовы программного интерфейса.
CAI на уровне приложения полезен в сценариях создания результатов с высокой ценой ошибки, когда требуется дополнительный уровень защиты сверх встроенных ограничений безопасности модели.
Три необходимые функции
Реализация CAI требует трёх функций, которые можно объединять: generate(), critique() и revise(). Каждая из них представляет собой отдельный вызов LLM. Объедините их в логике приложения.
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Связываем всё в один цикл
Основная функция приложения последовательно вызывает generate, critique и revise. Один раунд CAI добавляет 2 дополнительных вызова LLM к исходной генерации.
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)Выбор: 1 раунд или N раундов
Сколько раундов критики и доработки следует run? Практическое правило:
- 1 раунд: достаточно для большинства сценариев проверки безопасности и улучшения качества
- 2 раунда: если в первой критике обнаружены существенные проблемы, заслуживающие второго прохода
- 3 и более раундов: требуются редко — результат улучшается всё меньше, затраты растут, а риск чрезмерной коррекции увеличивается
Практический подход: всегда run 1 раунд и запускать второй только в том случае, если первая критика выявила серьёзные проблемы.
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])Стоимость циклов CAI
Каждая итерация цикла CAI добавляет 2 дополнительных вызова LLM (critique + revise). В большом масштабе это увеличивает расходы на токены:
- 1 раунд: в 3 раза больше токенов, чем при прямом ответе
- 2 раунда: в 5 раз больше токенов
- 3 раунда: в 7 раз больше токенов
Снизить затраты можно так: использовать меньшую модель для critique, кэшировать результаты критики и запускать CAI только для категорий запросов с высоким риском.
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Создание классификатора риска запросов
Применяйте CAI выборочно, сначала классифицируя риск запроса. Для запросов с низким риском выдавайте прямые ответы, а запросы с высоким риском направляйте через цикл критики и доработки. Это позволяет сбалансировать безопасность, стоимость и задержку.
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)Ведение журналов и мониторинг результатов CAI
В системах CAI в рабочей среде следует записывать как исходные, так и итоговые ответы. Это позволяет измерять, как часто critique приводит к доработке, выявлять повторяющиеся схемы сбоев и проверять ответы на соответствие требованиям.
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 для повышения пропускной способности
Для приложений с высокой пропускной способностью реализуйте CAI асинхронно с помощью asyncio. При обработке нескольких запросов можно также параллельно выполнять critique и следующую генерацию.
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']))Модульное тестирование конвейера CAI
Проверьте конвейер CAI на известных состязательных входных данных. Убедитесь, что вредоносные запросы дорабатываются, безобидные не подвергаются чрезмерной доработке, а итоговый результат лучше исходного.
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Когда CAI — неподходящий инструмент
Циклы CAI не всегда являются правильным решением. Рассмотрите альтернативы, если:
- Задержка критична: 3 вызова LLM добавляют 3–10 секунд
- Затраты ограничены: утроенная стоимость токенов может быть неприемлемой при большом масштабе
- Модель уже хорошо обеспечивает безопасность: CAI может привести к чрезмерной осторожности
- Вам нужна детерминированная безопасность: используйте фильтры по ключевым словам или классификаторы, а не вероятностную операцию critique с помощью LLM
Используйте CAI для создания контента с высокой ценой ошибки, сфер с жёсткими требованиями к соответствию и результатов, где критично качество.
Итеративное улучшение набора принципов
Ваши принципы CAI должны меняться в зависимости от того, что critique обнаруживает в рабочей среде. Если critique редко меняет исходный ответ, ваши принципы могут быть слишком расплывчатыми. Если critique всегда выявляет одну и ту же проблему, измените этап генерации, чтобы предотвращать её с самого начала.
Еженедельно просматривайте журналы critique: ищите повторяющиеся схемы критики, а затем либо усильте системную инструкцию для генерации, чтобы предотвращать такие проблемы, либо уточните принцип, точнее описав, что считать проблемой.
Проверка знаний: стоимость CAI
Сколько вызовов LLM требует один раунд CAI (generate → critique → revise) по сравнению с прямым ответом LLM за один вызов?
Итоги: реализация CAI в приложениях
CAI на уровне приложения реализует трёхэтапный цикл с помощью трёх функций: generate(), critique() и revise(). Один раунд добавляет 2 дополнительных вызова LLM; 2 и более раунда предназначены для ситуаций с высоким риском. Оптимизируйте затраты, используя меньшую модель для critique, классифицируя риск запросов для выборочного применения CAI и выполняя запросы асинхронно. Записывайте исходные и итоговые ответы, чтобы измерять, как часто действительно выполняется доработка. Применяйте CAI в сферах, критичных с точки зрения соответствия требованиям и цены ошибки; не используйте его для приложений с низким риском и жёсткими требованиями к задержке.
Изучай AI Prompt Engineering с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 53
- Уроки
- 199
Часто задаваемые вопросы
Урок «Реализация CAI в приложениях» бесплатный?
Да — полный текст урока «Реализация CAI в приложениях» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.
Чему я научусь в уроке «Реализация CAI в приложениях»?
Добавляйте циклы критики и доработки в рабочие конвейеры искусственного интеллекта. Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Prompt Engineering?
Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Реализация CAI в приложениях»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Prompt Engineering?
Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Принципы CAI и запросы для критики
- Шаблоны самокритики и переработки
- Противоречие между безвредностью и полезностью
- Реализация CAI в приложениях