Spaces:
Sleeping
Sleeping
File size: 7,899 Bytes
8cb2aac b5772b5 8cb2aac b5772b5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | ---
title: Truth Verification Pipeline
emoji: π
colorFrom: blue
colorTo: indigo
sdk: gradio
sdk_version: 6.20.0
app_file: app.py
pinned: false
license: mit
short_description: Grounded 14-stage fact-verification API with live search
---
# Truth Verification Pipeline

A multi-stage fact-verification API. Given a claim or question, it extracts
the underlying factual assertions, searches the live web for evidence,
scores and cross-checks that evidence, and returns a verdict with a
calibrated confidence score and the exact sources used.
It's built to be called programmatically (see **API usage** below) as much
as used through the demo UI above.
## Setup
This Space needs two secrets set under **Settings β Repository secrets**:
| Secret | Required | Purpose |
|---|---|---|
| `GROQ_API_KEY` | Yes (primary) | Runs the pipeline's reasoning/extraction stages via Groq (`openai/gpt-oss-120b`) |
| `GEMINI_API_KEY` | Recommended (fallback) | Used only if Groq is unavailable, via `gemini-3.1-flash-lite` |
If neither key is set, the API responds with a clear error instead of
crashing. If only one is set, that provider handles every stage.
No search API key is needed β evidence retrieval uses `ddgs`, a free
multi-engine metasearch library (no signup required).
## API usage
The UI above exposes a single endpoint, `verify`, via the Gradio client:
```python
from gradio_client import Client
client = Client("your-username/your-space-name")
result = client.predict(
"The Great Wall of China is visible from space with the naked eye.",
api_name="/verify"
)
print(result)
```
Or over plain HTTP:
```bash
curl -X POST https://your-username-your-space-name.hf.space/call/verify \
-H "Content-Type: application/json" \
-d '{"data": ["Is the Great Wall of China visible from space?"]}'
```
### Response shape
```json
{
"answer": "string β the final, evidence-grounded answer",
"confidence": 0.0,
"reasoningSummary": "string β why this verdict was reached",
"supportingEvidence": [{"fact": "string", "source": "url"}],
"sources": ["url", "..."],
"verdict": "Verified | Debunked | Uncertain | Disputed | Not Applicable β Opinion/Subjective | Rate Limited | No Input | Error",
"claimsAnalyzed": ["the atomic claims extracted from your input"],
"domains": ["subject-matter tags, e.g. Science, Health, Politics"],
"caveats": ["warnings, e.g. high-stakes domain or safety adjustment"],
"sourceCount": 0,
"knowledgeGraph": [{"subject": "...", "predicate": "...", "object": "..."}],
"pipelineWarnings": ["transparency notes about anything that degraded, e.g. a stripped fabricated source"],
"verifiedAt": "ISO 8601 timestamp"
}
```
`answer`, `confidence`, `reasoningSummary`, `supportingEvidence`, and
`sources` are the original fields and are always present with these exact
names/types. Everything else is additive.
Rate limit: 5 requests per client IP per 60 seconds.
## How the pipeline works
Every input goes through the same 14 stages. Stages 1β12 are LLM calls with
a specific, narrow job; stages 13β14 are plain Python β no model involved β
which is deliberate: the parts of the pipeline that most directly police
accuracy don't rely on an LLM grading its own homework.
1. **Query Analyzer** β classifies the input as a verifiable factual claim
vs. an opinion/preference. Opinions short-circuit immediately with a
`Not Applicable β Opinion/Subjective` verdict instead of being forced
through a Verified/Debunked judgment they were never suited for.
2. **Claim Extractor** β splits the input into distinct, atomic,
independently-checkable claims (a compound sentence can assert several
things at once; each is checked on its own).
3. **Domain Classifier** β tags the subject domain(s) (Science, Health,
Politics, Finance, etc.). Claims in high-stakes domains (health, legal,
financial, elections) get an explicit caveat appended to the final
answer.
4. **Search Query Generator** β writes real search-engine queries for each
claim. Deliberately generates queries aimed at *confirming* the claim
**and** queries aimed at *refuting* it, to avoid one-sided,
confirmation-biased research.
5. **Retrieval Engine** β runs those queries against `ddgs`, which itself
fans out across multiple engines (Bing, Brave, Google, DuckDuckGo,
Yahoo, Yandex, Wikipedia) and aggregates/de-duplicates results. Retried
with backoff on transient failures.
6. **Evidence Extractor** β pulls factual snippets out of the raw search
results. The model is only shown the URLs actually returned by search
and is explicitly told never to invent one; anything it cites that
doesn't match a real retrieved URL is discarded right here.
7. **Evidence Scorer** β scores each snippet for relevance and reliability.
Reliability is a *blend* of the model's judgment and a rule-based prior
(`.gov`/`.edu`/major wire services score higher, personal blogs score
lower) β so one model's guess about source quality isn't the only
signal.
8. **Verification Engine** β reaches a first-pass verdict (Verified /
Debunked / Uncertain) strictly from the scored evidence, with explicit
instructions not to guess confidently when evidence is thin or mixed.
9. **Conflict Resolver** β an adversarial second pass whose only job is to
find problems with the verdict from stage 8: underweighted
contradictions, sources disagreeing with each other, low-reliability
evidence being treated as decisive. It can downgrade or change the
verdict, or mark it "Disputed" if credible sources genuinely disagree.
10. **Truth & Safety Policy** β reviews the resolved verdict for
responsible-communication concerns (e.g. medical/legal framing,
defamation risk) and can attach a phrasing adjustment that the final
answer is required to apply.
11. **Knowledge Graph Builder** β structures the verified facts into
subjectβpredicateβobject triplets, surfaced in `knowledgeGraph`.
12. **Response Generator** β writes the final answer, reasoning summary,
and cites its supporting evidence, using only the exact source URLs
already validated in earlier stages.
13. **Grounding Audit** *(code, not a model call)* β a hard check that
strips any source in the final answer that isn't in the set of URLs
actually retrieved in stage 5. This is the last line of defense against
a fabricated citation slipping through.
14. **Confidence Calibration** *(code, not a model call)* β recomputes the
final confidence score from concrete signals rather than trusting the
model's self-reported number: it's capped hard if search returned
nothing, capped further if fewer than 2 independent sources back a
"Verified"/"Debunked" verdict, and capped again if the grounding audit
had to remove anything.
Throughout, every LLM call is wrapped in JSON-repair logic (strip markdown
fences β parse β extract the first balanced JSON block β one corrective
retry) with a typed fallback default, and the whole pipeline runs inside a
top-level try/except β so a single stage failing degrades that one part of
the result (and is logged in `pipelineWarnings`) instead of crashing the
request.
## Known limitations
- Web search quality depends on what the underlying engines surface; a
claim about something very recent or very obscure may return little or
no evidence, in which case the pipeline correctly reports low confidence
rather than guessing.
- The rule-based source-credibility list is a small, illustrative set of
high/low-credibility domain hints, not an exhaustive authority ranking.
- This is a research/demo tool, not a substitute for professional
judgment β see the caveats field for claims in high-stakes domains.
|