Project Info
About the Project Tweet FactChecker is a one-click fact-checking tool for X/Twitter posts. The idea is simple: when a user sees a suspicious tweet, they can click a “Fact Check” button directly inside the browser. The extension sends the tweet to a backend pipeline, where multiple agents extract claims, evaluate evidence, critique the reasoning, and return a concise verdict in an overlay.
Inspiration
Social media moves faster than truth. A misleading post can spread widely before most people have time to verify it. We wanted to build something that fits naturally into the place where misinformation appears: the timeline itself. Instead of asking users to copy a tweet, open another tab, search manually, and compare sources, Tweet FactChecker brings the verification workflow directly into the browser. Our goal was to make fact-checking feel lightweight enough that people would actually use it in the moment. What It Does Tweet FactChecker adds a fact-checking layer to X/Twitter: A browser extension detects tweets and injects a fact-check button. When clicked, the extension sends the tweet text to a FastAPI backend. The backend runs a multi-agent pipeline: ClaimAgent extracts checkable claims from the tweet. EvaluatorAgent searches for supporting or contradicting evidence. CriticAgent reviews the reasoning and catches weak conclusions. ClaimAgent extracts checkable claims from the tweet. EvaluatorAgent searches for supporting or contradicting evidence. CriticAgent reviews the reasoning and catches weak conclusions. The system aggregates the results into a final verdict. The extension displays the conclusion in a clean floating overlay. Conceptually, the pipeline turns a tweet into structured reasoning: tweet \rightarrow claims \rightarrow evidence \rightarrow critique \rightarrow verdict How We Built It The project is split into two main parts: extension/: a TypeScript + Vite + Manifest V3 browser extension backend/: a Python 3.12 FastAPI service The extension handles tweet extraction, UI injection, API calls, and result rendering. The backend owns the fact-checking pipeline, shared contracts, mock responses, real-agent wiring, and integration smoke tests. A key design decision was to keep the data contract frozen between frontend and backend. The Pydantic models in backend/contracts/models.py mirror the TypeScript types in extension/src/types.ts, so both sides agree exactly on the shape of requests and responses. We also built the system so it can run in two modes: Mock mode for local development without API keys Real agent mode using USE_REAL_AGENTS=1 for the full multi-agent pipeline This made it easier to develop the UI and backend independently while still preserving an end-to-end path. Challenges We Faced One of the hardest parts was keeping the frontend and backend synchronized. Since the extension depends on exact response shapes, even a small contract mismatch could break the overlay rendering. Freezing and mirroring the contract helped reduce that risk. Another challenge was designing the agent pipeline so it did more than produce a single rushed answer. We wanted the system to separate claim extraction, evidence evaluation, and critique, because fact-checking requires more than just confidence. It requires structured reasoning. We also had to balance real-world usability with development speed. The browser extension needed to feel immediate, while the backend needed enough structure to support mock testing, real agents, and future expansion. What We Learned We learned that fact-checking is not just a search problem. It is a workflow problem. A useful system needs to identify what is actually being claimed, evaluate evidence carefully, and explain the result in a way users can understand quickly. We also learned the value of strict contracts between frontend and backend. By treating the response schema as a shared source of truth, we made the system easier to test, debug, and extend. Most importantly, we learned that AI agents are most useful when they have clear roles. Splitting the pipeline into claim extraction, evaluation, and critique made the final result more reliable than a single all-purpose step. What's Next Next, we want to improve source citation quality, support multi-claim tweets more deeply, add richer verdict explanations, and make the extension more robust across different X/Twitter layouts. We also want to experiment with confidence scoring and user feedback so the system can better communicate uncertainty instead of pretending every answer is absolute.
Tweet FactChecker
在 X/Twitter 的每条推文旁加一个「核查」按钮。点一下,联网搜证、独立复核,给出带来源链接的结论。
没有服务器。 核查管道整个跑在浏览器扩展里,用你自己的 Anthropic API Key
直连 api.anthropic.com。密钥存在本机,不经过任何第三方。
它怎么工作
推文
└─ 抽取断言 Haiku 4.5 拆成可独立验证的事实性陈述,跳过观点与情绪
└─ 联网搜证 Sonnet 5 为每条断言检索权威来源,交叉验证
└─ 独立复核 Sonnet 5 以「魔鬼代言人」身份审查初判,挑证据缺口与逻辑跳步
└─ 聚合 按置信度加权,给出整体判定
结论分六档:属实 / 基本属实 / 真假参半 / 大体不实 / 不实 / 无法核实。
设计原则
可追溯优先。 每条证据必须带可点开的来源链接。模型偶尔会吐出相对路径、裸域名或 占位文字——这类「来源」在卡片上和真链接一样权威却无法核验,比没有来源更糟, 因此会被直接丢弃。若过滤后证据为空,判定强制降级为「无法核实」,绝不出现 「零证据却挂着确定结论」。
不确定就说不确定。 多条断言中只核实了一部分时,结论里会写明覆盖率 (「共 3 条断言,1 条已核实……另有 2 条无法核实,未计入整体判定」), 不让头部判定掩盖未核实的部分。
无服务器。 开发者不运营任何后端,看不到你核查了什么。这也是隐私政策 能写成「不收集任何数据」的前提。
安装
从源码构建
cd extension
npm install
npm run build # 产物在 dist/
Chrome → chrome://extensions → 打开开发者模式 → 「加载未打包的扩展程序」→ 选 dist/。
首次安装会打开设置页,填入 Anthropic API Key (在 console.anthropic.com 创建)。
费用
扩展免费。模型调用按 Anthropic 官方价目从你自己的账户扣除, 开发者不经手也不抽成。
典型单次核查约 $0.10–0.35,取决于推文里断言的条数: 一次 Haiku(抽断言)+ 每条断言两次 Sonnet(搜证 + 复核)+ 联网搜索。
已知限制
单次核查约 150 秒。 管道结构决定的:每条断言都要联网搜证再复核,且各条并行。 卡片有流式骨架和实时秒表来缓解等待感,但这仍是硬伤。
自动核查会出错。 模型可能误读断言、检索到不可靠来源,或对时效性极强的事件 给出过时结论。请把结论当作「带来源的调查起点」,而不是最终裁决—— 每条证据的链接都可点开,请自行判断。
界面仅中文。
隐私
密钥与反馈标记存在 chrome.storage.local(本机,不同步)。
你主动点击核查的推文文本会发往 Anthropic 用于核查;除此之外不收集、不上传、
不存储任何数据,没有分析埋点。
完整说明见隐私政策。
开发
extension/src/
content.ts 抓推文 + 注入按钮
overlay.ts 核查卡渲染(Shadow DOM 隔离,不污染 X 的样式)
background.ts service worker:核查管道的执行者
engine/ 管道本体
anthropic.ts 直连 API 的 fetch 封装 + 错误分类
structured.ts 强制工具调用 → 结构化输出 + 类型闸门
claim.ts / evaluator.ts / critic.ts
pipeline.ts 收敛 + 聚合 + 流式编排
npm run typecheck
VITE_USE_MOCK=true npm run build # 离线假数据,不花钱
ANTHROPIC_API_KEY=sk-ant-... npx tsx scripts/smoke.ts # 真链路冒烟(约 $0.3)
npm run package # 上架 zip
改动扩展后需在 chrome://extensions 点重载,并在 x.com 硬刷新(Cmd+Shift+R),
否则页面仍在跑旧包。
backend/ 是 v0.1 的 Python 参考实现,已不被构建或分发;
extension/src/engine/ 是它的 TypeScript 移植。改核查逻辑改后者。
Analysis
View
Metric
- 15
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- AnthropicIn code
- FastAPIIn code
- PythonIn code
- TypeScriptIn code
4 of 4 appear in the indexed code.
AI coding agents
- Claude CodeConfig · Commits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
105 KB
Source files
32
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
taohaoze7-prog/tweet-factchecker
41 files · 142 KB · @ c11767a
Structure
Application logic
27 files · 66%Domain rules, services and shared utilities.
+2 more
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Python68%
- TypeScript20%
- Markdown12%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
backend/requirements.txt
pypi · 7- anthropic
- fastapi
- httpx
- pydantic
- pytest
- pytest-asyncio
- uvicorn[standard]
extension/package.json
npm · 33 development-only dependencies.
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.