AI Prompt Engineering · Урок

Реализация CAI в приложениях

Добавляйте циклы критики и доработки в рабочие конвейеры искусственного интеллекта.

Урок 4 из 413 шагов

«Реализация 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 — локальная установка не требуется.

Все уроки этого курса

  1. Принципы CAI и запросы для критики
  2. Шаблоны самокритики и переработки
  3. Противоречие между безвредностью и полезностью
  4. Реализация CAI в приложениях
← Назад к AI Prompt Engineering