Практическое руководство

Передача задачи от AI-агента человеку без потери контекста

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

Уровень: средний Чтение: до 8 минут Результат: карточка передачи, причины и следующие шаги

Что именно теряется при передаче

Фраза «операция завершилась ошибкой» описывает симптом, но не помогает продолжить работу. Человеку нужны ответы как минимум на пять вопросов:

  • какой результат ожидался;
  • что агент уже сделал и в каком порядке;
  • какие изменения действительно применились;
  • почему агент остановился;
  • какое действие можно безопасно выполнить дальше.

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

Минимальная карточка передачи

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

{
  "handoff_id": "example-2026-07-28-001",
  "created_at": "2026-07-28T12:00:00Z",
  "status": "needs_human",
  "goal": "Обновить описание тестовой записи",
  "current_state": "Чтение выполнено, запись не изменена",
  "reason": {
    "code": "permission_denied",
    "summary": "Инструмент отклонил операцию записи",
    "evidence": "HTTP 403 при запросе обновления"
  },
  "actions": [
    {
      "step": 1,
      "action": "Получена тестовая запись",
      "result": "success",
      "changed_state": false
    },
    {
      "step": 2,
      "action": "Подготовлено новое описание",
      "result": "success",
      "changed_state": false
    },
    {
      "step": 3,
      "action": "Запрошено обновление записи",
      "result": "failed",
      "changed_state": false,
      "error": "HTTP 403"
    }
  ],
  "artifacts": [
    {
      "type": "draft",
      "location": "./handoff/example-description.txt"
    }
  ],
  "assumptions": [
    "У агента есть доступ на чтение, но нет доступа на запись"
  ],
  "next_steps": [
    "Проверить право на обновление тестовой записи",
    "После выдачи права повторить только шаг 3",
    "Сверить описание повторным чтением"
  ],
  "do_not_repeat": [
    "Не создавать новую запись вместо обновления существующей"
  ]
}

Поле current_state особенно важно: оно отделяет намерение агента от фактического состояния. Если часть операции успела выполниться, это должно быть указано прямо.

Как внедрить передачу: воспроизводимые шаги

1. Зафиксируйте цель до первого действия

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

goal: "Обновить существующую тестовую запись"
done_when: "Повторное чтение возвращает ожидаемое описание"
constraints:
  - "Не создавать дубликаты"
  - "Не изменять другие поля"

2. Записывайте наблюдаемые действия

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

action:
  step: 3
  operation: "update"
  target: "test-record"
  result: "failed"
  changed_state: false
  error_class: "permission_denied"

3. Отделите причину от предположения

Ошибка 403 — наблюдаемый факт. Вывод «не хватает права на запись» — предположение, пока права не проверены. Карточка должна хранить их раздельно:

evidence: "Операция обновления вернула HTTP 403"
hypothesis: "У используемой роли отсутствует право на запись"
confidence: "medium"

4. Определите условие остановки

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

handoff_when:
  - error_class == "permission_denied"
  - approval_required == true
  - required_input_missing == true
  - retry_count >= 2

5. Сформируйте следующие шаги

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

  1. Проверить текущие права используемой роли.
  2. Убедиться, что целевая запись существует и не была изменена параллельно.
  3. Если доступ разрешён, повторить только неуспешную операцию.
  4. Прочитать запись и сравнить результат с критерием готовности.

Безопасная локальная проверка карточки

Следующие команды только читают локальный JSON-файл. В примере предполагается, что карточка сохранена как handoff.json и в ней нет секретов.

python3 -m json.tool handoff.json > /dev/null
python3 -c '
import json
from pathlib import Path

data = json.loads(Path("handoff.json").read_text(encoding="utf-8"))
required = {"status", "goal", "current_state", "reason", "actions", "next_steps"}
missing = sorted(required - data.keys())

if missing:
    raise SystemExit("Отсутствуют поля: " + ", ".join(missing))

print("Структура карточки заполнена")
'

Перенаправление в /dev/null проверяет синтаксис, не печатая содержимое карточки в терминал. Вторая команда проверяет только наличие обязательных полей и не обращается к сети.

Проверка результата

Карточка готова к передаче, если сотрудник может продолжить задачу без повторного расследования. Проверьте её по короткому списку:

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

Практический критерий: человек должен суметь ответить «что уже произошло?» и «что делать дальше?» после одного чтения карточки.

Типовые ошибки

Передавать только текст исключения

Permission denied не сообщает, какая операция выполнялась и успели ли примениться предыдущие изменения. Добавляйте цель, шаг и текущее состояние.

Смешивать факты и выводы

Фраза «сервис недоступен» слишком категорична, если наблюдался лишь тайм-аут одного запроса. Запишите тайм-аут как факт, а недоступность — как гипотезу.

Не отмечать частичный успех

Если первые два шага изменили систему, повтор всего сценария может создать дубликаты или перезаписать данные. Указывайте changed_state для каждой операции.

Прикладывать сырой журнал целиком

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

Давать расплывчатый следующий шаг

«Разобраться с доступом» хуже, чем «проверить наличие права обновления у роли, использованной в шаге 3». Следующий шаг должен быть проверяемым.

Не указывать запрет на повтор

Если операция необратима или уже могла выполниться, добавьте поле do_not_repeat и сначала предложите чтение текущего состояния.

Ограничения

  • Карточка не заменяет системный аудит: она отражает известное агенту состояние на момент передачи.
  • Признак changed_state: false надёжен только тогда, когда инструмент достоверно сообщает результат или выполнена отдельная проверка.
  • При параллельных изменениях человеком или другим агентом состояние может устареть; добавляйте время снимка и при наличии — версию объекта.
  • Некоторые причины нельзя подтвердить без дополнительных прав. В таком случае сохраняйте их как гипотезы.
  • Чувствительные поля следует удалять или маскировать до сохранения карточки, но маскирование не должно скрывать сам класс ошибки.

Итоговый шаблон

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