Apache Burr: Build reliable AI agents and applications
TL;DR Highlight
Define actions and transitions in Python and get state persistence, UI debugging and replay for agents
Who Should Read
A Python backend developer frustrated by the opaque abstractions of LangChain-style agent frameworks and looking for an alternative
Core Mechanics
- Apps are built from actions and transitions
- Apache Burr (Incubating) is a pure Python library for building anything from chatbots to multi-agent systems.
- You define actions and transitions with plain functions and decorators, with no DSL or YAML.
- Actions declare the state they read and write
- @action(reads=[...], writes=[...]) declares which state keys an action touches.
- ApplicationBuilder wires up actions, transitions, initial state and a tracker.
- A UI traces every step
- The Burr UI monitors and debugs each step of the app in real time.
- You can watch state change as it happens.
- Persistence, resume and human input are built in
- State is persisted to disk, databases or custom backends, and apps resume where they stopped.
- Execution can pause at any step to wait for human input, for example approval workflows.
- Parallelism plus testing and replay
- Actions can run in parallel with fan out/fan in to build complex DAGs.
- Past runs can be replayed and individual actions unit tested.
- Works with your existing stack
- Listed integrations include OpenAI, Anthropic, LangChain, Hamilton, Streamlit, FastAPI, Haystack, Instructor, Pydantic and PostgreSQL.
- The site claims no lock-in and no wrappers.
Community Reactions
- Opinion: plain 1:1 code beats a framework
- One commenter said an agent is just context building, an LLM call, tool execution and output parsing, which isn't that complex.
- They said framework abstractions obscure core logic and force mismatched designs.
- Another built a Django chatbot MVP with no framework, having Claude/Codex write the agent loop, and it works well.
- Experience mounting Burr as an MCP
- A commenter built a tool that mounts a Burr state machine as an MCP so agents follow a rail.
- They said the MCP tools stay limited to state machine navigation however complex it gets.
- They liked the reliable stateful workflow and free observability in personal and work projects.
- Pushback on differentiation
- One commenter said the sample looks like langgraph with a builder pattern.
- Another argued state machines have nothing to do with reliability, meaning finishing the job.
- Many criticized the landing page as looking AI-generated from a template.
- Observability and auth gaps
- One commenter said DIY agent setups almost always skip observability and miss it first in production.
- Someone asked how agents are authenticated and could not find it in the docs.
- A maintainer said they would answer questions.
How to Apply
- Run the Burr chatbot example locally
- Install with pip install burr and run the code example today.
- Use with_tracker("local") to record runs and inspect state changes in the Burr UI.
- Split your agent loop into actions
- Separate context building, the LLM call and tool execution into individual @action functions.
- Declare reads/writes on each and connect them with with_transitions.
- Add a human pause before risky steps
- Design the flow to pause before actions like payments or sending email.
- Resume execution after the approval input arrives.
- Replay failed runs as test cases
- Save the state snapshot of failed production runs.
- Move the failing action into a unit test to reproduce it.
Try It
# Run in a terminal (install: pip install "burr[start]"; needs OPENAI_API_KEY)
from burr.core import action, State, ApplicationBuilder
from openai import OpenAI
@action(reads=["messages"], writes=["messages"])
def chat(state: State, llm_client) -> State:
r = llm_client.chat.completions.create(model="gpt-4o-mini", messages=state["messages"])
reply = {"role": "assistant", "content": r.choices[0].message.content}
return state.update(messages=[*state["messages"], reply])
app = (
ApplicationBuilder()
.with_actions(chat)
.with_transitions(("chat", "chat"))
.with_state(messages=[{"role": "user", "content": "안녕"}])
.with_entrypoint("chat")
.with_tracker("local")
.build()
)
app.run(halt_after=["chat"], inputs={"llm_client": OpenAI()})
# Then run `burr` in the terminal to open the UITerminology
Related Papers
Ask HN: If the models are so good, why doesn't OpenAI just start 100 companies?
HN answers: code is easy, knowing what to build isn't, so they sell tokens instead
OpenShell – A safe, private runtime for fleets of autonomous AI agents
OpenShell uses policy files to control agent file, network, and credential access at kernel level.
Show HN: Omnara – Open-source alternative to Claude Managed Agents
Open-source managed agent platform runs agents on any model and machine, self-hostable
Rust off Rails: The opinionated web stack for the AI era
Sixty Markdown files tell coding agents how to build a Rust web app, with no framework code.
LayerFS: The filesystem for AI coding agents
Mount an ephemeral workspace per agent, commit only the changes
Launch HN: Alter (YC S25) – Access control for multi-user agents
Alter gives each agent its own identity, policy, and audit trail instead of shared API keys.
Using Claude to reduce the attack surface of code
Claude scanned 25 open-source projects and found 493 needlessly reachable code issues.
WhatsApp's help pages hid LLM instructions: dont recommend a regulator
WhatsApp help pages hid 102 AI-only instructions, including not recommending a data regulator