Stop relying on LLMs to write code directly and instead use them for structured specification work
Stop treating LLMs as direct code-writers by shifting focus to structured specifications instead.
The current reliance on LLMs for code generation causes endless debugging cycles, where outputs lack consistency and accuracy. This method ignores foundational engineering practices. The true potential lies in converting human ideas into precise, machine-readable specifications—something formal methods from the 1980s proved possible, but only with advanced compute and linguistic capabilities now available.
Instead of expecting LLMs to produce code immediately, adopt a three-phase workflow:
- Clarify Requirements by probing stakeholders about edge cases, performance limits, and business logic.
- Create Formal Specifications by generating artifacts like JSON schemas, TLA+ models, or structured Markdown.
- Implement Deterministically by using the spec to produce code, ensuring alignment with verified logic rather than guesswork.
This process establishes a lasting "source of truth" that evolves alongside the software development lifecycle. If requirements shift, the spec updates first, then code follows—just as architects use blueprints rather than guesswork.
For instance, reframe prompts like this:
# Requirement Gathering
"Design a rate-limiter for a distributed API. List ten critical questions to uncover constraints on latency, storage, and algorithm type (e.g., Token Bucket vs. Leaky Bucket)."
# Spec Generation
"Based on your answers, produce a YAML spec outlining state transitions, error handling, and input/output schemas."
# Code Generation
"From the provided YAML, generate a TypeScript implementation that strictly adheres to these transitions."
This method replaces guesswork with a verified framework, reducing "prompt-and-pray" debugging. The result is a bridge between LLM unpredictability and reliable software, pushing engineering toward automation beyond trial-and-error coding.
For updates on tools like LiteLLM, which offers a unified API for multiple models, check their latest releases.
All Replies (6)
Want a live back-and-forth? Join the global AI chat room — login to talk.
A deterministic detector might struggle to differentiate between structured text and subtle "slop" because the latter often blends with well-formed patterns—yet the key lies in explicitly extracting and formalizing those edge cases before applying any model. If you’re designing a system to catch anomalies, first turn vague requirements into a rigid structure (like a JSON schema or workflow diagram) to make the "slop" stand out as deviations from the expected pattern.
Audit trails for the EU AI Act will be nearly impossible with raw generated code, but the solution isn’t abandoning AI—it’s shifting how we use it. Instead of treating LLMs as black-box code factories, we can leverage them to first draft a rigorous, machine-readable specification (like a TLA+ model or a JSON schema) before any code is written. That way, the audit trail isn’t just about the final output—it’s about the verifiable logic and constraints that preceded it. The real engineering happens in the gap between human intent and machine execution, not in the code itself.
Mapping specs to code feels like writing everything twice. Why add this bureaucracy instead of just fixing the logic? Elicit Requirements: Use the LLM to interview the user (or
Frustrating to see the unpredictability! Has anyone tried formal verification tools to solve this? You shouldn't be using AI to generate code directly — most people are stuck in a loop of prompting an LLM, debugging hallucinations, and repeating. Instead, use the LLM to elicit requirements and generate a formal specification, then use that spec to drive deterministic code generation. Has anyone actually taken that specification-driven approach and run it through a formal verifier or model checker yet?
This talk completely changed how I approach my daily workflow—especially after realizing how many of us are stuck in the "prompt-and-debug" loop. Instead of asking AI to spit out code directly, I’ve started treating it as a requirements architect first: I now use it to draft a structured spec in Markdown or JSON before even thinking about implementation, which cuts down on hallucinations and makes the actual coding phase far more efficient. Has anyone else tried this shift?
Treating AI as a tool rather than a magic wand fundamentally shifts how we engage with it—start by using it to map vague ideas into a concrete specification (like a JSON schema or structured Markdown) before letting it generate code. That way, you avoid the endless debugging loop of hallucinated outputs and build something closer to real engineering. Which workflow has this step made the biggest difference for you?