Human-in-the-Loop
Governed human review, the repeat/correct/approve pattern, and when to use it
Human-in-the-loop (HITL)
Audience: Customer developers and admins. HITL is how a workflow pauses for a governed human decision — and how you decide when a human is actually needed.
Full automation is the goal; a human in the loop is the exception you place deliberately. HITL lets a workflow stop at a well-chosen point, show a reviewer exactly the right information, and continue based on their decision — approve, correct, or repeat.
The philosophy: as little human interaction as possible
Insert a human review only before a critical business decision or action — the irreversible, high-consequence moments (releasing a payment, creating a master-data record, filing a submission). Everywhere else, let the automation run.
Why be sparing? Because errors cascade. If an early step extracts the wrong data — say a document extraction misreads a company name — every later step inherits the mistake (the Handelsregister check finds no matching company, and everything downstream fails). A human review bolted onto every step is slow, expensive, and still can't catch what it isn't shown.
So HITL forces a design question at each gate — and there's a tradeoff:
- Repeat (favor automation). Prefer sending the work back through the automation with feedback over having a human do it by hand. Re-running a corrected extraction is cheaper and more consistent than manual entry, and it keeps the process reproducible.
- Correct (optimize for minor fixes). For a small, obvious fix, let the reviewer correct the value directly and end the flow — repeating the whole pipeline for a one-character typo isn't worth it.
The HITL pattern
A workflow runs its steps, computes a result, then pauses at a review gate. From there the reviewer chooses one of three paths:
Scroll to zoom · Drag to pan · 100%
- Repeat → the reviewer's feedback becomes a prompt, and the loop re-runs from the repeat
target (
loop.target()) — automation gets another try. - Correct → the reviewer supplies a fix; the SDK agentically merges the correction into the calculated result, and the flow can end.
- Approve → the result stands as-is, and the flow ends.
This maps directly onto the correction loop: repeat loops the
async for; correct and approve let it fall through and finish.
Declaring a review: loop.hitl(...)
You add a review gate with one call. You declare what the reviewer sees, not how the UI is built:
await loop.hitl(
hitl_id=f"review_{loop.run_count}",
raw_keys=["ingest"], # requestor input — read-only, left panel
reviewable_keys=["review"], # calculated / generated data — right panel
display_fields=["value", "label"],
hitl_metadata={"risk_score": 40, "impact": "Reference Review"},
)
raw_keys— state keys holding the original requestor input. Shown read-only. If a key came fromloop.start(), any documents attached to it are surfaced automatically.reviewable_keys— state keys holding the data your workflow computed or an agent generated — the thing under review.display_fields— which fields of the entity to show, so the reviewer sees signal, not noise.hitl_metadata—risk_score(0–100) andimpact, used to route and prioritise the review in the approval queue.
The workflow then parks — durably, at no cost — until a reviewer submits a decision, which resumes it exactly where it stopped.
The review interface: declare the data, govern the decision
HITL registers a review interface in an ontology-like screen. As the workflow developer, you declare all the data a reviewer needs to make an educated decision:
- the documents behind the case (auto-attached from ingest steps),
- the requestor input (
raw_keys), - the generated/calculated data (
reviewable_keys), rendered from your typed entity model via itsdisplay_fields.
This is what makes the decision governed: the reviewer sees a complete, structured picture — inputs, evidence, and generated result side by side — rather than a bare "approve?" prompt. You control the content of that picture in code, so every review across the process is consistent and auditable.
The four decisions
A reviewer's submission resolves the gate one of four ways:
| Decision | Effect |
|---|---|
| Approve | The result stands; the gate opens and the flow continues/ends. |
| Correct | Field-level corrections are applied (agentically merged) onto the entity. |
| Discard correction | Undo a pending correction and keep reviewing. |
| Repeat | Send feedback back into the loop; re-run from loop.target() with the reviewer's prompt. |
Next: State & the entity model — how the data a reviewer sees is structured and kept auditable.