Inspiration
Every AI search engine does the same thing — blend sources into one clean answer. But what happens when those sources disagree? I was researching a topic using Perplexity and ChatGPT. Both gave me confident, well-cited answers. Then I opened the sources. Three of them directly contradicted each other on the central claim. The AI had smoothed over the conflict entirely.
That's when I realized: we've built search engines that answer questions, but not one that helps people think. Oracle was born from that frustration.
What it Does
Oracle is a Research Intelligence Platform with two core capabilities:
- Deep Research — A 5-round ReAct loop that iteratively searches, reads sources, identifies knowledge gaps, and searches again. Each round gets smarter than the last.
- 3D Knowledge Graph — After gathering sources, Oracle runs a 3-step claim analysis pipeline (topic clustering → pairwise comparison → cross-cluster mapping) and visualizes every source relationship in an interactive Three.js sphere.
Four relationship types are detected:
- Red — Sources directly contradict each other
- Green — Sources agree on the same conclusion
- Yellow — Partial overlap with differing specifics
- Blue — Complementary perspectives from different angles
How I Built It
Backend: 31 Node.js modules forming a Firecrawl-class web crawler with Playwright for JS-rendered pages, Cheerio + Turndown for content extraction, and a streaming LLM synthesis pipeline. The claim analysis uses a novel 3-step approach: first clustering sources by topic via LLM, then comparing all pairs within each cluster, then filling cross-cluster gaps computationally.
Frontend: React 18 with Three.js for the 3D knowledge graph. Each source is a domain-colored 3D sphere node. Edges pulse with confidence-weighted brightness. Constellation mode dims unrelated nodes on hover. Framer Motion handles transitions. The Ember Glass design uses OLED black, amber gold accents, and glassmorphism panels.
Search Pipeline: Tavily API for web search → parallel fetch + extract → LLM streaming synthesis → claim extraction → 3D graph rendering. Deep Research adds a ReAct planning loop on top.
Challenges
Small LLM context limits — Gemma 3 1B has ~2K context. Comparing 30 sources in one call fails silently. Solution: topic clustering splits sources into manageable groups of 6-8 for pairwise analysis.
Stale closures in Three.js animation loops — React props captured in
useEffectclosures become stale during 60fps rendering. Solution:useRefto sync latest claim data into the animation loop.Source panel UX — Positioning a hover panel near 3D nodes without overflow required measuring panel height post-render and dynamically flipping above/below the node.
Making contradictions visible — WebGL caps line width at 1px. Solution: cylinder mesh geometry for relationship edges, with variable thickness by type (disagree thickest, complementary thinnest).
What I Learned
- LLM prompts that say "find meaningful contradictions" produce conservative results. Explicitly enumerating pairs and demanding a verdict for each one produces dramatically better coverage.
- The relationship between sources is often more valuable than the sources themselves.
- 3D visualization isn't just eye candy when it encodes real analytical data — it becomes a thinking tool.
