Agent Runner: Stop Writing Glue Code for Your AI Agents

Here's a pattern that kept showing up across our projects: we'd build an agent that did something genuinely useful — analyzing files, monitoring a data feed, responding to webhooks — and then spend almost as much time writing the orchestration code around it. Retry logic. Logging. State management. Cron wrappers. Systemd units. Health checks.
Every. Single. Time.
The agent itself was maybe 200 lines. The infrastructure to run it reliably in production was another 400. And none of that code was interesting. It was the same boilerplate, copy-pasted and slightly modified, across a dozen projects.
The Problem
If you've shipped AI agents to production, you've hit this wall. Your agent works great locally. Now you need it to:
- Run once on demand (someone triggers it manually or via CI)
- Run on a schedule (every 15 minutes, check for new data)
- Run continuously (long-lived process, always listening)
- Run on webhook (HTTP request comes in, agent processes it)
Each of those patterns needs different infrastructure. A scheduled agent needs a cron-like scheduler with backfill logic. A continuous agent needs graceful shutdown handling and heartbeats. A webhook agent needs an HTTP server with request validation.
None of this has anything to do with what your agent actually does. But you end up writing it anyway, because there's no shared layer that handles it.
What We Built
Agent Runner is a Python framework where you define your agent once and deploy it in any of four execution modes. The agent definition is just a class with a run method:
from agent_runner import Agent, Context
class DataMonitor(Agent):
async def run(self, ctx: Context):
new_records = await ctx.fetch_since(ctx.last_checkpoint)
for record in new_records:
result = await self.analyze(record)
if result.needs_attention:
await ctx.notify(result)
await ctx.checkpoint()
That's it. That's your agent. Now deploy it however you want:
# One-off execution
agent-runner run data-monitor
# Every 15 minutes
agent-runner schedule data-monitor --interval 15m
# Long-running daemon
agent-runner daemon data-monitor
# Webhook endpoint
agent-runner serve data-monitor --port 8080
Same agent, four deployment patterns, zero changes to the agent code. The framework handles retries, logging, state checkpoints, graceful shutdowns, and health monitoring for all four modes.
Design Decisions Worth Calling Out
Redis for state, not a database. Agents need fast checkpoint reads and writes. They don't need complex queries. Redis gives us atomic operations and pub/sub for free, and every production environment already has it running.
Typer for the CLI, FastAPI for the webhook server. We didn't want to invent new interfaces. If you know Python CLI tools, the commands feel familiar. If you're exposing a webhook, you get a real ASGI server with proper request handling, not a toy HTTP listener.
No opinion on what your agent does. Agent Runner doesn't care if you're calling Claude, running local models, or doing pure computation. It manages the execution lifecycle, not the agent logic. Bring whatever SDK or library you want.
Structured logging from day one. Every agent run gets a correlation ID. Every checkpoint, retry, and notification is logged with context. When something breaks at 3am, you can trace exactly what happened without adding print statements after the fact.
When You'd Use This
Honestly, if you're running one agent in one mode, you probably don't need this. Just write a script.
But once you're running three or four agents, each in different modes, and you're maintaining separate orchestration code for each one — that's where the framework pays for itself. You stop thinking about how to run agents and start thinking about what they should do.
We use Agent Runner internally for monitoring agents, data processing workers, and webhook-triggered analysis jobs. It's the shared infrastructure layer that lets us ship new agents in a day instead of a week.
Try It
Agent Runner is open source. If you're building AI agents in Python and you're tired of the orchestration tax, check out the case study or grab the code from GitHub.
We're actively developing it, so if you run into rough edges or have ideas for a fifth execution mode we haven't thought of, open an issue. We read all of them.