LLM Council Threaded
April 7, 2026 ยท View on GitHub

A threaded, follow-up-friendly version of Karpathy's llm-council.
This app lets you ask multiple frontier models the same question, have them review each other's answers, and then produce a final synthesis. Unlike the original weekend hack, this version supports persistent conversations, follow-up questions, and full session context.
What changed in this version
- Persistent threaded conversations stored locally as JSON
- Follow-up questions inside the same conversation
- Context-aware replies that reuse prior user and chairman turns
- More reliable streaming UI so the app does not hang waiting on final stage events
- Working default model config for current OpenRouter model IDs
How it works
When you submit a prompt, the app runs a 3-stage council flow:
- Stage 1, first opinions
Each model answers the prompt independently. - Stage 2, peer review
The model identities are anonymized and each model ranks the responses. - Stage 3, chairman synthesis
A chairman model produces the final answer using the responses and rankings.
Why use this
Single-model answers are fast, but they can be shallow or confidently wrong.
A council is useful when you want:
- strategy debates
- pricing or offer decisions
- product tradeoff analysis
- content or positioning reviews
- a stronger final answer than one model alone
Upstream credit
This repo is based on Andrej Karpathy's original llm-council idea and implementation:
- Upstream repo: https://github.com/karpathy/llm-council
This version extends the original with conversation memory and follow-up support.
Quick start
1. Install dependencies
Backend:
uv sync
Frontend:
cd frontend
npm install
cd ..
2. Configure environment
Copy .env.example to .env:
cp .env.example .env
Then add your OpenRouter API key:
OPENROUTER_API_KEY=sk-or-v1-...
3. Run the app
Option 1:
./start.sh
Option 2:
Backend:
uv run python -m backend.main
Frontend:
cd frontend
npm run dev
Open:
- Frontend: http://localhost:5173
- Backend: http://localhost:8001
Default model setup
The default council is:
COUNCIL_MODELS = [
"openai/gpt-5.1",
"google/gemini-3.1-pro-preview",
"anthropic/claude-sonnet-4.5",
"x-ai/grok-4",
]
CHAIRMAN_MODEL = "anthropic/claude-sonnet-4.6"
You can change these in backend/config.py.
Storage
Conversations are stored locally in:
data/conversations/
Each thread is saved as a JSON file, which makes the app simple to inspect, back up, or extend.
Tested flow
This version has been tested with:
- new conversation creation
- first message + follow-up message in the same thread
- stored conversation history across replies
- frontend streaming completion without hanging on the final stage
Stack
- Backend: FastAPI, httpx, OpenRouter
- Frontend: React, Vite, react-markdown
- Storage: local JSON conversation files
- Python package manager: uv
Next useful improvements
- export conversation to Markdown
- preset modes for strategy, content, product, and trading
- file/context injection for project-specific debates
- model health checks and automatic fallbacks
If you build on this repo, credit the upstream and ship your own version.