Human-in-the-Loop (HITL) — управляемое включение человека в AI-процесс в конкретной точке, где системе нужен approval, экспертное решение, обработка исключения, takeover или дополнительная ответственность.
№48 Guardrails & Policies решает, когда действие требует человека; №49 реализует сам approval/review/wait/resume lifecycle. №45 Verification машинно проверяет результат; HITL подключает человека там, где автоматической проверки недостаточно или нужна accountability. №42 Events & Triggers может доставить событие о human decision. №50 Contracts формализует payload решения. №51 Permissions определяет, имеет ли конкретный человек право approve. №68 Durable Workflow позже углубит persistence/replay/timers.
Prerequisites: №10 State Management, №41 Cognitive Architecture, №42 Events, №45 Verification, №46 Observability, №48 Guardrails & Policies. Forward references: №50 contracts, №51 permissions, №57 queues/workers, №58 scheduler, №68 durable execution, №76 governance/privacy.
REQUEST-TIME: CONDITIONAL — процесс может остановиться на gate. CONTROL PLANE: YES — reviewer roles, routing, SLA, escalation policy. DATA PLANE: INDIRECT — review package/evidence проходит через human interface. OFFLINE: YES — sampling review, calibration, audit, feedback analysis.
Success: authorized decision связан с exact review version и корректно resumes process. Retryable: notification/UI/API delivery failure. Business terminal: REJECT, EXPIRE, CANCEL. Idempotency: повтор decision/resume не создаёт двойной side effect. Persist: task, review package hash/version, actor, decision, timestamps, expiry, reason, state transition. Trace: request → wait → decision → resume/outcome.
№49 не владеет policy definitions, human identity system, permissions engine, workflow engine целиком, queue infrastructure, final verification или business governance. Она владеет HUMAN DECISION LIFECYCLE: HANDOFF → WAIT → DECIDE → RESUME.
Публикация, деньги, удаление, privileged change, юридически значимое действие.
Система не может безопасно выбрать между materially different actions.
Нужна ответственность или знание, которое нельзя надёжно автоматизировать.
Tool/retrieval/verifier не смогли завершить задачу в допустимом budget.
Человек разрешает или запрещает exact side effect. Самый важный production pattern.
Оценивает output/evidence, когда automated verifier недостаточен.
Исправляет draft/artifact; correction может стать feedback/eval case.
Автоматизация исчерпала retry/replan/escalation budget.
Специалист выбирает вариант, который нельзя формализовать только моделью.
Человек проверяет долю автоматически завершённых случаев для calibration и learning.
| Сигнал | Пример | Действие |
|---|---|---|
| High irreversible risk | Публикация, платеж, delete, privileged write. | REQUIRE_APPROVAL. |
| Policy requirement | Для определённого resource обязательна подпись владельца. | Route to authorized approver. |
| Material ambiguity | Два допустимых решения ведут к разным business outcomes. | Clarify or human decision. |
| Verifier uncertainty | Critical claim cannot be verified automatically. | Expert review. |
| Automation exhausted | Retries/replans/model escalation не помогли. | Exception handoff. |
| Sampling rule | 1–5% low/medium-risk cases for quality audit. | Async review; не обязательно блокировать user path. |
{
"review_id": "REV-...",
"task_id": "TASK-...",
"review_type": "APPROVAL",
"risk": "HIGH",
"proposed_action": {
"type": "publish_post",
"resource": "channel:brand_A",
"payload_hash": "sha256:..."
},
"summary": "...",
"evidence_refs": ["..."],
"policy_reason": "EXTERNAL_PUBLICATION",
"options": [
"APPROVE",
"REJECT",
"REQUEST_CHANGES"
],
"expires_at": "..."
}Не заставлять reviewer читать 100k tokens raw trace.
{
"decision_id": "DEC-...",
"review_id": "REV-...",
"actor": "user:123",
"role": "brand_owner",
"decision": "APPROVE",
"review_version": 4,
"payload_hash": "sha256:...",
"reason_code": "CONTENT_APPROVED",
"comment": "...",
"decided_at": "...",
"expires_at": "..."
}APPROVE — продолжить exact version.
REJECT — terminate/narrow path.
REQUEST_CHANGES — вернуть в controlled repair loop.
REQUEST_INFO — собрать недостающие данные и повторно представить.
ESCALATE — передать reviewer с большей authority/expertise.
CANCEL — закрыть задачу без side effect.
Система выполняет обычный task path.
Trigger сработал; proposal frozen.
State persisted; reviewer notified.
Decision записан, но ещё не применён.
Authority/version/expiry/hash confirmed.
Workflow продолжен idempotently.
Completed / rejected / expired / cancelled.
RUNNING
│
├─ no human needed ─────────────→ CONTINUE
│
└─ trigger
↓
REVIEW_REQUIRED
↓ freeze exact review version
WAITING_HUMAN
├─ APPROVE ─────────→ VALIDATE AUTH/VERSION → RESUME
├─ REJECT ──────────→ TERMINAL / REJECTED
├─ REQUEST_CHANGES ─→ REPAIR → NEW REVIEW VERSION
├─ REQUEST_INFO ────→ GATHER → NEW REVIEW VERSION
├─ ESCALATE ────────→ NEW REVIEWER / SLA
└─ TIMEOUT ─────────→ EXPIRE / ESCALATE / SAFE CANCEL
Text/action/evidence frozen. Hash = ABC.
Reviewer sees exactly this version.
Decision contains review_version=4 and payload_hash=ABC.
PEP confirms current payload hash still ABC. If changed → old approval invalid.
Queue ranking должна учитывать не только FIFO. Critical irreversible action с коротким SLA важнее non-blocking sampling review.
Reviewer eligibility фильтруется до назначения: expertise, tenant, permission, conflict-of-interest, workload.
| Событие | Безопасное поведение | Нельзя делать автоматически |
|---|---|---|
| SLA approaching | Reminder / re-route / raise priority. | Не снижать risk, чтобы ускорить. |
| Reviewer unavailable | Route to equivalent authorized role. | Не назначать случайного пользователя без authority. |
| Timeout high-risk approval | EXPIRE / SAFE CANCEL / escalate. | Не auto-approve. |
| Timeout low-risk review | По заранее заданной policy: continue/cancel/escalate. | Не импровизировать runtime behavior. |
| Decision arrives after expiry | Reject stale decision; issue new review if still relevant. | Не resurrect старый action silently. |
Имеет право принять binding decision для конкретного resource/action/risk class.
Может оценить качество/содержание, но не обязательно имеет permission на side effect.
Может выполнить действие после approval, но не обязательно имеет право его одобрять.
| Режим | Когда | Архитектура |
|---|---|---|
| Synchronous blocking | High-risk side effect должен ждать approval. | User/task waits; action not executed. |
| Asynchronous blocking | Decision может занять минуты/часы. | Persist wait state, notify, resume by event. |
| Asynchronous non-blocking | Quality sampling / audit уже завершённых low-risk cases. | User path completes; feedback enters eval/learning. |
| Post-action audit | Only where policy permits side effect before human check. | Human can flag/rollback/escalate, but not substitute required pre-gate. |
resume(review_id, decision_id):
if decision_id already_applied:
return previous_result
load task_state
verify review_version
verify payload_hash
verify actor_authority
verify not_expired
transition WAITING -> RESUMING
execute_or_continue_with_idempotency_key()
persist outcome
mark decision_id applied
transition -> RUNNING / TERMINALHuman UI может повторно отправить request. Notification webhook может прийти дважды. Worker может упасть после side effect, но до записи результата.
Поэтому decision ingestion и downstream action должны иметь idempotency semantics.
Policy/risk/verifier/exception reason code.
Queue age, SLA, reminders, reassignment.
Actor, role, version, choice, reason.
Resume path, actual side effect, final verification.
| Eval question | Как проверить |
|---|---|
| Правильно ли система escalates? | Representative set с expected HUMAN_REQUIRED / AUTO_OK. |
| Есть ли unnecessary HITL? | False escalation rate на low-risk cases. |
| Пропускаем ли risky cases? | Missed-gate rate / high-risk escape. |
| Полезен ли reviewer? | Paired quality before/after human decision; downstream incident rate. |
| Согласны ли reviewers? | Inter-reviewer agreement на duplicated cases. |
| Сколько стоит HITL? | Human minutes / successful task, queue latency, cost per reviewed case. |
hitl/ ├── trigger.py ├── review_package.py ├── decisions.py ├── resume.py ├── timeout.py ├── routing.py └── tests/ tables: tasks reviews review_decisions state_transitions notifications review fields: review_id task_id review_type review_version payload_hash required_role status requested_at expires_at decision fields: decision_id review_id actor_id decision reason_code decided_at applied_at
Отдельный queue/workflow service добавляется позже при реальной нагрузке и durability requirements.
% tasks, где реально понадобился человек.
Median/p95 time in WAITING_HUMAN.
Cases, которые человек считает безопасно автоматизируемыми.
Cases, где human gate должен был сработать, но не сработал.
Как часто human меняет предложение AI.
Согласие нескольких reviewers на одинаковых cases.
Backlog / SLA breach по risk tiers.
Ошибки/инциденты после human-approved actions.
| Вопрос | Ответ |
|---|---|
| Стоит ли реализовывать? | Да, как механизм. Особенно до появления внешних irreversible actions. |
| Separate Component? | NO по архитектурному плану. HITL — responsibility внутри Executive Controller + Quality Engine. UI/queue/notification могут быть отдельной инфраструктурой. |
| Минимум 80% ценности? | Trigger, exact review version, WAITING state, authorized decision, timeout/escalation, idempotent resume, audit. |
| Когда overkill? | Когда human review добавлен даже для низкорисковых deterministic read tasks. |
| Trigger? | High risk, policy gate, material uncertainty, unresolved verification, automation exception, sampling audit. |
| Как измерить uplift? | Missed-gate, false escalation, post-review quality delta, incident rate, latency, reviewer minutes/task. |
| Можно ли rule/tool/code вместо LLM-agent? | Да. Handoff state machine, queue, permissions и resume — обычный код. LLM может только помогать собрать review summary. |
Не review-by-default. Trigger должен иметь reason code и measurable value.
Сначала сохранить checkpoint/review, потом ждать человека.
Approval связывается с exact version/hash.
Reviewer eligibility и permissions проверяются системой.
EXPIRE / ESCALATE / CANCEL по policy. Не auto-approve high risk.
Повтор webhook/click не повторяет side effect.
Хранить provenance и измерять reviewer disagreement.
Показывать decision-ready package, а не raw context dump.
Human correction → verified feedback → eval/regression/rule candidate.
NORMAL AGENT LOOP
↓
RISK / POLICY / UNCERTAINTY / EXCEPTION
↓
IS HUMAN REQUIRED?
├─ NO ───────────────→ CONTINUE AUTOMATION
│
└─ YES
↓
FREEZE EXACT PROPOSAL / ACTION / ARTIFACT
↓
BUILD REVIEW PACKAGE
↓
PERSIST CHECKPOINT
↓
WAITING_HUMAN
↓
ROUTE TO AUTHORIZED REVIEWER
↓
APPROVE / REJECT / CHANGE / INFO / ESCALATE
↓
VALIDATE:
actor + permission + review_version + payload_hash + expiry
↓
IDEMPOTENT RESUME
↓
EXECUTE / REPAIR / TERMINATE
↓
VERIFY ACTUAL OUTCOME
↓
TRACE + METRICS + OPTIONAL LEARNING
CORE PRINCIPLE:
HUMAN-IN-THE-LOOP
IS NOT "A PERSON LOOKS AT THE ANSWER".
IT IS:
A FORMAL, PERSISTED, AUTHORIZED,
VERSION-BOUND DECISION POINT
INSIDE THE SYSTEM.
A. Related ECC ideas. Context-as-cache, scoped memory, lifecycle hooks, selective capabilities, feature flags, deterministic enforcement, provider-neutral adapters and eval-gated learning are applied only where relevant to №49 Human-in-the-Loop.
B–E. Existing boundary and placement. The existing conceptual boundary, class PRODUCTION, default CONDITIONAL and owner Executive Controller + Quality Engine remain authoritative. Runtime/control/data/offline placement is unchanged; durable state stays outside model context.
F–H. Hooks and contracts. Use bounded PRE_MODEL/POST_MODEL, PRE_TOOL/POST_TOOL, CHECKPOINT and TASK_COMPLETED events as applicable. Illustrative fields and canonical contracts are defined in NEW_CONTRACTS_SPEC.md; no universal schema is implied.
I–J. Security and evaluation. Host-side schema, permission, secret, budget, idempotency and audit checks take precedence over LLM output. Optional mechanisms require a feature flag and WITH/WITHOUT ablation; measure quality, acceptance, correction, latency, cost, escalations and severe errors.
K–L. Task profiles and cross-references. A TaskProfile selects the relevant skill, tool/context slice, memory scope and enforcement profile independently from FAST/STANDARD/DEEP. See cross-reference map, hook spec and ablation plan. Provider adapters remain outside the core.