Проблема ориентации в масштабных репозиториях
Работая с LLM‑агентами, практически сразу сталкиваешься с «периодом адаптации»: первые несколько минут уходит на поиск точки входа, выяснение зависимостей и определение публичных API. В небольших проектах это лишь небольшая раздражающая задержка, а в монолитных системах стоимость токенов и внимания растёт экспоненциально. Каждый запрос к LLM, в котором требуется передать части кода, сразу же ограничивает объём контекста, а значит, и глубину анализа. Необходимо решение, которое бы позволило агенту быстро ориентироваться в структуре проекта, не переполняя контекстный буфер.
Что такое Data Structure Protocol
Data Structure Protocol (DSP) представляет собой внешний, версионируемый граф, описывающий структуру репозитория. Он хранит минимальный, но достаточный набор метаданных: сущности проекта (модули, классы, функции), их зависимости и публичные интерфейсы. Файл .dsp генерируется автоматически и находится рядом с кодом, поэтому всегда синхронен с текущей веткой. Для LLM‑агентов он выступает в роли «долговременной памяти» и индекса, позволяющего выполнять поиск без необходимости загрузки полного исходного дерева.
Структура графа и основные сущности
Граф DSP построен на простом принципе «сущность → зависимости». Каждая вершина содержит:
| Поле | Описание |
|---|---|
uid | Уникальный идентификатор (обычно хеш или путь) |
type | Тип сущности (module, class, function, variable) |
name | Читаемое название |
api | Описание публичных методов/полей |
imports | Список импортов (исходящие зависимости) |
exported_by | Объекты, которые экспортируют данную сущность |
description | Краткое свободное описание (может быть получено из docstring) |
Связи между вершинами отражают реальные зависимости кода: импорт, наследование, вызов функций и т.п. При необходимости граф можно расширять кастомными метками (например, «тестовый», «deprecated»), что сохраняет гибкость без усложнения основной схемы.
Как DSP сокращает токены и ускоряет поиск
LLM‑агент, получив доступ к файлу .dsp, может выполнить три базовых операции:
- Поиск по UID – мгновенно возвращает полную информацию о нужной сущности без загрузки её исходного кода.
- Навигация по графу – раскрывает входящие и исходящие зависимости, позволяя понять, как объект используется в проекте.
- Фильтрация по описанию – поиск по ключевым словам в
descriptionиapiпозволяет находить релевантные части кода без полного сканирования репозитория.
Эти операции реализуются в виде лёгкого API (обычно HTTP или локального CLI), а ответы формируются в компактных JSON‑структурах, которые занимают лишь несколько сотен токенов. Таким образом, агент получает контекстную «карту» проекта, а не сырые файлы, что существенно уменьшает нагрузку на модель.
Интеграция в рабочий процесс
Внедрение DSP в существующий пайплайн выглядит следующим образом:
- Генерация графа – при каждом коммите или в CI запускается скрипт, который анализирует дерево исходников (парсит импортные декларации, собирает docstring и метаданные) и создаёт/обновляет файл
.dsp. Инструменты часто используют AST‑парсеры для популярных языков (Python, JavaScript, Go). - Версионирование – файл включается в репозиторий, поэтому каждая ветка имеет собственный граф, отражающий её состояние. При слиянии веток происходит автоматическое объединение графов.
- Обращение из LLM‑агента – агент получает путь к
.dspи через предоставленное API запрашивает нужные данные. В случае, когда требуется посмотреть реальный код, агент может запросить конкретный файл по UID, получив лишь небольшую часть кода, необходимую для выполнения задачи. - Кеширование – результаты запросов к графу часто кешируются в памяти агента, что позволяет избежать повторных обращений к файлу в рамках одной сессии.
Пример использования
Предположим, агенту необходимо исправить баг в функции process_data модуля analytics.pipeline. Вместо того, чтобы передавать весь модуль, агент:
- Выполняет запрос
search("process_data")→ получает UIDanalytics.pipeline::process_data. - Запрашивает
node(uid)→ получает список импортов, экспортов и зависимостей. - На основе полученных связей определяет, какие другие модули используют
process_data, и какие типы данных ожидаются. - При необходимости запрашивает только фрагмент кода функции:
code(uid, lines=30).
В результате агент имеет полное представление о месте функции в архитектуре, не перегружая контекст модели лишними строками кода.
Преимущества и ограничения
Плюсы:
- Экономия токенов – контекст ограничивается лишь метаданными, а не полными файлами.
- Быстрая ориентация – граф позволяет мгновенно увидеть архитектурные связи.
- Версионируемость –
.dspхранится в репозитории, что гарантирует согласованность с кодовой базой. - Языковая независимость – схемы графа одинаковы для разных языков, требуется лишь соответствующий парсер.
Минусы:
- Накладные расходы на генерацию – парсинг большого проекта может занимать время, особенно в CI.
- Ограниченность информации – граф не хранит всю бизнес-логику, а лишь структуру; для глубоких аналитических задач всё равно понадобится доступ к коду.
- Поддержка обновления – при частых рефакторингах необходимо следить за синхронностью
.dsp.
Перспективы развития
С ростом популярности LLM‑агентов в DevOps и автоматизации разработки, протоколы вроде DSP становятся фундаментальными элементами инфраструктуры. Возможные направления развития включают:
- Автоматическое обогащение графа за счёт анализа runtime‑трассировок, что позволит добавить информацию о реальном использовании функций.
- Интеграция с системами управления знаниями (например, Confluence) для объединения кода и документации в едином графе.
- Поддержка дифференциальных запросов – возможность получать только изменённые части графа между версиями, что ускорит обновления в больших монорепозиториях.
Data Structure Protocol демонстрирует, как структурированный, версионируемый индекс может существенно снизить стоимость взаимодействия LLM‑агентов с крупными кодовыми базами, предоставляя им «долговременную память» и ускоряя процесс ориентации в проекте.