Describe an agent. Get a working agent in 5 minutes.
Agents from a paragraph.¶
looplet treats agents as data — a cartridge is a directory of
files (config.yaml, prompts/system.md, tools/<name>/{tool.yaml,
execute.py}) that the loader materialises into a runnable agent.
The agent_factory cartridge builds new cartridges from English
briefs; the loop engine runs them. Underneath, the same
composable_loop iterator gives you full control if you'd rather
hand-write the agent. Zero runtime dependencies.
289ms
Cold import
0
Runtime deps
4
Hook protocols
1,492
Tests, ~1s

How it works¶
Every turn follows the same five-step story:
- The LLM proposes a tool call.
- The registry validates and dispatches it.
- Hooks observe or steer the turn.
- State records the step.
- The loop yields a
Stepto your code.
Bundles, presets, provenance, and evals all compile into this same mechanism.
flowchart LR
subgraph Loop["composable_loop()"]
direction LR
P[pre_prompt] --> L[llm.generate]
L --> D[pre_dispatch]
D --> T[tool.execute]
T --> R[post_dispatch]
R --> C{check_done}
C -- no --> P
C -- yes --> Y([yield Step])
end
Y --> Caller[Your for-loop]
Caller -. "stop / log / score" .-> Loop
classDef hook fill:#EEF2FF,stroke:#4F46E5,stroke-width:1.5px,color:#1E1B4B
class P,D,R,C hook
Four hook methods on any Python object. Implement only the ones you
need. The loop uses hasattr — no base class, no registration.
The promise¶
- Own the loop. Your code iterates over
Stepobjects and can stop, log, approve, score, or redirect at any point. - Compose behavior. Hooks are plain Python objects. Add redaction, permission checks, compaction, metrics, or quality gates without subclassing a framework.
- Keep the trace. The same step stream powers live debugging, provenance, replay, and pytest-style evals.
- Package capabilities. Skills and bundles let you share a runnable agent folder while keeping the core loop inspectable Python.
Why looplet?¶
-
Fast to start, fast to run
289 ms cold import. Zero runtime dependencies.
pip installstays snappy on serverless and short-lived scripts. -
Composable by Protocol
Four
@runtime_checkablehook methods. Any object implementing one or more is a hook. No base classes, no registration. -
Observable by default
step.pretty(),ProvenanceSink, andeval_*all read the sameStepdataclass. One artifact, three uses. -
Safe by design
redact=scrubs PII before the provider sees it and before the trace is written. No wrapping-order footguns. -
Compose agents as tools
Any looplet agent is a function that returns a result. Wrap it in a
ToolSpecand plug it into the next agent. -
Debugging is evaluation
What you do while debugging (
print(step.pretty())) is a trajectory. Evals are pytest-style functions over the same data.
See the difference¶
for step in composable_loop(
llm=llm, tools=tools, task=task,
hooks=[BudgetCap(10_000), Redactor()],
):
if step.tool_call.tool == "delete":
if not approve(step): # (1)
break
log(step) # (2)
- Intercept any tool call with ordinary Python — no custom graph node needed.
- One
Stepobject is the trace, the eval context, and the checkpoint unit.
Custom agent example¶
Start with Dependency Doctor if you want a demo people remember: point it at a repo and it audits dependency files for security, license, and maintenance risk. The agent is useful, concrete, and shows the looplet difference: every lookup, warning, and final claim is visible as a step you can log, gate, replay, or evaluate.
# Load the workspace; pass --workspace to point at the project to audit.
OPENAI_BASE_URL=http://127.0.0.1:11434/v1 \
OPENAI_API_KEY=ollama OPENAI_MODEL=llama3.1 \
python -c "from looplet import cartridge_to_preset; \
p = cartridge_to_preset('examples/dep_doctor.cartridge', runtime={'workspace': '/path/to/project'})"
Then explore examples/git_detective.cartridge/ for codebase-health reports,
examples/threat_intel.cartridge/ for local-first security briefings, and
examples/coder.cartridge/ for a coding-agent reference implementation —
each is a self-contained Workspace under
examples/
that round-trips losslessly with an AgentPreset via preset_to_cartridge
/ cartridge_to_preset.
# More dogfood — load each cartridge and run a scripted loop.
python -m looplet.examples.hello_world --scripted
python -m looplet.examples.ollama_hello --scripted
python -m looplet.examples.coding_agent "Implement add" --scripted --workspace /tmp/demo
python -m looplet.examples.data_agent --scripted --auto-approve --clean
Honest benchmarks¶
All numbers regenerate in one command on a fresh Python 3.11 venv. See Benchmarks for the full methodology.
looplet 289 ms · 0 deps
strands-agents 1,885 ms · 6 deps
LangGraph 2,294 ms · 31 deps
Claude Agent SDK 2,409 ms · 13 deps
Pydantic AI 3,975 ms · 12 deps
Cold-import time, median of 9 fresh subprocess runs. Python 3.11.13, Linux x86_64, PyPI wheels from 2026-04-21.
Start here¶
-
Install. Run. Understand the loop in five minutes.
-
Build an agent with hooks, context management, crash-resume, and approval — in five steps.
-
The four extension points. Recipes for every common pattern.
-
pytest-style scoring over the same trajectory you debug with.
-
Capture every prompt and step to a diff-friendly directory.
-
Ollama, OTel, MCP, cost accounting, checkpoints.
-
Ten sharp edges worth knowing — with the "right way" for each.
-
Cold import and dependency footprint, with the harness.
Extension points at a glance¶
-
pre_promptInject context into the next prompt. Context managers, retrieval-augmented briefings, step-specific guidance.
-
pre_dispatchIntercept a tool call before it runs. Cache hits, permission gates, argument rewriting, approval flows.
-
post_dispatchReact to a tool result. Duplicate-call warnings, error remediation messages, metric collection, streaming events.
-
check_doneReject premature completion. Quality gates, minimum-evidence thresholds, required-tool checks.
Talks and writing¶
- Blog: "The loop is the product" — the design argument behind the library.
- THIRD_PARTY_USERS.md — who is building on looplet.