← Назад Harupa
2026-07-04RU EN UA BY PL

My Architect, частка 10: памяць пра рэпазіторый — код-граф, якому забаронена верыць на слова

Гэта дзясяты артыкул серыі пра My Architect і працяг дзявятага — гісторыі скіла recursive-context, які вучыць агента дысцыпліне працы з данымі, большымі за кантэкстнае акно. На гэты раз: чатыры рэлізы за адзін дзень (v1.14.0 → v1.16.1), якія далі агенту персістэнтны граф коду, і кантраляваны эксперымент, які вымераў яго рэальную карысць замест пераказу чужога маркетынгу. Усе лічбы нашых прагонаў — з тэлеметрыі рэальных запускаў 2026-07-03; факты пра Graphify — з яго README і жывой устаноўкі; ацэнкі пазначаны яўна. Нічога не дадумана.

Пралог. Агент з амнезіяй

У LLM-агента няма памяці паміж сесіямі. Кожная новая размова пра твой рэпазіторый пачынаецца з чыстага аркуша: агент зноў grep'ае, зноў чытае тыя ж файлы, зноў будуе ў галаве тую ж карту — і выкідае яе ў канцы сесіі. Мы гэта вымералі на ўласным рэпазіторыі: збор фактаў пра добра знаёмую кодавую базу каштаваў ~77 тысяч токенаў і 20 выклікаў інструментаў — і так кожную сесію, па крузе.

Асобная бяда — пытанні кшталту «што зламаецца, калі я памяняю сігнатуру гэтай функцыі?». Адказ патрабуе ведаць усіх спажыўцоў сімвала. Grep знаходзіць іх, але за цану поўнага праходу; а галоўнае — у агента няма месца, дзе гэта веданне магло б перажыць сесію.

Вакол гэтага болю ўжо вырас рынак інструментаў «код-як-граф» — з лозунгамі ўзроўню «90% эканоміі токенаў» і «агент у 500 разоў разумнейшы». Нам патрэбныя былі не лозунгі, а адказ на два пытанні: якія класы памылак гэта прыбірае і дзе эканомія сапраўдная, а дзе папулізм. Спойлер: у канцы артыкула — табліца з вымеранымі лічбамі.

Раздзел 1. Не будаваць сваё: Graphify

Інструмент для персістэнтнай памяці пра код ужо існуе — Graphify (open source, MIT, ~77k зорак): парсіць код tree-sitter'ам цалкам лакальна (36 моў, без API-выклікаў і тэлеметрыі), складае граф сімвалаў і сувязяў у graphify-out/graph.json, побач кладзе інтэрактыўную HTML-карту і гатовую тэкставую справаздачу пра рэпазіторый. Свежасць індэкса падтрымліваюць git-хукі; для каманднай працы ёсць merge-driver, каб граф можна было каміціць без канфліктаў.

Мы свядома не сталі будаваць свой граф-рухавік. Замест гэтага навучылі наш скіл decomposition-дысцыпліны распазнаваць індэкс, які ляжыць у рэпазіторыі, і правільна ім карыстацца. Уся фіча — гэта markdown-даведнік з правіламі плюс некалькі радкоў-указальнікаў: у плагіна не з'явілася ніводнай жорсткай залежнасці. Няма графа — усё працуе як раней; няма графа, а задача цяжкая — агент адзін раз прапануе ўладальніку паставіць і сабраць (і зробіць гэта сам пасля «так»; маўклівыя ўстаноўкі забаронены).

Наколькі гэта танна на практыцы: на нашым рэпазіторыі (351 файл) зборка графа заняла секунды і дала 2655 вузлоў, 4948 рэбраў і 153 аўтаматычна знойдзеныя кластары — 6.1 МБ на дыску, нуль API-выдаткаў. Адзін запыт пасля гэтага выглядае так:

$ graphify explain "getBlockers"
Node: getBlockers()   Source: src/hierarchy/model.ts L419   Degree: 9
  <-- NodePropertiesPanel.tsx [imports]
  <-- validator.ts [imports]
  <-- validateHierarchy() [calls]
  ...

Секунда — і ў агента ўсе спажыўцы функцыі са шляхамі. Тое, што раней патрабавала поўнага праходу па рэпазіторыі, стала запытам. Важная дэталь для ўсёй далейшай размовы пра эканоміку: сам граф токенаў не траціць наогул — і зборка, і запыты гэта лакальныя ўтыліты, а не выклікі мадэлі.

Раздзел 2. Правіла, дзеля якога ўсё задумвалася

Індэкс — гэта кэш, а кэш умее хлусіць: ён адстае ад коду паміж перазборкамі. Таму ў цэнтры фічы не каманды, а тры правілы:

  1. Граф — навігацыя і кандыдаты, НЕ крыніца фактаў. Адказ графа кажа, КУДЫ глядзець; фактам становіцца толькі тое, што пацверджана жывым файлам. Кантракт фактаў ({сцвярджэнне, шлях-доказ, упэўненасць}) не змяніўся ні на ёту.
  2. Freshness-check абавязковы. Найперш агент параўноўвае час зборкі індэкса з часам апошняга каміту. Пратух — сказаць уголас, прапанаваць уладальніку перазборку (а калі git-хук не стаіць — адзін раз прапанаваць і хук, каб пратуханне не паўтаралася кожную сесію), кандыдатаў пазначаць «па састарэлым індэксе».
  3. Verify — эканомна, рэгіёнамі. Кандыдат прыходзіць з шлях:радок — праверка чытае ±30 радкоў вакол, а не файл цалкам. Без гэтага правіла праверка з'ядае ўсё, што граф зэканоміў на пошуку.

Раздзел 3. Як мы гэта тэставалі

Скіл — гэта тэкст, які павінен мяняць паводзіны мадэлі. Тэкст не скампілюеш і юніт-тэстам не пакрыеш, таму праверка — слаёная, і кожны слой ловіць свой клас памылак. Жалезнае правіла ўсіх рэлізаў: тэсты пішуцца да правак, і спярша фіксуецца «як агент памыляецца без іх».

Слой 1 — трыгеры: ці загрузіцца скіл сам. Суддзі бачаць толькі імя і апісанне скіла (роўна тое, што бачыць Claude Code пры выбары) плюс запыт; тры незалежныя суддзі на кейс; у наборы — пазітывы на дзвюх мовах, падступныя амаль-трапленні («пераймянуй зменную» — падобна на impact-пытанне, але скіл павінен маўчаць) і крос-праверка, што новы скіл не крадзе трыгеры суседняга. Фінальны прагон: 30/30 галасоў роўна па ключы.

Слой 2 — паводзіны: ці выконваецца дысцыпліна. Выканаўца чытае скіл з дыска і піша план па сцэнарыі; незалежны грэйдар радок за радком звярае з загадзя запісанымі сцвярджэннямі. Кожны сцэнарый б'е ў канкрэтны спосаб зламацца: свежы граф → запыты да grep, але факты па файлах; пратухлы → заўважыць і не давяраць; графа няма → прапанаваць адзін раз і не ставіць моўчкі.

Слой 3 — злое рэўю самога тэксту. Асобны рэўюер не чытае скіл ветліва — ён яго выконвае: запускае шэл-сніпеты на межавых уваходах, падымае docker, звярае кожнае імя каманды з README апстрыму.

Слой 4 — live-прагоны: сапраўдная ўстаноўка (па згодзе), сапраўдны граф, сапраўдны агент на сапраўдным рэпазіторыі.

Слой 5 — кантраляваны эксперымент (раздзел 5): калі якасныя праверкі пройдзены, застаецца пытанне «а колькі гэта каштуе?» — і на яго адказвае толькі A/B з тэлеметрыяй.

Раздзел 4. Што злавілі да эксперыменту. Чатыры гісторыі

Пастка ўмоўнага роўтынгу. Мы дадалі галінку «графа няма → прапануй уладальніку сабраць» — а рэўю паказала, што яна недасяжная: усе ўказальнікі, якія вядуць агента ў даведнік графа, пачыналіся са слоў «калі граф ЁСЦЬ». Агент без графа проста не адкрыў бы файл з прапановай. Класічная памылка: новая галінка ёсць, але ўсе дарогі да яе гейцяцца на стан, пры якім яна не патрэбна.

Баг, які жыў бы толькі на Linux. Сніпет freshness-праверкі выкарыстоўваў macOS-сінтаксіс stat з фолбэкам на GNU-варыянт. Рэўюер падняў docker і паказаў: у GNU stat той жа флаг значыць іншае — каманда «паспяхова» друкуе смецце, і гейт вечна адказвае STALE. На любой Linux-машыне graph-first не ўключыўся б ніколі, ціха.

Апстрым ведае лепш. Мы раілі хаваць graphify-out/ у .gitignore — а README Graphify рэкамендуе камандам граф каміціць (агульная карта; канфлікты вырашае іх merge-driver). Наша парада моўчкі выкідала камандны сцэнарый; цяпер прапанова шчыра дае выбар. Заадно высветлілася, што PyPI-пакет называецца graphifyy — з дзвюма «y».

Выканаўца, які не паверыў умове задачы. Сцэнарый паводзінскага тэсту сцвярджаў «граф свежы» — агент праверыў mtime па-сапраўднаму, выявіў, што граф яго рэальнага асяроддзя пратух (нашы ж каміты паспелі яго абагнаць), і апрацаваў разыходжанне па рэцэпце. Дысцыпліна «не давярай, правярай» спрацавала нават супраць тэксту задання.

Асобным заходам мы правялі аўдыт «да чаго агент не дадумаецца сам» — і закрылі тры прабелы: impact-пытанні атрымалі ўласны ўваход у скіл (раней «што зламаецца, калі памяняю X?» па-за трэкаванай задачай не вяло да графа наогул), гатовая справаздача GRAPH_REPORT.md цяпер чытаецца першай пры аўдыце (зводка ўжо палічана — неразумна збіраць яе запытамі), а пры пратухлым графе без хука агент прапануе хук.

Раздзел 5. Эксперымент: мераем самі, а не цытуем маркетынг

Дызайн. Незнаёмы абедзвюм групам буйны рэпазіторый — NestJS, 2125 файлаў (на парадак больш за наш). Два ідэнтычныя клоны: плячо A — з графам (12309 вузлоў, 22895 рэбраў, 738 кластараў; сабраны tree-sitter'ам за секунды, $0), плячо B — без. Тры класы пытанняў, промпты ідэнтычныя з дакладнасцю да шляху, пра граф — ні слова (плячо A абавязана знайсці яго само па дысцыпліне скіла), адна мадэль (Sonnet), адзін кантракт вываду (≥8 фактаў са шляхамі + шчырае пакрыццё + журнал усіх выклікаў). Метрыкі — токены і выклікі з тэлеметрыі, якасць — колькасць фактаў і выбарачная зверка шляхоў.

Вынікі:

Клас пытанняA (граф)B (без графа)Дэльта
Impact: «спажыўцы ModuleRef, што зламаецца пры змене get()»71.4k токенаў · 26 выклікаў · сола · 12 фактаў71.9k · 31 выклік · сола · 14 фактаўпарытэт (A: −16% выклікаў і часу)
Разуменне: «HTTP-request lifecycle end-to-end»75.9k · сола · 13 фактаў56.1k зверху + 205.8k у схаваных суб-агентах (вымерана) ≈ 262k · 21 фактграф таннейшы ў ~3.5× (−71%)
Карта: «packages/core: модулі, API, рызыкі»≈445k (8 суб-агентаў, ацэнка*) · 24 факты≈500k (9 суб-агентаў, ацэнка*) · 25 фактаў~парытэт

\* Ацэнка ўкладзенага кошту адкалібравана на адзінай дакладна вымеранай ячэйцы (Q2-B: 205 759 токенаў на 5 агентаў) і пазначана як ацэнка; напрамак хібнасці невядомы.

Вывад 1: эканомія сапраўдная, але селектыўная. На класе «зразумець падсістэму» — вымераныя −71%: не таму што запыты графа таннейшыя за grep, а таму што граф адразу звузіў корпус, і адзін агент справіўся там, дзе плячо B было вымушана моўчкі разгарнуць пяцярых. На impact-класе эканомія — нуль (grep па літаральным імені сімвала танны нават на 2125 файлах; выйгрыш графа там — паўната і хуткасць, не токены). На поўным аўдыце — нуль (аркестрацыя патрэбна абодвум; граф дае гатовае партыцыянаванне і кандыдатаў, не зніжку). Універсальнага множніка «90%» не існуе — існуе клас задач.

Вывад 2, метадалагічны — схаваная аркестрацыя. Па верхніх лічбах плячо B на «разуменні» выглядала таннейшым (56k супраць 76k) — пакуль мы не ўскрылі ў яго транскрыптах 205.8k токенаў укладзеных агентаў. Прыгожыя параўнанні «агент з інструментам супраць агента без» сістэматычна недаацэньваюць плячо, якое ціха дэлегуе. Шчыры замер абавязаны лічыць усё дрэва агентаў — падазраём, што немалая частка папулярных лічбаў гэтым не займаецца.

Дысцыпліна недаверу да графа адпрацавала і ўнутры эксперыменту: плячо A на impact-пытанні адсеяла ілжывастаноўчых кандыдатаў графа (barrel-імпарты) жывым grep'ам, а на аўдыце верыфікавала цыклы з графа і два ілжывыя адкінула. Граф даваў наводкі — фактамі станавілася толькі пацверджанае.

Бонус, якога не заказвалі: аўдыт-агенты пляча B знайшлі ў ядры NestJS два падобныя на сапраўдныя багі (прысваенне ў Map праз індэкс, якое ніколі не чытаецца; return замест continue, які моўчкі абразае рэгістрацыю middleware) — незапланаванае пацверджанне, што глыбіня аўдыту ў дысцыпліны сапраўдная.

Абмежаванні — шчыра: n=1 на ячэйку (без дысперсіі), адзін рэпазіторый, адзін тыр мадэлі; укладзены кошт дзвюх ячэек ацэнены па каліброўцы на адзінай дакладна вымеранай (і пазначаны як ацэнка); плечы самі выбіралі стратэгію — гэта фіча дызайну (мераем сістэму цалкам), але яна змешвае «граф» з «рашэннем не аркестраваць»; доўгатэрміновая амартызацыя паўторных сесій гэтым эксперыментам не мералася — яна застаецца гіпотэзай з моцным апрыёры (~77k «падатку на перавывучэнне» за сесію супраць аднаразовай бясплатнай зборкі).

Раздзел 6. Было → стала

БылоСтала
Веданне рэпо паміж сесіяміне перажывае сесію; ~77k токенаў на перавывучэннеграф збіраецца за секунды адзін раз; кандыдаты — імгненныя бясплатныя запыты
«Хто кліча X / што зламаецца?»поўны grep-праход; па-за трэкаванай задачай агент пра граф не ведаўсамастойны ўваход: graphify affected "X" → verify рэгіёнамі ±30 радкоў — уключна з indirect-сувязямі, якіх grep не бачыць
Разуменне падсістэмы на вялікім рэпосхаваны fan-out суб-агентаў, ~262k токенаўадзін агент з графам, ~76k — −71%, вымерана
Аўдыт рэпазіторыяразведка з нуляGRAPH_REPORT.md (гатовыя хабы, кластары, нечаканыя сувязі) чытаецца першым
Давер да індэксаfreshness-гейт; пратух → уголас + прапанова перазборкі і хука; факты — толькі па жывых файлах
Устаноўкапа яўным «так» уладальніка: агент прапануе адзін раз, ставіць і збірае сам; адмова паважаецца ўсю сесію

Эпілог

Формула фічы: існуючы інструмент (Graphify) + дысцыпліна абыходжання з ім (наш скіл) + слаёныя тэсты, якія не вераць нікому — ні аўтару тэксту, ні прыгожаму сніпету, ні ўмове ўласнага сцэнарыя, ні, як высветлілася ў раздзеле 5, верхняму радку чужога бенчмарка. З усіх істотных знаходак чатырох рэлізаў ніводная не была знойдзена «вычыткай» — усё прынесла выкананне: суддзі, грэйдары, docker, жывыя прагоны і тэлеметрыя эксперыменту.

Свядома адкладзена: трыяж pull request'аў праз граф (у нас няма PR-працэсу — інструмент без спажыўца не робім), пятля памяці запытаў save-result/reflect (асобная размова) і паўтарэнне эксперыменту з n>1 і другім рэпазіторыем — калі селектыўная эканомія пацвердзіцца і там, у «90% хайпу» з'явіцца шчырая замена: «−70% на класе „разуменне“, нуль на астатніх».

Як паспрабаваць

Код-граф едзе ў плагіне my-architect пачынаючы з v1.14.0 (актуальная — v1.16.1). Рукамі клікаць не трэба: скіл сам распазнае граф у рэпазіторыі, а на цяжкай задачы без графа — сам прапануе паставіць.

  1. Завядзі акаўнт на my-architect.app, вазьмі токен на старонцы API Keys і экспартуй яго ў той жа сесіі, дзе запускаеш Claude Code:

``bash export MCP_API_KEY=mcp_ВАШ_ТОКЕН ``

  1. Дадай маркетплейс і пастаў плагін:

`` /plugin marketplace add d7561985/my-architect-marketplace /plugin install my-architect@my-architect-marketplace ``

  1. Граф можна сабраць і рукамі, не чакаючы прапановы агента:

``bash pip install graphifyy && graphify build . ``

  1. Ужо стаіць плагін? /plugin marketplace update my-architect-marketplace/plugin update my-architect.

---

Факты і спасылкі