Обновить

Я потратила $9 000 на ИИ-агентов и в итоге сделала Crossweft — проверку того, что они ломают между файлами

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели13K
Всего голосов 7: ↑5 и ↓2+6
Комментарии17

Комментарии 17

Отличная статья! Проблема «швов» (seams), которые ломают AI-агенты из-за ограниченного контекста, сейчас одна из самых острых. Но эта боль начинается еще раньше — на уровне архитектуры и ТЗ. Агент может легко описать систему как «высокодоступную», упустив, что там «один мастер БД + асинхронная репликация + ручные бэкапы по SSH». Это классический SPOF (ровно тот, что положил GitLab на 6 часов в 2017-м), и тесты это не поймают. Выход, который мы видим — двухуровневая защита: 1. До кода: Детерминированная проверка ТЗ и архитектурных описаний на логические противоречия (мы делаем это через взвешенные паттерны + LLM-дебаты, находя такие «бомбы» за секунды). 2. В коде: Ваш подход с  crossweft  и жесткими сторожами (guards) на границах компонентов. Если связать валидацию архитектуры с вашими хуками, можно вообще блокировать генерацию кода агентом, если его предложение противоречит базовым принципам отказоустойчивости. Планируете ли вы в будущем валидировать сами архитектурные описания (ADR/README), а не только код? Было бы круто обсудить стык наших подходов!

Спасибо! Частично это уже есть: Crossweft проверяет документацию там, где в ней записано конкретное значение. Команды из README обязаны существовать в CLI, версия в трёх файлах сверяется, каждое утверждение карты привязано к литералу в коде. А вот «высокодоступная система» — это уже не значение, а суждение, тут без модели не обойтись. Crossweft я специально держу детерминированным, чтобы зелёная проверка значила одно и то же при каждом запуске. Ваш слой до кода выглядит хорошим соседом: если ваша проверка умеет выдавать код возврата, её можно подключить к тем же хукам как ещё один валидатор, раннер crossweft validators для этого и сделан. Напишите в issues на GitHub, давайте посмотрим.

Да! на уровне кода и конфигов детерминизм — это закон, и  crossweft  должен давать предсказуемый, воспроизводимый результат. ИИ-слой как раз и задуман как «сосед» сверху: он ловит смысловые противоречия (вроде «высокой доступности» на одном мастере БД) до того, как агент вообще сгенерирует код или конфиг, который потом будет проверять  crossweft . Насчет интеграции: да, наш анализатор умеет отдавать стандартные exit codes (например,  1  при обнаружении критических архитектурных рисков в описании). Идея подключить его как кастомный валидатор через  crossweft validators  звучит отлично и очень логично. Обязательно открою issue на GitHub с конкретным примером пайплайна: как AI-валидатор может блокировать коммит еще на этапе описания архитектуры, не давая агенту даже начать писать код с фундаментальными изъянами. Спасибо за открытый диалог и за крутой инструмент!

https://github.com/AnastasiyaW/crossweft/issues/1

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

Подключить анализатор при этом можно и без изменений. crossweft validators запускает любой validate_*.py, если тот выполняет простой контракт из docs/validators.md: умеет --self-test, печатает строку SCANNED и возвращает ненулевой код при находке. Обёртка вокруг вашего CLI займёт пару десятков строк. Если соберёте такой пример у себя в репозитории, киньте ссылку, будет интересно посмотреть, что он находит на реальных задачах.

Отличная статья!) Подскажите, вкратце вопрос: Crossweft интегрируется в реальный CI/CD? Есть ли возможность автоматического прогона регрессионных тестов для ИИ-агентов при изменении схемы данных, или сейчас инструмент больше ориентирован на runtime-мониторинг и алертинг разработчиков?

Спасибо! Да, в CI он встаёт и это его основное место. Runtime-мониторинга в нём нет вообще: Crossweft ничего не запускает и не смотрит на работающий сервис, он статически читает исходники и сверяет обе стороны каждого шва.

В CI это GitHub Action (одна строка uses: в workflow), pre-commit хук или просто crossweft check с кодом возврата. Расхождение роняет сборку и подсвечивается на строке в диффе, есть вывод в SARIF для code scanning. Для больших репозиториев есть check --changed, он гоняет только сторожей, которые читают изменённые файлы.

Про схему данных: если одна сторона описана схемой (OpenAPI JSON или .proto), crossweft import выводит из неё сторожей для рукописной стороны. Поменяли поле в схеме и забыли клиент, CI упадёт.

Регрессионные тесты самих агентов он не гоняет, это другая задача. Он проверяет то, что агент написал, а не самого агента: агент правит одну сторону, хук сразу называет файл на другой и не даёт закончить, пока стороны расходятся.

доброго времени!) Зцепила цифра в $9 000...Очевидно, что рассинхронизация данных генерирует тонны пустых запросов и цикличных ошибок, сжигая бюджет...Проводили ли вы замеры: сколько бюджета на токены экономит Crossweft за счет того, что вовремя ловит несоответствие контрактов и не дает агенту уйти в бесконечный цикл саморефлексии? Окупилась ли разработка инструмента чисто на экономии токенов?

Доброе утро! Я инструмент делала не ради экономии токенов, для этого у меня в обвязке стоят другие вещи. rtk сжимает вывод команд до того, как он попадёт в контекст агента; по его собственному счётчику с середины июля это около 1,25 млрд токенов, 65% вывода. Плюс набор правил Benjamin-Plus, который заставляет агента делать меньше шагов и не перечитывать лишнее.

Crossweft отвечает за другое: чтобы не ломались стыки. К 4 октября в реестре было 146 найденных рассинхронов между компонентами, 117 из них закрыты. Раньше такое место всплывало на тестах а агент подолгу ходил по кругу, чиня не ту сторону. Теперь оно ловится сразу после правки, хук называет файл на другой стороне, и агент чинит его в том же ходе.

Понял) Значит, экономия токенов вообще задача обвязки (rtk), а Crossweft просто прерывает сборку, если агент сломал контракт. Разделение логичное тут) спасибо за разъяснение)

ИИ текст и такие же комментарии для продвижения. Если думаете, что это незаметно, то сильно ошибаетесь.

Я не сразу понял, на на уровне подсознания, чувствовал что странные комментарии)

Пидорги Киборги - они заполонили всё вокруг (с)

надеюсь вы оба сможете от меня убежать при восстании машин

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

Да, ровно так. Каждый прав внутри своей задачи, а сломано между ними, и это видно только сверху. Вопрос в том, кто этот «сверху» и откуда он знает, что сравнивать.

Проверяющий агент над двумя исполнителями у меня тоже есть: отдельный, в свежем контексте, он не видит рассуждений исполнителей и смотрит только на результат. Но он ловит то, что догадался проверить. Если он не знает, что версия API живёт и в Go, и в TypeScript, он посмотрит оба диффа, оба будут аккуратными, и он тоже скажет «зелёное».

Crossweft делает эту проверку сверху механической для одного класса ошибок. Карта говорит, какие места в двух задачах обязаны совпадать, а сторож читает обе стороны при каждом прогоне, независимо от того, какой агент что правил и помнит ли кто-то про этот стык. Поведение целиком это не заменяет, интеграционные тесты всё равно нужны. Но рукописные стыки, которые никто не держит общим кодом, проверяются уже не памятью проверяющего, а картой.

Интересная работа! Особенно понравилась идея не верить агенту, когда он радостно докладывает: «Готово, всё проверено». :) Но вот что меня зацепило, вы научили агентов проверять известные зависимости. А кто проверяет, что найдены вообще все зависимости?

Я работаю с AI-агентами на legacy-проектах. Там настоящий археологический заповедник, часть логики в файлах, часть в базе, сниппеты вызывают сниппеты, а некоторые зависимости существуют только в голове разработчика, который уволился лет десять назад. И вот агент построил карту, Crossweft всё проверил, везде зеленые галочки. А где-то осталась неизвестная зависимость.

Не получается ли, что мы просто переносим проблему доверия с агента на составленную им карту?

Рассматривали ли вы способы независимой проверки полноты такой карты? А то сторож исправно работает, только охраняет не ту дверь. :)

Да, отчасти доверие переезжает с агента на карту. Полноту карты Crossweft не доказывает и доказать не может. Он делает так, чтобы пропуск было сложнее не заметить.

Что есть сейчас:

  • покрытие: каждая папка с кодом обязана принадлежать какому-то блоку карты, иначе проверка красная. Пол-системы за бортом оставить нельзя, можно только явно вынести папку в исключения с причиной;

  • crossweft discover сам ищет значения, которые набраны в двух языках (маршруты, заголовки, версии API, URL, имена событий, env-переменные), и предлагает сторожа на каждое, которого нет на карте;

  • сканеры маршрутов: если клиент зовёт адрес, который сервер не объявляет, это ошибка, даже если на карте такой связи нет;

  • каждое утверждение карты привязано к литералу в файле, поэтому выдумать связь агент не может, а перепутать её сложно.

Чего нет: всё это видит только код в репозитории. Логика в базе, сниппеты, которые собираются в рантайме, и зависимости в голове уволившегося разработчика для него невидимы, и на легаси вы как раз про это. Там я бы сначала прошлась по всему коду поиском таких совпадений и расспросила людей, кто что помнит. Каждое «а вот это ещё дёргает вон то» сразу записываем на карту, и дальше про эту связь уже никто не забудет.

Так что сторож действительно охраняет только известные двери. Но список дверей теперь лежит в репозитории, его видно на ревью, и новая дверь, которую нашёл дискавер, становится красной проверкой.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации