It’s 2025 and we’re still seeing new AI frameworks and SaaS products coming out every month. It started with LangChain, LlamaIndex, and AutoGPT. Then the big tech companies joined in with OpenAI’s Swarm, Vercel’s AI SDK, and Microsoft’s Autogen. Now they are dressed up as coding or research agents like [Devin]()/[OpenHands](), or HuggingFace’s smolagents open_deep_research. And let’s not even get into all the agents-as-a-service you can buy.
All of these frameworks promise the same things:
- Create powerful AI Agents (whatever that word means)
- …with only a few lines of code
- …that are testable, observable, and (fairly) deterministic
- …that can be easily deployed and accessed
But under the hood there’s a striking similarity: they’re all just abstractions on top of LLM calls. And if your team knows how to code, you can build your own abstractions that are customized to your business’ use case using nothing fancier than a state machine.
🧠 State Machines Are All You Need (And Maybe Even Better)
A finite state machine is a simple but powerful abstraction. It defines clear checkpoints (states) and transitions between them. Think of it like a choose-your-own-adventure book: at each page, there are a few options. You pick one, and jump to the next page. Repeat.
Business tasks often follow a step-by-step flow (and if you’re lucky, these steps are already written down somewhere!), so state machines are already a good fit. State machines also have built-in ways to evaluate decisions, fall back if something is unexpected, and execute tasks simultaneously.
And unlike most black-box SaaS tools, a state machine is always:
- Testable: You can unit test your state machines by feeding them cached data and walking through the steps without needing a real user to click through.
- Composable: You can nest workflows, loop through subtasks, and reuse logic across projects.
- Transparent: You always know exactly what the system is doing and why.
⚙️ It’s Simpler Than You Think
In a recent product, we built a research assistant on top of a state machine abstraction. We used Python for both the state machine definition and execution, and Pydantic for strong typing. Not only was the abstraction clear and easy to extend, but the LSP goodies like autocomplete, type checking, and code navigation kept developer velocity high and bugs low.
The entire abstraction has fewer than 100 lines of code, and it lays a solid foundation to build real business automations on. Small abstractions like this are powerful not because they do everything, but because they give complexity the right place to live. By keeping your framework minimal, you let the messy business logic live in well-named implementations, not tangled inside someone else’s SDK.
🛠️ You Can Still Be Fancy (If You Want)
Want more flexibility? Define your state machines as data instead of code. You can write them in JSON, YAML, or a DSL of your choice and pass them into the executor. Store these configurations in a database and hot-load them on runtime so that you’re always running the latest versions.
Want modularity? Use abstract classes and factory methods to swap out components (LLMs, data connectors, channels) without rewriting your core logic. We did that, too, but that’s a different blog post.
📦 Deployment Is Dead Simple
One of the nicest side effects of this approach is how easy it is to deploy.
The simplest way: bundle your state machine execution and configuration in a single container. Push it. Deploy it. Done. That’s how we’re running things for one client right now and it is super low-friction, easy to debug, and quick to update.
Want more dynamic behaviour? You can separate your execution and configuration into separate places and connect them at-runtime for all sorts of fun like running specific versions of workflows or executing code on specific regional servers.
Either way your team (not some silicon-valley startup) stays in full control.
🧮 State Machine vs. SaaS Platform: A Practical Comparison
Feature | State Machine (In-House) | SaaS Platform (Off-the-Shelf) |
---|---|---|
Developer Familiarity | ✅ High — Your developers will be the ones building the system. State machines are a well-established software pattern. | ⚠️ Medium — New frameworks can be easy to start out with, but developers tend to run into walls when they try to customize functionality. |
Learning Curve | ❌ Steep — Must plan and document design decisions and communicate them clearly to the rest of the team. | ⚠️ Medium — Docs (hopefully) handle basic features and use cases, but more custom functions might not be well documented. |
Transparency | ✅ Add your own monitoring and logging to see as much (or as little) as you’d like. | ❌ Often a black box or limit builders to a small selection of logging and observability tools. |
Testability | ✅ Build as many unit and integration tests as your heart desires. Easy to mock LLM calls to avoid running up AI token costs. | ⚠️ Often limited, requires sandbox/test plan and no way to mock or replay conversations. |
Customization | ✅ Complete flexibility, from logic to execution. | ❌ Limited by vendor roadmap. |
Maintainability | ✅ Version control is under your control. | ⚠️ Reliant on platform stability & updates. |
Security & Compliance | ✅ Can be self-hosted, audit every layer. BUT you’re also responsible for SOC2/GDPR compliance. | ⚠️ SaaS vendor might already have SOC2/GDPR certification… or they might not! |
Initial Speed | ⚠️ Slower — requires large upfront engineering effort. | ✅ Fast — prebuilt flows and templates make it easy to get a prototype/MVP up and running. |
Long-term Cost | ✅ Predictable infra + team maintenance. | ⚠️ Potentially expensive per-seat or API-based. |
Ownership | ✅ You own everything. | ❌ You rent, and it might change tomorrow. |
🚨 When Not To Do This
If your team is mostly not technical, or if you’re moving at a breakneck pace without time for any internal tooling, use a low-code SaaS product. They are still your best shot for quick validation, marketing workflows, and hacky demos.
But if you’ve got engineers on staff, and you’re building something you want to own, understand, and grow over time…
You don’t need a low-code orchestration tool. You just need a state machine.
Bonus image: State Machines At Home
This one was just too much fun to leave out 😂 SaaS.
❤️
Gordy