Переписали JSONata на Go с помощью ИИ за день — экономия $500K в год
Один инженер. Семь часов работы. $400 на токены для ИИ. Результат — чистая Go-библиотека, которая заменила целый флот Node.js-подов в Kubernetes и сэкономила компании $500 000 в год на инфраструктуре.
Это не абстрактный кейс из маркетингового блога. Это реальная история от Reco — SaaS-платформы безопасности, которая обрабатывает миллиарды событий в день. Их инженер Нир Барак взял подход, описанный Cloudflare в статье о переписывании Next.js с помощью ИИ, и применил его к собственной инфраструктуре. Получилась библиотека gnata — полная реализация JSONata 2.x на чистом Go с ускорением до 1000x на типовых выражениях.
JSONata — это язык запросов и трансформации JSON-данных. Его можно представить как jq, но с поддержкой лямбда-функций и более выразительным синтаксисом. JSONata позволяет писать сложные правила обработки данных без необходимости лезть в код основного приложения. Это делает его популярным в системах, где бизнес-аналитики или исследователи пишут правила детекции, а инженеры обеспечивают инфраструктуру.
Главное из статьи:
- JSONata-выражения через RPC обходились в $300 000/год на инфраструктуру
- ИИ-ассистированная перезапись на Go заняла 7 часов и стоила $400 в токенах
- Результат: 13 000 строк Go-кода, 1 778 пройденных тестов из официального набора
- Ускорение до 1000x на простых выражениях за счёт устранения RPC и JSON-парсинга
- Суммарная экономия после оптимизации пайплайна — $500 000/год
Проблема — JSONata как узкое место
У Reco есть policy engine, который проверяет JSONata-выражения на каждом событии в потоке данных. Миллиарды событий, тысячи различных выражений. Исследователи безопасности пишут правила детекции на JSONata, а инженеры обеспечивают их выполнение в реальном времени.
Загвоздка: референсная реализация JSONata написана на JavaScript, а весь пайплайн Reco — на Go. Годами компания держала в Kubernetes отдельный флот Node.js-подов (jsonata-js), к которым Go-сервисы обращались через RPC.
Для каждого события и каждого выражения это означало:
- Сериализовать данные на стороне Go
- Отправить по сети в Node.js-под
- Выполнить JSONata-выражение
- Сериализовать результат
- Отправить обратно в Go-сервис
Во что это обходилось
Прямые затраты на инфраструктуру jsonata-js составляли около $300 000 в год, и сумма росла с каждым новым клиентом и правилом детекции. На одном из крупных кластеров количество реплик jsonata-js перевалило за 200 — и команда столкнулась с лимитом IP-адресов в Kubernetes.
Но денежные затраты были даже не главной проблемой. RPC round-trip занимает ~150 микросекунд ещё до начала вычисления. Для простого выражения вроде user.email = "admin@co.com", которое должно выполняться за наносекунды, основная цена — пересечение языковой границы. На масштабе Reco эти микросекунды складываются в ощутимые задержки.
Команда пробовала разные подходы: оптимизировала выражения, кэшировала результаты, даже встраивала V8 прямо в Go-процесс. Всё это давало инкрементальные улучшения, но не решало корневую проблему — данные всё равно пересекали языковую границу.
Решение — переписать на Go с помощью ИИ
Толчком стала статья Cloudflare о том, как один инженер за неделю переписал API Next.js на Vite, потратив $1 100 на токены. Нир Барак прочитал её и понял: у Reco та же самая ситуация — есть спецификация, есть тестовый набор, нужна реализация на другом языке.
Подход: спецификация + тесты = контракт
Метод прямолинейный:
- Портировать официальный тестовый набор jsonata-js на Go
- Направить ИИ на реализацию, пока все тесты не пройдут
- Добавить оптимизации, специфичные для Go и задачи Reco
В выходные Нир составил план, разбитый на «волны» (с помощью ИИ). На следующий день нажал «старт».
Инструменты и затраты
Конкретные модели и инструменты автор не раскрывает, но ключевые цифры говорят сами за себя:
- Время работы: 7 часов (один инженер)
- Стоимость токенов: $400
- Результат: 13 000 строк Go-кода
- Тесты: 1 778 пройденных тест-кейсов из официального набора jsonata-js
Библиотека получила название gnata — полная реализация спецификации JSONata 2.x на чистом Go.
Технические результаты
Двухуровневая архитектура вычислений
gnata использует двухуровневую архитектуру оценки выражений. На этапе компиляции каждое выражение анализируется и классифицируется.
Быстрый путь (fast path) обрабатывает простые выражения: поиск по полям, сравнения и 21 встроенную функцию на чистых путях (например, $exists(a.b) или $lowercase(name)). Эти выражения вычисляются прямо по сырым JSON-байтам, без полного парсинга документа. Для выражения вроде account.status = "active" результат — ноль аллокаций в куче.
Полный путь (full path) — полноценный парсер и вычислитель с полной семантикой JSONata 2.x. Он парсит JSON, но только нужные поддеревья, а не весь документ целиком.
Потоковая обработка
Поверх двухуровневой оценки работает потоковый слой (StreamEvaluator), спроектированный под конкретную задачу Reco: применить N скомпилированных выражений к каждому событию, где события структурно похожи.
- Все пути из всех выражений объединяются в один проход по данным — количество выражений не влияет на скорость чтения
- После прогрева горячий путь работает без блокировок (lock-free)
- Планы вычислений создаются один раз на схему событий и кэшируются неизменяемо — чтение через один атомарный load без синхронизации
- Память ограничена: кэш с настраиваемой ёмкостью, вытесняющий старые записи
Бенчмарки
Ускорение на простых выражениях — в основном за счёт полного устранения RPC: gnata вычисляет прямо по сырым байтам без парсинга JSON. На сложных выражениях, где нужен полный парсинг и AST-вычисление, разрыв сужается, но они всё равно в 25–90 раз быстрее, чем через RPC.
На простых lookups ускорение достигает 1000x.
Пример использования
Экономический эффект
Этап 1: устранение RPC-флота
Первый и самый очевидный эффект — полное устранение jsonata-js подов в Kubernetes:
- До: ~$25 000/мес на compute для jsonata-js (200+ реплик Node.js)
- После: $0 — gnata работает как библиотека внутри существующих Go-сервисов
- Экономия: ~$300 000/год
Этап 2: рефакторинг rule engine
Но на этом история не закончилась. Старый JSONata через RPC мог обрабатывать только одно выражение за раз, и вся инфраструктура вокруг него была вынуждена подстраиваться. Rule engine запускал десятки тысяч горутин для максимизации параллелизма — со всеми вытекающими: избыточное потребление памяти и высокая конкуренция за CPU.
gnata не имеет таких ограничений. Команда заменила внутренности rule engine на более простую и эффективную реализацию с just-in-time батчингом (паттерн request coalescing), короткоживущими кэшами и групповыми запросами обогащения данных.
Результат: ещё ~$18 000/мес, или ~$200 000/год экономии.
Итого
$500 000/год снято с пайплайна за две недели работы. Из них 7 часов — создание gnata, остальное — тестирование, code review и раскатка.
Как внедряли — от shadow mode до продакшена
Создать библиотеку — половина дела. Вторая половина — убедиться, что она выдаёт ровно те же результаты, что и оригинал, на миллиардах реальных событий.
У Reco уже была инфраструктура для shadow-тестирования: feature flags, параллельное вычисление, логирование расхождений. Подключить gnata к ней было несложно.
Хронология раскатки:
- День 1: gnata готова, PR открыт
- Дни 2–6: code review, QA на реальных продакшен-выражениях, деплой в preprod в shadow mode. gnata вычисляет всё, но результаты jsonata-js остаются основными. Расхождения логируются и алертятся. Найденные edge-кейсы исправляются
- День 7: три дня подряд ноль расхождений. gnata переведена в primary
К моменту перевода gnata уже обработала миллиарды событий и выдала идентичные результаты. Более того, в процессе обнаружились баги в самом jsonata-js — случаи, где референсная реализация не соответствует собственной спецификации.
Побочный эффект: gnata стала одним из первых крупных PR в Reco, где ИИ-агенты ревьюили ИИ-сгенерированный код. Агенты помечали всё подряд — и реальные проблемы с конкурентностью, и косметические замечания. Команде пришлось научить их отличать одно от другого, и этот опыт теперь используется шире.
Уроки — когда ИИ-переписывание работает
gnata — удачный кейс. Но не каждая задача подходит для ИИ-переписывания. Вот что сделало этот проект идеальным кандидатом:
- Чёткая спецификация. JSONata имеет формальную спецификацию и обширный тестовый набор. ИИ не нужно придумывать поведение — нужно реализовать заданное
- Детерминированная проверка. Каждое выражение имеет однозначный правильный ответ. Можно автоматически проверить корректность — не нужен человек для оценки каждого результата
- Глубокая экспертиза инженера. Нир не просто «нажимал кнопку». Он спроектировал двухуровневую архитектуру, потоковую обработку и стратегию кэширования. ИИ генерировал код, но архитектурные решения принимал человек
- Существующая инфраструктура тестирования. Shadow mode, feature flags, сравнение результатов — всё это было готово до gnata. Без этого раскатить ИИ-сгенерированный код в продакшен было бы рискованно
- Ограниченная область. JSONata — это чётко ограниченная задача. Не «перепишите весь бэкенд», а «реализуйте этот конкретный язык на другом стеке»
Как отметил Андрей Карпати: программирование становится неузнаваемым, и на верхних уровнях глубокая техническая экспертиза — «ещё больший мультипликатор, чем раньше, из-за увеличенного рычага». gnata — хорошая иллюстрация этой мысли.
FAQ
Что такое JSONata и зачем он нужен?
JSONata — это язык запросов и трансформации для JSON-данных. Он позволяет писать выражения для фильтрации, преобразования и агрегации JSON без написания кода на языке общего назначения. Используется в IoT-платформах, ETL-пайплайнах и системах обработки событий.
Почему нельзя было просто оптимизировать существующий подход?
Reco пробовали: оптимизация выражений, кэширование, встраивание V8 в Go. Всё это давало инкрементальные улучшения, но корневая проблема — пересечение языковой границы через RPC — оставалась. Единственное радикальное решение — нативная реализация на Go.
Насколько gnata совместима с оригинальной JSONata?
gnata проходит 1 778 тест-кейсов из официального набора jsonata-js и 2 107 интеграционных тестов в продакшен-обёртке Reco. В процессе тестирования были обнаружены баги в самом jsonata-js, где референсная реализация не соответствует собственной спецификации.
Можно ли повторить этот подход в другом проекте?
Да, если есть формальная спецификация и тестовый набор. Подход Cloudflare (vinext) и Reco (gnata) одинаков: берём спеку + тесты, направляем ИИ на реализацию до прохождения всех тестов. Ключевое требование — детерминированная проверка результата.
Выводы
История gnata — это не про то, что ИИ «волшебным образом» пишет продакшен-код. Это про то, как опытный инженер с глубоким пониманием задачи использует ИИ как мультипликатор своей экспертизы.
Ключевые выводы:
- ИИ-переписывание работает, когда есть чёткая спецификация и автоматизированная проверка
- Экономический эффект может быть огромным: $400 на токены превратились в $500 000/год экономии
- Архитектура важнее генерации кода: двухуровневая оценка, потоковая обработка и батчинг — решения инженера, не ИИ
- Shadow mode обязателен: ИИ-сгенерированный код нельзя просто «выкатить» — нужна параллельная проверка на реальных данных
- ROI считается просто: если задача имеет спеку и тесты, стоимость ИИ-переписывания предсказуема
gnata доступна как open-source библиотека: github.com/RecoLabs/gnata.
Источник: We Rewrote JSONata with AI — блог Reco.