Хватит переписывать промпты: что такое harness engineering

Знакомая ситуация: агент выдал сломанный результат, и рука сама тянется переписать промпт. Потом в ход идёт другая модель, потом тариф с окном контекста побольше. А модель всё так же забывает инструкции, берёт не тот инструмент, пропускает проверку и рапортует об успехе там, где всё сломано.

Причина обычно сидит за пределами весов модели, в среде, где она работает. Эту среду называют harness (по-русски ближе всего слово «обвязка»), а её проектирование получило название harness engineering. Разберём, из чего состоит обвязка и как собрать свою за пять минут.

Модель рассуждает, обвязка управляет

Дарио Амодеи говорил об этом прямо на запуске Claude Code: моделям нужен интерфейс и нужна обвязка, чтобы ими можно было пользоваться. Модель умеет предсказать следующий логичный шаг. Стабильную операционную систему вокруг себя она построить не может.

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

Посадите топовую модель в пустой чат, и она будет писать гладкую прозу. Дайте той же модели репозиторий с терминалом, тестами, картой проекта и изолированными рабочими директориями, и она начнёт выпускать рабочий софт. Веса в обоих случаях одинаковые.

В OpenAI наблюдали ту же картину, когда обучали агентов на Codex. Ранние запуски проваливались из-за плохо описанной среды, и проблему решили явными проверками возможностей и механическими ограничениями. Если агент раз за разом ошибается, прилагательные в системном промпте вряд ли помогут. Смотреть стоит на окружение модели.

Три слоя надёжной ИИ-системы

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

Первый слой, сама обвязка, отвечает за среду и память. Сюда входит всё, что лежит вне весов: доступ к файловой системе, переменные окружения, токены авторизации, долговременные файлы. Андрей Карпати предлагает удобную аналогию: LLM работает как процессор, а контекстное окно как оперативная память. Процессор без хранилища и ОС бесполезен. Когда в один промпт вываливают двадцать страниц фоновой информации, память переполняется, и модель теряет внимание к важным правилам. Хорошая обвязка хранит знания о проекте во внешних markdown-файлах и подгружает только тот фрагмент, который нужен на текущем шаге.

Второй слой, цикл, отвечает за доказательства и сходимость. Вопрос «ты уверен, что всё правильно?» запускает замкнутый круг: модель оценивает собственное вероятностное предсказание и подтверждает исходную ошибку. Цикл подключает объективные датчики. Это тест-раннеры вроде pytest, vitest или cargo test, валидаторы JSON-схем и линтеры, а также бюджет попыток, например не больше четырёх, после чего решает человек. Модель предлагает исправление, обвязка запускает тесты и возвращает ей сырой вывод терминала. Работа продолжается, только когда механическая проверка подтвердила фикс.

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

Пять правил личной обвязки

Для harness engineering не нужна корпоративная платформа. Хватит пяти механических правил в повседневной работе.

Каждый запрос оформляйте как контракт. Разговорный промпт позволяет модели тихо переопределить успех. Встретив трудность, она решает соседнюю задачу попроще и докладывает о победе. Контракт до начала генерации фиксирует точное имя и формат результата, ограничения (разрешённые зависимости, стиль, бюджет токенов), список того, что трогать нельзя, и условие, при котором задача считается закрытой. Без контракта модель сама решает, когда закончила. С контрактом это решают критерии приёмки.

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

Выносите память в файлы. История чата годится только как черновик. В долгой сессии внимание падает, окно заполняется. Архитектурные решения, предпочтения и открытые баги храните в отдельном файле проекта: в Claude Code это CLAUDE.md, в Cursor файл .cursorrules. Новая сессия начинается с его чтения, и работа продолжается с того же места. Такая память переживёт очистку чата, лимиты и смену модели.

Сначала датчики, потом автономия. Агент не исправит ошибку, которую не видит. Просьба «пиши код без багов» ничего не меняет. Команда, которая возвращает нулевой код выхода или стектрейс, даёт модели опору на факты. Компиляторы и тайпчекеры, тестовые скрипты для проверки преобразований данных, валидаторы обязательных полей превращают субъективное «вроде нормально» в проверяемый результат. Модель создаёт артефакт, датчик выдаёт вердикт, обвязка решает, засчитан ли запуск.

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

Микро-обвязка за пять минут

Вот структура, которую можно положить в любой репозиторий, Claude Project или рабочее пространство Cursor. Сохраните её как HARNESS.md в корне проекта:

# Операционный контракт проекта ## Рабочие границы - Разрешённая зона: меняй только файлы, явно указанные в текущей задаче - Запрещено: удалять существующие тесты, добавлять непроверенные зависимости ## Карта проекта - /src: исходный код приложения - /tests: наборы тестов - /docs/decisions.md: журнал принятых архитектурных решений ## Протокол проверки Прежде чем отметить задачу выполненной, по порядку запусти: 1. Линтер: npm run lint 2. Тесты: npm test 3. Проверку, что формат вывода соответствует запрошенной схеме ## Эскалация ошибок Если тест дважды падает с одной и той же ошибкой: - останови автономные правки - выведи точный лог ошибки - опиши предлагаемое исправление и жди подтверждения пользователя

Этот короткий файл заменяет двадцать строк повторяющихся инструкций в каждом чате. Он задаёт рамки проекта, контролирует доступ к файлам и заставляет модель проходить механическую проверку.

Два прохода вместо одного

Для сложных задач на рассуждение в обычном чате пригодится цикл из двух проходов. Большинство пользователей принимают первый же черновик, а в продакшене генерацию и критику разносят по разным шагам. Первый проход отвечает за исполнение:

Подготовь техническую спецификацию для [Фича X]. Соблюдай ограничения из HARNESS.md. Пока не оценивай собственный результат. Выведи черновик как есть и перечисли все сделанные допущения.

Второй проход устраивает разбор с позиции скептика:

Проверь черновик выше как скептичный senior-ревьюер. Пройдись по конкретным точкам отказа: 1. Обрабатываются ли граничные случаи, когда входной массив пуст? 2. Добавляет ли логика лишние зависимости? 3. Нарушает ли решение какое-то ограничение из HARNESS.md? Перечисли все найденные проблемы. Затем выведи исправленную версию, закрыв эти пробелы.

По наблюдениям автора оригинальной статьи, разделение ролей автора и ревьюера сокращает выдуманные утверждения примерно вдвое. Модели сложно защищать свои ошибки, когда ей прямо поручено их искать.

Почему обвязка окупается

Модели обновляются раз в несколько месяцев. Промпт, который работает сегодня, на следующем чекпоинте может вести себя иначе. Когда выходит новый Claude или очередная reasoning-модель от OpenAI, промпты, возможно, придётся слегка подправить. Тесты, карта проекта, границы прав и файлы состояния останутся на месте и сразу заработают с новой моделью.

Модель даёт вычислительную мощность, обвязка прокладывает рельсы, по которым эта мощность превращается в надёжный результат. Так что в следующий раз, когда агент споткнётся, начните с обвязки, а промпт оставьте напоследок.