Улучшаем харнес с помощью ast-grep
Утро сегодня началось не с кофе. Пока мы переезжаем (с разной степенью успешности) в другой дц, расскажу про недавнее интересное открытие, связанное с тем как сделать улучшить работу агентов и сделать больше надежных автоматических проверок разных архитектурных правил.
Понятно что со временем появляется все больше и больше правил, которые описываются в AGENTS.md (или что лучше в CODING_STANDARDS.md). Но хотелось бы чтобы они чекались автоматом. Клод нам сам постоянно предлагал и в какой-то момент начал писать скрипты допом к линтингу, которые, в основном, регулярками, проверяли что-то. Кушать не просит и ладно, я не сопротивлялся, но видел что это решение на тоненького, хотя и лучше чем ничего.
Когда эти скрипты начали копиться, я подумал, хм, а ведь мне ничего не стоит попросить его переписать правила как плагины к линтерам на конкретных языках. Кое что мы так действительно переписали, но в какой-то момент сам клод говорит, а давай заюзаем ast-grep. Я посмотрел и понял что проспал очень логичную штуку. Еще в 22 году, когда полетел treesitter, кто-то замутил инструмент, который грепает не исходники, а AST. Причем что важно, независимо от языка, оно все языки превращает AST и грепает по его нодам.
Это резко повышает точность рабатываний, потому что вместо регулярок, которые ловят ненадежно, плюс херово работают с вложенностью, мы имеем по сути универсальный способ представить весь код (и все форматы) в виде единого AST пространства, по которому идет поиск. Ну и естессно переписали все проверки, потому что у этой штуки еще есть sdk для ноды. А все подобные скрипты у нас агент фигачит на TypeScript. Пара примеров:
1. no-unknown-in-generated-types: в сгенерированных фронт-типах (app/javascript/types/serializers/) не должно быть unknown. Typelizer пишет unknown, когда не смог вывести тип поля. Это бывает у атрибута поверх T::Struct или у вычисляемого атрибута без typelize. Тип нужно объявить явно в ресурсе.
2. no-untyped-resource-dsl: в сгенерированных RBI-сигнатурах DSL ресурсов не должно быть T.untyped. Чинить надо в ресурсе или в компиляторе typelizer.rb, а не в RBI.
Но это еще оказалось не все. ast-grep в принципе полезен даже вместо обычного грепа, особенно для самих агентов, которые постоянно ищут какие-то символы в исходниках. У ast-grep есть дока с инструкцией, как подключить его к агенту, чтобы агент начал использовать его вместо grep там где это имеет смысл.
p.s. Какие еще фишки вы знаете?
Telegram | YouTube | AI Клуб | Внедрение AI
Post #528
2.45K

- 👍 26
- ❤ 10
- 🔥 5