Skip to main content
Every step the Engine takes flows through a pipeline: decide, act, reduce, then critic. The critic sits between reduce and check_stop, giving you a structured hook to inspect the agent’s latest decision and its results, assign a quality score, and — when necessary — force a retry or halt execution. This tutorial covers the full critic API: the CriticResult contract, built-in critics, the @critic decorator, instruction and state patches, and composing multiple critics together.

Step 1: The CriticResult Contract

Every critic returns a CriticResult — a dataclass that tells the Engine what to do next.
The fields: The three actions control the loop:
  • "continue" — proceed to the next step as normal.
  • "stop" — halt the Engine immediately. The state’s stop reason is set to StopReason.CRITIC_STOP.
  • "retry" — discard the current step and re-run decide. Any instruction_patch or state_patch is applied before the retry.
A minimal continue result:
A retry with an instruction patch:
A hard stop:

Step 2: Using Built-in Critics

QitOS ships with ready-made critics in qitos.kit.critic.

PassThroughCritic

The simplest critic — always continues with a perfect score.
This is the default when you create an Engine without specifying critics. It is useful as a no-op placeholder or as part of a composed chain where later critics do the real work.

SelfReflectionCritic

Inspects tool results for errors and retries automatically up to a configurable limit.
Behavior:
  • If any tool result contains an {"error": ...} key and retries have not been exhausted, it returns action="retry" with score=0.2.
  • If errors persist beyond max_retries, it returns action="stop" with score=0.0.
  • If no errors are found, it returns action="continue" with score=1.0.
Pass it to the Engine:

ReActSelfReflectionCritic

A richer variant designed for ReAct agents. On error, it builds a structured reflection note describing the failed action and the observed error, then appends it to the state’s metadata so the LLM can learn from the failure on the next retry.

Functional Equivalents

Each built-in critic also ships as a decorated function:

Step 3: Writing a Custom Critic with the @critic Decorator

The @critic decorator converts any plain function into a Critic instance. The function receives (state, decision, results) and can return a quick shorthand or a full CriticResult.
Quick-return shorthands: A bare decorator (no arguments):
With keyword arguments — set a custom name and default score:
When the function does not set a score explicitly, the decorator’s score parameter is used as the default. In the example above, a "continue" return gets score=0.8 instead of the usual 1.0. Wire the critic into the Engine:

Step 4: Critic with Instruction and State Patches

When a critic returns action="retry", it can guide the next iteration in two ways:
  • instruction_patch — a string appended to the agent’s system prompt, giving the LLM additional guidance.
  • state_patch — a dictionary whose keys and values are merged into the agent’s state object via setattr.
These are applied before the Engine calls decide again, so the LLM and the state are already updated when the retry begins.
Using state_patch to inject tracking data:
You can also use the tuple shorthand with an instruction patch:

Step 5: Combining Critics

The Engine accepts a list of critics. They are evaluated in order, and the first non-continue result wins. This lets you stack critics from strictest to most permissive.
Wire them into the Engine — safety first, then format, then the built-in self-reflection as a fallback:
With this ordering:
  1. If safety_gate returns "stop", the Engine halts immediately. Later critics are never called.
  2. If safety_gate returns "continue" but format_check returns "retry", the Engine retries with the instruction patch.
  3. If both return "continue", the SelfReflectionCritic gets a chance to catch tool errors.
This layered approach keeps each critic small and focused, while the ordering gives you full control over priority.

Hooks Lifecycle

Understand the full Engine event lifecycle that critics participate in.

Agent Module

Deep dive into the AgentModule interface that critics inspect.

Critics and Stop Criteria

How critics interact with stop criteria and retry budgets.