Elfbot is a FastAPI application prototype for disinformation operations with four core surfaces:
- review-gated social response workflow,
- Bluesky ingestion and publishing,
- CIB (coordinated inauthentic behavior) analytics for a sample X dataset (Provided by Hoo-Talk),
- multi-source fact-checking with auditable citations.
🎥 Technical Video: Watch on Google Drive
🎥 Video Pitch: [Watch on YouTube] (https://www.youtube.com/watch?v=VetENEzbFA8&t=14s) Designed by Tom Greenwood from Logiq.Media and Nima Thing (main developer of this application).
The fact-check pipeline (LangGraph) verifies claims using multiple providers and returns:
- verdict,
- confidence,
- grounded summary,
- clickable numbered citations,
- source cards with stance badges.
Current UI/logic highlights:
- Why this verdict block (
supporting,contradicting,mixed/unclear,assessed,total sources) - Source coverage badges by provider/tool
- clickable verdict pills that highlight linked source cards
- citation index stability (
[N]in summary maps to source[N]card) - normalization/cleanup of malformed citations
- guardrails for temporal claims and unsupported date literals
Queue-first moderation workflow with policy checklist and explicit state transitions.
- statuses include:
new,triaged,needs_review,approved,posted,rejected,error,needs_attention - review decisions are persisted and auditable
- posting is controlled separately from review
Operational integration for account connection, polling, queue ingestion, and controlled publishing.
Supported operations:
- connect/disconnect account session
- poll notifications (
mention,reply,quote) - ingest to review queue
- publish approved items manually or via worker
- worker start/stop/status + metrics + debug endpoints
CIB views are powered by CSV baseline data and designed to show transparent, explainable coordination signals.
Primary outputs include:
- narrative burst timeline,
- coordination network,
- coordinated cluster table,
- keyword signatures,
- strict-mode windowing controls.
High-level structure:
api.pybootstraps app + routersroutes/handles transport onlyservices/contains business logicrepositories/isolates persistence accessschemas/defines request/response contracts
cd elfbot_prototype
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-llm.txt
# Optional (RAG extras)
pip install -r requirements-rag.txt
uvicorn api:app --reload --port 8000Open:
- App:
http://127.0.0.1:8000 - API docs:
http://127.0.0.1:8000/docs
OPENAI_API_KEYorELFBOT_LLM_API_KEYELFBOT_LLM_BASE_URL(optional)ELFBOT_LLM_MODEL(default:gpt-4o-mini)
TAVILY_API_KEY(recommended)NEWS_API_KEYorNEWSAPIKEY(optional)GEMINI_API_KEY(optional)GEMINI_MODEL(optional; defaultgemini-3-flash-preview)
LANGGRAPH_RECURSION_LIMIT(default30)ELFBOT_FACTCHECK_MAX_TOOL_STEPS(default10)
ELFBOT_FACTCHECK_RAG_CORPUS_DIRELFBOT_FACTCHECK_RAG_CHROMA_DIR
ELFBOT_BSKY_HANDLEELFBOT_BSKY_APP_PASSWORDELFBOT_BSKY_PDS_URL(optional)ELFBOT_POSTING_ENABLED(trueto allow publishing)ELFBOT_MAX_POSTS_PER_RUN(default10)
GET /GET /reviewGET /social-accountsGET /cibGET /chatGET /fact-check
POST /check(async submit)GET /results/{task_id}POST /fact-check(sync)GET /fact-check/providers
GET /queueGET /items/{item_id}POST /items/{item_id}/reviewDELETE /items/{item_id}
GET /integrations/accountsPOST /integrations/bluesky/connectPOST /integrations/bluesky/disconnectGET /integrations/logsPOST /bluesky/auth-checkPOST /bluesky/poll-oncePOST /bluesky/debug-notificationsPOST /bluesky/publish-readyPOST /bluesky/publish-onePOST /bluesky/worker/startPOST /bluesky/worker/stopGET /bluesky/worker/statusPOST /bluesky/metrics
GET /healthPOST /analyzePOST /generate-responseGET /sample-reportGET /cib-summaryPOST /cib-analyzePOST /api/chat
pytest -q- Push this repo to GitHub (or connect GitLab/Bitbucket).
- Go to render.com → New → Web Service.
- Connect your repo. Render will detect
render.yaml(Blueprint). - Add Environment Variables in the Dashboard (these stay secret; your supervisor never sees them):
OPENAI_API_KEYorELFBOT_LLM_API_KEY(required)TAVILY_API_KEY(recommended for fact-check)NEWS_API_KEYorNEWSAPIKEY(optional)ELFBOT_DISABLE_GEMINI=true(default; keeps Gemini off)
- Deploy. Your app will be live at
https://<service-name>.onrender.com.
Note: On the free tier, the service sleeps after ~15 minutes of inactivity. First load after sleep may take ~30 seconds. SQLite/Chroma data is ephemeral and resets on redeploy.
- The current prototype prioritizes auditability and human control over full autonomy as only human approval (individual or batch)would lead to publishing verdict in social media comments.
- Fact-check quality depends on provider availability and source quality. At the moment, limited fact-check sources are designated based on the availability of the free API credits. In the future, more nuanced and trusted fact-checking sources could be integrated.
- Publishing result at Bluesky is limited by the number of character limit (300 characters) - so full summary gets truncated. So in the future, we would address this by integrating in multiple threads.
- Integrating with other social media platforms such as Facebook, TikTok, Instagram, X would be contingent upon the access of API or programmatic access of these platforms.
For the major part of the application design process, I am highly thankful to Tom Greenwood and Dirk Kunze from Logiq.Media, because Elfbot was their initial conceptual product, and they provided me what their product is supposed to do. As I started volunteering in their project, I thought it would be cool to turn it into a product, and show case the prototype.
I would want to highlight that the Fact-Checking part was inspired by broader agentic fact-check design patterns from a Open Source GitHub called Tathya (means Fact in Hindi/Nepali) Fact Checking Source. (https://github.com/Kaos599/Tathya-Fact-Checking-System/tree/main). It was later then adapted into one of the features of Elfbot’s design.
I would like to note that, AI coding agent such as Open AI GPT-5.2-Codex been instrumental in designing the majority of this application, though I ensured that the business logic of coding, and programming was understood before fully implementing it.