← Agent Reliability Lab Harness Engineering
0/8 модулей

Почему способные агенты всё равно проваливаются

Модуль 1 · AI-агенты и harness engineering

🔑 Главный тезис

Способность модели не равна надёжности исполнения. Когда задача выходит за пределы одного простого промпта, узкое место почти всегда — harness (окружение агента), а не сама модель.

Метафора: «Дело в седле, а не в лошади.»
Самая умная лошадь спотыкается на неровной трассе без правильной экипировки. Та же модель — победитель в тестах — будет раз за разом проваливаться в реальных задачах, если окружение не настроено.

🧪 Контролируемый эксперимент

В лекции показан один и тот же проект — создание 2D-игры с нуля — с двумя разными подходами:

❌ Без harness

  • Время: ~20 минут
  • Стоимость: ~$9
  • Результат: нерабочий код
  • Агент самостоятельно выводил конвенции, забывал их, нарушал

✅ С полным harness

  • Время: ~6 часов
  • Стоимость: ~$200
  • Результат: играбельная игра
  • Harness направлял агента на каждом шаге
30× разница в стоимости — и это разница между «сломанным» и «работающим». Дороже не значит умнее; дороже означает: агент не ходил по кругу.

🧱 5 защитных слоёв: модель провалов

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

Слой 1 — Расплывчатая спецификация задачи

Нет явного, проверяемого Definition of Done. Агент заканчивает, когда ему кажется, что задача решена — без объективного критерия завершения.

Признак: «Реализовать авторизацию» вместо «POST /login возвращает 200 с токеном; тест test_login_ok проходит».

Слой 2 — Неизвестные конвенции / архитектура

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

Признак: Агент пишет код, синтаксически верный, но нарушающий скрытые архитектурные соглашения.

Слой 3 — Неполное dev-окружение

Непонятно, как собрать, запустить и протестировать проект. Переменные окружения, зависимости, конфигурация не задокументированы.

Признак: Агент запускает тесты «как придётся» — и они проходят случайно или не проходят по внешним причинам.

Слой 4 — Отсутствие механизмов верификации

Команды-гейты (линтеры, тесты, проверки конвенций) либо отсутствуют, либо есть, но агент их не запускает перед отгрузкой.

Признак: Агент сообщает «готово», но ни одна автоматическая проверка не была запущена.

Слой 5 — Потеря контекста между сессиями

В каждой новой сессии агент заново выводит знания о проекте с нуля. Решения, принятые вчера, неизвестны сегодня.

Признак: Агент задаёт одни и те же вопросы или делает одни и те же выводы снова и снова.

📏 Verification gap

Verification gap — расстояние между «агент сказал "готово"» и «результат реально корректен».

gap = false_done / N
N — количество задач; false_done — сколько раз агент отрапортовал «готово», а внешняя проверка показала провал. Измеряется на реальном корпусе прогонов.
На корпусе из 21 прогона в notify-эксперименте gap составил 4/21 ≈ 19%. Почти каждая пятая задача — ложное «готово».

🔄 Diagnostic loop

Главный механизм улучшения harness — итеративный цикл диагностики:

  1. Воспроизведи провал — повтори условия, при которых агент ошибся.
  2. Отнеси к слою — какой из 5 слоёв стал причиной?
  3. Почини этот слой — только его, не трогай остальные.
  4. Перезапусти — убедись, что провал не воспроизводится.
  5. Повтори 3–5× — пока все системные проблемы не устранены.
Diagnostic loop — не отладка кода агента. Это отладка окружения. Ты чинишь не модель, а трассу.

🧩 Интерактив 1: Отнеси провал к слою

Реальные сценарии из notify-эксперимента (lesson 1). Для каждого — выбери правильный слой.

📋 Агент сделал import urllib.error в channels.py, нарушив скрытую конвенцию «HTTP только через notify.http.post_json». Он не знал об этой конвенции. Какой слой?
Слой 1 — расплывчатая спецификация
Слой 2 — неизвестные конвенции
Слой 3 — неполное dev-окружение
Слой 4 — отсутствие верификации
🔍 Линтер scripts/conventions.py существовал в репо, но агент его ни разу не запустил и отгрузил нарушение, считая задачу выполненной. Какой слой?
Слой 2 — неизвестные конвенции
Слой 3 — неполное dev-окружение
Слой 4 — механизм верификации был, но не запущен
Слой 5 — потеря контекста
⚙️ Тесты требуют NOTIFY_ENV=test, но это нигде не задокументировано. Агент запустил их без переменной — они прошли случайно (упали бы в CI). Какой слой?
Слой 1 — расплывчатая спецификация
Слой 2 — неизвестные конвенции
Слой 3 — неполное dev-окружение
Слой 5 — потеря контекста
🔁 Каждую новую сессию агент заново выводит те же конвенции проекта с нуля, тратит время и иногда приходит к другим выводам. Какой слой?
Слой 1 — расплывчатая спецификация
Слой 2 — неизвестные конвенции
Слой 4 — отсутствие верификации
Слой 5 — потеря контекста между сессиями

🧮 Интерактив 2: Калькулятор verification gap

Введи параметры своего корпуса прогонов — и узнай, насколько велик разрыв между «агент сказал готово» и «реально корректно».

Пример из notify-эксперимента (lesson 1): на одной конкретной задаче gap был 1/1 = 100% — агент отрапортовал «готово», но единственная проверка показала провал. На корпусе из 21 прогона: 4 ложных «готово» → gap ≈ 19%.

🔭 Что дальше?

Теперь ты знаешь, почему агенты проваливаются и как классифицировать провалы. В следующем модуле разберём, из чего harness сделан — конкретные инструменты и практики для каждого из пяти слоёв.

Теперь ты видишь: проблема почти всегда в окружении, не в модели. Ты умеешь отнести любой провал агента к одному из 5 защитных слоёв и знаешь, как измерить verification gap на своём корпусе задач.

🔧 Из чего сделан harness

5 подсистем — анатомия инженерной инфраструктуры агента

В модуле 1 мы разобрали 5 слоёв провалов — места, где агент ломается. Теперь разберём, чем наполнен хорошо устроенный harness, чтобы эти провалы не случались. Ключевое определение:

Harness — всё в инженерной инфраструктуре вне весов модели. Модель — это черный ящик, который вы не трогаете. Harness — всё вокруг него.

Репозиторий — это и есть спецификация harness. Если чего-то нет в репо, для агента этого не существует.

🍳 Кухонная метафора: 5 подсистем

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

📋 1. Instructions — полка рецептов

AGENTS.md / CLAUDE.md — примерно 100 строк. Содержит:

  • Цель проекта в одну фразу
  • Стек и версии зависимостей
  • Bootstrap-команды для старта
  • Жёсткие ограничения и конвенции

Детали — в docs/, читаются по требованию. Не пытайтесь запихнуть всё в один файл.

🔪 2. Tools — ножи

Адекватный доступ к shell, CLI, сети. Принцип: least-privilege, но не «всё выключено».

Агент, которому запрещено pip install, не может установить зависимость — он просто застрянет. Инструменты должны соответствовать задаче.

🍳 3. Environment — плита

Самоописываемый рантайм: lock-файлы, .python-version / .nvmrc, Docker / devcontainer.

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

🗂 4. State — стол для заготовок

PROGRESS.md: done / in-progress / blocked. Пишется в конце сессии, читается в начале следующей.

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

✅ 5. Feedback — окно ОТК

Явные команды верификации: тесты, типы, линт — и единая точка входа:

make check
или python check.py — один вызов запускает все проверки

Без явного Feedback агент не понимает, готов ли результат. Он говорит «готово» — и ошибается.

⚡ Порядок атаки: Feedback first

Когда вы строите harness с нуля — не начинайте с самого очевидного. Начните с того, что даёт максимальный ROI при минимальных затратах:

  1. Feedback — один скрипт проверки. Агент наконец понимает «готово» vs «сломано».
  2. Instructions — краткий AGENTS.md. Контекст проекта с первых секунд.
  3. StatePROGRESS.md. Память между сессиями.
  4. Environment — lock-файлы и .python-version.
  5. Tools — разрешения, CLI-доступ. Обычно уже есть, нужна настройка.
Feedback — самая дешёвая подсистема в реализации и самая дорогая в отсутствии. Даже один тест лучше, чем ни одного.

🔗 Связь двух линз: слои провалов → подсистемы

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

Слой провала (M1) Подсистема harness
L1 — нет контекста задачи 📋 Instructions
L2 — нарушены конвенции 📋 Instructions
L3 — не воспроизводит окружение 🍳 Environment + 🔪 Tools
L4 — не верифицирует результат ✅ Feedback
L5 — теряет контекст между сессиями 🗂 State

📊 Интерактив 1: Эффект harness на реальном проекте

Кейс из практики: TypeScript + React, ~20 000 строк, модель GPT-4o. Модель не менялась. Добавлялись подсистемы harness — и росли результаты.

С 20% до 80–100% успешных прогонов — без смены модели. Это и есть harness engineering: окружение делает модель умнее, чем она «умеет» сама.

🧩 Интерактив 2: Слой провала → какая подсистема чинит?

Три сценария — определите, в какую подсистему harness нужно инвестировать.

❶ «Агент отправляет пулл-реквест с пометкой "готово", но тесты падают — он этого не знал.» Какая подсистема harness не настроена?
📋 Instructions
✅ Feedback
🗂 State
🍳 Environment
❷ «Каждую новую сессию агент заново расспрашивает: "Что мы уже сделали? Какие файлы трогать не надо?" — тратит на это 10 минут.» Чего не хватает?
🔪 Tools
✅ Feedback
🗂 State
🍳 Environment
❸ «Конвенция "все ошибки должны наследовать NotifyError" нигде не зафиксирована. Агент создаёт исключения произвольно.» Что нужно добавить?
📋 Instructions
✅ Feedback
🗂 State
🍳 Environment

🔬 Интерактив 3: Ablation-калькулятор

Isometric model control — экспериментальный метод: держите модель постоянной, отключайте (ablate) по одной подсистеме за раз, измеряйте просадку успеха. Так узнаёте, какая подсистема важнее именно для вашего проекта.

Самая большая просадка при отключении подсистемы → туда инвестировать harness-работу первой. Не угадывайте — измеряйте.
Теперь вы знаете 5 подсистем harness: Instructions, Tools, Environment, State, Feedback. Можете диагностировать провал через слой (M1) и направлять фикс в нужную подсистему. Начинайте с Feedback — дёшево, высокий ROI. Дальше — почему репозиторий должен стать системой записи (системой единой истины о проекте).

🗄️ Репозиторий как система записи

Модуль 3 · Harness Engineering — только то, что попало в репо, существует для агента

Единственный источник истины для агента

Агент работает в изолированном информационном пузыре: он видит системный промпт, текст задачи, файлы репозитория и вывод инструментов. Всё остальное — Slack-треды, Jira-тикеты, Confluence-страницы, устные договорённости — для него не существует.

🔑 Центральный тезис модуля

«Информации, которой нет в репозитории, для агента не существует.»

Это означает: репо должно стать системой записи — авторитетным источником по решениям, ограничениям, текущему состоянию проекта и стандартам проверки. Не вторичным архивом, а единственным местом, куда агент (и любой новый член команды) смотрит за правдой.

Сравни с базой данных: строка, которую не записали, — потеряна навсегда. Знание, которое «все знают», но ни разу не зафиксировали в файле, — потеряно для агента навсегда.

Cold-Start Test — пять вопросов

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

❶ Что это за система?

Назначение, домен, основные пользователи. → README.md

❷ Как она устроена?

Архитектура, модули, интерфейсы. → ARCHITECTURE.md

❸ Как её запустить?

Зависимости, команды, env-переменные. → CLAUDE.md

❹ Как проверить?

Тесты, lint, критерии приёмки. → AGENTS.md

❺ Каково текущее состояние?

Что в процессе, что заблокировано, какие решения приняты. → PROGRESS.md

Пробел в любом из пяти = пробел знаний в репо. Агент либо застрянет, либо придумает ответ сам — и ошибётся.

🧮 Interactive 1 — Cold-Start Scorer

Оцени свой репозиторий по каждому вопросу (0 = нет информации, 1 = исчерпывающий ответ). Калькулятор покажет итоговый балл и примерный KVG (Knowledge Visibility Gap).

📊 Реальные замеры (курс harness engineering):
  • Репо с AGENTS.md + PROGRESS.md: 4.7 / 5, KVG 6%
  • Базовый репо (только код): 3.2 / 5, KVG 36%

Цель: KVG < 10%. При KVG > 30% агент системно галлюцинирует критичные детали.

Три метрики здоровья репозитория

KVG — Knowledge Visibility Gap

Доля проектно-критичных решений и ограничений, которые живут вне репозитория: в головах, Slack, почте.

KVG = (решения_вне_репо / все_критичные_решения) × 100%
Цель: KVG < 10%. Выше — агент систематически принимает решения без нужного контекста.

Discovery Cost — стоимость обнаружения

Сколько токенов контекст-бюджета агент тратит, чтобы найти нужное, даже если оно есть в репо. Информация может существовать, но быть закопанной в гигантский файл или рассыпанной по десяткам папок.

Принцип «знание рядом с кодом»: ARCHITECTURE.md и CONSTRAINTS.md в каждом модуле → агент находит контекст за 1 шаг. Один мега-документ → 10+ шагов поиска.

Knowledge Decay Rate — скорость устаревания

Доля документов, которые дрейфуют от кода со временем. Код эволюционирует — документация часто остаётся на месте.

Устаревшая документация хуже отсутствующей. Когда документации нет — агент остановится и спросит. Когда она есть, но неверна — агент уверенно пойдёт по ложному пути. Mis-route стоит дороже остановки.

Решение: размещать доки рядом с кодом, который они описывают (src/payments/ARCHITECTURE.md, а не docs/legacy/payments.md). Тогда PR, меняющий код, неизбежно проходит мимо документации — и reviewer замечает расхождение.

ACID для управления состоянием агента

Принципы ACID из баз данных применимы к git-репозиторию как к хранилищу состояния агентской работы.

A — Atomicity (Атомарность)

Каждый логический шаг = один git-коммит. Незавершённая работа — в git stash, не в рабочей директории. Откат всегда возможен.

git add -p          # только нужные изменения
git commit -m "feat: add retry logic"
git stash           # если нужно прервать
C — Consistency (Согласованность)

Верификация (тесты / lint) гейтит каждый коммит. Сломанные состояния не попадают в историю. Pre-commit hook — простейший способ.

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: run-tests
        entry: pytest -q
I — Isolation (Изоляция)

Параллельные агенты используют отдельные ветки или git worktree. State-файлы именуются по агенту, чтобы не конфликтовать.

git worktree add ../agent-b feature/b
# agent A: main
# agent B: ../agent-b (изолировано)
D — Durability (Долговечность)

Кросс-сессионное знание живёт в трекаемых файлах репо, а не в истории чата. История чата исчезает при старте новой сессии.

PROGRESS.md      ✓ переживает сессию
DECISIONS.md     ✓ переживает сессию
chat history     ✗ исчезает
git init → Atomicity (коммит-юниты) + Isolation (ветки/worktree)
Первая команда в новом проекте автоматически включает два из четырёх измерений ACID. Consistency даёт pre-commit hook; Durability — PROGRESS.md в первом коммите.

Знание рядом с кодом

Один мега-документ в корне — антипаттерн. Когда репо вырастает, агент тратит весь бюджет на поиск нужного абзаца. Правило:

  • Каждый модуль / сервис / библиотека — своя ARCHITECTURE.md и CONSTRAINTS.md
  • Корневой CLAUDE.md — только навигация и команды запуска/проверки
  • Корневой PROGRESS.md — живое состояние: что в работе, что заблокировано, какие решения приняты сегодня
project/
├── CLAUDE.md              # навигация + команды
├── PROGRESS.md            # текущее состояние
├── src/
│   ├── payments/
│   │   ├── ARCHITECTURE.md   ← агент читает сразу при входе в модуль
│   │   ├── CONSTRAINTS.md    ← ограничения рядом с кодом
│   │   └── *.py
│   └── auth/
│       ├── ARCHITECTURE.md
│       └── *.py
└── tests/
    └── AGENTS.md          # критерии приёмки тестов

🧠 Проверь себя

git init на проекте автоматически поднимает какие два измерения ACID?
Atomicity + Isolation
Consistency + Durability
только Durability
ни одно из четырёх
Почему устаревшая документация хуже, чем её отсутствие?
Занимает лишнее место на диске
Она активно сбивает агента с пути (mis-route), создавая ложную уверенность
Нет разницы — отсутствие и устаревание одинаково плохи
Она замедляет операции git
Теперь ты знаешь: агент видит только то, что есть в репозитории. Cold-Start Test (5 вопросов) выявляет пробелы знаний. KVG < 10% — цель. Discovery Cost снижается, когда документация лежит рядом с кодом. Устаревшие доки активно вредят — размещай их рядом с кодом, который они описывают. ACID-принципы git (Atomicity + Isolation «из коробки») делают состояние агента атомарным, согласованным и воспроизводимым между сессиями.

Дальше — почему один гигантский файл инструкций начинает вредить и как правильно структурировать контекст агента.

М4 📄 Почему один гигантский файл инструкций проваливается

Instruction Bloat, Lost-in-the-Middle и принцип Progressive Disclosure

В М1–М3 мы убедились, что наличие правила в AGENTS.md критически важно. Теперь разберём оборотную сторону: если продолжать складывать всё в один файл, он начинает вредить. Файл размером ~300+ строк замедляет агента, снижает точность и размывает приоритеты.

🗻 Феномен Instruction Bloat

Instruction Bloat — когда файл инструкций разрастается настолько, что занимает значительную долю контекстного окна. Эмпирическое правило: файл инструкций > ~10–15% окна контекста начинает вытеснять рабочую информацию о задаче.

Механика: у современных моделей окно ~128–200 K токенов. Системный промпт, история чата, код файлов, diff — всё конкурирует за это место. AGENTS.md на 600 строк ≈ 4–6 K токенов. При задаче с большим diff или несколькими файлами инструкции буквально выдавливают рабочий контент на периферию окна.
bloat_ratio = len_instructions / context_window · 100%
Если bloat_ratio > 10–15% — пора делить файл. При 128 K окне это ≈ 13–19 K токенов (~1 900–2 700 слов, ~150–200 строк плотного текста).

📍 Lost in the Middle (Liu et al., 2023)

Исследование показало, что LLM лучше используют информацию в начале и конце длинного контекста. Информация в середине — «тонет». Практический вывод: критичные правила нельзя зарывать в середину длинного файла.

Честный эмпирический угол. Эффект lost-in-the-middle проверяли руками (15 прогонов Sonnet, три позиции критичного правила в 288-строчном AGENTS.md): результат — 0 из 15 нарушений. Позиционный эффект не появился на ~300 строках с современным Sonnet.

Чтобы получить сигнал, нужно: ~1 000+ строк, правило, которое перебивает дефолтное поведение (а не подкрепляет его), более слабая модель или конкурирующая ложная альтернатива в середине.

Вывод: заявление про позицию правила калибровано под раздутые файлы (~600+ строк). На ~300 строках современный Sonnet не теряет правила ни в одной позиции. Зато вывод М1 — присутствие правила важно — остаётся в силе.

📊 Signal-to-Noise Ratio инструкций

Instruction SNR — доля пунктов файла, релевантных текущей задаче. Если агент работает над добавлением нового канала уведомлений, а в AGENTS.md 37 пунктов, из которых к этой задаче относятся только 30 — SNR = 81%. Если же он запускает тесты, релевантны только 18–19 пунктов — SNR = 50%.

Низкий SNR — это шум: агент тратит внимание на нерелевантные правила и может применить их некстати («правило про webhook неожиданно применяется к рефакторингу»).

🔢 Интерактив 1 — SNR-калькулятор

Введите число релевантных пунктов и общее число пунктов в файле — получите SNR. В Lesson 4 «всегда-релевантных» через все 5 типов задач оказалось 9 из 37 — это скелет будущего routing-файла (SNR скелета = 100%).

📊 Интерактив 2 — SNR по типам задач

Один и тот же AGENTS.md даёт разный SNR в зависимости от типа задачи. Среднее по 5 типам ≈ 48% — почти половина инструкций в любой задаче является шумом.

Данные Lesson 4: T1 — добавление канала, T2 — отладка ошибок, T3 — написание тестов, T4 — рефакторинг, T5 — обновление зависимостей. Среднее SNR ≈ 48%.

🗺️ Routing File: таблица вместо прозы

Routing File — короткий файл (50–200 строк), который не содержит деталей, а указывает на тематические документы. По сути это таблица: условие → документ.

Пример структуры Routing File:
## Условия → документация

| Условие                          | Документ                     |
|----------------------------------|------------------------------|
| Добавляешь новый канал           | docs/channels.md             |
| Меняешь схему БД                 | docs/db-migrations.md        |
| Пишешь или меняешь тесты         | docs/testing-guide.md        |
| Деплой / CI                      | docs/deploy.md               |
| Изменения в зависимостях         | docs/deps-policy.md          |
| Любая задача (safety-правила)    | docs/safety-critical.md      |

Главный routing-файл сам — не длиннее 50–80 строк. Детали — только в тематических доках.

Тематические доки скоупируй по области кода (channels, db, deploy), а не по теме (security, performance). Агент работает с кодом — он знает, что меняет, но не всегда знает, к какой «теме» это относится.

🔭 Progressive Disclosure

Progressive Disclosure — принцип «обзор сейчас, детали по требованию». Routing-файл даёт быстрый ориентир, детальные доки загружаются только когда нужны. Агент не «читает весь учебник» перед каждой задачей — он ищет нужную главу.

❌ Монолит (антипаттерн)
  • AGENTS.md — 600 строк
  • Все правила в одном месте
  • Агент читает всё целиком
  • SNR ≈ 30–50% для любой задачи
  • Критичные правила тонут в середине
✅ Routing + тематические доки
  • AGENTS.md — 50–80 строк (таблица)
  • Детали — в отдельных файлах
  • Агент читает только нужный doc
  • SNR ≈ 80–100% для каждого дока
  • Safety-правила — отдельный файл, всегда загружается

📖 Кейс: SaaS-команда, 50 → 600 строк → рефакторинг

Команда начала с AGENTS.md на 50 строк. За год, добавляя правила по одному, файл вырос до 600 строк. Что произошло:

  • Успешность задач: 45% (агент применял правила не к тем контекстам)
  • Соблюдение safety-правил: 60% (критичные правила оказались в середине)
  • Жалобы команды: «агент игнорирует наши требования к деплою»

После рефакторинга: routing-файл (80 строк) + 6 тематических документов:

  • Успешность задач: 45% → 72%
  • Соблюдение safety-правил: 60% → 95% (критичные правила вынесены в отдельный doc, который загружается всегда)
Ключевое изменение — safety-правила ушли из середины 600-строчного монолита в отдельный файл docs/safety-critical.md, который routing-файл явно указывает для любой задачи.

🧪 Интерактив 3 — Проверь понимание

Вопрос 1. Когда пора рефакторить AGENTS.md в routing-файл + тематические доки?
Сразу, всегда — routing-файл лучше любого монолита
Когда файл > ~150 строк ИЛИ SNR частой задачи < 50%
Когда файл > 1 000 строк
Никогда — один файл всегда удобнее
Вопрос 2. Воспроизвёлся ли эффект «lost-in-the-middle» на файле в 288 строк с Sonnet (эксперимент, 15 прогонов)?
Да — правило в середине регулярно игнорировалось
Да — правило в середине нарушалось примерно в 50% случаев
Нет — 0/15 нарушений, позиция правила не повлияла на этом размере
Эксперимент не проводился — это теоретическое утверждение
Теперь ты умеешь диагностировать Instruction Bloat и Instruction SNR, знаешь, что «lost-in-the-middle» калибровано под ~600+ строк и современными Sonnet-моделями не воспроизводится на ~300 строках, и можешь спроектировать Routing File с Progressive Disclosure: короткий обзорный файл-таблица + тематические доки, скоупированные по области кода.

Дальше — жизненный цикл сессии: инициализация и преемственность контекста между запусками агента.

Жизненный цикл сессии

Инициализация как отдельная фаза · Преемственность контекста между сессиями

В предыдущих модулях мы разбирали, как агент выбирает задачи и строит план. Теперь — про то, что происходит внутри одной сессии и на стыке сессий: инициализация и передача контекста.

A. Инициализация как отдельная фаза

Типичная ошибка: агент сразу пишет бизнес-код, не заложив фундамент. Инструменты не настроены, тесты не запускаются, пути не созданы — и первый же import рушит всё. Это смешивание Initialization и Implementation.

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

Аналогия: фундамент и стены

Заливать фундамент и строить стены одновременно — гарантия переделок. Сначала фундамент схватывается, потом стены. Так же с агентом: сначала среда проверяется, потом пишется код.

Bootstrap Contract — 4 обязательных условия

Инициализация считается завершённой, когда выполнены все четыре пункта:

  1. Можно запустить — среда поднимается без ошибок
  2. 🧪 Можно протестировать — хотя бы один тест проходит зелёным
  3. 📊 Виден прогресс — есть измеримый артефакт (файл, лог, строка в БД)
  4. 🔗 Можно подхватить — следующий агент (или следующая сессия) понимает, что сделано и что дальше
Тёплый старт (шаблонная инфраструктура, готовые Makefile / pyproject.toml / AGENTS.md) сокращает инициализацию в разы. Пустая папка — самый медленный вариант.

TTFV — Time To First Verification

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

TTFV = t(first_green_test) - t(session_start)
Низкий TTFV → Bootstrap Contract выполнен быстро → фаза Implementation начинается на прочном основании.

🧩 Интерактив: Bootstrap Contract

Проверь понимание четырёх условий Bootstrap Contract.

Что НЕ входит в Bootstrap Contract?
Среда поднимается и запускается без ошибок
Следующая сессия понимает, что сделано и что дальше
Красивый README с бейджами покрытия и статусом сборки
Хотя бы один тест проходит зелёным

B. Контекст между сессиями

Каждая новая сессия начинается с чистого контекста. Без структурированного хэндоффа агент читает состояние с нуля и рискует принять решения, уже принятые ранее — и принять их иначе.

Recovery cost

Токены, потраченные на восстановление ментальной модели в начале сессии. Без артефактов преемственности — это чтение всех файлов подряд в надежде понять «что тут вообще происходит».

С хорошим PROGRESS.md и git-чекпойнтами recovery cost стремится к нулю: агент читает один файл и сразу знает, где он.

Context Anxiety

Находка Anthropic: Sonnet 4.5 вблизи лимита контекста проявляет преждевременную сходимость — выбирает более простые решения, пропускает верификацию, торопится закрыть задачу. Это не баг поведения, это рациональный ответ на ресурсное давление.

Если задача большая — дроби на сессии до наступления Context Anxiety, а не после. Разрыв между тем, что агент знает, и тем, что реально в репозитории — это Drift. Он накапливается незаметно.

Continuity Artifacts

📄 PROGRESS.md

Что сделано, что временно, почему выбрано именно это решение. Сохраняет почему, не только что.

📋 DECISIONS.md

Архитектурные решения и их обоснования. Предотвращает повторное открытие велосипеда в следующей сессии.

🔖 Git-чекпойнты

Чистые коммиты в конце каждой значимой фазы. Следующая сессия может сделать git log --oneline и мгновенно понять хронологию.

Честный вывод: когда PROGRESS.md действительно нужен?

PROGRESS.md — это страховка, а не ускорение. Он load-bearing только для ограничений, которые сам код выразить НЕ может. Code-выразимое состояние (хелперы, паттерны, интерфейсы) само течёт вперёд через код — следующая сессия находит его, просто читая файлы.
  • Lesson 2 ablation: удаление PROGRESS.md сломало рефакторинг — шим был помечен как «временный, удалить», но этой пометки не было в коде. Без записи шим выжил как мёртвый груз.
  • Lesson 5: на code-выразимой задаче arm без PROGRESS.md оказался дешевле по всем метрикам — код сам нёс решения.
Правило: пиши в PROGRESS.md только то, что код выразить не может. Всё остальное — в код.

🧩 Интерактив: Нужен ли тут PROGRESS.md?

Три сценария из реальных воркlogов. Для каждого — определи, нужен ли PROGRESS.md.

Сценарий 1. Сессия 1 извлекла хелпер _post_with_retry в channels.py; сессия 2 продолжает добавлять каналы.
Нет — решение выражено в самом коде, следующая сессия найдёт хелпер, просто читая файл
Да, обязательно — без записи следующий агент не поймёт, зачем нужен хелпер
Да — лучше задублировать в PROGRESS.md для надёжности
Сценарий 2. Шим обратной совместимости временный — его надо удалить после миграции, но в коде он выглядит как постоянный.
Нет — шим можно найти по имени файла
Да — «временность» нельзя выразить кодом; без записи шим выживет как мёртвый груз (реальный случай из lesson 2)
Нет — достаточно TODO-комментария в коде
Сценарий 3. Выбрали wire-ключ JSON "message", а не "body", потому что этого требует HTTP-контракт — и НЕТ теста, который это проверяет.
Нет — имя ключа видно в коде
Нет — надо просто добавить тест
Да — неочевидное решение без code-носителя; иначе следующая сессия «причешет» и тихо сломает контракт

📊 Стоимость дробления: marathon vs несколько сессий

Данные из lesson 5: одна и та же 3-канальная задача решалась тремя способами. Метрика — суммарные токены.

Загрузка графика…
Правило split-vs-marathon: дроби, когда одна сессия переполнила бы контекст — а не «всегда дроби». На малом масштабе marathon (один субагент на всё) в 3–4× дешевле дробления. Каждый хэндофф стоит токены: запись артефакта + его чтение в следующей сессии.
Когда дробить ✂️
  • Задача явно выходит за контекстное окно
  • Нужны разные специализации агентов
  • Есть независимые подзадачи для параллелизма
Когда marathon 🏃
  • Задача умещается в одну сессию
  • Высокая связность — агент несёт весь контекст в голове
  • Экономия на хэндофф-артефактах существенна
Разделяй Initialization и Implementation — Bootstrap Contract (запуск, тест, прогресс, подхват) и низкий TTFV — признаки здоровой инициализации. PROGRESS.md нужен только для того, что код выразить не может: временные решения, неочевидные выборы без тестов. Code-выразимое состояние само течёт через код. Marathon в 3–4× дешевле дробления на малых задачах — дроби только когда контекст реально переполняется.

Дальше — почему агенты берут слишком много задач одновременно и доводят слишком мало до конца (WIP=1).

Overreach и Under-finish: почему WIP=1

Агенты активируют слишком много задач за сессию и завершают слишком мало. Разберём механику и противоядие.

Overreach: слишком много задач в работе

Агент начинает сессию с амбициозного плана: «реализую сразу 5 фич». Каждая задача активируется — создаётся ветка, пишутся первые строки кода. Но к концу сессии ни одна не прошла верификацию. Это overreach: разбросанные частичные реализации вместо одной завершённой фичи.

📊 Кейс: REST API с 8 фичами

Без ограничений (WIP=∞)

  • Сессия 1: 5 фич активировано
  • ~800 строк, ~12 файлов
  • E2E-проход: 20%
  • За 3 сессии готово: 3/8 фич
  • Итоговый VCR: 37.5%

WIP=1

  • Сессия 1: 1 фича активировано
  • ~200 строк, ~4 файла
  • E2E-проход: 100%
  • За 4 сессии готово: 7/8 фич
  • Итоговый VCR: 87.5%

Under-finish и VCR

Under-finish — доля активированных задач, которые провалили верификацию несмотря на сгенерированный код. Overreach напрямую порождает under-finish: чем больше задач в работе, тем выше вероятность, что каждая из них не будет доведена до исполняемого доказательства.

VCR = verified_passing / activated
VCR (Verified Completion Rate) — доля задач, прошедших исполняемую верификацию. Блокируй новые активации, пока VCR < 1.0.

Proof of Completion: исполняемое доказательство

«На глаз» не считается. Задача завершена только тогда, когда существует исполняемое условие, которое можно запустить и которое проходит.

❌ Не доказательство

  • «Код выглядит правильно»
  • Code review прошёл
  • Линтер не нашёл ошибок
  • «Я проверил вручную»

✅ Исполняемое доказательство

  • pytest tests/test_feature.py -v → PASSED
  • curl -s /api/v1/item | jq '.id' → не null
  • assert result == expected в CI
  • Интеграционный тест, запущенный автоматически

Little's Law: математика WIP

Закон Литтла — фундаментальный результат теории очередей. Для стабильной системы:

L = λ · W
L = WIP (число задач в работе) · λ = пропускная способность (фич/день) · W = среднее время цикла одной задачи. Отсюда: W = L / λ.

Если λ = 1 фич/день и L = 5 (пять задач одновременно), то W = 5 дней на задачу. Держи L = 1 → W = 1 день → вероятность накопления ошибок минимальна.

🧮 Интерактив 1 — Калькулятор времени цикла (Little's Law)

Little's Law: W = L / λ
Передвиньте слайдеры для расчёта

📊 Интерактив 2 — Цена дисциплины WIP=1

Данные из реального эксперимента (lesson 7, worklog): ~700 строк, 6 фич, Sonnet. WIP=1 дороже по инструментам — но ловит то, что гейт пропускает.

Вызовов инструментов: без ограничений vs WIP=1

⚠ Честный эмпирический вывод

На малом масштабе (~700 строк / 6 фич / Sonnet) VCR-дифференциал лекции не воспроизвёлся — оба режима дали 100% на гейте. Что реально различалось: WIP=1 поймал 2 test-invisible бага, которые без-ограничений-режим отгрузил молча.

🐛 Test-invisible баги из реального worklog

Баг 1 — неверное наследование исключения:

# Без ограничений — отгружено молча:
class DispatchNotFound(Exception): ...   # ← НЕВЕРНО

# WIP=1 — поймано при внимательном обходе:
class DispatchNotFound(NotifyError): ... # ← ВЕРНО

# Вызыватели с "except NotifyError" промахиваются мимо
# DispatchNotFound — линтер по regex не видит наследование.

Баг 2 — потеря config-оверрайдов при retry:

# retry() пересоздаёт Dispatcher.from_config() со свежими
# дефолтами — config-оверрайды исходной отправки теряются.
# Тест проходил, потому что тестировал happy-path без оверрайдов.
Реальная ценность WIP=1 на небольшом масштабе — не сырой VCR, а три вещи:
1. Страховка от test-invisible пробелов — агент фокусируется на одной задаче и замечает тонкие несоответствия.
2. Bisectable git-история — один коммит на фичу, легко откатить и локализовать проблему.
3. Предсказуемое время цикла — по Little's Law W = L/λ, меньший WIP = меньше дней на фичу.

WIP=1 на практике: правила активации

  1. Одна активная задача за раз. Следующую задачу начинаем только после того, как текущая прошла executable proof of completion.
  2. Блокировка при VCR < 1.0. Если предыдущая задача не прошла верификацию — не активируем новую, сначала доводим текущую.
  3. Коммит на каждую фичу. После прохождения верификации — коммит с чётким сообщением. Это и bisectable история, и явная точка завершения.
  4. Proof of completion прописан заранее. Перед активацией задачи определяем конкретный исполняемый тест — иначе «готовность» остаётся субъективной.

🧠 Проверь себя

Когда WIP=1 реально окупается?
Всегда и на любом масштабе — VCR всегда выше
Когда есть test-invisible конвенции (которые гейт не ловит) и/или больший масштаб
Никогда — это просто медленнее без видимой пользы
Только на фронтенде, где тесты труднее писать
Little's Law: WIP вырос вдвое при той же пропускной способности λ. Что произошло со временем цикла W?
Не изменилось — λ же не изменилась
Выросло вдвое
Упало вдвое — больше задач, быстрее завершаем
Выросло вчетверо — нелинейный эффект перегрузки
Теперь ты знаешь: overreach → under-finish по механике Little's Law (W = L/λ). WIP=1 + executable proof of completion = предсказуемый цикл и защита от test-invisible багов. На небольшом масштабе главные выгоды — фокус, bisectable история и страховка от конвенциональных пробелов, а не просто сырой VCR. Дальше — фичи как структуры данных и многоуровневая валидация.

📋 Списки фич как структуры данных + многоуровневая валидация

Модуль 7 · AI-агенты и harness engineering

В модулях 1–6 мы говорили о том, что проверять и как строить гейты. Здесь — о том, где хранить скоуп и почему агенты объявляют победу слишком рано. Оба вопроса связаны: плохая структура данных о фичах = слепой гейт = ложная победа.

A. Список фич — структура данных, не планёрка

Типичная ошибка: список фич живёт в чате, трелло или голове менеджера. В harness-подходе список фич — это артефакт в репо, на котором работает автоматика. Он имеет строгую схему, версионируется и является входом для верификационного пайплайна.

🔷 Triplet — обязательная запись

Каждая строка списка фич несёт ровно три поля. Нет хотя бы одного — запись неполна и не может войти в пайплайн:

{ description, verify_cmd, state }
description — что система должна делать (поведение, не задача); verify_cmd — команда, которую harness выполняет для проверки; state — текущее состояние в машине состояний.
Пример полной записи:
{
  "description": "POST /api/send возвращает 200 и записывает сообщение в БД",
  "verify_cmd":  "pytest tests/test_send.py::test_send_200 -x -q",
  "state":       "passing"
}

Запись без verify_cmd — это пожелание, не фича. Запись без state — не отслеживается.

🔄 Feature State Machine

Каждая фича проходит 4 состояния. Переход → passing совершается только по успешному результату verify_cmd. Состояние passing — необратимо: регресс означает новый баг, а не откат.

  not_started ──→ active ──→ passing  (необратимо)
                    ↕
                 blocked
  • not_started — фича в скоупе, но работа не начата
  • active — в работе
  • blocked — есть блокер (ждёт зависимость / решение)
  • passingverify_cmd вернула exit 0 в CI; только так
Агент не может сам перевести фичу в passing. Только harness — после выполнения verify_cmd. Это State Passing Gate: доказательство, не самооценка.

📌 SSoT — Single Source of Truth

Вся информация о скоупе исходит из одного списка фич. Это цепочка: source → derived → executable. Каждое звено может дрейфовать — если PROGRESS.md расходится с кодом, harness теряет ориентир.

Дисциплина SSoT важнее всего на самом часто редактируемом артефакте — обычно PROGRESS.md, а не на самом большом файле. Фиксировать нарушение — не «удалить дубли», а явно пометить источник и обеспечить derivation: каждый производный артефакт помечается «сгенерировано из X, не редактируй вручную».

📊 State Pressure — метрика готовности

Число фич, не находящихся в passing — это State Pressure. Ноль = проект завершён. Это количественная, объективная метрика готовности — в отличие от субъективного «кажется, всё готово».

pressure = total_features − passing_features
Цель команды — свести pressure к нулю. Дашборд harness показывает давление в реальном времени.

🧮 Калькулятор State Pressure

B. Почему агенты объявляют победу слишком рано

Агенты судят по принципу «код, что я написал, выглядит правильно», а не «система E2E удовлетворяет спеке». Это систематическая ошибка, подкреплённая математикой.

📐 Calibration bias

Guo et al. (ICML 2017) показали: современные нейросети систематически переуверены — заявленная уверенность выше фактической точности. Модель говорит «95% что готово» там, где реальная точность — 70%.

Практический вывод: уверенность агента («выглядит готово», «должно работать») — не операциональное определение «готово». Операциональное определение — результат verify_cmd.

📊 Данные из worklog: weak vs strict проверка

Lesson 8 — 11 специально подброшенных багов. Два режима проверки:

FPR по режиму проверки
Что значат эти числа. Smoke (weak) проверяет лишь: «модуль импортируется + один вызов не падает». Это ловит только полные крэши. Из 11 подброшенных багов — 0 пойманы (FPR = 100%). Strict (unittest) — 9% FPR (1 из 11 пропущен). Даже strict имеет слепые зоны: баг F01 — вызов clear() внутри send(), но тест делает один send и не видит деградации при следующих вызовах. Вывод: smoke в качестве единственного гейта — операционально бесполезен.

📊 Данные из worklog: false-done и слепота гейта

Lesson 9 — 21 прогон, calibration bias = 24% (5/21 false-done). Ключевой ковариат: покрытие гейта:

false-done % по покрытию гейта
Главный вывод модуля: bias ≠ переуверенность модели как таковой — это заражение слепотой гейта. Там, где гейт покрывает всё → 0% false-done (0/16). Там, где у гейта слепая зона (правило, невидимое тестам) → 80% false-done (4/5). «Гейт зелёный» = операциональное определение «готово». Расширяй гейт — снижаешь ложные победы.

🔒 Dual verification-validation gateway

Чтобы победа была честной, нужны два независимых гейта:

L1 — Verification
«Код реализует спеку?»
unit-тесты, статический анализ, контракты
L2 — Validation
«Система отвечает E2E-требованиям?»
интеграция, E2E-сценарии, нагрузка

Оба обязательны. L1 без L2 = проверил детали, упустил систему. L2 без L1 = ловишь симптомы, не причины.

🏗️ 3-уровневая валидация

  1. Синтаксис / статический анализ — lint, type checker, компиляция. Быстро, локально, дёшево. Обязателен всегда.
  2. Рантайм-поведение — тесты выполняются, приложение стартует, критические пути проходят. Обнаруживает ошибки логики.
  3. Системное подтверждение — E2E, интеграция, acceptance-критерии. Единственный уровень, который подтверждает работу системы целиком.

Агент может пройти уровни 1 и 2 и всё равно провалить уровень 3. Это не исключение — это норма для сложных систем.

⚡ Completion priority constraint

Строгий порядок приоритетов:

functional → performance → style
Рефакторинг, оптимизация и улучшение стиля запрещены до подтверждения функциональности на всех трёх уровнях. Агент, занявшийся рефакторингом до прохождения E2E, нарушает это правило.
Классическая ловушка: агент чистит код и улучшает архитектуру, пока критический E2E-сценарий провален. Harness обнаруживает это через State Pressure — pressure не снижается, хотя работа «идёт».

🎯 Проверь себя

Вопрос 1: Что переводит фичу в состояние passing?
Самооценка агента «выглядит готово»
Только успешное выполнение её команды верификации
Code review
Прошёл дедлайн
Вопрос 2: Сколько из 11 подброшенных багов поймала weak smoke-проверка (lesson 8)?
0 (FPR 100%)
Все 11
9
5
Теперь ты умеешь: хранить фичи как Triplet (description + verify_cmd + state) в репо, а не в чате; отслеживать State Pressure как количественную метрику готовности; понимать, что переуверенность агента — это слепота гейта, а не характер модели; строить Dual L1+L2 гейт и соблюдать приоритет functional → performance → style.

Дальше — E2E, наблюдаемость рантайма и чистый выход из сессии.

Модуль 8: E2E-тестирование, наблюдаемость рантайма и чистый выход из сессии

Синтез курса: калибруй harness по давлению, а не по моде

A. Только E2E-тестирование меняет результат

Юнит-тесты проверяют каждый компонент в изоляции. Но агент — это система, где компоненты взаимодействуют. Межкомпонентные сбои юнит-тестам не видны:

  • Рассогласование интерфейсов — модуль A ожидает строку, B отдаёт dict: тесты обоих зелёные, система сломана.
  • Распространение состояния — ошибка в шаге 2 тихо меняет результат шага 4; каждый шаг тестируется независимо и проходит.
  • Зависимости окружения — тест мокает файловую систему, но в реальном окружении путь другой.

🔺 3-уровневая архитектура валидации

  1. Уровень 1 — Синтаксис / статика
    «Код парсится»: линтер, type-checker, python -m py_compile. Это необходимо, но не достаточно. Агент может генерировать синтаксически корректный код, который делает не то.
  2. Уровень 2 — Рантайм-поведение
    Тесты выполняются, приложение стартует, критические пути проходят (юнит + интеграция). Уже намного лучше — но межкомпонентные взаимодействия по-прежнему в слепой зоне.
  3. Уровень 3 — Системное подтверждение (E2E)
    Полный пользовательский сценарий: от входных данных до наблюдаемого результата. Только здесь проверяется, что система работает как целое.
Агент, чей verification gate остановлен на уровне 1–2, будет раз за разом сообщать «готово» — и раз за разом оказываться неправым в продакшне.

Кейс Anthropic: ретро-игровой редактор

Anthropic сравнил два подхода к одной задаче (идентичный промпт — разработать ретро-игровой редактор):

🤖 Голый одиночный агент
  • Время: ~20 минут
  • Стоимость: $9
  • Результат: нерабочий редактор
⚙️ Harness: planner + generator + evaluator
  • Время: ~6 часов
  • Стоимость: $200
  • Результат: полностью играбельный редактор

30× по стоимости — и это оправданная инвестиция: дешёвый прогон даёт сломанный артефакт, дорогой — рабочий. Evaluator-агент в harness выполнял именно E2E-проверку после каждой итерации.

📊 Сравнение стоимости: голый агент vs harness

Стоимость прогона, $

B. Сделай рантайм агента наблюдаемым

Агент без наблюдаемости работает в режиме «чёрного ящика»: он сам сообщает о своём состоянии, а его самооценка систематически смещена в сторону завершённости. Как в М3 мы говорили об ACID: нельзя доверять агенту, что транзакция завершена, — нужен внешний наблюдатель.

🔍 Инструменты наблюдаемости

  • Логи с уровнями — структурированные записи каждого шага агента. Позволяют ретроспективно понять, что именно произошло, а не что агент думал, что произошло.
  • Состояния процессов — явные статусы: pending / running / done / failed. Нет промежуточных «почти готово».
  • Health-checks — периодические автоматические пробы: «сервис отвечает?», «файл создан?», «схема БД соответствует?».
  • Пробы побочных эффектов — проверяй не только return value, но и то, что изменилось в окружении: файловая система, сеть, внешний сервис.
Наблюдаемость превращает «кажется, работает» в проверяемые сигналы. Только объективные сигналы могут служить основой для вывода о завершённости.

Практически: добавь в свой check.py (из М2) не только юнит-тесты, но и минимальный E2E-smoke: запусти приложение, пройди критический путь, убедись, что output совпадает с ожидаемым. Это и есть наблюдаемость рантайма в минимальной форме.

python check.py --e2e --smoke-only 2>&1 | tail -20
Запуск E2E smoke-теста из verification gate; последние 20 строк покажут результат критического пути.

C. Каждая сессия должна оставлять чистое состояние

Как в ACID-Durability (М3): транзакция либо применена полностью, либо откатана. Сессия агента — это транзакция над codebase. Нельзя оставлять half-done состояние, красный гейт или недокументированные решения.

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

✅ Чек-лист выхода из сессии

Отметь каждый пункт перед закрытием сессии:

Выполнено: 0 / 5

D. Синтез курса — мета-вывод

🧭 Главный мета-вывод: harness engineering калибруется по давлению

Через все восемь модулей прошла одна нить: методология harness engineering калибрована под режим, где harness-давление реально.

На малом масштабе (≤ ~700 строк, чистый код, сильная модель типа Sonnet, одна сессия) многие количественные заявления лекций не воспроизводятся:

  • М4: позиция правила в AGENTS.md не меняет результат
  • М5: PROGRESS-файл не ускоряет работу
  • М6: выделенный init даёт меньше фич, чем без него
  • М7: VCR-дифференциал незначим
  • М8: 45%-дифференциал качества не наблюдается

Это null-результаты — они не опровергают методологию. Они говорят о границе её применимости.

Два класса вещей окупаются ВСЕГДА — на любом масштабе:
  1. Присутствие ключевых артефактов: verification gate + явный проверяемый Definition of Done. Даже если гейт никогда не краснел — он задаёт контракт, который агент не может молча нарушить.
  2. Работа с test-invisible конвенциями: то, что гейт физически не ловит — именно там живут все false-done. Стиль, архитектурные решения, неявные ожидания — это нельзя проверить автоматически, но можно сделать явным через документацию и чек-листы.
Практическое правило: инвестируй в harness там, где давление реально — большой или грязный код, слабее модель, многосессионность, многоагентность. Не неси cargo-cult полный harness на toy-проекты.

🧪 Финальный квиз: синтез курса

Главный мета-вывод курса о методологии harness engineering?
Всегда применяй полный harness любой ценой
Harness не нужен с сильными моделями
Она калибруется по масштабу: присутствие гейта + явного DoD и работа с test-invisible конвенциями окупаются всегда, а количественные дифференциалы лекций воспроизводятся только под реальным harness-давлением
Всё дело в размере модели
Что юнит-тесты систематически не видят, из-за чего нужен E2E?
Синтаксические ошибки
Межкомпонентные сбои: рассогласование интерфейсов, распространение состояния, зависимости окружения
Опечатки в строках
Стиль кода
Ты прошёл все 5 слоёв harness engineering (verification gate, контекстная подсистема, подсистема инициализации, рантайм-наблюдаемость, E2E-подтверждение) и 5 подсистем harness-фреймворка. Теперь ты умеешь калибровать harness по масштабу: всегда ставь гейт + явный DoD, всегда работай с test-invisible конвенциями — и наращивай остальное только там, где давление реально.

Готово 🎉

8 модулей пройдены. Что теперь у тебя в инструментарии:

  • Видеть, что узкое место — не модель, а harness; относить каждый провал к одному из 5 защитных слоёв.
  • Различать 5 подсистем harness (Instructions / Tools / Environment / State / Feedback) и чинить Feedback первым.
  • Делать репозиторий системой записи: Cold-Start Test, KVG, ACID-состояние.
  • Разбивать раздутый AGENTS.md на routing-файл + topical-доки (SNR, lost-in-the-middle).
  • Держать контекст между сессиями: init-фаза, continuity-артефакты, handoff.
  • Вводить WIP=1 и executable proof of completion; считать VCR и Little's Law.
  • Строить feature lists как структуры данных и многоуровневую валидацию (weak vs strict).
  • Требовать E2E, делать рантайм наблюдаемым и оставлять чистое состояние сессии.
  • Калибровать методологию по масштабу — отличать заявления, что воспроизводятся, от тех, что работают только под реальным harness-давлением.

Что читать дальше

  • Walking Labs — «Learn Harness Engineering». Первоисточник курса: walkinglabs.github.io/learn-harness-engineering
  • Liu et al. (2023) — «Lost in the Middle». Эмпирика про деградацию внимания LLM к середине длинного контекста.
  • Guo et al. (ICML 2017) — «On Calibration of Modern Neural Networks». Почему нейросети систематически переоценивают свою уверенность.
  • Anthropic — инженерные заметки про агентов и контекст. Context anxiety, многоагентные harness, init-фаза.