Everyone's talking about AI agents. Autonomous this, agentic that. But here's what almost none of the big AI proponents want to say out loud: you can't just let AI do things and hope. Not in production. Not with real data. Not with real money.
AI needs supervision. And right now, the best we've got is... JSON.
That's it. The grand innovation in AI output control is "make it return JSON." With a schema because you're feeling fancy. And sure, JSON is better than free-form text. But it has no semantics. It doesn't know anything about your domain. You can validate that a field is a string, but you can't validate that it's a sensible thing to do.
An obvious answer is to use domain-specific languages. And I think almost nobody is talking about this because most of you have never built a DSL.
In Concrete Terms
You tell an AI to handle some business workflow. Instead of getting back a JSON blob that you need to squint at to understand, or a wall of natural language where the AI explains its reasoning for three paragraphs before getting to the point, you get back something like:
SEND invoice #4821 TO client@example.com
APPLY 10% DISCOUNT TO order #1192
SCHEDULE followup call FOR 2026-03-10
Each line is a well-defined operation. It maps directly to what your system can do. You can approve each operation individually, reject it, or go back and argue with the AI about it. The AI can't sneak in something weird because the parser won't let it.
And when the AI produces something that doesn't check out? The parser returns an error, and that error is domain-specific. Not "unexpected token at position 47" but "SEND requires a valid invoice number, got 'all of them'." The AI gets useful feedback, tries again, and you end up with operations your system can actually execute.
Why Not Just JSON Schema
"Just use JSON Schema, it solves the same problem."
No it doesn't. JSON Schema constrains the shape of data. It can tell you "this must be an array of objects with these fields." It cannot tell you "this must be a valid sequence of operations in our billing system where discounts can't exceed 15% and you can't send invoices to addresses that aren't in the customer database."
A DSL gives you semantic validation, not just structural validation. And - this matters more than people think - it's human-readable. A reviewer can scan ten DSL statements and understand what's about to happen in seconds. Try doing that with a nested JSON object.
There's No One DSL to Rule Them All
There won't be a universal "AI action language." That would just be another general-purpose programming language with extra steps.
What there should be is a million small, focused DSLs. One for billing workflows. One for email automation. One for inventory management. One for appointment scheduling. Each one is tiny, purpose-built, and easy to validate.
And yeah, I know - a million DSLs sounds like a nightmare. But it's not. Each one is small enough to fit in your head. The grammar is maybe 20-30 rules. The parser is a few hundred lines of code. This is not hard to build if you have the right tools.
This Is Where OCaml Comes In
I'm biased, obviously. But OCaml is genuinely one of the best languages in existence for building parsers and DSLs. Pattern matching, algebraic data types, a type system that catches entire categories of bugs at compile time - it's like the language was designed for this. (Parts of it were, actually. OCaml has deep roots in programming language research.)
You can define a DSL's abstract syntax tree as a type, write a parser with Menhir or even just recursive descent, and have a working, type-safe interpreter in an afternoon. The compiler will tell you if you forgot to handle a case. Try getting that from Python.
Most of the AI tooling world is built in Python and TypeScript. And those are acceptable languages for a lot of things. But building reliable parsers and language tooling is not one of those things. If DSLs become a real pattern in AI supervision - and I think they will - the people who know how to build them properly will have a real advantage.
Where This Doesn't Work
However: this pattern doesn't work for everything. Software engineering is too open-ended. The space of possible actions is too large, too varied, and requires too much context to evaluate. That's why coding tools use a different model - permission-based gates on tool use, not structured action proposals.
But a lot of workflows aren't like coding. There's a finite, well-defined set of possible actions. And for those, a reviewer scanning a list of ten proposed actions and saying "yes, go" or "no, change the third one" is exactly the right level of supervision.
The Pattern
- Human describes what they want in natural language
- AI produces a list of proposed actions in a domain-specific language
- A parser validates the actions are well-formed and semantically valid
- A human reviews the action list - approves, modifies, or rejects individual items
- Approved actions get executed
That's it. The tools for building parsers and DSLs have existed for decades. What's new is the motivation: AI agents that need structured, reviewable, domain-specific output instead of free-form text that you just have to trust.
