Перейти к содержимому

Понимание кодовой базы

Модель не «знает» ваш репозиторий. Всё, что она понимает, приходит из контекста запроса: открытые файлы, найденные фрагменты, имена символов, инструкции проекта. Отсюда практическое следствие — качество понимания определяется не моделью, а тем, как собран контекст.

Отсюда же типичная жалоба «ассистент не видит, что у нас уже есть такой хелпер». В 90% случаев хелпер существует, но не попал в контекст: он лежит в модуле, который поиск не вернул, а агент не догадался туда заглянуть.

МеханизмКак работаетСильная сторонаСлабое место
Окно целикомВ запрос кладут файлы или документацию полностьюМаксимальная точность, ничего не теряетсяДорого, ограничено размером окна
Поискgrep, glob, поиск по символам, эмбеддинги фрагментовМасштабируется на большой репозиторийПромахи поиска не видны: нашлось «похожее», а не нужное
Структурированный контекстAGENTS.md, README, архитектурные заметки, repo mapДешёво, задаёт рамку и соглашенияУстаревает без сопровождения

Рабочая система использует все три: структурированный слой отвечает на «как устроен проект», поиск — на «где это лежит», окно — на «покажи целиком и не ошибайся».

Два приёма заслуживают отдельного упоминания, потому что дают наибольший прирост на реальных репозиториях:

  • Repo map — компактная карта проекта: список файлов, классов, функций и их сигнатур без тел. Модель видит структуру целиком и сама просит открыть нужный файл. Так работает, например, Aider: карта строится по графу зависимостей и ранжируется относительно текущей задачи.
  • Индекс символов — точный поиск по определениям и ссылкам (LSP, tree-sitter, SCIP). Он не «семантический»: он отвечает на вопрос «где объявлен этот метод и кто его вызывает», и для кода это часто важнее векторного сходства.

Векторный поиск по коду полезен как дополнение — например, чтобы найти комментарии и документацию по смыслу, — но плохо заменяет навигацию по символам: getUserById и findUser семантически близки, а вызывать нужно ровно один.

  • Устаревший индекс. Код переименовали, индекс не обновился — агент правит несуществующий метод с уверенным видом.
  • Неявные соглашения. DI-контейнеры, магические хуки, регистрация через конфиг: связь между файлами не видна статически, и агент её не находит.
  • Монорепозитории. Границы сервисов и пакетов не выводятся из структуры папок; без карты зависимостей агент правит не тот пакет.
  • Только «похожее». Retrieval возвращает 20 файлов, из которых релевантны три, а модель уверенно опирается на остальные.
  • Отсутствие документации решений. Код отвечает «как», но не «почему». Агент предлагает решение, которое команда уже отвергла два года назад.
  1. Заведите AGENTS.md — короткий файл о том, как запускать сборку, тесты и линтеры, какие границы у модулей и чего делать нельзя. См. Контекст для агентов.
  2. Фиксируйте архитектурные решения. Один абзац в docs/specs/ или ADR дешевле, чем десять объяснений в чате, и работает для всех инструментов сразу.
  3. Держите имена честными. retryWithBackoff находит нужное в поиске; process2 — нет.
  4. Проверяйте качество поиска отдельно. Если инструмент приносит не те файлы, никакая модель не поможет. Это задача RAG, просто на корпусе кода.
  5. Следите за свежестью индекса. Для локальных индексов это вопрос настройки, для внешних — политики обновления.
  • Онбординг. «Объясни, как здесь проходит запрос от роутера до БД» — самый частый и самый полезный сценарий для нового человека в проекте.
  • Поиск точки изменения. «Где формируется цена заказа» — с проверкой по цепочке вызовов, а не по одному совпадению.
  • Анализ влияния. «Что сломается, если я поменяю сигнатуру этого метода» — ответ должен опираться на реальные вызовы, а не на догадку.
  • Миграции. «Где ещё используется этот устаревший API» — здесь поиск по символам точнее любого ассистента.