Skip to main content

Hallucination diagnosis for RAG systems — Sufficiency, Faithfulness, Completeness verdicts plus rule-based remediation.

Project description

Veralith

Hallucination diagnosis for RAG systems. Wrap one line around your retrieval-augmented pipeline and get structured reports on what failed and how to fix it — not just a single yes/no hallucination flag.

Veralith decomposes every (query, context, response) trace into atomic sub-questions and claims, runs three LLM-as-judge metrics over them (Sufficiency, Faithfulness, Completeness), and classifies the trace into one of six diagnostic cells with a concrete remediation suggestion.

Status: alpha (0.1.x). Public API is stable; expect additions, not breaking changes.


Why Veralith

A monolithic "is this response hallucinated?" judge is a smoke alarm — it can tell you something is wrong but not what or where. Veralith is a diagnostic dashboard:

  • Sufficiency — was the retrieval adequate for each part of the query?
  • Faithfulness — is each claim in the response grounded in the retrieved context?
  • Completeness — does the response actually answer every part of the query?

Cross-tabulating these gives you a named failure mode (retrieval gap, intrinsic hallucination, padded answer, etc.) plus actionable fixes (lower temperature, bump retrieval-K, tighten generator prompt, ...) for every trace.


Install

pip install veralith

Optional extras:

pip install "veralith[langchain]"   # LangChain auto-tracing adapter
pip install "veralith[dev]"          # pytest, ruff, build, twine (contributors)

Set your OpenAI key:

export OPENAI_API_KEY=sk-...

30-second quickstart

import veralith

result = veralith.evaluate(
    query="What is a P/E ratio and what was Apple's P/E in 2023?",
    context=[
        "The price-to-earnings (P/E) ratio is computed by dividing a company's "
        "share price by its earnings per share."
    ],
    response=(
        "A P/E ratio divides share price by earnings per share. "
        "Apple's P/E in 2023 was 42.7."
    ),
    persist=False,
)

print(result.diagnosis.failure_cell.value)   # 'incomplete_ungrounded'
print(result.suggestion.title)               # 'Worst-case failure'
for action in result.suggestion.actions:
    print(" -", action)

You get back a typed EvaluationResult with per-claim verdicts, per-Qi sufficiency, a failure-cell diagnosis, and a concrete suggestion. Optionally persisted to a local SQLite database for later analysis.


Integration patterns

1. Explicit one-liner — works with any RAG stack

import veralith

def answer(query: str) -> str:
    chunks = my_retriever(query)
    response = my_generator(query, chunks)

    veralith.log(query=query, context=chunks, response=response)   # background eval
    return response

2. Decorator — zero code reshape

import veralith

@veralith.trace
def my_rag(query: str):
    chunks = my_retriever(query)
    response = my_generator(query, chunks)
    return response, chunks   # the decorator captures (response, context)

3. Synchronous eval — full result inline

result = veralith.evaluate(query, context, response, persist=False)
if result.diagnosis and result.diagnosis.failure_cell.value.endswith("ungrounded"):
    handle_hallucination(result.faithfulness)

4. LangChain — zero-code auto-tracing

import veralith.adapters.langchain as adapter
adapter.install()

# every RetrievalQA.invoke() now auto-traces to Veralith

What Veralith detects

Each evaluated trace lands in one of six cells from the cross-tab of Completeness × Faithfulness. The cell name follows the pattern <completeness>_<faithfulness>, so you can decode any cell without a lookup chart:

Grounded (every claim supported) Ungrounded (some claim invented)
Complete answer complete_grounded complete_ungrounded
Incomplete answer incomplete_grounded incomplete_ungrounded
Extra unrequested content extra_grounded extra_ungrounded

Read each cell as "the response is <X> and the claims are <Y>." So incomplete_ungrounded means the response didn't cover everything asked AND some of what it did say is unsupported — the worst-case trace.

Plus a per-trace Sufficiency level (HIGH/LOW), learned per knowledge base from the distribution of healthy traces. Together they drive a rule-based suggester that maps every diagnosis to a concrete remediation (lower temperature / bump K / tighten generator prompt / etc.).


Configuration

Defaults work out of the box. Tunable via environment variables or veralith.config.settings:

Variable Default Purpose
OPENAI_API_KEY Required
VERALITH_JUDGE_MODEL gpt-4o Model for S/F/C judges
VERALITH_DECOMPOSER_MODEL gpt-4o-mini Model for query / response decomposition
VERALITH_DB_PATH veralith.db SQLite persistence path

Each evaluation costs roughly 5 LLM calls (3 batched judges + 2 decomposition) — about $0.005 per trace on the default models. Cost is tracked per call via veralith.observability.cost.


The result object

class EvaluationResult:
    trace_id: int
    query: str
    sub_questions: list[SubQuestion]           # decomposed Q
    claims: list[Claim]                         # decomposed R
    sufficiency: list[SufficiencyJudgment]      # per-Qi verdicts
    faithfulness: list[FaithfulnessJudgment]    # per-Ri verdicts + grounding chunks
    completeness: CompletenessJudgment | None   # Ri ↔ Qi alignment
    diagnosis: Diagnosis | None                 # failure_cell + sufficiency level + counts
    suggestion: Suggestion                      # title + body + actionable steps
    created_at: datetime
    errors: dict[str, str]                       # any per-metric failures (D3)
    latency_ms: dict[str, float]                 # per-phase wall-clock timing

Every field is a typed Pydantic model.


Roadmap

What's in 0.1:

  • Three judges (Sufficiency, Faithfulness, Completeness) with batched LLM calls.
  • Diagnostic classifier and rule-based suggester.
  • Outcome-based threshold calibration per knowledge base.
  • SDK: log(), @trace, LangChain adapter, background eval worker.
  • SQLite persistence with self-healing migrations.
  • Cost tracking with per-trace budget guard.
  • CLI entry point.

On the roadmap:

  • LLM-enriched trace-specific suggestions (Suggestion.detailed_body).
  • Cross-trace pattern detection ("you keep hallucinating on time-sensitive queries").
  • Additional judges (reasoning validity, temporal validity).
  • More framework adapters (LlamaIndex, raw OpenAI tools).
  • Hosted dashboard with multi-tenant projects.

Authors

Srijan Shekhar and Kaustav Dasgupta.

License

MIT — see LICENSE.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

veralith-0.2.0.tar.gz (64.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

veralith-0.2.0-py3-none-any.whl (62.4 kB view details)

Uploaded Python 3

File details

Details for the file veralith-0.2.0.tar.gz.

File metadata

  • Download URL: veralith-0.2.0.tar.gz
  • Upload date:
  • Size: 64.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.9

File hashes

Hashes for veralith-0.2.0.tar.gz
Algorithm Hash digest
SHA256 830791a8b4271464b4ef11d5bd46bf32f95f170932e244b299cc22014fbc7be3
MD5 7396fa8dca926c47213c865408248a4c
BLAKE2b-256 c33caf93238612176598c97bbde27c1623a1c17cc58a7e4a211d50ac27161a83

See more details on using hashes here.

File details

Details for the file veralith-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: veralith-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.9

File hashes

Hashes for veralith-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 18c0a6ee926897d7c301789b6715a8e990bdb64207ea94e7fe671e5474e0027e
MD5 f346e8e89eab55cd619079c53bceab4a
BLAKE2b-256 2038e4b989446a54faf71cdc3fda315abaee0bc034e5bad27a3bbe00460faee6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page