Вы когда-нибудь смотрели на сгенерированный нейросетью код и думали: «Боже, это работает, но почему так уродливо?» Я смотрел. И не раз. Дело не в том, что LLM тупые — дело в том, что мы подсовываем им мусор. Контекстное окно растёт: GPT-4o в 2026 году легко жуёт 200K токенов, Claude 4 — 500K, а Gemini — под миллион. Но парадокс в другом — чем больше окно, тем меньше ИИ понимает ваш код. Потому что архитектура не менялась. А она должна.
Забудьте про «склей всего файла и попроси дописать функцию». Это путь в зелёный CI и пустую архитектуру. Хотите, чтобы ИИ генерировал код, который вы не переписываете каждые пять минут? Придётся проектировать под него. И я покажу как.
Когда контекстное окно лопается по швам
Представьте: вы пишете микросервис на Python. 50 файлов, 10 dependency injection, куча async-магии. Вы бросаете в контекст весь проект — упираетесь в лимит токенов. LLM начинает галлюцинировать: придумывает несуществующие методы, путает названия, забывает про типы. Знакомо?
Проблема не в модели — проблема в сигнал/шум. Чем больше кода вы пихаете в окно, тем меньше соотношение полезной информации к общему объёму. Исследования 2025-2026 годов (Anthropic, Google DeepMind) показали: средняя плотность значимых данных в современных проектах падает до 12-15%. Остальное — импорты, комментарии-заглушки, шаблонный код.
Ошибка: Думать, что модель сама отфильтрует шум. Ничего подобного. LLM — это вероятностный предсказатель. Чем больше шума, тем выше энтропия ответа.
Принцип «говорящих имен» и «чистых границ»
Чтобы LLM эффективно использовала контекст, код должен быть самодокументируемым и атомарным. Не в смысле «микросервисы по 100 строк», а в смысле — каждый файл делает одну вещь и делает это очевидно.
1 Правило «20/80» для ИИ
20% кода занимают 80% логики. Остальное — бойлерплейт. Выносите бойлерплейт в отдельные утилиты или абстракции. В контекст тащите только смысл.
# Плохо — всё в одном классе
class PaymentProcessor:
def process(self, order):
# 50 строк логики + 30 строк валидации + 20 строк логирования
...
# Хорошо — атомарно, с явными интерфейсами
class PaymentProcessor:
def __init__(self, validator: Validator, logger: Logger, gateway: Gateway):
self.validator = validator
self.logger = logger
self.gateway = gateway
def process(self, order: Order) -> PaymentResult:
self.validator.validate(order)
result = self.gateway.charge(order)
self.logger.log(order, result)
return result
Теперь, когда LLM видит этот код, он сразу понимает роли. Не надо гадать — всё по именам. Интерфейсы — это промпты для разработчика.
2 Документация как часть контекста
Не надейтесь, что LLM додумает. Прописывайте docstring, типы, контракты. Я в каждом модуле добавляю краткий блок __init__.py с описанием модуля и ссылками на связанные файлы. Это как заголовок для RAG-системы — контекстный движок скажет спасибо.
"""Pipeline для обработки заказов.
Зависимости:
- OrderRepository (order_repo.py)
- PaymentGateway (payment.py)
- NotificationService (notify.py)
Usage:
pipeline = OrderPipeline(repo, gateway, notify)
await pipeline.run(order_id)
"""
Токены не бесконечны: считайте их как бюджет
Когда я вижу, что разработчик суёт в промпт целый файл на 500 строк ради правки одной строчки — мне хочется плакать. Токены стоят денег (или времени на генерацию). А главное — каждый токен снижает точность на длинных дистанциях.
| Длина контекста (токены) | Среднее качество ответа (Bleu) | Время генерации (сек) |
|---|---|---|
| 1K | 0.85 | 1.2 |
| 10K | 0.72 | 8.5 |
| 50K | 0.58 | 42.0 |
| 200K | 0.44 | 180.0 |
Данные усреднённые по GPT-4o и Claude 3.5 Sonnet (внутренние бенчмарки 2025). Вывод: не кормите модель просто так. Отсекайте лишнее.
Решение: используйте контекстные суммаризаторы перед отправкой. Можно свой RAG, можно просто хэшировать импорты — но всегда контролируйте бюджет.
Рефакторинг для LLM: практический кейс
В одном проекте мы переписывали легаси-монолит на Python. 3000 файлов. ИИ генерировал микросервисы через неделю после того, как мы наводили порядок. Проблема была в архитектурном долге ИИ — нейросеть просто копировала плоскую структуру оригинала.
Мы сделали просто:
- Разбили на доменные модули. Каждый модуль — отдельная папка с чётким интерфейсом наружу.
- Оптимизировали зависимости. Убрали круговые — они убивают любой контекст.
- Добавили схемы данных в JSON Schema. LLM на них обучается быстрее.
- Написали «промпт-маппинг». Каждая функция в коде имела git-blame с описанием задачи — генерация подхватывала контекст.
Результат: снижение размера контекста для типичной задачи с 80K до 12K токенов. Качество кода выросло — ИИ перестал придумывать чепуху. Подробнее о похожем подходе — в статье про управление контекстом в играх — принципы универсальны.
Не делайте так: не пишите универсальный «ContextBuilder», который тянет всё подряд. Лучше сделайте несколько специализированных билдеров: для запросов, для схем, для бизнес-логики. Так LLM легче фокусироваться.
FAQ: ответы на то, что вы боялись спросить
Что делать, если проект уже большой и рефакторинг дорог?
Начните с малого: выделите одну критическую цепочку вызовов (например, payment -> validation -> gateway) и приведите её к атомарному виду. Часто 80% задач тыкаются в 20% кода — с них и начните. Потом можно использовать LoopCoder для автоматического распиливания моно-файлов.
А если я использую codex или суперагента?
Суперагенты (как Devin или OpenHands) тоже ограничены контекстом. Разница только в том, что они пишут промпты сами. Если архитектура проекта не упорядочена, агент будет бесконечно чинить одно и то же. Это путь к выгоранию от AI-кодинга.
Нужно ли добавлять мета-теги в сами файлы?
Обязательно. В каждом модуле укажите его ответственность и связи. Я делаю файл .ai-context.json в корне модуля — там список ключевых сущностей, типы ошибок, адреса документации. В JanusCoder это сделано через SVG-схемы — имхо, крутая альтернатива.
Лучший способ сделать код понятным для ИИ — перестать писать для ИИ. Пишите для человека, который будет читать его через полгода. ИИ — это просто безумно быстрый читатель. Если ваш код удобен человеку (короткие функции, явные имена, нет магии), он будет удобен и LLM. А контекстное окно само перестанет быть проблемой, если вы перестанете в него сваливать всё подряд.
P.S. Спорим, вы сейчас откроете свой проект и найдёте три функции, которые можно разбить прямо сейчас? Сделайте это — и увидите, как изменится качество AI-генерации.