反馈循环就是你所需要的。
The Feedback Loop Is All You Need

原始链接: https://zernie.com/blog/feedback-loop-is-all-you-need/

## AI 编程与安全防护的需求 Claude Code 等 AI 编程助手承诺实现自动化开发——在你休息时工作的代理。然而,将这些工具直接应用于实际代码库存在风险。复杂项目通常存在隐藏的依赖关系、不断演进的设计系统和未记录的规则,AI 很容易违反这些规则,导致微妙的性能下降,而不是明显的错误。 关键不在于更好的提示词或技能库,而在于**收紧反馈循环**:更快的故障检测至关重要。不要依赖 AI “理所当然”,而要专注于通过诸如代码检查工具、静态分析(SonarJS)、严格的 TypeScript 以及全面的测试(Playwright、基于属性的测试)等工具进行**确定性强制执行**。 具体而言,**严格的复杂度限制**(最大行数、循环复杂度)至关重要。这些不是风格偏好,而是防止过度复杂代码的结构性约束。即使伴随着相关成本,投资于这种“反馈基础设施”也是必不可少的。它将 AI 从一种潜在风险转化为强大的杠杆,确保质量并防止架构漂移。 最终目标是构建一个自我改进的系统,AI 生成的代码能够持续验证和完善,从而创建一个健壮且易于维护的代码库。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 反馈循环是你所需要的 (zernie.com) 7 分,来自 zernie 4 小时前 | 隐藏 | 过去 | 收藏 | 2 条评论 帮助 zetalyrae 3 小时前 [–] > 指令只是建议——代码检查是规则 由 AI 编写。 br-senselab 3 小时前 | 父评论 [–] 是的 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

Я не могу использовать CRON на реальной кодовой базе

Несколько дней назад в Claude Code появился CRON. Регулярные задачи, нативно, прямо из коробки. То, о чём мы мечтали с первых AI-кодинг-демо — запланировал агента, лёг спать, проснулся — PR смёржены. Инженер, который работает, пока ты не работаешь.

И я понимаю… я даже не могу это использовать. Не в проде. Не на работе. Я работал в archive.com четыре года — мы прошли через три дизайн-системы. Начинали с Shopify Polaris, перешли на Ant Design, когда выросли из Shopify, потом мигрировали на shadcn/ui и Tailwind, потому что Ant Design сам стал легаси. Четыре года, три UI-фреймворка, конвенции, которые жили в головах у людей, бизнес-правила, которые никто никогда не записывал. Направишь на это агента — он побежит. Выдаст код. Красивый, идиоматичный, адский код — тот, что импортирует из всех трёх дизайн-систем в одном файле и каким-то чудом проходит все проверки.

И что делать? Всё ревьюить невозможно. Замедлять агентов нельзя. И уж точно нельзя надеяться, что они сами разберутся, какую дизайн-систему использовать.

Эта статья — о том, что реально работает. Я пользуюсь Claude Code, поэтому примеры отсюда — но паттерн одинаковый, используй ты Cursor, Copilot, Codex или Devin.


Старый цикл vs новый

Старый цикл: пишешь или ревьюишь код, замечаешь код-смеллы по опыту, оставляешь комментарии с объяснением замысла, обещаешь починить «потом» — что обычно значило «никогда».

Новый цикл: зафиксировать правила один раз, дать агентам работать в их рамках, наблюдать, что падает, ужесточать ограничения. Меньше «запомни на следующий раз», больше «это физически не может произойти».

Агенты ломают старый цикл полностью. Когда код генерируется непрерывно, ручное ревью становится самым слабым звеном.


Настоящий враг: незаметная деградация

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

Простой пример: агент добавляет форму на страницу, которую ты мигрировал на shadcn/ui. Он тянет <Form.Item> из Ant Design — потому что другая форма на этой же странице всё ещё его использует. Компилируется. Рендерится. Твоя миграция только что откатилась на один компонент, и ничего в пайплайне этого не заметило.

Или смотри, как это происходит с CSS. Агент пишет новый компонент на Tailwind-утилитах — правильно, по текущему стандарту. Но копирует значение отступа из старого Ant Design-компонента по соседству: p-[24px] вместо шкалы p-6. Одно магическое число не убьёт. Пятьдесят — убьют. Каждый коммит выглядел нормально по отдельности. Деградация была невидима, пока не стала очевидной.

Люди ловят это интуицией. Агенты — нет. Им нужны детерминированные, мгновенные сигналы. Без них ты просто пишешь «всё ещё сломано» в пятнадцатый раз.

AI IDE after I send "Still broken" for the 15th time Source: ProgrammerHumor.io

Вся игра — в том, чтобы затянуть фидбек-луп: чем меньше времени между ошибкой и сигналом о ней, тем лучше.


Инструкции — лишь пожелания, линтеры — закон

Большинство разработчиков, активно использующих AI, всё ещё живут в старой реальности. CLAUDE.md. Библиотеки скиллов. Аннотации в документах. Опишешь достаточно чётко, думают они, и агент всё сделает. Даже Vercel выпустил библиотеку скиллов — 40+ правил React-производительности, красиво написанных, структурированных как SKILL.md-файлы для AI-агентов. Это действительно отличная работа и реальный шаг вперёд для экосистемы.

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

The code is more what you'd call guidelines than actual rules

Инструкции важны — они помогают агенту попасть в точку с первой попытки, и хороший CLAUDE.md значительно сокращает цикл итераций. Но «помогает» и «гарантирует» — разные вещи. CLAUDE.md — это пиратский кодекс. А мы надеемся, что вероятностная система будет попадать в яблочко каждый раз. Иногда да. Иногда получаешь красивый, идиоматичный код с первой попытки. А иногда она добавляет неиндексированный запрос в нагруженный эндпоинт, и ты узнаёшь об этом, когда база плавится в 2 ночи в пятницу.

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

И теперь мы делаем ровно то же самое с LLM. «Просто напиши очень хороший CLAUDE.md.» «Просто добавь больше skills.» Это то же магическое мышление, только с более модной технологией. Мы уже знаем, чем это заканчивается.

CLAUDE.md объясняет «зачем» и помогает агенту сделать правильно с первого раза. Lint-правило гарантирует, что он не накосячит. Skills ускоряют. Линтеры не дают схалтурить. Если можно выбрать только одно — бери линтер.


Guardrails: сложность — главное ограничение

Вот что запускается на каждое изменение:

  • ESLint — потому что у агента нет десяти лет набитой руки с твоими конвенциями импортов
  • SonarJS — целые классы багов убиваются на корню
  • Строгий TypeScript — если типы нестрогие, агент воспользуется каждой трещиной
  • Строгие React-ограничения — никаких «креативных» паттернов компонентов в 3 часа ночи
  • Prettier — обязательно, без обсуждений, больше никогда не думай о форматировании

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

В ESLint есть строгие правила именно для этого: complexity ограничивает цикломатическую сложность функции, max-depth — вложенность, max-lines-per-function и max-lines заставляют декомпозировать на уровне функций и файлов, max-params держит интерфейсы узкими, max-statements не даёт функции делать двенадцать вещей одновременно. SonarJS добавляет cognitive-complexity — более умную метрику, которая штрафует вложенные условия и разрывы потока сильнее, чем простое ветвление.

LLM по умолчанию идут по пути наименьшего сопротивления. Получив задачу, агент с радостью сгенерирует одну функцию на 150 строк с шестью уровнями вложенности, тремя ранними return'ами и switch внутри try-catch внутри цикла. Оно компилируется. Проходит тесты. Даже работает. Но это нереально поддерживать, и следующий агент, который это тронет, сделает только хуже. Поставь max-lines-per-function: 40, complexity: 10, max-depth: 3, добавь --max-warnings=0 — и агент вынужден декомпозировать. Он выделяет хелперы, именует промежуточные шаги, разделяет ответственности. Конкретные числа менее важны, чем сам факт их наличия — подстрой под свою кодовую базу, но начинай строго и ослабляй только когда правило реально мешает. Ты поставил число, и машина разобралась сама.

Стек не важен — RuboCop, Ruff, clippy работают по тому же принципу. Думай об этом как о функциональном программировании — хороший код минимизирует возможные состояния, и хорошая AI-инфраструктура делает то же самое. Но готовые линтеры убирают споры о синтаксисе. Архитектурные решения требуют чего-то кастомного.

Прежде чем писать что-то кастомное, прошерсти экосистему. SonarJS, unicorn, perfectionist — проверенные временем плагины, до которых у большинства команд никогда не доходили руки. Это было дёшево, пока люди писали весь код сами. Это дорого, когда агент находит каждый пробел, который ты оставил открытым. Пять минут, recommended-конфиг, целые классы багов исчезают. Обычный блокер — сотни существующих нарушений при включении нового правила — перестаёт быть проблемой. Агент может разобрать их оптом: починить простые, сгруппировать остальные по паттерну, расставить точечные eslint-disable там, где фикс пока не оправдан.

Можно ли из этого сделать lint-правило?

Каждый раз, когда видишь что-то, что не должно повториться, спроси: можно ли из этого сделать lint-правило? Этот вопрос — и есть настоящий сдвиг. Он превращает тебя из ревьюера в архитектора, который строит постоянные guardrails — как команда архитектуры, работающая 365 дней в году и никогда ничего не забывающая.

Порог входа реальный — первое правило самое трудное. Но как только паттерн установлен, правила накапливаются и дают кумулятивный эффект. У нас агенты добавляли console.log в продакшн-код вместо нашего кастомного логгера, который шлёт логи в Datadog. Lint-правило на 10 строк это починило — запретить console.log, предложить logger.error. Как только это в линтере, проблема исчезает навсегда.

Люди пугаются 50 кастомных правил. Хорошо — этот дискомфорт и есть сигнал. И некоторые правила будут неидеальными. Это нормально. Правила улучшаются так же, как законы — кто-то не согласен, предлагает изменение, и система становится лучше через спор. Кто-то натыкается на правило, раздражается, открывает PR — и вот у тебя происходит архитектурная дискуссия, которой раньше не было. Кодовая база с плохими правилами — в состоянии, которое можно улучшить. Кодовая база без правил — это просто vibes. А когда правило требует миграции существующего кода, AI + кодмоды делают очистку возможной за часы, а не за кварталы.

Но линтинг — лишь одна форма детерминированного enforcement'а. Тестирование — другая, и AI сделал его написание радикально дешевле. Детальные спецификации, исчерпывающие граничные случаи, property-based тестирование — вещи, которые людям было слишком трудоёмко писать тщательно, теперь тривиально генерируются. Линтинг ловит структурные нарушения. Тесты ловят поведенческие. Вместе они покрывают то, что никакая документация никогда не покроет.

Правила ловят то, что ты уже видел. А как насчёт сбоев, о которых ты ещё не думал?


Что на самом деле ловит CI

Каждый пуш запускает полную проверку — не потому что я не доверяю агенту, а потому что я не доверяю ничему, что не было проверено.

Визуальная регрессия. Playwright-скриншот-тесты проверяют, что UI выглядит как задумано — а не просто что тесты зелёные. Они ловят вещи, невидимые для юнит-тестов: регрессия z-index, которая хоронит модалку под оверлеем, сдвиг макета из-за рефакторинга flex-контейнера, кнопка, которая рендерится, но абсолютно некликабельна. Chromatic делает то же самое для Storybook-воркфлоу — визуальные диффы на каждый PR, никакого ручного QA. Суть одна: если никто не смотрит на экран, экран сломается.

Property-based тестирование. Вместо ручного написания отдельных тест-кейсов ты определяешь свойство, которое должно выполняться всегда: «эта функция никогда не должна возвращать отрицательное число» или «кодирование, а затем декодирование всегда должно возвращать оригинальный вход». Фреймворк генерирует сотни случайных входов и пытается его сломать. Невероятно эффективно для поиска граничных случаев — но большинство команд так и не внедрили, потому что написание хороших определений свойств было трудоёмким. AI это перевернул. Агент может прочитать твой код, вывести, какие свойства должны выполняться, и сгенерировать тесты. Одна команда запустила агентов на 933 модулях — 984 баг-репорта, 56% валидных, примерно $10 за реальный баг. Это фидбек-луп, работающий внутри CI.

Структурная безопасность. DryRun Security протестировали Claude Code, Codex и Gemini при создании двух приложений — 87% PR содержали хотя бы одну уязвимость. Не синтаксические баги. Структурные пробелы: WebSocket-эндпоинты без аутентификации, хотя REST API был защищён, rate-limiting middleware, определённый в файле, но так и не подключённый. Агент написал middleware правильно — он просто не знал, что оно не работает. Статический анализ видит, что файл существует. Он не может определить, что файл не подключён. Нужен CI, который запускает приложение и проверяет поведение, а не только код.

Мониторинг рантайма. Sentry и Datadog прокидывают продакшн-сигналы в очередь задач. Когда что-то падает в 2 ночи, это становится задачей, а не загадкой.

Много механизмов — линтеры, тесты, визуальная регрессия, сканирование безопасности, мониторинг рантайма. Поговорим о том, сколько это стоит — и сколько стоит без этого.


Инвестиция

Настоящая цена — не токены и не SaaS-подписки, а инженерное время на создание инфраструктуры. Написание кастомных lint-правил. Настройка скриншот-тестов. Подключение observability к очереди задач. Ничего из этого не бесплатно, и ничего из этого не деплоит фичи.

Are ya shipping, son? — I'm building the pipeline that builds the pipeline. Source: Memedroid

Но посмотри, за что ты платишь без этого. CodeRabbit проанализировал 470 GitHub PR и обнаружил, что AI-сгенерированный код содержит в 1.7 раза больше багов, чем написанный людьми. В 2.74 раза больше уязвимостей безопасности. Их вывод: «У нас больше нет проблемы создания. У нас проблема уверенности».

Да, ты платишь за токены. Таксисты платят за бензин — и за машину, за лицензию, за страховку — при марже 5–10%, и никто не задаётся вопросом. Это стоимость ведения бизнеса. В софте мы немного избалованы: 80%+ валовая маржа, а всё средство производства — ноутбук и стул, которые у тебя уже есть. Тул за $200/мес, который ловит хотя бы один продакшн-баг в квартал, уже окупился десятикратно.

Senior-инженер в США обходится компании в $150–200/час. Баг на продакшне, найденный клиентом — это дни расследования, экстренные фиксы и доверие, которое не вернуть. Кастомное lint-правило пишется за полдня и ловит этот класс багов на каждом коммите, навсегда. Playwright-скриншот-сьют настраивается за день и ловит визуальные регрессии, которые никакое ручное ревью не поймает в масштабе. Вопрос никогда не был «можем ли мы позволить себе тулинг?» — вопрос в том, можем ли мы позволить себе без него.

И вот что даёт кумулятивный эффект: каждый добавленный guardrail умножает то, что агент может шипить автономно. Ещё одно правило — на один failure mode меньше для ревью. Десять правил — и целые категории деградации просто перестают происходить. Инфраструктура — это не оверхед, это то, что превращает агента из liability в рычаг.

Цель — получить рычаг от использования агентов, но без компромиссов в качестве софта. — Карпати

Рычаг не даётся бесплатно — ты получаешь его, инвестируя в фидбек-инфраструктуру, которая делает рычаг безопасным.


Организм

Вот к чему всё это вело. Собери всё вместе — и система начнёт сама себя улучшать:

    ┌─────────────────────────────────────────┐
    │                                         │
    ▼                                         │
  Agent ──▶ Rules ──▶ CI ──▶ Observability    │
                                  │           │
                                  ▼           │
                                Tasks ────────┘

Вот как это работает на практике. Агент открывает PR. Кастомное lint-правило ловит нарушение barrel-файлов — агент исправляет. CI запускает Playwright; скриншот показывает сдвиг макета — агент корректирует CSS. Sentry сообщает о росте 404-х на staging-деплое — создаётся новая задача. Агент подхватывает её. Каждый сбой ужесточил систему. Ни один человек не написал ни строчки кода.

Каждый баг, дошедший до CI, становится правилом, предотвращающим следующий. Система не просто сопротивляется сбоям — она становится сильнее от них. Это не тулчейн. Это организм.

Это не теория. Spotify построили фонового кодинг-агента Honk поверх фидбек-инфраструктуры, в которую инвестировали с 2022 года — за три года до AI-части. Результат: 650+ PR от агентов, смёрженных в продакшн ежемесячно. Merge rate у Devin удвоился с 34% до 67%, когда улучшили понимание кодовой базы — не модель, а контекст.

Паттерн везде одинаковый: побеждают не те команды, которые запускают лучшие модели. Побеждают те, у кого более плотный фидбек-луп.


С чего начать

Где ты сейчас?

УровеньКак это выглядитПризнак
0 — VibesНет кастомного линтинга, нет CI, всё ревьюишь вручную«Мои глаза — единственное, что стоит между агентом и продакшном»
1 — GuardrailsСтандартные линтеры + CI, но без кастомных правил«Агент проходит линт, но всё равно деградирует архитектурно»
2 — Architecture as CodeКастомные lint-правила, кодирующие конвенции команды«Правила из CLAUDE.md мигрируют в линтер»
3 — The OrganismСамоужесточающийся цикл: агент → правила → CI → observability → задачи → агент«Я ставлю агентов на ночь и ревьюю диффы утром»

Если ты на уровне 0, не стыдно — все там начинают. Суть не в том, чтобы прыгнуть на уровень 3 за ночь. Суть — понимать, куда ты движешься, и начать с первого кастомного правила, которое сделает твою конкретную кодовую базу честнее.

Сегодня: Возьми PR-комментарий, который твоя команда оставляет снова и снова — про конвенции импортов, или barrel-файлы, или console.log в продакшне — и преврати его в кастомное lint-правило. Это твой первый кусочек architecture-as-code.

На этой неделе: Добавь Playwright-скриншот-тесты для трёх самых критичных страниц. Удивишься, что они поймают, чего не ловят юнит-тесты.

В этом месяце: Запланируй CRON-задачу на что-нибудь безопасное — обновление зависимостей, поддержание тестов, чистка заброшенных веток. Пусть агент работает ночью. Ревьюй PR утром. Начни с Claude Code web или Codex web; когда этого станет мало, дешёвый VPS даст больше мощности для той же идеи.

Тест: Если ты можешь делегировать задачу с телефона, ревьюить дифф в дороге и доверять результату — твой фидбек-луп достаточно плотный. Фишка не в том, чтобы работать меньше. А в том, чтобы не быть привязанным к машине.

Если хочешь отправную точку — я собрал playbook с сетапами инструментов на разных бюджетах, и companion-репо — vigiles — которое автоматизирует часть паттернов enforcement из этой статьи.


Заключение

Три дизайн-системы за пять лет. Агент не знает, какую из них использовать — если ты не скажешь ему детерминированно, на каждом коммите.

Вот и весь инсайт, по сути. Агент, который вроде бы простаивал, ждал не лучшую модель — он ждал лучшие сенсоры.

LLM по природе вероятностны. Они угадают в большинстве случаев, а на реальной кодовой базе это значит — недостаточно часто. Никакой prompt engineering этого не изменит. Это не баг, который можно починить; это архитектура.

Так что хватит гнаться за умными промптами. Гонись за скучным, детерминированным, занудным фидбеком — тем, что срабатывает независимо от того, смотрит ли кто-то, тем, которому плевать, насколько уверена была модель.

Линтеры не спят. Тесты не забывают. CI не устаёт.

Название — отсылка к "Attention Is All You Need" (Vaswani et al., 2017) — статье, представившей архитектуру Transformer.

联系我们 contact @ memedata.com