QuillCode: Архитектура кодинг-агента, инструменты и ошибки | AiManual
AiManual Logo Ai / Manual.
07 Мар 2026 Гайд

QuillCode: разбор архитектуры своего кодинг-агента, выбор инструментов и анализ ошибок

Пошаговый разбор архитектуры своего AI-агента для программирования. Выбор инструментов, AST-анализ, ratatui интерфейс и патчинг через diff.

Зачем строить своего кодинг-агента, если есть десятки готовых?

Все началось с банального раздражения. Я устал от агентов, которые пишут код, но не понимают его. От инструментов, которые предлагают исправления, ломающие сборку. От интерфейсов, где нельзя увидеть, что именно модель собирается изменить, пока не станет слишком поздно. Если вы читали мою статью про RTX 5090 в слезах, то знаете - локальные модели часто генерируют бессмыслицу. А облачные сервисы вроде тех, что описаны в гайде по AI-ассистентам, слишком абстрактны и не дают контроля.

QuillCode - это ответ. Агент, который не просто генерирует код, а понимает его структуру, показывает изменения до применения и работает в терминале. Почему в терминале? Потому что все настоящие разработчики в итоге возвращаются туда. Это не про красивый интерфейс - это про скорость и контроль.

Архитектура QuillCode: три слоя, которые не дадут агенту сойти с ума

Самый частый провал при создании агента - попытка сделать всё одной нейросетью. LLM получает задачу, генерирует код, вы его применяете... и ломаете проект. В QuillCode архитектура разделена на три независимых слоя, которые проверяют друг друга.

1Слой интерфейса и контроля (ratatui)

Здесь живет ratatui - библиотека для терминальных интерфейсов на Rust. Почему Rust? Потому что он не прощает ошибок, а в кодинг-агенте ошибки стоят дорого. Интерфейс показывает:

  • Исходный код с подсветкой синтаксиса
  • Предлагаемые изменения в виде diff (как в git)
  • Контекст задачи и историю диалога с LLM
  • Кнопки подтверждения или отмены каждого изменения

Этот слой - ваш щит от слепой веры в ИИ-генерацию. Вы видите каждую строчку, которую агент хочет изменить. Никаких сюрпризов.

2Слой анализа и трансформации (AST + diff)

Самый технический слой. Здесь код не текст, а дерево (Abstract Syntax Tree). Использую библиотеки наподобие tree-sitter для парсинга и difftastic для сравнения AST, а не просто текста.

Почему AST, а не строки? Потому что LLM часто меняет форматирование - добавляет лишние пробелы, переносы строк. Текстовый diff покажет эти изменения как значимые, хотя семантика кода не изменилась. AST diff игнорирует форматирование, показывает только структурные изменения.

Представьте, что LLM переформатировала функцию. Текстовый diff покажет 20 измененных строк. AST diff скажет "ноль изменений в логике". Это экономит часы ручной проверки.

3Слой исполнения и коммуникации (LLM Engine)

Движок, который общается с нейросетью. Поддерживает несколько провайдеров: OpenAI GPT-4.5 (актуально на март 2026), Anthropic Claude 3.7, локальные модели через Ollama. Ключевое - система промптов, которая заставляет LLM думать в терминах AST.

Вместо "напиши функцию" промпт говорит: "Проанализируй AST текущего файла, найди узлы X, Y, Z, предложи изменения в виде операций над AST". Это радикально меняет качество ответов.

Инструменты, которые не подведут в 2026 году

Выбор инструментов - это 80% успеха. Ошибетесь здесь - будете бороться с багами вместо работы. Вот стек, который прошел проверку боем.

Компонент Инструмент Зачем нужен
Интерфейс Ratatui 0.26+ (Rust) Терминальный UI, который не тормозит и не глючит. Поддержка вкладок, скроллинга, хоткеев.
Парсинг кода Tree-sitter с грамматиками для 15+ языков Превращает код в AST. Быстрее и точнее регулярных выражений.
Сравнение изменений Difftastic 8.0+ Diff на уровне AST. Игнорирует пробелы, показывает только смысловые изменения.
LLM API OpenAI GPT-4.5, Anthropic Claude 3.7 Модели 2026 года понимают код лучше предшественников. Контекст до 200k токенов.
Работа с файлами ignore 0.6+ (Rust) Учитывает .gitignore, чтобы не лезть в node_modules и вендорные пакеты.

Для доступа к мощным LLM вроде GPT-4.5 можно использовать OpenAI API (партнерская ссылка) - это дает стабильность и качество. Для локальных экспериментов подойдет Ollama с моделями CodeLlama 70B или DeepSeek Coder V3.

Цикл выполнения: как агент принимает решения

Архитектура - это скелет, а цикл выполнения - нервная система. Вот как работает QuillCode от запроса до изменения кода:

  1. Прием задачи: Вы вводите "добавь валидацию email в регистрационную форму". Интерфейс фиксирует это как цель.
  2. Сбор контекста: Агент сканирует проект, находит все файлы, связанные с регистрацией. Парсит их в AST.
  3. Анализ LLM: Движок отправляет LLM промпт с AST текущих файлов и задачей. Модель возвращает не код, а набор операций над AST: "добавить узел проверки здесь, изменить параметры функции там".
  4. Генерация diff: Система применяет операции к AST, создает новое дерево. Сравнивает старое и новое деревья через AST diff. Показывает изменения в интерфейсе.
  5. Человеческое подтверждение: Вы видите diff, нажимаете Y для принятия, N для отклонения, M для ручного редактирования. Это критически важно - никаких авто-применений.
  6. Применение и валидация: Если изменения приняты, система патчит исходные файлы. Затем запускает быстрые тесты или проверку синтаксиса, чтобы убедиться, что ничего не сломалось.
💡
Этот цикл предотвращает 90% ошибок, которые возникают при прямой генерации кода. Вы всегда видите, что меняется, и можете отменить на любом этапе. Если сомневаетесь, прочитайте мой разбор как ИИ увеличивает поток ошибок - там именно про отсутствие таких циклов контроля.

Ошибки, которые съедят ваше время (и как их избежать)

Я построил QuillCode за три месяца. Два из них ушли на борьбу с ошибками, которые не описаны в туториалах. Вот главные из них.

Ошибка 1: Прямая работа с текстом вместо AST

Как выглядит: Вы берете код как строку, отправляете в LLM, получаете новую строку, заменяете. Кажется логичным? Это ловушка.

Что пойдет не так: LLM перепишет комментарии, изменит форматирование, добавит лишние импорты. Diff будет показывать сотни изменений, хотя реальных правок - пять строк. Вы утонете в шуме.

Решение: Работайте только с AST. Заставляйте LLM возвращать операции над деревом, а не готовый код. Используйте AST diff для сравнения. Это сразу отсекает 70% мусорных изменений.

Ошибка 2: Отсутствие инкрементальности

Как выглядит: Агент каждый раз анализирует весь проект с нуля. Для небольшого репозитория работает, для монолита из 500 файлов - зависание на минуты.

Что пойдет не так: Разработчик ждет 30 секунд, чтобы добавить одну строчку. Бросает инструмент, возвращается к ручному кодингу.

Решение: Кэшируйте AST. При изменении файла пересчитывайте только его поддерево. Используйте инкрементальный парсинг tree-sitter. Храните историю изменений, чтобы LLM не анализировала одни и те же файлы повторно.

Ошибка 3: Слепая вера в промпты

Как выглядит: Вы написали промпт "ты - эксперт по Python", отправили задачу, получили код. Он выглядит нормально. Вы применяете его. Через час обнаруживаете, что он ломает наследование в трех соседних классах.

Это именно то, о чем я писал в статье про зеленый CI и пустую архитектуру - ИИ создает долг, который не виден сразу.

Решение: Промпты должны быть конкретны и ограничивать модель. Вместо "напиши функцию" - "проанализируй AST этих трех файлов, найди все вызовы метода register, предложи изменение только для валидации email, не затрагивая другие параметры". Чем уже фокус, тем меньше побочных эффектов.

Ошибка 4: Игнорирование состояния проекта

Как выглядит: Агент работает с файлом изолированно. Предлагает добавить библиотеку, которая уже есть в проекте. Или меняет API, забывая про типизацию в соседних модулях.

Решение: Всегда анализируйте контекст. Проверяйте зависимости в package.json/pyproject.toml. Смотрите на импорты и экспорты. Используйте языковые серверы (LSP) для понимания типов. Это сложнее, но без этого агент будет писать код, который не интегрируется.

Собираем своего агента: пошаговый план

Теория без практики - просто болтовня. Вот как собрать базовую версию QuillCode за неделю (если знаете Rust).

1День 1-2: Каркас на Rust

Создайте новый крейт. Добавьте зависимости: ratatui, tokio для асинхронности, serde для конфигурации. Настройте базовый интерфейс с двумя панелями - исходный код и diff.

[dependencies]
ratatui = "0.26"
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

2День 3: Интеграция tree-sitter

Добавьте парсинг для одного языка (начните с Python или JavaScript). Научитесь загружать файл, строить AST, обходить дерево. Не пытайтесь сразу поддерживать все языки.

let mut parser = tree_sitter::Parser::new();
parser.set_language(tree_sitter_python::language()).unwrap();
let tree = parser.parse(source_code, None).unwrap();
let root_node = tree.root_node();
// Обход дерева...

3День 4: Подключение LLM API

Выберите провайдера. Для начала используйте OpenAI API (партнерская ссылка) - у них стабильный интерфейс. Напишите функцию, которая отправляет промпт с AST и возвращает описание изменений. Ключевое - формат ответа: JSON с операциями, а не код.

4День 5: Diff и применение изменений

Интегрируйте difftastic или напишите простой diff для AST. Показывайте изменения в интерфейсе. Реализуйте логику применения патчей - это проще, чем кажется, потому что у вас уже есть AST операции.

5День 6-7: Отладка и полировка

Протестируйте на реальных задачах. Найдете кучу краевых случаев - пустые файлы, синтаксические ошибки, экзотические конструкции. Добавьте обработку ошибок. Настройте конфигурацию (API ключи, игнорируемые пути).

Не стремитесь к совершенству с первой версии. Лучше рабочий прототип, который делает одну вещь хорошо, чем монстр, который пытается делать всё и ничего не завершает.

Что дальше? Агент, который не устареет завтра

Самая большая иллюзия - что можно построить агента раз и навсегда. Языки меняются, библиотеки обновляются, LLM становятся умнее. QuillCode в марте 2026 - это не финальный продукт, а платформа для экспериментов.

Следующий шаг - интеграция с языковыми серверами (LSP). Чтобы агент понимал не только синтаксис, но и семантику: типы, интерфейсы, документацию. Потом - обучение на вашем коде, чтобы он знал ваши паттерны и антипаттерны. Как в статье о Code Smells и паттернах - агент должен учиться на ваших ошибках.

Но главное - не дать агенту превратиться в того самого "пьяного стажера". Всегда оставляйте последнее слово за человеком. Всегда показывайте diff. Всегда позволяйте откатиться. ИИ - инструмент, а не замена. Когда вы это понимаете, архитектура становится не набором компонентов, а философией контроля в мире, где код генерируется быстрее, чем мы успеваем его проверить.

P.S. Если после прочтения вам кажется, что это слишком сложно - возможно, вы правы. Но альтернатива - использовать готовые инструменты, которые создают технический долг быстрее, чем вы его осознаете. Выбор за вами.

Подписаться на канал