В прошлой статье мы успешно настроили базовый изолированный пайплайн на связке uv + Aider + Ollama в Ubuntu и научились собирать одиночные .patch файлы в неинтерактивном режиме с помощью флага --message.

Однако при переходе от простейших скриптов к промышленной автоматизации — например, когда нужно одной командой сгенерировать синхронную документацию сразу на двух языках (русском и английском) — разработчики натыкаются на неочевидные архитектурные барьеры: циклическую ошибку 404 Not Found, лавинообразное раздувание контекста и затирание Git-диффов.

Разбираем продвинутую инженерию автоматизации ИИ-агентов на примере генерации мультиязычной документации для реактивного декоратора withStaleWhileRevalidate.

1. Разделение Глобального Каркаса и Локальной Задачи

Чтобы ИИ-агент работал стабильно, его мышление необходимо разделить на два независимых слоя: Глобальные инструкции (Стиль и Структура) и Локальная задача (Контекст и Данные). Для этого мы полностью изолируем среду документирования с помощью файлов .aider.instructions.md и специализированного .env.doc.

Схема взаимодействия компонентов конвейера

[ .env.doc ] ───────> ( Динамические переменные: Таргет сущности / Пути к файлам )
                                    │
                                    ▼
[ .aider.instructions.md ] ─> [ ИИ-Агент Aider ] <─── [ Исходный код, Типы и Тесты ]
( Глобальный каркас стиля )         │                   ( src/core/types.ts, .test.ts )
                                    ▼
                           ┌─────────────────┐
                           │  Последователь    │
                           │  Сплит-Сессий     │
                           └────────┬────────┘
                                     │
                 ┌────────────────┴────────────────┐
                 ▼                                 ▼
          [ Сессия 1: RU ]                  [ Сессия 2: EN ]
      (docs/decorators/.md)            (docs/en/decorators/.md)
                 │                                 │
                 └────────────────┬────────────────┘
                                     ▼
                      [ Атомарный Git-дифф сборки ] ──> [ docs_multilang_update.patch ]

Реализация Глобального Каркаса (.aider.instructions.md)

Этот файл содержит неизменяемые правила игры, написанные на английском языке (наиболее приоритетный язык для системных промптов локальных моделей). Он заставляет ИИ строго следовать структуре исходных примеров документации (withCache) [source: 0.1.1], запрещает галлюцинации и фиксирует правила перевода технических терминов.

# Role & Objective
You are an expert technical writer specializing in reactive architecture. Your job is to create documentation pages for decorators or methods in the Reactive Engine library. Maintain strict layout constraints and 100% technical accuracy based on source code and tests.

# Language Strategy
- You will be told which language to use (**Russian** or **English**) in the task command.
- Generate all headers, explanations, and code comments strictly in the target language.
- Keep technical signatures, types, and API methods (.push, ResourceState) in English.

# Output Document Structure Constraint
Every markdown page MUST follow this exact structure:
# {Entity Name}
{High-level summary}.
## Синтаксис / Syntax
\`\`\`typescript
// Precise type signature
\`\`\`
## Параметры / Parameters
- **paramName** (`Type`): Description.
## Возвращаемое значение / Return Value
- List all public properties, methods, and flags.
## Примеры / Examples
1. Basic usage scenario.
2. Advanced scenario (error handling, mutations from tests).
## Дополнительная информация / Additional Information

Изоляция Локальной Задачи (.env.doc)

Для запуска пайплайна документации создается обособленный конфигурационный файл. В нем мы полностью отказываемся от OpenAI-совместимого эндпоинта /v1, так как библиотека liteLLM в составе Aider пытается выполнить служебный запрос api/show на некорректный адрес .../v1/api/show, вызывая краш 404. Мы используем нативный контур Ollama:

# --- Нативный эндпоинт Ollama (Без /v1 для обхода бага 404 в liteLLM) ---
OLLAMA_API_BASE="http://127.0.0.1:11434"
AIDER_MODEL="ollama/qwen2.5-coder:14b"

# --- Архитектурные флаги ИИ-агента ---
AIDER_CHAT_MODE="code"
AIDER_MAP_TOKENS=0
AIDER_DISABLE_AUTO_COMMITS="true"
AIDER_OUTPUT_PATCH="docs_multilang_update.patch"

# --- Имя целевой сущности и точечный контекст ---
DOC_TARGET_ENTITY="withStaleWhileRevalidate"
AIDER_FILES="src/core/types.ts,src/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.ts,src/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.test.ts,docs/decorators/withStaleWhileRevalidate.md,docs/en/decorators/withStaleWhileRevalidate.md"

2. Выбор LLM в Зависимости от Вычислительных Ресурсов

KV-кэш (Key-Value Cache) — это...

Локальный запуск на процессоре AMD Ryzen AI 9 HX 470 с графикой Radeon 890M означает, что модель выполняется на CPU с задействованием системной оперативной памяти, используя мощное аппаратное ускорение инструкций AVX-512.

AVX-512 — это...

Разбор математики контекста на моем примере

Эффективность разделения сессий наглядно подтверждается метриками токенов. В изолированном конвейере на первом шаге (RU-локализация) локальная модель получает 4.9k токенов входящего контекста (архитектура, исходный код, типы и системные правила) и генерирует 1.2k токенов ответа. На втором шаге (EN-локализация) Aider запускается с чистой историей диалога: на вход подается 6.0k токенов (исходный код плюс уже созданный на диске русский файл для синхронизации структуры), а модель выдает 977 токенов чистого английского текста. Если бы мы объединили эти шаги в одну общую интерактивную сессию, входящий контекст второго шага раздулся бы до 7.5k+ токенов за счет накопленной истории чата. Для локальной модели это критический порог: перегрузка KV-кэша приводит к эффекту «потери в середине» (Lost in the Middle), когда ИИ начинает игнорировать системные инструкции из начала диалога, путает структуру markdown-разметки и допускает лингвистическое перетекание (интерференцию) русского текста в английский код.

Сравнительный анализ подходов с учетом аппаратных факторов

Критерий сравненияНакопительные сплит-сессии (Выбранный подход)Единая долгоживущая сессия (Интерактивный чат)
Объем входящего контекста (Sent)Минимальный (4.9k / 6.0k). Модель видит только файлы на диске, история диалога пуста.Лавинообразный (7.5k+). Входной контекст постоянно растет за счет истории предыдущих ответов.
Состояние KV-кэша памятиЧистый и сфокусированный. Стирается между шагами. Исключает эффект «потери в середине».Раздутый и зашумленный. Память забита старыми ответами; модель игнорирует инструкции.
Нагрузка на CPU (Ryzen AI 9)Низкая. Легкий KV-кэш позволяет инструкциям AVX-512 мгновенно рассчитывать векторы внимания.Высокая. Процессор тратит критически много времени на прочесывание тяжелого и грязного KV-кэша в RAM.
Лингвистическая изоляцияПолная. Модель находится в жестких рамках одного целевого языка на каждую сессию.Нарушена. Высокий риск смешивания языков и калькирования фраз из-за присутствия старого текста в чате.
Устойчивость к сбоямВысокая. Падение второй сессии не уничтожает результаты первой; Git атомарно соберет частичный патч.Нулевая. Любая ошибка локальной Ollama в конце долгого диалога приводит к потере всего сгенерированного текста.

Выбор моделей

При текущей конфигурации памяти и в перспективе апгрейда (две плашки по 64 ГБ RAM, суммарно 128 ГБ), а также при альтернативном сценарии с дискретной видеокартой (VRAM), выбор распределяется следующим образом:

Вычислительный ресурсРекомендуемая LLMТокенов в сек. (TPS)Архитектурное поведение и качество
Текущий CPU

(Ryzen AI 9 + AVX-512 + Shared RAM)
qwen2.5-coder:14b15 – 25Оптимальный баланс. Быстрый отклик. Четко держит структуру markdown, но может точечно нарушить языковое табу (например, перевести .push на русский).
Текущий CPU

(Ryzen AI 9 + AVX-512 + Shared RAM)
qwen2.5-coder:32b4 – 8Тяжело для CPU. Высочайшее качество и строгое следование промпту, но TDD-цикл может казаться зависшим из-за низкой скорости.
Апгрейд до 128 ГБ RAM

(2x64 ГБ SODIMM DDR5 на CPU)
qwen2.5-coder:32b

(или qwen3-coder:30b)
8 – 14Целевой режим. Огромный объем RAM нивелирует раздувание KV-кэша на сложных многофайловых рефакторингах. Модель полностью загружается в память без риска своппинга.
Альтернатива на VRAM

(Дискретная GPU Nvidia с 16 ГБ VRAM)
qwen2.5-coder:14b

(полный инференс на GPU)
40 – 60Мгновенный TDD. Идеально для частых итеративных правок кода. Ограничение — 14B предел по объему памяти карты.
Альтернатива на VRAM

(Дискретная GPU Nvidia с 24 ГБ VRAM, e.g., RTX 3090/4090)
qwen2.5-coder:32b

(квантование Q4_K_M / Q8_0)
35 – 50Ультимативный индустриальный стек. Максимальное качество кодинга, мгновенный инференс, полное следование графу Tree-sitter.

3. Разделение Сессий: Борьба с Раздуванием Контекста

Почему автоматический Bash-скрипт ai_ollama_aider_generate_doc.sh запускает Aider дважды (сначала для RU, затем для EN), а не просит сгенерировать оба файла в рамках одной длинной интерактивной сессии?

Это обусловлено тремя критическими факторами ИИ-инженерии:

1. Математика KV-Кэша и Эффект «Потери в Середине» (Lost in the Middle)

Когда Aider инициализирует сессию, он строит карту репозитория (Repo Map) через Tree-sitter и подгружает типы types.ts, код декоратора и тесты. Это формирует тяжелый стартовый контекст.

  • Если заставить модель писать сначала русский текст, а затем английский в одном диалоге, контекстное окно раздувается лавинообразно.
  • К моменту генерации английской версии KV-кэш переполняется, локальная модель начинает «забывать» инструкции из начала диалога (из файла .aider.instructions.md) и начинает путать структуры заголовков или мешать языки.
  • Выигрыш сплит-сессий: Каждая сессия стартует с чистым контекстом истории диалога. Модель помнит исходный код, но сфокусирована только на одной задаче генерации.

2. Исключение Лингвистической Интерференции

У локальных моделей среднего размера (14B–32B) при генерации больших объемов текста на разных языках в рамках одного контекстного окна возникает «перетекание» токенов. Модель может начать комментировать английский код русскими словами или использовать кальку с русского синтаксиса в секциях английской документации. Разделение сессий гарантирует ментальную изоляцию: модель находится либо в жестком контуре [LANGUAGE: RUSSIAN], либо [LANGUAGE: ENGLISH].

3. Контроль Сбоев и Сохранение Git-Диффа

Если при генерации второго (английского) файла локальная Ollama выдаст ошибку или сбойнет по таймауту, первая (русская) версия уже будет физически записана на диск. Накопительный режим работы скрипта (когда git checkout -- . выполняется строго до начала всех сессий, а не между ними) позволяет Git атомарно отследить изменения в обоих файлах и упаковать их в единый патч-артефакт docs_multilang_update.patch без потери данных.

Разбор математики контекста на реальном примере

Эффективность разделения сессий наглядно подтверждается метриками токенов. В изолированном конвейере на первом шаге (RU-локализация) локальная модель получает 4.9k токенов входящего контекста (архитектура, исходный код, типы и системные правила) и генерирует 1.2k токенов ответа. На втором шаге (EN-локализация) Aider запускается с чистой историей диалога: на вход подается 6.0k токенов (исходный код плюс уже созданный на диске русский файл для синхронизации структуры), а модель выдает 977 токенов чистого английского текста. Если бы мы объединили эти шаги в одну общую интерактивную сессию, входящий контекст второго шага раздулся бы до 7.5k+ токенов за счет накопленной истории чата. Для локальной модели это критический порог: перегрузка KV-кэша приводит к эффекту «потери в середине» (Lost in the Middle), когда ИИ начинает игнорировать системные инструкции из начала диалога, путает структуру markdown-разметки и допускает лингвистическое перетекание (интерференцию) русского текста в английский код.

Итог: Сравнительный анализ подходов управления контекстом

Критерий сравненияНакопительные сплит-сессии (Выбранный подход)Единая долгоживущая сессия (Интерактивный чат)
Объем входящего контекста (Sent)Минимальный (4.9k / 6.0k). Модель видит только файлы на диске, история диалога пуста.Лавинообразный (7.5k+). Входной контекст постоянно растет за счет истории предыдущих ответов.
Качество следования промптуИдеальное. Системные правила .aider.instructions.md имеют максимальный приоритет в окне внимания модели.Деградирует. Инструкции «вымываются» из памяти модели под давлением сгенерированных портянок текста.
Лингвистическая изоляцияПолная. Модель находится в жестких рамках одного целевого языка на каждую сессию.Нарушена. Высокий риск смешивания языков и калькирования фраз из-за присутствия старого текста в чате.
Нагрузка на CPU (Ryzen AI 9)Низкая. Меньше токенов в памяти — быстрее пересчет матрицы внимания и выше скорость генерации (TPS).Высокая. Процессор тратит критически много времени на обработку тяжелого и грязного KV-кэша.
Устойчивость к сбоямВысокая. Падение второй сессии не уничтожает результаты первой; Git атомарно соберет частичный патч.Нулевая. Любая ошибка локальной Ollama в конце долгого диалога приводит к потере всего сгенерированного текста.