What is Bridle
A Python library that harnesses an agent into a deterministic program with typed I/O. Code does control flow. The model does judgment.
Bridle is a Python library for writing agents the way you write any program: control flow in code, judgment in the model.
from bridle import agent, branch, loop, step
from pydantic import BaseModel
class Source(BaseModel): url: str; summary: str
class Brief(BaseModel): headline: str; body: str
@agent(input=str, output=Brief, model="claude-sonnet-4-6")
def brief_writer(topic: str) -> Brief:
sources = loop(
f"gather sources on {topic}",
schema=Source,
until=lambda acc: len(acc) >= 3,
)
if not branch("is the evidence sufficient?", context=sources):
return brief_writer(f"{topic} — go deeper")
return step("write the brief", schema=Brief, context=(topic, sources))The model never decides what runs next. It produces typed values; your Python decides where to go from there.
The mental model
A Bridle program is regular Python with three holes a model fills:
step— produce one typed value, calling tools as needed.branch— produce one typed decision, no tools. Use as the condition in anif.loop— produce typed values until a Python predicate is satisfied.
Wrap a function in @agent to make it a typed, traceable, model-aware unit. Wrap a tool in @tool to expose it to the model. Compose calls with wrappers — cache, retry, timeout, with_model, fallback, mock, log — without changing the call itself.
Every primitive returns a Call: a lazy description of work that resolves on first use. Every run emits a trace you can inspect, replay, or stream.
What you get
- Typed I/O. Pydantic models in, Pydantic models out. The model's output is validated against the schema before your code sees it.
- Real Python control flow.
if,for,while, function calls, exceptions. The model never picks the next state. - A trace by default. Every call, every model turn, every tool result, every retry — captured as structured events.
- Caching, retries, timeouts, fallbacks as wrappers. Compose them on any call.
- Mockable everywhere. Replace any call with a constant for tests.
Status
v0.1.0 — Anthropic-only, sync, single-agent. See the v0.1.0 release notes for what ships and what does not.