Hallucination prevention

1 min read
On trails:AGSAFEstep 3/7

Hallucination, an answer that sounds right and is not, cannot be turned off. Preventing it takes prompt engineering, context engineering and flow engineering together: tell the model what to do, give it the facts, and shape the path so a guess has nowhere to land. See promptPrompt engineeringEngineering the instruction given to the model.Opens in a new tab, contextContext engineeringDeciding what the model sees on every call, because the window is finite.Opens in a new tab and flowFlow engineeringDesign the task as a flow of steps: a model where judgement is needed, plain code everywhere else.Opens in a new tab engineering.

Habits that cut it down

  • Retrieval tool grounding. The answer comes from what a tool returned, not from the model’s memory (see retrieval at query timeRAG at query timeA one-way chain: embed the query, search, stuff the chunks into the prompt, generate.Opens in a new tab).
  • No answer from history. A fact that can change, like a status or a balance, is fetched again, not read back from earlier in the chat.
  • Never invent IDs or tool config. If the lookup finds nothing, the right output is “not found”, not a plausible ID.
  • Low temperature. Sampling is less random. It helps, but a confident wrong answer is still possible.
  • Structural guards. Take the choice away from the model, as in the tenant guard below.
  • Reflection agents. A second pass critiques the first before it is final (see reflectionReflectionCritique the output before finalizing it: one agent does, another reflects.Opens in a new tab).

Anthropic’s guide adds three prompt-level ones: allow the model to say it does not know, have it quote the source first, and have it retract any claim it cannot back with a quote. It also says plainly that these reduce hallucination and do not eliminate it.

A tenant guard

The model should not pick whose data it reads. Here the tenant comes from the runtime, and a missing order returns a refusal to guess.

Python
from dataclasses import dataclass from langchain.tools import ToolRuntime, tool  @dataclassclass Ctx:    tenant_id: str  ORDERS = {("acme", "A-1001"): "shipped"}  @tooldef get_order_status(order_id: str, runtime: ToolRuntime[Ctx]) -> str:    """Look up an order's status by its ID."""    status = ORDERS.get((runtime.context.tenant_id, order_id))    return status or "No such order. Do not guess one."

The runtime parameter is hidden from the tool schema, so the model sees only order_id and cannot supply a tenant of its own.


Sources