Building Relay — An Agent Task Orchestrator
Notes on building a lightweight orchestration layer for multi-agent tasks. What worked, what broke, and what I'd do differently.
GitHub Repository
utkarshapoorva/relay ↗Relay is a task orchestration layer I built to coordinate multi-agent workflows. The core problem: when you're working with several AI agents on a project, you end up doing a lot of manual state management — copying outputs from one context into another, tracking what's been approved, deciding what happens next.
Relay removes that friction by providing a lightweight structure: tasks have states (pending, in-progress, review, done), agents are assigned to tasks, and outputs get stored with enough context for the next agent (or human) to pick up cleanly.
What Works
The approval gate model works well. Relay's default assumption is that agent outputs should be reviewed before being acted on. This sounds obvious but most workflow tools make approval the exception, not the default. Flipping the default changes the psychology of the whole system — you stop feeling like you're checking the AI's work and start feeling like you're directing it.
The structured output format also works. Relay asks agents to return JSON with defined fields (summary, confidence, blockers, next_steps) rather than freeform text. This is more constraining but makes it much easier to pass context downstream.
What Broke
State management is hard. Relay's first version stored task state in memory, which meant any restart wiped everything. Moving to file-based state (JSON files per task) solved persistence but created a new problem: concurrent agents writing to the same state file caused corruption. The fix was a file lock mechanism, but that introduced latency that made interactive workflows feel sluggish.
The second thing that broke was the agent assignment model. I'd assumed agents would specialize — one for research, one for writing, one for code review. In practice the models good enough to do research are also good enough to write and review code. Specialization ended up being more overhead than benefit for most tasks.
What I'd Do Differently
Use a proper event-sourced state model from the start. Append-only event logs with derived state would have solved the concurrency and corruption problems without the file lock complexity.
Less structure in the output format. The JSON constraint helped in some cases but made agent responses feel mechanical. A lighter format — just requiring a summary and a "status" field — would have been enough.
Relay is available on GitHub (link above). It's rough but functional. Happy to field questions in the issues tab.