Truth_API / README.md
Adedoyinjames's picture
Update README.md
b5772b5 verified
|
Raw
History Blame Contribute Delete
7.9 kB
---
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
![Truth Verification Pipeline](https://i.ibb.co/PsycpCXP/Chat-GPT-Image-Jul-7-2026-11-28-32-AM.png)
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.