Есть паттерн, который видит кажд��й, кто работает с агентами: первые 5–15 минут уходят не на задачу, а на “ориентацию”. Где точка входа? Откуда растут зависимости? Почему эта библиотека, а не другая? Кто считает это публичным API? В маленьком проекте раздражает. В большом — превращается в постоянный налог на токены и внимание.
DSP (Data Structure Protocol) “выносит карту проекта наружу” — в простой, версионируемый, языковой граф, который живёт рядом с кодом и доступен агенту как постоянная память.
k-kolomeitsev/data-structure-protocol
Цель в архитектуре сформулирована так:
1) Цель и границы
Цель DSP — хранить минимальный, но достаточный контекст о репозитории/системе артефактов в виде графа «сущности → зависимости/публичный API», чтобы LLM могла:
- быстро находить нужные фрагменты по UID,
- понимать «зачем» сущности существуют и «как» они связаны,
- не требовать загрузки исходников целиком в контекстное окно.
DSP — это долговременная память и индекс проекта для LLM. Агент может в любой момент выполнить поиск (grep) по проекту, найти нужные сущности по описаниям/ключевым словам и от найденного UID раскрутить весь граф связей: входящие зависимости, исходящие импорты, реципиентов через exports. Это заменяет необходимость «помнить» структуру проекта или загружать его целиком — вся карта проекта всегда доступна через .dsp.
Что такое DSP
DSP = граф сущностей + причины связей
DSP хранится в каталоге .dsp/. Каждая “сущность” (entity) получает стабильный UID и небольшой набор файлов:
-
description: где находится (source), что это (kind), зачем существует (purpose). -
imports: кого эта сущность использует (UID-ссылки). -
shared: что она выставляет как публичный API (экспорты). -
exports/: обратный индекс — кто импортирует эту сущность и зачем (текстwhyрядом с потребителями).
В больших системах особенно важна одна деталь: DSP фиксирует не только “что зависит от чего”, но и почему. Это резко снижает количество догадок в задачах рефакторинга, миграций и удаления легаси.
Сущностей всего два базовых типа
-
Object: модуль/файл/класс/конфиг/ресурс/внешняя зависимость — “всё, что не функция”.
-
Function: функция/метод/хэндлер/пайплайн.
Отдельный плюс: DSP язык-агностичен. Он одинаково работает с TS/JS, Python, Go, инфраструктурными YAML, SQL, ассетами и так далее. Причём в архитектуре прямо прописана “полнота импортов”: если что-то импортируется — оно должно существовать в .dsp, включая стили, картинки, JSON, wasm и прочие артефакты. Это важнее, чем кажется: агенты чаще теряют не код, а именно ресурсные зависимости.
Почему UID — центральная идея
DSP строится на идентичности по UID, а не по пути. Путь — это атрибут. UID — это “личность” сущности.
-
Переименовали файл → делаете
move-entity, UID остаётся прежним. -
Переставили код / отформатировали → UID прежний.
-
UID меняется только когда меняется назначение (semantic identity): модуль реально стал про другое.
Чтобы привязать UID к сущностям внутри файла (экспортируемым функциям/классам), используется простой маркер-комментарий @dsp <uid> прямо в исходнике. Прагматичное решение: не зависит от строк, работает в любом языке, ищется grep’ом.
Как агент “ходит” по DSP вместо бесконечного чтения кода
Типичный цикл работы агента в DSP-проекте выглядит так:
-
Найти сущность:
searchпо ключевым словам илиfind-by-sourceпо пути файла. -
Понять границы: прочитать
description,shared,imports. -
Собрать контекст пакетами: вместо “давай весь репозиторий” агент подтягивает только нужные узлы и 1–2 уровня зависимостей.
-
Оценить влияние: кто потребляет сущность и зачем (
get-parents/get-recipients), ес��ь ли циклы, есть ли “сироты”.
Примеры команд (в PowerShell-стиле; CLI поставляется внутри скилла):
python ..cursorskillsdata-structure-protocolscriptsdsp-cli.py --root . search "авторизация"
python ..cursorskillsdata-structure-protocolscriptsdsp-cli.py --root . get-entity obj-a1b2c3d4
python ..cursorskillsdata-structure-protocolscriptsdsp-cli.py --root . get-children obj-a1b2c3d4 --depth 2
python ..cursorskillsdata-structure-protocolscriptsdsp-cli.py --root . get-recipients obj-a1b2c3d4
python ..cursorskillsdata-structure-protocolscriptsdsp-cli.py --root . get-path obj-a1b2c3d4 func-7f3a9c12
Что добавляет скилл data-structure-protocol (и почему это важнее, чем кажется)
Архитектура DSP — это правила. Но агент без дисциплины легко их нарушает: лезет в код наугад, тащит полрепо в контекст, не обновляет индекс, ломает целостность графа.
Скилл закрывает именно операционную часть:
-
Вшивает Agent Prompt: “перед изменением — найди сущности; при создании — зарегистрируй; при импорте — добавь
why; при удалении — сделай каскадную очистку”. -
Даёт справочники в
references/: формат хранения, bootstrap-алгоритм (DFS от entrypoint’ов), семантика операций. -
Поставляет production-ready CLI
scripts/dsp-cli.py, который реализует операции изARCHITECTURE.mdи умеет навигацию/диагностику (cycles/orphans/stats).
DSP становится не “документом”, а живым контрактом, который агент исполняет в ходе работы — и поддерживает консистентность .dsp без ручного вмешательства.
Цена входа: bootstrap большого проекта будет дорогим
Да. Первичный bootstrap на большом репозитории стоит дорого — временем, вниманием и токенами.
Почему:
-
Нужно определить root entrypoint’ы (а в монорепо их много).
-
Нужно пройти зависимости в глубину (DFS), зафиксировать все достижимые модули/файлы/ресурсы.
-
Для каждого узла нужно написать минимальное, но точное
purpose. -
Нужно дисциплинированно заполнить причины (
why) для связей импорта — иначе половина ценности DSP пропадает. -
Иногда нужно проставить
@dspмаркеры в исходниках для экспортируемых сущностей (чтобы UID был “якорем” в коде).
На больших системах это реально может быть отдельным мини-проектом.
Почему это окупается (и обычно окупается быстрее, чем кажется)
Ценность DSP не в “красивой структуре”. Она в экономике работы агентов:
-
Меньше токенов на ориентацию: вместо повторного “прогрева” контекста агент читает короткие
description/imports/shared/exportsи берёт ровно те файлы, которые нужно менять. -
Контекст не растворяется между задачами:
.dsp— это внешняя память, не зависящая от текущего окна контекста и настроения модели. -
Быстрый поиск по смыслу:
searchнаходит сущности по ключевым словам, аexports/отвечает на вопрос “зачем это тут вообще”. -
Рефакторинг становится безопаснее: impact analysis дешевеет — быстро получаешь всех реципиентов сущности и проходишься по ним точечно.
-
Внешние зависимости прозрачны: внешние пакеты фиксируются как
kind: external, не раздувая граф, но остаются навигируемыми черезexports index.
И важная вещь из архитектуры — контроль гранулярности, чтобы DSP не превратился в свалку:
10) Гранулярность и политика минимального контекста
- Полнота по файлам, но не по коду внутри файла. «Полнота импортов» (раздел 2) означает, что каждый файл/модуль, который импортируется в проекте, должен иметь Object в .dsp. Это про файлы и модули — не про каждую переменную внутри файла. Внутри одного файла отдельный UID получает только та сущность, которая шарится наружу (shared) или используется из нескольких мест. Локальные переменные, внутренние хелперы, приватные поля — остаются частью родительского Object, без собственного UID. Если гранулярность растёт — что-то делается не так.
- Обновление реципиентов — через exports. Для обновления библиотеки/модуля/символа достаточно открыть exports импортируемой сущности и получить список импортёров (реципиентов) по UID, а затем точечно обновить их.
- Отслеживание изменений. По git diff видно, что поменялось — создался новый файл, изменилась функция или объект. Изменённые файлы отдаются в LLM для обновления DSP. Изменения внутри функций зачастую не требуют обновления DSP, потому что описание фиксирует назначение, а не детали реализации — если только не добавились/убрались импорты.
Именно это делает DSP жизнеспособным на дистанции: индекс остаётся компактным, обновления — редкими и осмысленными.
Когда DSP особенно хорошо “заходит”
-
Большие монолиты и монорепо, где контекст “не влезает никогда”.
-
Долгоживущие продукты, где агенты будут работать месяцы и годы, а не один спринт.
-
Команды, которые часто делают рефакторинги/миграции/замены зависимостей.
-
Проекты со сложной ресурсной частью (ассеты/конфиги/генерация), которую агентам трудно держать в голове.
Итог
DSP — это попытка сделать для LLM-агентов то, что люди давно делают неформально: держать в голове карту системы. Только вместо головы — граф на диске, вместо “я так помню” — минимальные описания, связи и причины, вместо “прочитай весь проект” — точечная навигация от entrypoint’ов.
Да, бутстрап на большом проекте будет дорогим. Но если вы реально планируете использовать агентов системно, эта цена обычно возвращается через:
-
меньше токенов на ориентацию,
-
меньше потерь контекста между задачами,
-
более быстрый поиск нужных модулей/зависимостей,
-
более предсказуемое выполнение задач (особенно рефакторинговых).
Автор: kolkoni


