Skip to main content
QitOS provides method templates — ready-made Agent + Critic pairs that implement well-known agentic reasoning patterns. Each template packages a specialized state, critic, and agent so you can apply the pattern without rewriting the control loop.

What is a method template?

A method template combines:
ComponentRole
StateA StateSchema subclass with pattern-specific fields (reflections, drafts, refinement counts)
CriticA Critic subclass that drives the pattern’s loop by returning retry, continue, or stop at the right times
AgentAn AgentModule subclass with pattern-aware build_system_prompt(), prepare(), and reduce()
The critic is the key: it evaluates each step and decides whether to retry (with an instruction patch), continue, or stop. The agent enriches prompts with pattern context (previous reflections, draft versions, critiques).

Self-Refine

The Self-Refine pattern (Madaan et al. 2023) iterates: generate → critique → refine until quality meets a threshold or max refinements are reached.

When to use it

  • Text generation tasks where quality matters more than speed
  • Summarization, translation, code generation with self-evaluation
  • Any task where iterative improvement reliably produces better output

Quick start

from qitos.recipes.self_refine import SelfRefineAgent, SelfRefineCritic

agent = SelfRefineAgent(llm=my_llm)
result = agent.run(
    task="Write a concise summary of the research paper on ...",
    critics=[SelfRefineCritic(max_refinements=3, quality_threshold=0.7)],
    max_steps=10,
    return_state=True,
)
print(result.state.draft)       # the refined output
print(result.state.final_result) # FINAL ANSWER if extracted

How it works

  1. Generate: The agent produces an initial draft.
  2. Critique: SelfRefineCritic evaluates the draft quality using heuristic scoring (longer drafts after more refinements score higher; very short drafts are penalized). In production, replace heuristics with an LLM-based scorer.
  3. Refine: If the score is below quality_threshold and refinements remain, the critic returns retry with an instruction_patch asking the agent to improve. The agent sees its previous draft and the critique in the next prompt.
  4. Accept: When the score meets the threshold or max_refinements is reached, the critic returns continue or stop.

SelfRefineCritic parameters

ParameterDefaultDescription
max_refinements3Maximum refinement iterations
quality_threshold0.7Minimum score (0.0–1.0) to accept the draft

SelfRefineState fields

FieldTypeDescription
draftstrCurrent draft text
refinement_countintNumber of refinements so far
max_refinementsintRefinement budget
critique_historyList[str]Accumulated critiques

Customizing the quality scorer

The built-in critic uses heuristics. For production use, subclass and override evaluate():
from qitos.recipes.self_refine import SelfRefineCritic, SelfRefineState
from qitos.engine.critic_result import CriticResult

class LLMScorerCritic(SelfRefineCritic):
    def evaluate(self, state, decision, results):
        refine_state = state if isinstance(state, SelfRefineState) else None
        if refine_state is None:
            return CriticResult(action="continue")

        # Call an LLM to score the draft
        score = self._llm_score(refine_state.draft, refine_state.task)

        if score < self.quality_threshold and refine_state.refinement_count < self.max_refinements:
            return CriticResult(
                action="retry",
                score=score,
                instruction_patch="Critique and improve the draft.",
                state_patch={"refinement_count": refine_state.refinement_count + 1},
            )
        return CriticResult(action="stop", score=score)

Reflexion

The Reflexion pattern (Shinn et al. 2023) iterates: act → evaluate → reflect → retry with memory. On failure, the critic generates a verbal reflection stored in state and injected into future prompts.

When to use it

  • Debugging and error-correction tasks where the agent must learn from failures
  • Tasks where different strategies should be tried after failure
  • Multi-attempt problems (coding, reasoning) where reflections improve subsequent attempts

Quick start

from qitos.recipes.reflexion import ReflexionAgent, ReflexionCritic

agent = ReflexionAgent(llm=my_llm)
result = agent.run(
    task="Debug the failing test in tests/test_module.py",
    critics=[ReflexionCritic(max_reflections=3)],
    max_steps=15,
    return_state=True,
)
print(result.state.reflections)    # list of verbal reflections
print(result.state.final_result)  # FINAL ANSWER if extracted

How it works

  1. Act: The agent takes an action toward the task.
  2. Evaluate: ReflexionCritic checks for failures (errors, non-zero return codes, empty results).
  3. Reflect: On failure, the critic generates a verbal reflection from the error context and returns retry with the reflection as an instruction_patch. The reflection is stored in state.reflections.
  4. Retry with memory: The agent’s build_system_prompt() includes all previous reflections, so the LLM can avoid repeating the same mistakes.

ReflexionCritic parameters

ParameterDefaultDescription
max_reflections3Maximum reflection iterations before forced stop
success_threshold0.6Minimum score to consider the trajectory successful

ReflexionState fields

FieldTypeDescription
reflectionsList[str]Accumulated verbal reflections
reflection_countintNumber of reflections generated
max_reflectionsintReflection budget
last_action_successboolWhether the last step succeeded
attemptintCurrent attempt number

LATS

The LATS pattern (Zhou et al. 2023) applies Monte Carlo Tree Search to language agents: select → expand → evaluate → backpropagate. Failed trajectories generate reflections that guide future exploration away from similar mistakes.

When to use it

  • Tasks requiring systematic exploration of multiple solution paths
  • Logic puzzles, coding challenges, and multi-step reasoning
  • Problems where trying different strategies improves success

Quick start

from qitos.recipes.lats import LATSAgent, LATSCritic

agent = LATSAgent(llm=my_llm)
result = agent.run(
    task="Solve the logic puzzle ...",
    critics=[LATSCritic(max_simulations=5, exploration_weight=1.41)],
    max_steps=20,
    return_state=True,
)
print(result.state.best_answer)    # best answer found
print(result.state.best_reward)    # best reward score

How it works

  1. Simulate: The agent takes an action, producing a result.
  2. Evaluate: LATSCritic computes a reward from the result (errors → low reward, FINAL ANSWER → high reward).
  3. Reflect: Failed paths (reward < 0.3) generate reflections stored in state.reflections.
  4. Guide: On retry, the critic provides an instruction_patch that includes reflections and UCB1-style exploration guidance.
  5. Stop: When a path succeeds (reward ≥ success_threshold) or max_simulations is reached.

LATSCritic parameters

ParameterDefaultDescription
max_simulations5Maximum simulation iterations
exploration_weight1.41UCB1 exploration constant (c)
success_threshold0.8Reward value for early stopping

LATSState fields

FieldTypeDescription
simulations_doneintNumber of simulations completed
max_simulationsintSimulation budget
exploration_weightfloatUCB1 c parameter
best_rewardfloatBest reward found so far
best_answerstrAnswer from the best trajectory
failed_pathsList[str]Descriptions of failed paths
reflectionsList[str]Reflections from failures

MoA (Mixture-of-Agents)

The MoA pattern (Wang et al. 2024) runs multiple proposers independently and synthesizes their outputs: propose → aggregate. Diversity of proposals improves quality, even when individual proposers are weaker models.

When to use it

  • Tasks benefiting from diverse perspectives or creative responses
  • Analysis, evaluation, and synthesis problems
  • Quality improvement through ensemble reasoning

Quick start

from qitos.recipes.moa import MoAOrchestrator, MoACritic

agent = MoAOrchestrator(llm=my_llm)
result = agent.run(
    task="Evaluate the system architecture design for ...",
    critics=[MoACritic(proposer_count=3, max_rounds=1)],
    max_steps=15,
    return_state=True,
)
print(result.state.synthesis)  # the aggregated answer

How it works

  1. Collect: MoACritic checks if enough proposals have been gathered. If not, it returns retry with an instruction to gather more proposals.
  2. Aggregate: When all proposals are collected, the critic prompts for synthesis.
  3. Output: When synthesis is complete and meets the quality threshold, the critic returns stop.
For parallel proposer execution with actual multi-agent delegation, use qitos.kit.patterns.moa.build_moa_system().

MoACritic parameters

ParameterDefaultDescription
proposer_count3Expected number of proposals
max_rounds1Maximum proposal-aggregation rounds
quality_threshold0.6Minimum score to accept synthesis

MoARecipeState fields

FieldTypeDescription
proposalsList[Dict]Collected proposals with proposer and content
synthesisstrFinal synthesized answer
round_countintCurrent round number
max_roundsintRound budget
proposer_countintExpected proposal count

Magentic-One

The Magentic-One pattern (Furtado et al. 2024) uses an orchestrator with a dual-ledger architecture: plan → delegate → track progress → re-plan when stuck. The orchestrator maintains a Fact Bank and Task Ledger, delegates to specialist agents, and re-plans when progress stalls.

When to use it

  • Complex, multi-step tasks requiring coordination of different capabilities
  • Tasks where an orchestrator needs to adapt its plan based on intermediate results
  • Open-ended problems with research, coding, and analysis subtasks

Quick start

from qitos.recipes.magentic_one import (
    MagenticOneOrchestrator,
    ProgressCritic,
    MagenticOneState,
)

agent = MagenticOneOrchestrator(llm=my_llm)
result = agent.run(
    task="Research and summarize the latest findings on ...",
    critics=[ProgressCritic(max_stalls=3)],
    max_steps=30,
    return_state=True,
)
print(result.state.fact_bank)        # accumulated facts
print(result.state.completed_tasks)  # finished subtasks

How it works

  1. Plan: The orchestrator creates a task ledger and gathers initial facts.
  2. Delegate: At each step, a subtask is assigned to a specialist.
  3. Track: ProgressCritic evaluates whether new facts have been gathered or tasks completed.
  4. Re-plan: If no progress is detected for max_stalls consecutive steps, the critic returns retry with re-planning guidance.
  5. Stop: When a FINAL ANSWER is provided, or when stall budget is exhausted.

ProgressCritic parameters

ParameterDefaultDescription
max_stalls3Maximum consecutive no-progress steps
progress_threshold0.5Minimum score to consider progress

MagenticOneState fields

FieldTypeDescription
fact_bankList[str]Accumulated facts and educated guesses
task_ledgerList[str]Current plan of subtasks
completed_tasksList[str]Finished subtasks
stall_countintConsecutive no-progress steps
max_stallsintStall budget before forced stop
specialist_callsintNumber of specialist delegations
current_subtaskstrCurrently active subtask

Scaffolding a new agent

Use the qit new CLI command to scaffold a new agent project from the built-in cookiecutter template:
# Create a new agent with default settings
pip install qitos[cookiecutter]
qit new --agent-name my_agent --agent-description "My custom agent"

# List available templates
qit list-templates

# Create with full customization
qit new \
  --agent-name code_reviewer \
  --agent-description "Reviews code for security issues" \
  --author "My Team" \
  --default-model qwen-plus \
  --max-steps 20
The scaffolded project includes:
  • src/agent.py — Agent class with State, init_state, build_system_prompt, reduce
  • configs/default.yaml — Default model and step configuration
  • tests/test_agent.py — Basic smoke tests
  • snowl_compat.py — Snowl evaluation compatibility adapter
  • eval_config.yaml — Evaluation configuration

Building your own method template

To create a custom method template, follow the same Agent + Critic pattern:
  1. Define a state that extends StateSchema with your pattern’s tracking fields
  2. Implement a critic that returns retry with instruction_patch and state_patch when the pattern requires iteration
  3. Implement an agent whose build_system_prompt() injects pattern context from state
from dataclasses import dataclass, field
from typing import Any, Dict, List
from qitos import AgentModule, Decision, StateSchema
from qitos.engine.critic import Critic
from qitos.engine.critic_result import CriticResult
from qitos.kit.parser import ReActTextParser

@dataclass
class MyMethodState(StateSchema):
    iteration: int = 0
    max_iterations: int = 5
    history: List[str] = field(default_factory=list)

class MyMethodCritic(Critic):
    def evaluate(self, state, decision, results):
        if not isinstance(state, MyMethodState):
            return CriticResult(action="continue")
        if state.iteration < state.max_iterations:
            return CriticResult(
                action="retry",
                score=0.5,
                instruction_patch="Try again with a different approach.",
                state_patch={"iteration": state.iteration + 1},
            )
        return CriticResult(action="stop", reason="Max iterations reached.")

class MyMethodAgent(AgentModule[MyMethodState, Dict[str, Any], Any]):
    def __init__(self, llm=None, **kwargs):
        super().__init__(llm=llm, model_parser=ReActTextParser(), **kwargs)

    def init_state(self, task, **kwargs):
        return MyMethodState(task=task, max_steps=kwargs.get("max_steps", 10))

    def build_system_prompt(self, state):
        prompt = "You are a method agent. Iterate until done."
        if state.history:
            prompt += "\n\nPrevious attempts:\n" + "\n".join(state.history)
        return prompt

    def prepare(self, state, observation):
        return f"Task: {state.task}\nIteration: {state.iteration}"

    def reduce(self, state, observation, decision, action_results):
        return state