Reasoning Loop
AI agents follow a reason-act-observe loop that can run for minutes or hours, repeating until the LLM determines the task is complete or a deterministic exit condition is met (max iterations, timeout, tool signal).
In Hatchet, this is implemented as a durable task with a loop. At each iteration, the task spawns a child to call the LLM, execute any tool calls, and determine whether additional iterations are required. Each completed iteration is checkpointed, so the agent survives crashes and worker slots are freed between iterations.
When to use
| Scenario | Fit |
|---|---|
| Chatbot that picks tools based on user messages | Good: the loop runs until the agent has a final answer |
| Multi-step research that may take minutes | Good: durable execution survives long-running loops |
| Agent that needs human approval mid-loop | Good: combine with Human-in-the-Loop |
| Fixed pipeline (prompt, generate, validate) | Skip: use LLM Pipelines instead |
| One-shot classification or extraction | Skip: a single task is simpler |
Step-by-step walkthrough
You’ll build a durable agent task that streams tokens and survives restarts.
Reasoning loop
Define the core loop. Each iteration calls the LLM, executes any tool calls, and checks whether the task is complete.
The examples above use a mock LLM. To call a real provider, swap get_llm_service() with one of these. Tool execution is typically your own APIs; encapsulate them in a service module like the get_tool_service() helper shown above.
OpenAI’s Chat Completions API provides access to GPT models for text generation, function calling, and structured outputs. It’s the most widely adopted LLM API and supports streaming, tool use, and JSON mode.
Wrap it in a durable task
Create a durable task that invokes the reasoning loop from Step 1. Concurrency is set to CANCEL_IN_PROGRESS so new user messages cancel stale runs.
Stream the response
Emit LLM tokens from the task as they are generated. Clients subscribe to the stream and receive them in real-time. See Streaming for the full API.
Run the worker
Start the worker. The task definitions above use CANCEL_IN_PROGRESS concurrency so new user messages cancel stale runs. Pass session_id in input for per-session grouping.
Always set a timeout and max iteration count on agent loops. Without bounds, an agent can loop indefinitely. See Timeouts for configuration.
Variant: Evaluator-Optimizer
The evaluator-optimizer is a specialized reasoning loop that uses two LLM calls per iteration: one to generate a candidate output and one to evaluate it against a rubric. If the score is below a threshold, the evaluator provides feedback and the generator tries again. This trades compute cost for output quality.
| Use case | Generator | Evaluator |
|---|---|---|
| Content writing | Draft post/email/copy | Score clarity, tone, length; provide edit suggestions |
| Code generation | Write function or query | Run tests or linter; feed back errors |
| Data extraction | Extract fields from text | Validate against schema; flag missing fields |
| Translation | Translate text | Back-translate and compare; score fidelity |
Define the generator and evaluator tasks
Create separate tasks for generation and evaluation. The generator takes a topic and optional feedback; the evaluator scores a draft.
Optimization loop
The evaluator-optimizer task loops: generate, evaluate, check score. Each generator and evaluator call is a spawned child task that is checkpointed on completion.
Related Patterns
The core loop pattern behind agent reasoning, where a task re-spawns itself until a goal is met.
Child SpawningPause agents for human feedback or scheduled retries without holding worker slots.
Long WaitsAdd approval gates to agent workflows. Pause for human review, then resume.
Human-in-the-LoopAgents that spawn parallel tool calls or sub-agent tasks.
FanoutRoute agent behavior based on LLM tool call decisions or user preferences.
BranchingNext Steps
- What is an Agent?: overview and pattern index
- Durable Workflows: understand checkpointing and replay
- Streaming: set up real-time LLM output streaming
- Concurrency Control: configure CANCEL_IN_PROGRESS for chat agents