PromptForge Academy
hallucinationsprompt-engineeringreliabilityclaude

How to Prevent AI Hallucinations in Code Generation

Why LLMs invent function signatures, library methods, and config options that don't exist — and the five concrete prompting techniques that shut it down in real codebases.

"The AI made up a method that doesn't exist" is the single most common complaint about AI-assisted coding — and it's also one of the most preventable. Hallucination isn't a random bug you have to tolerate; it's a predictable failure mode with predictable fixes, once you understand why it happens.

Why LLMs hallucinate code

An LLM generates the statistically most plausible next token given everything before it — it does not look anything up. When you ask for "a method to retry a failed HTTP call with exponential backoff," the model isn't recalling a specific library's API; it's generating something that looks like what such a method typically looks like across its training data. Most of the time that's close enough. Sometimes it invents `HttpClient.RetryWithBackoffAsync()` — a method that sounds exactly right and doesn't exist anywhere.

This gets worse, not better, with obscure APIs

Well-known libraries (System.Net.Http, React, Express) have enough training coverage that hallucination is rarer. Internal company libraries, less common NuGet/npm packages, and anything released after the model's training cutoff are where invented APIs show up most.

Five techniques that actually work

  1. Ground it — paste the real API surface. If you're using an internal library or an unusual package, paste the actual type definitions, method signatures, or a working example before asking for new code that uses it.
  2. Add an explicit negative constraint. "Only use methods, types, and imports that are visible in the context I've given you" measurably reduces invention — it's a direct instruction, not a hope.
  3. Ask for a self-check pass. After generation, a second turn — "review the code above and flag anything that calls an API you're not certain exists" — catches a meaningful fraction of the first pass's mistakes.
  4. Compile or run it before trusting it. This sounds obvious, but the failure mode is skimming AI output that looks right and shipping it unverified. A hallucinated method call is a compiler error waiting to happen — let the compiler happen.
  5. Prefer retrieval over memory for anything version-specific. If the task depends on exact current API shape (a fast-moving SDK, a recent framework version), give the model the actual current docs/types rather than relying on training data that may be a year stale.

Worked example

Prompt without grounding

"Write a function that uploads a file to our blob storage service and returns the URL." With no context about which SDK, which method names, or which auth pattern your storage service actually uses, the model will generate a plausible-looking call against an imagined API.

Prompt with grounding + negative constraint
Context: We use Azure.Storage.Blobs v12. Here is our existing upload helper for reference:

[paste an existing working call, e.g. BlobContainerClient usage]

Task: Write a function UploadFileAsync(Stream content, string fileName) that uploads to the 'user-uploads' container and returns the blob URL.

Constraints:
- Only use types and methods from Azure.Storage.Blobs that appear in the reference snippet above, or that you are certain exist in v12.
- If you are not certain a method exists, say so explicitly instead of guessing.
- Include error handling for upload failure (throw a typed exception, don't swallow it).

Common hallucination patterns to watch for

PatternExampleWhy it happens
Invented method on a real class`list.SafeGet(index)` on a standard List<T>Model generalizes from similar "safe accessor" patterns it has seen elsewhere
Plausible-sounding config key`enableStrictValidation: true` in a config that has no such optionModel pattern-matches to common naming conventions rather than the actual schema
Confident but wrong library version behaviorDescribing a method that existed in v11 but was removed in v12Training data spans multiple versions; model doesn't reliably track which version you're on
Fabricated citation or source referenceA specific RFC section or vendor doc URL that doesn't say what's claimedSame root cause — plausible continuation, not lookup

The discipline this actually requires

None of this is about distrusting AI-assisted coding wholesale — it's about treating unverified generated code the same way you'd treat unverified code from any source: compile it, test it, and don't merge what you haven't checked. The prompting techniques above shrink the failure rate; code review and CI are still what catches the rest.

The Foundations program covers this failure mode in depth as part of teaching the core mental model of how LLMs generate text — understanding why hallucination happens is what makes the prevention techniques stick instead of feeling like arbitrary rules.