Финтех на ИИ-агентах: как за 15 месяцев выросло качество go-кода

Пятнадцать месяцев финтеха на ИИ‑агентах: как менялась кривая качества кода на протяжении проекта

У меня 12 лет опыта в Go - и в какой-то момент я поймал себя на неприятной мысли: свой "лучший рукописный код" я больше не могу считать эталоном. Не потому, что я внезапно разучился программировать, а потому что планка качества в проектах с ИИ‑агентами стала выше, чем то, что я обычно выдавал руками. Формально планку ставил я, но по факту её подняли сами агенты - я лишь закреплял требования и превращал их в правила.

Это звучит вызывающе, поэтому опираюсь не на ощущения, а на измерения. У меня есть график: красная пунктирная линия - уровень качества моего лучшего ручного кода, синяя кривая - качество кода, который производят агенты при текущем контуре проверок. В апреле 2026 года синяя кривая опустилась ниже красной и продолжила снижаться - то есть число проблем, которые допускают агенты, стало меньше, чем у моего "идеального" ручного режима.

Меня зовут Александр. Я удалённый разработчик в финтех‑стартапе. С мая 2025 года я один веду закрытый финтех‑продукт, где код с первого дня пишет связка ИИ‑агентов. С февраля 2026 добавился второй проект - платёжный. И там, и там модель делает основную работу, но качество держится не "магией нейросети", а жёстким периметром автоматических проверок вокруг неё. Важная деталь: этим проверкам безразлично, кто автор - агент, я или коллега. Правила одинаковые для всех, поэтому качество становится измеряемым и воспроизводимым.

Откуда взялся "нейрослоп" и почему стандартных линтеров не хватило

Весной 2025 года появился Claude Code - и процесс закрутился. Поначалу это выглядело как ускорение: агенты быстро накидывают фичи, закрывают задачи, генерируют обвязку, тесты, интеграции. Но через несколько месяцев накопилась обратная сторона - нейросеть начала "расти вширь". К осени кодовая база раздулась до 224 тысяч строк, и существенная часть объёма оказалась не ценностью, а балластом: дубли, "брошенные ветки" внутри кода (не git‑ветки), забытые эксперименты, заготовки, которые никто не довёл до конца.

Самая показательная цифра того периода - срез на октябрь 2025 года: 105 пакетов проекта не проходили проверку типов. Я коммитил часто, потому что рабочее состояние было хрупким: пока я вёл код обратно к сборке, агенты успевали "уехать" ещё дальше. Сейчас это звучит как безумие, но тогда иначе было сложно не потерять прогресс. Сегодня картина противоположная: не проходит типизацию один пакет, и все коммиты собираются. Но "само" это не стало.

Я почти сразу подключил стандартный набор: `go vet`, `staticcheck`, `golangci-lint`. Они реально помогли - но лишь наполовину. Проблема вскрылась неожиданная: классические линтеры проектировались под человеческие ошибки. А агенты ломают код иначе - так, как человек обычно не ломает. И на такие поломки никто не писал правил, потому что людям они попросту не свойственны.

Корень ошибок агента - короткий контекст и имитация понимания

Человек, как правило, помнит, что делал 10-15 минут назад: какие решения уже приняли, что обещали интерфейсу, где "тонкое место" в бизнес‑логике. Модель - нет. Отсюда хронические симптомы: бесконечные повторы одной и той же логики, галлюцинации, ветки, которые не используются, локальные "временные" решения, превращённые в постоянные.

Но самый опасный класс для финтеха - маскировка непонимания. Когда агент не разобрался, он может не упасть и не вернуть ошибку, а тихо отдать что-то правдоподобное: пустую структуру, `false` из функции, которая вообще не предикат, объект с `nil`‑зависимостью внутри. И что особенно токсично - он может честно залогировать проблему и... продолжить, как будто ничего не произошло.

Под это у меня постепенно вырос отдельный "букет" проверок: `error-masking`, `fallback-return`, `log-and-return-zero`, `empty-struct-return`, `constructor-swallows-nil-dep`. Против человека почти ни одно из этих правил не нужно - люди обычно так не ошибаются. Против агентов эти проверки срабатывают до сих пор и окупаются постоянно.

Пятьдесят велосипедов и один инструмент вместо зоопарка

Моя схема была примитивной, но эффективной: заметил повторяемый класс проблем - написал анализатор. Эти анализаторы сначала жили прямо внутри проекта. К январю 2026 их накопилось около 50.

В январе стало ясно: так дальше нельзя. Правила надо выносить в отдельный инструмент и применять ко всем проектам - и к нему самому. За день появился каркас с первым десятком правил, а через неделю я одним коммитом выкинул все 50 проектных анализаторов. Общие правила переехали в единый линтер, продуктовая специфика - в отдельный проектный набор. Общий инструмент называется glint, он открыт под MIT, и все метрики, о которых я говорю дальше, посчитаны им.

Тогда же случилась большая уборка: за две недели из проекта ушло 140 тысяч строк мёртвого кода, дублей и протухших инструментов. На графике это выглядит как первый резкий обрыв - не потому, что мы "ухудшили продукт", а потому что перестали считать мусор частью системы.

Как баг превращается в правило - и почему агенты замыкают цикл сами

С тех пор процесс стабилизировался и повторяется по кругу:

1) Я вижу дефект сам или получаю репорт.
2) Агент исследует систему и находит первопричину.
3) Я предполагаю, что случай не единичный, и прошу найти похожие места по всей кодовой базе.
4) Смотрим, можно ли формализовать это как правило.
5) Прогоняем правило по всему проекту - и оно часто вскрывает ещё несколько скрытых случаев.
6) Контур замыкается: модель находит баги, пишет правило, читает результаты правила и дорабатывает его. Моё участие - в нескольких ключевых решениях: что считать ошибкой, насколько жёстко блокировать сборку, где допустимы исключения.

Важно: это не "линтер ради линтера". В финтехе цена тихой деградации выше цены строгих ограничений. Поэтому правила должны быть не красивыми, а полезными - ловить то, что иначе превращается в деньги, риск и объяснения с бизнесом.

Пример продуктового правила: типы сходятся, ошибки обработаны - а деньги всё равно могут уйти "в никуда"

Есть класс проверок, которые невозможно положить в универсальный линтер, потому что они завязаны на конкретные имена, роли и доменную модель проекта.

Например, в платёжном проекте есть железное требование: команда платёжному провайдеру не должна уходить раньше, чем в нашем хранилище появилась durable‑запись о намерении её отправить. Если процесс упадёт между фактической отправкой денег и записью намерения, получится самый неприятный сценарий: деньги ушли, а следа нет - нечего повторить, нечего сверить, нечего показать пользователю, нечем доказать корректность.

И вот что коварно: оба вызова по отдельности абсолютно корректны. Типы сходятся. Ошибки обработаны. Логи есть. Дефект - в порядке операций. Чтобы поймать такое, проверке нужно знать, как именно в этом проекте называются провайдеры, как устроены хранилища и какие функции считаются "отправкой наружу", а какие - "фиксацией намерения". Это уже не общая статическая проверка языка, а проверка бизнес‑инварианта.

---

Что я добавил к процессу за эти 15 месяцев (и почему без этого график бы не поехал вниз)

1) Качество измеряется не "впечатлением", а счётчиком нарушений.
Главный сдвиг произошёл, когда я перестал оценивать код "на глаз" и начал жить по метрикам: сколько нарушений каждого класса на тысячу строк, сколько блокирующих правил, сколько "предупреждений", сколько исключений. Так синяя кривая стала не метафорой, а инструментом управления.

2) Правила делятся на блокирующие и обучающие.
В CI блокируется только то, что реально опасно: маскировка ошибок, подозрительные возвраты, неинициализированные зависимости, нарушения критичных инвариантов. Всё остальное - в режиме сигналов, чтобы не парализовать разработку. Для агента это особенно важно: если блокировать "слишком многое", он начинает метаться, вместо того чтобы чинить.

3) Для агентов нужен "периметр", а не надежда на аккуратность.
Агент может быть блестящим генератором кода, но он не "ответственный сотрудник" в человеческом смысле. Поэтому систему надо проектировать так, чтобы неверный код не мог пройти: типизация, тесты, линтеры, статические анализаторы, запрет опасных паттернов, контроль порядка операций в критичных местах.

4) Порог допуска к продакшену должен быть одинаковым для всех авторов.
Самая разрушительная практика - делать поблажки "потому что это агент" или "потому что срочно". Как только появляются исключения, агент начинает воспроизводить их как норму. Ровно наоборот: чем больше автоматизации, тем меньше должны быть ручные "ну ладно".

5) Агентам полезны короткие итерации и узкие задачи.
Если давать модели огромные абстрактные цели, она неизбежно начнёт достраивать недостающие детали фантазией. Лучше дробить: маленькое изменение, прогон проверок, фиксация, следующее изменение. Это снижает и дублирование, и "лог‑и‑верни‑ноль".

6) "Чистка" - не разовое событие, а плановая гигиена.
140 тысяч строк ушли не потому, что я героически сел и вымарал всё лишнее. Просто появился механизм, который регулярно делает мусор видимым: неиспользуемые ветки, мёртвые пакеты, копипастные реализации, лишние уровни абстракции. Когда мусор виден, его проще удалить, чем защищать.

7) В финтехе критично фиксировать намерение до внешнего действия.
Это отдельная философия устойчивости: всё, что уходит во внешние системы (деньги, сообщения, подтверждения), должно иметь внутренний "след" до факта отправки. Иначе любой сбой превращается в расследование без фактов. Агентам такие правила нужно вшивать проверками, потому что сами они охотно пишут "логично", но не всегда "надёжно".

8) Самое ценное - не генерация кода, а ускорение обратной связи.
Агенты дают скорость только тогда, когда быстро узнают, что ошиблись. Чем короче цикл "написал → проверил → исправил", тем меньше нейрослопа. В этом смысле линтеры и анализаторы для агентного кода - не бюрократия, а педаль газа.

9) Роли меняются: разработчик становится редактором правил и инвариантов.
Моя работа всё меньше похожа на "написать функцию" и всё больше - на "определить, что является ошибкой, и сделать так, чтобы её нельзя было повторить". В одиночных проектах это особенно заметно: код пишет агент, а человек строит систему ограничений, метрик и гарантии.

---

Итог этих 15 месяцев простой: качество агентного кода не появляется из воздуха и не зависит только от модели. Оно появляется там, где есть дисциплина проверок, понятные инварианты и процесс превращения любого повторяемого бага в формализованное правило. Когда этот контур замкнут, синяя кривая действительно может уйти ниже "лучшего ручного кода" - и, что важнее, оставаться там, даже когда проект растёт и усложняется.

Прокрутить вверх