尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Extracts claims from any text, URL, or image, retrieves real-world evidence using web search, and evaluates each claim as True, False, or Uncertain.
Powered by the qwen-3.8-27b model on Cerebras and Parallel Search.
Based on the OpenAI Cookbook: Build Your Own Content Fact-Checker, adapted to use qwen-3.8-27b instead of gpt-oss-120B.檢視完整 README ↗Extracts claims from any text, URL, or image, retrieves real-world evidence using web search, and evaluates each claim as True, False, or Uncertain.
Powered by OpenAI's gpt-6-luna and Parallel Search. Cerebras (qwen-3.8-27b) is supported as an alternate provider; see Changing the Provider or Model.
Based on the OpenAI Cookbook: Build Your Own Content Fact-Checker, adapted to use gpt-6-luna (or qwen-3.8-27b on Cerebras) instead of gpt-oss-120B.
Check Text tab — paste any text to fact-check:
Check URL tab — enter a URL to analyze:
Check Image tab — upload a screenshot, chart, or infographic to analyze:
Progress — each claim is checked in real time:
Results — verdicts with reasoning and source links:
LLM_PROVIDER=cerebrasgit clone https://github.com/bryancowan/content-fact-checker.git
cd content-fact-checker
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
Edit .env and add your keys:
OPENAI_API_KEY=your_openai_key_here
PARALLEL_API_KEY=your_parallel_key_here
To use Cerebras instead, set LLM_PROVIDER=cerebras and provide CEREBRAS_API_KEY.
Activate the virtual environment first:
source .venv/bin/activate
streamlit run web_app.py --server.headless true
Then open http://127.0.0.1:8501 in your browser.
Safari users: If you get an HTTPS error with
localhost, usehttp://127.0.0.1:8501instead.
Check text:
python cli.py --text "The Eiffel Tower is located in Berlin."
Check a URL:
python cli.py --url "https://www.snopes.com/fact-check/some-article/"
Check an image:
python cli.py --image path/to/screenshot.png
Interactive mode:
python cli.py
Type text or paste a URL at the > prompt. Type quit to exit.
content-fact-checker/
├── src/fact_checker/ # Core library (shared by CLI and web)
│ ├── config.py # API keys, provider and model settings
│ ├── clients.py # OpenAI, Cerebras, OpenRouter + Parallel client init
│ ├── llm.py # LLM call wrapper (text + image inputs, reasoning)
│ ├── search.py # Web search via Parallel
│ ├── claims.py # Claim extraction from text/URL/image
│ ├── checker.py # Fact-check pipeline
│ └── rate_limiter.py # Client-side request rate limiting
├── evals/ # Model A/B tests: labeled claims and images, runners, scoring, results
├── cli.py # Command-line interface
├── web_app.py # Streamlit web interface
├── requirements.txt # Python dependencies
└── .env.example # API key template
The client-side limiter paces requests at LLM_REQUESTS_PER_MIN, default 300, for
whichever provider is active. A typical 6-claim fact-check makes 7 API calls. OpenAI's
actual limits depend on your account tier; the SDK retries server-side 429s with
exponential backoff either way.
On Cerebras, the defaults target the paid Developer tier: 300 requests/min, no
daily token cap, and up to 10 images per request. On the free trial tier the limits
are much tighter — 5 requests/min, 1M tokens/day, and 2 images per request. Set
LLM_REQUESTS_PER_MIN=5 so the limiter paces requests instead of letting the API
reject them; a fact-check will then take a bit over a minute.
The app pauses and resumes automatically when it hits the client-side limit.
Set these in your environment, Streamlit secrets, or the Render dashboard, then restart (keys and settings are read at import time). No code change is needed.
| Setting | Default | Notes |
|---|---|---|
LLM_PROVIDER | openai | openai, cerebras or openrouter |
LLM_MODEL_NAME | gpt-6-luna (openai), qwen-3.8-27b (cerebras), nvidia/nemotron-3.5-super-vl (openrouter) | Overrides the per-provider default. On OpenRouter use its provider/model slugs |
OPENAI_REASONING_EFFORT | high | none, low, medium, high, xhigh, max |
CEREBRAS_REASONING_EFFORT | high | |
OPENROUTER_REASONING_EFFORT | high | Sent as OpenRouter's reasoning.effort; models without reasoning support may ignore it |
LLM_MAX_COMPLETION_TOKENS | 16384 | Reasoning tokens count against this budget |
Models get retired (Cerebras has already retired zai-glm-4.7 and gemma-4-31b under
this app). Check the OpenAI or
Cerebras deprecation list,
then set LLM_MODEL_NAME. The old CEREBRAS_MODEL_NAME, CEREBRAS_REQUESTS_PER_MIN,
CEREBRAS_MAX_COMPLETION_TOKENS, CEREBRAS_MAX_RETRIES and
CEREBRAS_MAX_IMAGES_PER_REQUEST still work as fallbacks.
Both providers reason by default and count reasoning tokens against the completion
budget. If you switch to a model with different reasoning behavior, revisit the
reasoning effort and LLM_MAX_COMPLETION_TOKENS.
On OpenAI's GPT-6 models, temperature and top_p are rejected while reasoning is on,
so the app only sends them when OPENAI_REASONING_EFFORT=none.
Looking to deploy this somewhere? See docs/hosting for what this app needs from a host and which platforms fit (and which, like traditional shared hosting, don't).
| Problem | Fix |
|---|---|
ModuleNotFoundError | Activate the venv: source .venv/bin/activate |
| Safari HTTPS error | Use http://127.0.0.1:8501 instead of localhost |
| Rate limit pauses | Normal on the free tier (5 req/min). The app waits and resumes automatically |
| "API key not set" error | Check that .env exists with the key for your LLM_PROVIDER and PARALLEL_API_KEY filled in |
| "Unsupported image type" error | Only PNG and JPEG images are supported |
| Intermittent 401s, or errors that come and go | Check the provider status pages before debugging — see below |
This app depends on external APIs. When calls fail intermittently, or an error message doesn't match what you're actually sending, check these first:
LLM_PROVIDER=cerebras) — https://status.cerebras.aiLLM_PROVIDER=openrouter) — https://status.openrouter.aiA real outage can produce misleading errors. On 2026-09-07 a Parallel incident
returned 401 "No API key provided" for requests that did include a valid key,
which looks exactly like a credential problem and isn't. See
docs/incidents/2026-09-07-parallel-search-401.md.