Why Natural Language Specs Aren't Vague
The precision objection
Whenever someone proposes natural language as the foundation for software specifications, the same objection comes up: natural language is ambiguous. It’s imprecise. It’s open to interpretation. How could you possibly use it to define behavior rigorously enough to generate or validate code?
It’s a fair question. And if we were talking about casual, unstructured prose, the kind you find in most requirements documents, the objection would be fatal. “The system should handle errors gracefully” is not a specification. It’s a wish.
But natural language isn’t inherently imprecise. It can be made rigorous. And there’s an entire profession that’s been doing it for centuries.
Lawyers figured this out a long time ago
A legal contract is written in natural language. It’s also enforceable in court.
Contracts work because they use natural language within a set of constraints: defined terms, explicit conditions, enumerated obligations, and unambiguous scope. When a contract says “the Seller shall deliver the Goods within thirty (30) calendar days of the Effective Date,” there’s no ambiguity about who does what, when, or what counts as a day.
The language is still English. Anyone can read it. But it’s structured English, constrained by convention, precedent, and the expectation that it will be interpreted literally. The precision comes from the structure, not from abandoning natural language for something formal.
This is the model that software specifications should follow. Not the vague, narrative-style requirements that teams write today. Structured natural language: readable by humans, interpretable by machines, precise enough to validate against.
The spectrum of precision
There’s a spectrum between casual prose and formal notation. Most software teams operate at the casual end. Academic formal methods operate at the other end. Both extremes have problems.
Casual specs are too vague to be actionable. “Users should be able to log in” tells you nothing about authentication methods, session duration, failure handling, rate limiting, or what “logged in” even means across different parts of the system.
Formal specifications, written in languages like Z, TLA+, or Alloy, are precise but inaccessible. They require specialized training to write and read. A product manager can’t review a TLA+ specification. A business stakeholder can’t validate that it captures their requirements. The precision exists, but it’s locked behind a formalism that excludes most of the people who need to participate in defining what the software should do.
This is why formal methods never achieved mainstream adoption. It’s not that they don’t work, they work beautifully for the problems they’re applied to. Amazon has used TLA+ to find critical bugs in distributed systems. But adoption requires everyone involved in defining software behavior to learn a new language. That’s a non-starter for most organizations.
The sweet spot is in the middle. Natural language with enough structure to be precise, without requiring anyone to learn a formalism.
What structured specifications look like
A structured natural language specification constrains how behavior is described. It doesn’t read like a paragraph in a requirements document. It reads more like a contract clause, or a well-written test case.
Instead of: “The system should retry failed API calls.”
You write:
- When an outbound API call returns an HTTP status code of 500, 502, 503, or 504
- Then the system retries the call up to 3 times
- With exponential backoff starting at 200ms, doubling on each retry
- And if all retries are exhausted, returns the last received error response to the caller
- And logs each retry attempt with the attempt number, elapsed time, and status code
This is still English. A product manager can read it. A QA engineer can turn it into test cases. A developer knows exactly what to implement. And an AI can parse it, generate an implementation, and validate the result against each clause.
The structure is what creates precision. Each clause is a verifiable assertion. You can look at the implementation and confirm: does it retry on 500? Yes or no. Does it use exponential backoff starting at 200ms? Yes or no. There’s no room for interpretation because the spec doesn’t leave room for it.
Why this works for AI
Large language models are exceptionally good at interpreting structured natural language. Better, in fact, than most people give them credit for.
An LLM can take a structured specification and generate code that targets each clause. It can take existing code and evaluate whether it satisfies a given specification. It can compare a specification against an implementation in one language and generate a conforming implementation in another. These are tasks that play directly to the strengths of language models: pattern recognition, semantic understanding, and structured generation.
Formal specification languages are harder for LLMs to work with. They’re niche, with less training data and more rigid syntax. Natural language is the medium LLMs understand best. Structured natural language gives them the precision they need to act on it reliably.
The key insight is that AI doesn’t need formal notation to be precise. It needs structured intent expressed in the language it’s best at processing.
The universal interface
The strongest argument for natural language specifications isn’t technical. It’s organizational.
Software isn’t built by engineers alone. It’s defined by product managers, validated by QA, funded by executives, and used by customers. Every one of these stakeholders has a legitimate interest in what the software does. And every one of them can read natural language.
When specifications are written in code, only engineers can review them. When they’re written in formal notation, only specialists can review them. When they’re written in structured natural language, everyone can participate. The product manager can confirm that the business rules are correct. The QA engineer can derive test cases directly from the spec. The executive can understand what they’re funding.
This isn’t just a convenience. It’s a correctness mechanism. The more people who can read and validate a specification, the more likely it is to be right. Specs that only one person can understand are specs that only one person can catch errors in.
Precision is a choice, not a language feature
The problem with software specifications has never been the language they’re written in. It’s the lack of discipline in how they’re written. Teams produce vague specs because nothing forces them to be specific. There’s no structure, no template, no validation step that catches ambiguity before it reaches the implementation.
Natural language can be as precise as you need it to be. Legal contracts prove it. Medical protocols prove it. Building codes prove it. The question isn’t whether natural language is capable of precision. It’s whether the industry is willing to adopt the structures that make precision possible.
We think it is. Especially now that AI can serve as the bridge between structured natural language and code, interpreting the spec, generating the implementation, and validating the result. The tooling that makes this practical is arriving. The language was always there.