Inspiration

What it does

How we built it

Challenges we ran into

Accomplishments that we're proud of

What we learned

What's next for VeriNews AI

Inspiration

I've spent the last couple of years building local-first RAG and LLM systems — from a medical Q&A assistant to conversational agents — and one thing kept nagging at me: static RAG (search once, generate once) breaks down fastest on exactly the questions where it matters most. Fact-checking is the sharpest version of that problem. A viral claim published an hour ago is invisible to an LLM's training data, and worse, the model won't necessarily tell you it doesn't know — it'll often just generate a fluent, confident-sounding answer anyway. I wanted to build something that couldn't do that: a system that has to go find real, current evidence before it's allowed to render a verdict, and that reasons about which kind of evidence a claim actually needs, rather than treating every question the same way.

What it does

VeriNews AI takes a claim, headline, or article URL and runs it through an agentic research pipeline instead of a single fixed search. An LLM planner breaks the input into several targeted sub-queries and decides, per sub-query, which SerpApi engine is actually appropriate — a scientific claim gets routed toward Google Scholar, a product announcement toward Google Patents and News, a general assertion toward Google Search. Results across all four engines are aggregated, then a second LLM pass verifies the original claim strictly against that live evidence, producing a structured report: an overall truth score, per-claim verdicts with citations, and a breakdown of source credibility (academic/official vs. mainstream news vs. unverified web) — so the output shows not just what was concluded, but how trustworthy the evidence behind it actually is.

How I built it

The pipeline is a plan → execute → aggregate → verify loop. The planner and verifier both run on Gemini 2.5 Flash with Pydantic-validated structured outputs, so the system can't return a malformed research plan or an unparseable report. Live evidence comes entirely from SerpApi across four engines (Search, News, Scholar, Patents), with retry and exponential backoff built in, since live APIs fail sometimes and the system needs to degrade gracefully rather than crash mid-audit. For claims that pull in a large volume of evidence, results are indexed into a FAISS vector store and narrowed to the most relevant chunks via similarity search, rather than dumping everything into the prompt and risking context overflow. The frontend is a Streamlit interface with a dedicated tab comparing the live-evidence-grounded verdict against the same model's unassisted, parametric-memory-only answer — making the actual value of live search visible side by side, not just claimed in a README.

I built this with heavy use of AI coding assistance — I made the architecture decisions and drove every implementation choice, but leaned on AI for a lot of the scaffolding and debugging support. I think that's worth being upfront about rather than glossing over, especially given how much of the real work ended up being debugging rather than writing new code in the first place.

Challenges I ran into

The most important bug I found wasn't in a search integration — it was a silent data-loss path. My evidence-aggregation layer had two modes: a simple mode for small result sets, and a FAISS-indexed mode for large ones. The verifier only knew how to read evidence from the simple mode's output field. Whenever a claim generated enough evidence to trigger the FAISS path — which is exactly the case where you'd expect the best grounding — the verifier silently received an empty context and had to generate a verdict from nothing. It never crashed, and a quick manual test wouldn't have caught it, since the LLM still produced a fluent, complete-looking report either way. Finding it meant actually tracing what each function returned across both code paths rather than trusting that "it runs without errors" meant "it works correctly." I added a proper retrieval step for the FAISS path so the verifier always receives real evidence text, regardless of which mode triggered.

A second challenge was resisting scope creep during cleanup: an earlier version of the project had a second, parallel SerpApi integration (a LangChain tool-based approach) that was never actually wired into the app, plus a duplicate retrieval implementation. Neither was broken, but keeping unused, overlapping code in a hackathon submission makes it harder for anyone reviewing it to tell what's actually running — so I traced every import to confirm nothing depended on them, then removed both rather than leaving dead code for a judge to puzzle over.

Built With

  • beautifulsoup4
  • faiss
  • gemini
  • google-generative-ai
  • google-patents
  • google-scholar
  • langchain
  • pydantic
  • python
  • rag
  • serpapi
  • streamlit
Share this project:

Updates

Submission history