Chain of Code (цепочка кода) — техника от Google DeepMind, при которой модель формулирует шаги рассуждения как код, а затем исполняет их там, где это возможно. Если шаг можно доверить интерпретатору (арифметика, логика, преобразование структур) — он выполняется как программа. Если шаг не сводится к исполнимому коду (семантика, здравый смысл, оценка тона) — модель временно играет роль LMulator и возвращает значение сама.
В 2026 году CoC полезнее понимать не как «ещё один prompt trick», а как гибридный runtime-паттерн между Program of Thoughts, tool use и reasoning orchestration. Он окупается там, где одна и та же задача сочетает точные вычисления и неформальные выводы, но почти не нужен там, где всё можно либо полностью формализовать, либо полностью оставить текстовому reasoning.
Представьте повара с рецептом. Некоторые шаги можно выполнить точно по инструкции: «варить 7 минут при 100°C» — это как исполнение кода. Но другие шаги требуют чутья: «добавить соль по вкусу» — это невозможно запрограммировать, и повар импровизирует. Chain of Code работает так же: где можно — считает точно (выполняет код), где нельзя — «импровизирует» (эмулирует код текстом).
Chain of Code развивает идею Program of Thoughts: модель записывает рассуждения в виде кода. Но в отличие от PoT, где весь код должен быть исполняемым, CoC допускает «псевдокод» для семантических задач.
Ключевая идея — LMulator (Language Model emulator): если строка кода не может быть выполнена интерпретатором Python (например, is_sarcastic = detect_sarcasm("Конечно, прекрасная погода")), модель сама определяет результат и подставляет значение. Получается гибрид: точные вычисления через интерпретатор + семантическое понимание через LLM.
ПромптClaude
Используй подход Chain of Code. Задача: В отзыве «Доставка приехала через 3 дня вместо обещанного 1 дня. Товар рабочий, но коробка помята. Цена 2500 руб. за такое качество — ну ок.» Определи: 1) задержку доставки в днях, 2) тональность отзыва, 3) соотношение цена/качество.
Ответ модели
# Шаг 1: Задержка доставки (исполняемый код)
promised_days = 1
actual_days = 3
delay = actual_days - promised_days # = 2 дня
# Шаг 2: Тональность (LMulator — эмуляция)
review = "Доставка приехала через 3 дня вместо обещанного 1 дня. Товар рабочий, но коробка помята. Цена 2500 руб. за такое качество — ну ок."
sentiment = analyze_sentiment(review) # = "негативно-нейтральная"
# Пояснение: есть недовольство задержкой и упаковкой, но товар работает
# Шаг 3: Соотношение цена/качество (гибрид)
price = 2500
product_works = True # из текста: "товар рабочий"
packaging_damaged = True # "коробка помята"
value_score = rate_value(price, product_works, packaging_damaged) # = "среднее"
result = {
"delay_days": delay, # 2
"sentiment": sentiment, # негативно-нейтральная
"value_rating": value_score # среднее
}
CoT — всё текстом (гибко, но ошибается в вычислениях). PoT — всё кодом (точно, но не работает для семантических задач). CoC — гибрид: код для вычислений, эмуляция для семантики. Используйте CoC, когда задача сочетает числа и понимание смысла.
Задержка: 3 - 1 = 2 дня. ✓
Штраф за задержку: 2500 × 0.01 × 2 = 50 руб. ✓
Но иногда: 2500 × 0.01 × 2 = 75 руб. ✗ (арифметическая ошибка)
Тональность: негативная ✓ (модель хорошо понимает)
Всё в одном формате — нет разделения ответственности.
Качество эмуляции напрямую зависит от мощности модели. GPT-4o и Claude Sonnet хорошо эмулируют семантические функции. Модели слабее (GPT-3.5, мелкие open-source) могут давать неточные результаты при эмуляции, сводя преимущество CoC к нулю.
В текущем стеке reasoning-систем CoC стоит между тремя мирами:
PoT и PAL, где вычислительная часть полностью уходит в исполнимый код
tool use, где модель вызывает отдельные калькуляторы, SQL, Python sandbox или внешние функции
обычным CoT, где всё остаётся в тексте и цена ошибки в промежуточных вычислениях выше
Поэтому главный вопрос уже не «лучше ли CoC, чем CoT вообще», а «есть ли у задачи смешанный контур». Если половина шага требует точного исполнения, а другая половина остаётся оценочной, CoC даёт более естественную рамку, чем попытка либо всё программировать, либо всё проговаривать текстом.
У CoC есть три типичных ограничения, которые часто недооценивают:
LMulator не превращает неформальную функцию в надёжный инструмент. analyze_sentiment(text) всё ещё остаётся обычным LLM-выводом, просто упакованным как код.
Гибридный пайплайн сложнее дебажить: ошибка может жить либо в коде, либо в эмуляции, либо в переключении между ними.
Чем больше в задаче фальшивых «псевдофункций», тем меньше остаётся реального преимущества перед обычным CoT.
Хорошее эмпирическое правило: если более 60-70% шагов в трассе оказываются неисполняемыми, вы уже не используете Chain of Code по назначению, а просто маскируете текстовое reasoning под код.
COC_SYSTEM_PROMPT = """Ты решаешь задачи методом Chain of Code.
Правила:
1. Запиши каждый шаг рассуждения как строку Python-кода
2. Для вычислений используй стандартные операции Python
3. Для семантических задач используй описательные функции:
- analyze_sentiment(text) → str
- classify(text, categories) → str
- extract_entities(text) → list
- is_relevant(text, topic) → bool
4. Добавляй комментарии, объясняющие логику
5. В конце собери результат в словарь result = {}
Интерпретатор выполнит арифметику и логику.
Семантические функции ты выполняешь сам (LMulator)."""
async def chain_of_code(task: str, model: str = "gpt-4o") -> dict:
"""
Двухпроходный Chain of Code:
1. Генерация кода (модель пишет решение)
2. Выполнение с LMulator
"""
# Проход 1: генерация кода
gen_response = await client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": COC_SYSTEM_PROMPT},
{"role": "user", "content": task}
],
temperature=0
)
generated_code = gen_response.choices[0].message.content
# Извлекаем код из markdown-блока
if "```python" in generated_code:
code = generated_code.split("```python")[1].split("```")[0]
else:
code = generated_code
# Проход 2: выполнение с LMulator
return execute_with_lmulator(code, model)
exec() без песочницы — никогда не используйте exec() на LLM-сгенерированном коде в продакшене без изоляции. Используйте Docker, RestrictedPython или безопасные интерпретаторы.
Слишком сложные эмуляции — LMulator лучше работает с простыми семантическими функциями (analyze_sentiment), чем с многоступенчатыми (build_full_report_with_recommendations).
Потеря контекста — при эмуляции передавайте текущие переменные в промпт. Без контекста LMulator не знает значения предыдущих шагов.