Skip to main content
Version: Latest (main)

Hallucination Signal

Overview​

hallucination finds the claims in the model's answer that its grounding context does not support. It asks the hallucination preset, a span question over the answer, with the label unsupported, at the response stage. The grounding context is the documents RAG retrieved and the request's tool results.

Key Advantages​

  • Separates detecting an unsupported claim from what the Router does about it.
  • Returns the spans of the unsupported claims, not only a verdict.
  • Reports an answer that could not be checked as unknown, never as verified.
  • Checks only the answers worth grounding, when combined with fact_check.

What Problem Does It Solve?​

A model given evidence can still answer past it: a wrong number, an invented name, a detail the context never states. hallucination reads the answer against that evidence and publishes what it finds as a signal that a response_guard acts on.

When to Use​

Use hallucination when:

  • answers grounded in tool results or retrieved documents must be checked before they are trusted;
  • a decision should annotate or block unsupported answers;
  • Router Replay should record whether an answer was checked, and with what result.

Configuration​

recipes:
- name: default
signals:
fact_check:
- name: needs_fact_check
hallucination:
- name: ungrounded
decisions:
- name: grounded-qa
priority: 100
rules:
operator: AND
conditions: []
modelRefs:
- model: answer-model
plugins:
- type: response_guard
configuration:
rules:
- when:
operator: AND
conditions:
- {type: fact_check, name: needs_fact_check}
- {type: hallucination, name: ungrounded}
action: annotate
details: true
on_unknown: annotate
FieldMeaning
nameThe rule's name, which guard rules use as {type: hallucination, name: ...}
predicateThe least probability of an unsupported span; by default the model's own span thresholds decide
deployment, timeout_msThe deployment that answers, and the answer's deadline

A rule matches when the model finds an unsupported span. The guard rule above checks only the answers to requests that need facts: an AND stops at a false condition, so the question is not asked when needs_fact_check does not match.

Stage and outcomes​

The question is asked after the model has answered, so a decision cannot read it: a decision that does, directly or through a projection, is refused at load. Only a response_guard reads it, from the recipe the request resolved to. The rule is unknown when the request carried no grounding context, when the model gave no answer, or when the response had no text to check; the guard's on_unknown decides what an unknown rule does.

A streamed answer is checked once the stream ends. The guard above holds the stream until then, because its rule can write a note into the answer (details: true): the client receives the answer once it has been checked, with the note at its head when the rule matched. A guard whose rules only flag answers in x-vsr-warnings, or only record them, keeps the stream live and records the result when it ends. See Streamed Answers.

The model that answers​

The decision model answers every hallucination rule, unless the hallucination binding or the rule's deployment names another; see Choose a deployment. The question needs spans: vela3-fast (the default), the Vela 3.0 d3 sizes and Vela 2.0 answer it with their own hallucination question. A rule that resolves to a deployment without span answers, such as a d3 model, fails to load with span_required.

The question sends the request, the answer and the grounding context to the deployment. See a complete example: config/fragments/signal/hallucination/grounded-answer.yaml.