Skill · doctrine · agent-loop
The agent loop
Implement the agent loop in raw SDK calls: context → structured next step → execute → compact-append. Use when building an agent from scratch, hiding the loop inside a framework, adding termination/budgets/pause, or the user asks how an agent actually works.
GET /api/canon/skills/agent-loop?format=md
The model never executes anything. It emits structured intent. Code executes. The observation is data. Termination is a first-class intent, not an accident.
When
You need a loop you can pause, inspect, eval, and resume. Frameworks wrap this; they must not own it.
Do
- 01
Implement it raw first
No graph library. Read the prompt you send. Structured next step with intent: tool | done | ask_human.
- 02
Budget the loop
Max steps, max tokens, max USD, wall clock. 'Done' is a schema. execute() is the sandbox and the permission gate.
- 03
Compact every observation
Append the smallest string that enables the next correct action. Bulk → files with a pointer.
Don't
- while True with no done schema.
- Hide the loop so nobody can pause it.
- Let the model 'just finish' without a budget.
Hard rules
- Termination, sandbox, context builder, eval set, pause API — name all five.
- execute() allow / ask / deny lives here, not in the prompt.
- Pause serializes the blob; resume does not re-execute the side effect.
The loop
context = [event]
budget = Budget(max_steps=20, max_tokens=80_000, max_usd=2.0)
while True:
budget.check(context)
nxt = llm.determine_next_step(
context,
tools=allowed_tools(state),
schema=NextStep, # intent: tool | done | ask_human
)
if nxt.intent == "done":
return nxt
if nxt.intent == "ask_human":
save_checkpoint(state, context)
return await pause_for_human(nxt)
result = execute(nxt) # allow / ask / deny
context.append(compact(result))
Refuse
- Unbounded loop — No max-turns, token, wall-clock, or money budget. The agent rambles until the bill or the context dies.
- Unowned prompt — The policy lives in a framework black box you cannot diff, test, or revert.
- HITL that cannot resume — The human answers and the run is gone. Approval as a side channel, not a tool.
Load with this
Load next
- Twelve-factor agentsSomeone will pay, wait, or sue. A framework got you a demo. The last 20% is software engineering.
- Compact observationsEvery tool return. Compaction is not a later optimization.
- Allow / ask / denyThe agent can touch a workspace, a browser, or production. The model proposes; code decides.
- Humans as toolsA side effect needs a person, or the agent is missing information only a person has.
Trigger tests
Should fire
- “Show me the agent loop”
- “Implement a ReAct loop with a budget”
- “How do we pause and resume the agent?”
Should not
- “Explain backpropagation”
- “Design the marketing site”