Bridle

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 an if.
  • 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 wrapperscache, 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.

Next

On this page