Tukey
Compare LLM responses side-by-side with local persistence.
pipx install tukey-llm
tukey
Open http://localhost:8000. A guided setup walks you through connecting your first provider — or bring your own API keys.
What it does
Send a prompt once, get parallel streaming responses from every model you selected. Configure each model independently — system prompt, temperature, max tokens, reasoning effort — or broadcast settings across all of them.
- Side-by-side comparison — parallel fan-out to any mix of OpenAI, Anthropic, Google, DeepSeek, or OpenAI-compatible providers
- Multiple completions — generate 1–9 completions per model per prompt to observe variance, not just a single sample
- Per-response metadata — tokens, cost, duration, tok/s for every response
- Local-first — all data stored in
~/.tukey/, nothing leaves your machine except API calls - Experiments — named test suites with batch execution, human annotation, and reproducible manifests (API/CLI — UI coming soon)
- Text annotation — select text in any response to rate and comment on specific sections; highlights persist across page reloads
- Search — full-text search across all chatrooms, chats, and messages
- Import/export — per-chatroom JSON export for backup or transfer
Install
Requires Python 3.11+.
# With pipx
pipx install tukey-llm
# Or with uv
uv tool install tukey-llm
Verify it works:
tukey
# Tukey is running at http://localhost:8000
Options
tukey --port 9000 # different port (default: 8000)
tukey --host 127.0.0.1 # bind to localhost only
tukey --data-dir ./my-data # custom data directory (default: ~/.tukey)
Configuration
On first launch, a guided setup helps you connect your first provider. The fastest path is OpenRouter — one API key gives you access to Claude, GPT, Gemini, and more (including free models).
Alternatively, click "I already have API keys" to add any provider directly:
| Provider | What to enter |
|---|---|
| OpenRouter | API key from openrouter.ai/keys (recommended — access to 100+ models) |
| OpenAI | API key from platform.openai.com |
| Anthropic | API key from console.anthropic.com |
| Google AI | API key from aistudio.google.dev |
| OpenAI-compatible | Base URL + API key (local servers, custom gateways, etc.) |
Keys are stored in ~/.tukey/config.json. They are never sent anywhere except to the provider's API. You can switch data directories at runtime via the folder path in the sidebar.
Usage
- Create a chatroom
- Add models from the sidebar — pick any combination across providers
- Configure each model's system prompt, temperature, and other settings (or use "Apply to all")
- Type a prompt and send — responses stream in side-by-side
- Toggle the metadata bar to see cost, speed, and token counts per response
Annotations
Select any text in a completed response to annotate it:
- Highlight a text range in a response card
- Rate it thumbs up or thumbs down, add an optional comment
- Annotations appear as colored highlights (green = positive, red = negative)
- Click a highlight to review, edit, or delete the annotation
Annotations are stored per-response and survive page refresh.
Experiments
For systematic evaluation beyond ad-hoc chat:
- Define a named experiment with test cases and evaluation criteria
- Run the test suite — Tukey executes all cases across all models with concurrency
- Have domain experts annotate results with pass/fail judgments and notes
- Export the full manifest for reproducibility
REST API
Drive Tukey programmatically via its REST API. Use any HTTP client:
import httpx
BASE = "http://localhost:8000"
with httpx.Client(timeout=120) as client:
# List chatrooms
chatrooms = client.get(f"{BASE}/api/chat/chatrooms").json()
chatroom_id = chatrooms[0]["id"]
# Create a chat session
chat = client.post(f"{BASE}/api/chat/chatrooms/{chatroom_id}/chats").json()
# Send a message — fans out to all configured models concurrently
turn = client.post(
f"{BASE}/api/chat/chatrooms/{chatroom_id}/chats/{chat['id']}/messages",
json={"content": "Your prompt here"},
).json()
for response in turn["responses"]:
print(response["model_id"], response["content"])
See GET /api/health for a quick sanity check. Full endpoint reference: start the server and visit http://localhost:8000/docs.
Contributing
git clone https://github.com/zhao-weijie/tukey.git
cd tukey
uv sync --extra dev
cd ui && npm ci && npm run build && cd ..
uv run tukey
Tests: uv run pytest
License
MIT
Metadata
Release files for tukey-llm 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| tukey_llm-0.4.0.tar.gz | 413.2 kB | With provenance | Details for tukey_llm-0.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| tukey_llm-0.4.0-py3-none-any.whl | Python 3 | none | any | Details for tukey_llm-0.4.0-py3-none-any.whl |
Total release size: 828.2 kB
Release files / tukey_llm-0.4.0.tar.gz
| Download URL | tukey_llm-0.4.0.tar.gz |
|---|---|
| Size | 413.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
71b7e984d80f88ede6a179588d8e7e0be7708bdc86b3e1d35070245091eb6d76
|
|
BLAKE2b-256 checksum How to use checksums |
084a266b2cae4100a62c9ca53b284a8aea97c5a144a7de37f2f5b1a81311739f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 23, 2026.
Transparency logRelease files / tukey_llm-0.4.0-py3-none-any.whl
| Download URL | tukey_llm-0.4.0-py3-none-any.whl |
|---|---|
| Size | 415.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1ffc286db94b084120ea44b9e4cab59d7e95326cccb194438e4048f20fff63c
|
|
BLAKE2b-256 checksum How to use checksums |
b5503202358cdd197100be60c089a66dfd6005326892fdaa6aa3717404ad7dc9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 23, 2026.
Transparency logSecurity for tukey-llm 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for tukey_llm-0.4.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.