Skip to content

About

Bangladesh-first multi-agent rumor verification for text claims and news photocards

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Jachai

Evidence before belief.

Jachai is a Bangladesh-first rumor scanner for verifying text claims and news photocards. It searches the live web, evaluates source quality and independence, and returns an inspectable evidence report instead of an unsupported AI answer.

The interface is English, while the verification engine can investigate both English and Bengali claims and sources.

System architecture

Jachai intelligence system architecture

Download the full-resolution architecture PDF

The pipeline is designed around three principles:

  1. Retrieve before reasoning — conclusions must be connected to attributable URLs.
  2. Audit deterministically — source tiers, reachability, dates, entities, and publisher independence are checked in code.
  3. Escalate only when necessary — cached and routine claims stay inexpensive; weak, sensitive, or conflicting evidence receives another research pass.

Verification flow

Stage What happens
Input Accepts one text claim or a JPG, PNG, or WebP photocard up to 10 MB. Images can also be pasted from the clipboard.
Cache Checks exact claims, strict semantic matches, and perceptual image fingerprints. A cache hit uses no model call.
Intake Detects language, enforces a single factual claim, and runs local Tesseract OCR for images.
Retrieval Searches known fact-checks, configured search providers, Gemini Search when available, and Google News RSS as a fallback.
Classification The active LLM converts the retrieved material into structured, claim-specific evidence.
Audit Validates URLs and grades relevance, provenance, independence, entity match, and date match.
Decision Requires a relevant Tier A source or multiple independent Tier B sources for a decisive verdict.
Report Returns the verdict, confidence, limitations, source tiers, and clickable evidence links.

Verdicts and source tiers

Jachai returns one of four evidence states:

  • supported — qualifying evidence directly supports the claim.
  • contradicted — qualifying evidence directly contradicts the same claim and event.
  • mixed — reliable sources conflict or support different parts of the claim.
  • insufficient_evidence — the available evidence is not strong enough to decide.

Missing evidence is never treated as proof that a claim is false.

Tier Meaning Examples
A Primary evidence Official notices, court records, government data, original documents, direct statements
B Established reporting Independent newsrooms with editorial standards, dates, bylines, and attributable evidence
C Context only Blogs, aggregators, social posts, or sources with limited provenance

Tier C evidence can provide context but cannot determine a verdict by itself.

Technology

  • API: FastAPI with asynchronous verification jobs
  • Progress: Server-sent events
  • Frontend: Responsive HTML, CSS, and vanilla JavaScript
  • Models: OpenRouter or Google Gemini
  • Retrieval: Google Fact Check, Tavily, Brave, Gemini Search, and Google News RSS
  • OCR: Local Tesseract with optional Google Cloud Vision fallback
  • Caching: In-memory locally; Redis for shared production jobs and cache
  • Validation: Pydantic schemas and deterministic source auditing

Quick start

Requirements:

  • Python 3.11 or newer
  • Tesseract with English and Bengali language data for local photocard OCR
  • An OpenRouter or Gemini API key
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env

Configure one model provider in .env.

OpenRouter free models

OPENROUTER_API_KEY=your_key_here
LLM_PROVIDER=openrouter
OPENROUTER_MODEL=openrouter/free

Free OpenRouter models are useful for development and demonstrations, but their availability, latency, model selection, and daily rate limits can vary. Use a specific paid model for predictable production behavior.

Gemini

GEMINI_API_KEY=your_key_here
LLM_PROVIDER=gemini
INTAKE_MODEL=gemini-2.5-flash-lite
RESEARCH_MODEL=gemini-2.5-flash
CLASSIFICATION_MODEL=gemini-2.5-flash-lite
ESCALATION_MODEL=gemini-3.6-flash

Start the application:

./start.sh

Open http://localhost:8000.

Configuration

Variable Default Purpose
LLM_PROVIDER auto Selects openrouter, gemini, or the first configured provider.
OPENROUTER_MODEL openrouter/free OpenRouter model or router slug.
SEARCH_PROVIDER auto Prefers Tavily, then Brave, then native Gemini Search, then RSS fallback.
FACT_CHECK_API_KEY empty Enables Google Fact Check lookup before general research.
TAVILY_API_KEY empty Enables Tavily news search.
BRAVE_SEARCH_API_KEY empty Enables Brave web search.
VISION_API_KEY empty Enables Cloud Vision when local OCR is insufficient.
ENABLE_IMAGE_WEB_DETECTION false Enables paid visual-match discovery during escalation.
ENABLE_QUALITY_ESCALATION true Runs a second research pass for uncertain or high-risk claims.
RESULT_CACHE_TTL_SECONDS 86400 Keeps verification results for 24 hours.
SEMANTIC_CACHE_THRESHOLD 0.92 Controls strict semantic cache reuse.
MAX_CLAIMS_PER_VERIFICATION 1 Prevents one submission from multiplying model and search calls.
RATE_LIMIT_PER_HOUR 10 Per-client verification limit.
REDIS_URL empty Enables shared production jobs and cache.

See .env.example for the full configuration template. Never commit .env or production API keys.

API

Create a text verification:

curl -X POST http://localhost:8000/api/v1/verifications \
  -H "Content-Type: application/json" \
  -d '{"text":"The government has announced a nationwide public holiday tomorrow."}'

Create a photocard verification:

curl -X POST http://localhost:8000/api/v1/verifications \
  -F "file=@photocard.jpg"

The API responds with 202 Accepted and provides URLs for job status, live SSE progress, and the final report. A running job can be cancelled with:

DELETE /api/v1/verifications/{request_id}

Completed jobs expire according to JOB_TTL_SECONDS.

Testing and evaluation

Run the automated suite:

PYTHONPATH=backend .venv/bin/pytest -q

The tests cover evidence decisions, URL normalization, API validation, cache safety, image fingerprints, OCR quality gates, single-claim enforcement, and the crucial no-evidence behavior.

For quality benchmarking, prepare a JSONL dataset with claim, expected_status, and optional required_domains, then run:

PYTHONPATH=backend .venv/bin/python scripts/evaluate_pipeline.py benchmark.jsonl

The evaluator reports verdict accuracy, source recall, latency, and individual case failures. Use human-reviewed claims rather than synthetic ground truth.

To regenerate the architecture image:

PYTHONPATH=backend .venv/bin/python scripts/render_system_graph.py

Deployment

render.yaml defines a Docker web service and managed Redis. Before deployment:

  1. Add model and optional search keys as secret environment variables.
  2. Set ALLOWED_ORIGINS to the deployed HTTPS origin.
  3. Set OPENROUTER_SITE_URL to the public application URL when using OpenRouter.
  4. Keep image web detection disabled unless its additional cost is intentional.
  5. Monitor provider usage, cache-hit rate, latency, and insufficient-evidence rate.

The Docker image includes English and Bengali Tesseract language data for the zero-cost OCR path.

Responsible use

Jachai reports the strength of available evidence; it does not declare absolute truth. Important political, legal, medical, financial, or safety decisions should always be checked against the original primary sources and qualified experts.

About

Bangladesh-first multi-agent rumor verification for text claims and news photocards

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages