Groundedness Evaluation#
Groundedness measures whether an LLM's response is supported by the source material it claims to be based on β a key RAG quality metric. TruLens implements this in LLMProvider.groundedness_measure_with_cot_reasons inside src/feedback/trulens/feedback/llm_provider.py. The function takes a source string (the retrieved context) and a statement string (the LLM response), and returns a (float, dict) tuple: a normalized 0β1 score and per-statement chain-of-thought reasons.
A second variant, groundedness_measure_with_cot_reasons_consider_answerability, also accepts a question argument and adjusts scoring for abstentions based on whether the source could actually answer the question (see Answerability and Abstention below).
Pipeline Overview#
The evaluation runs in four sequential stages:
statement βββΊ sentence splitting βββΊ trivial filtering βββΊ per-statement LLM scoring βββΊ average
1. Sentence Splitting#
The statement is split into individual hypotheses . Two modes are available, controlled by GroundednessConfigs.use_sent_tokenize :
use_sent_tokenize=True(default): Uses NLTK'ssent_tokenize(punkt tokenizer) β fast and cost-free .use_sent_tokenize=False: Calls the LLM withLLM_GROUNDEDNESS_SENTENCES_SPLITTER, which maps toGroundedness.sentences_splitter_prompt. Results are split on newlines. This is more accurate for complex text but incurs extra LLM cost and may hit context-window limits.
2. Trivial Statement Filtering#
When GroundednessConfigs.filter_trivial_statements=True (default), _remove_trivial_statements is called. It sends the full statement list to the LLM with the Trivial class prompts:
- System: "Identify and remove sentences that are stylistic, contain trivial pleasantries, or lack substantive information relevant to the main content. Respond only with a list of the remaining statements in the format of a python list of strings."
- User:
ALL STATEMENTS: {statements} \n IMPORTANT STATEMENTS:
The LLM response is eval()-ed to produce the filtered list . If parsing fails, a warning is emitted and all statements are kept. If all statements are filtered out, the function returns (0.0, {"reason": "No non-trivial statements to evaluate"}) immediately .
Why this matters: Without filtering, filler sentences like "Hi. I'm here to help." would dilute scores for factual claims in the same response .
3. Per-Statement LLM Scoring#
Each remaining hypothesis is scored in parallel via ThreadPoolExecutor . For each hypothesis:
- The system prompt comes from
Groundedness.generate_system_prompt. It instructs the LLM to act as an "INFORMATION OVERLAP classifier" scoring on a 0β3 Likert scale . - The user prompt is
LLM_GROUNDEDNESS_USER/Groundedness.user_prompt, which passesSOURCE: {premise}andStatement: {hypothesis}and requests a structuredCriteria / Supporting Evidence / Scorereply. - Scoring criteria from
Groundedness.criteria_template:- Directly supported β high score
- Not supported β low score
- Abstentions ("I don't know") β max score (treated as grounded)
- Indirect/implicit evidence should not be penalized, but false positives should be guarded against
Scores are normalized from the raw 0β3 range to 0β1, and the score embedded in the reason string is also normalized for display .
4. Score Aggregation#
The final score is the mean of all per-statement scores . Reasons are concatenated as STATEMENT 0: ...\nSTATEMENT 1: ... in the returned dict .
Answerability and Abstention#
groundedness_measure_with_cot_reasons_consider_answerability adds two extra sub-evaluations per hypothesis :
- Abstention detection via
Abstention: Scores 0β1 whether the statement is a form of "I don't know." - Answerability check via
Answerability: Scores 0β1 whether the source could answer the question.
Decision logic :
- Abstention + answerable source β score
0.0("Answerable abstention" β penalized) - Abstention + unanswerable source β score
1.0("Unanswerable abstention" β grounded) - Non-abstention β standard groundedness scoring
Configuration Reference#
| Parameter | Type | Default | Effect |
|---|---|---|---|
use_sent_tokenize | bool | True | Use NLTK vs. LLM for sentence splitting |
filter_trivial_statements | bool | True | Remove stylistic/filler sentences before scoring |
min_score_val / max_score_val | int | 0 / 3 | Raw LLM score range before normalization |
criteria | str | None | Override default scoring criteria |
temperature | float | 0.0 | LLM sampling temperature |
GroundednessConfigs is defined at src/core/trulens/core/feedback/feedback.py:123 and passed to the Feedback constructor via groundedness_configs .
Key Source Files#
| File | Purpose |
|---|---|
llm_provider.py | Main groundedness_measure_with_cot_reasons implementation |
v2/feedback.py | Groundedness, Trivial, Answerability, Abstention prompt classes |
prompts.py | Convenience aliases: LLM_GROUNDEDNESS_SYSTEM/USER, LLM_TRIVIAL_*, etc. |
core/feedback/feedback.py | GroundednessConfigs model |