Reference implementation of the Symposium protocol — structured, sequential, adversarial multi-agent deliberation.
Project description
Symposium
A panel of AI experts that actually argue — structured, sequential, and replayable to the byte.
Symposium runs a small panel of AI personas through a structured debate — each takes a turn, a neutral coordinator steers, and you get back one synthesized answer. Every session is saved as a tamper-evident artifact you can replay byte-for-byte.
It's not another free-form "group chat" framework. Symposium enforces exactly one conversation shape — fixed panel, one turn per agent per round, a coordinator that recommends but never decides when to stop. You trade flexibility for something most multi-agent stacks can't give you: reproducibility.
critic ── logician
/ \
engineer (coordinator) visionary
\ /
researcher ───────
→ one debate, one synthesized answer, one replayable artifact
Why Symposium
- 🔑 No API key needed. By default it drives your local
claude/codexCLI login — nothing metered, nothing to configure. - 🧠 A real panel. Five complementary personas (logician, visionary, researcher, critic, engineer) plus a separate coordinator. Add your own on the fly.
- 🔁 Byte-identical replay. Every run is a SHA-256-sealed artifact; re-render it or re-execute it and prove it didn't change.
- 📺 Watch it live.
symposium watchopens a browser viewer — personas on a circle, a glow on the speaker, arrows for every direct question. - 🧩 Built for Claude Code. Ships an MCP server: kick off a deliberation and stream the debate straight into your client.
- 📜 A spec, not just code. The protocol is language-independent; this Python package is one reference implementation.
Install
pip install symposium-protocol # import symposium
pip install "symposium-protocol[mcp]" # + the Claude Code / Desktop MCP server
Python 3.11+.
Quick start
In Claude Code (the easy path — no key). Register the server, then just ask:
claude mcp add symposium -- symposium-mcp
Then just ask Claude in plain language:
> Use symposium to debate whether we should migrate the monolith to microservices.
The panel debates over your local claude / codex login and streams each turn back live. That's it.
From the terminal (no key, no network). Run the deterministic demo, then replay it:
symposium run \
--config examples/configs/walking-skeleton.yaml \
--script examples/scripts/walking-skeleton.json \
--output runs/ examples/problem.md
symposium replay runs/demo-walking-skeleton-001 # byte-identity check
symposium watch runs/demo-walking-skeleton-001 # ↑ watch it in the browser
Use it in Claude Code
Once the server is registered, you don't type any special syntax — just ask Claude in plain language and it calls the right tool. The default routes each persona to a local CLI (the creative visionary to codex, the rest to claude) and falls back to whichever you have installed. No API key.
> Use symposium to debate whether we should migrate the monolith to microservices.
> Run a symposium on our caching strategy, and pull in experts on
GDPR compliance and Postgres internals if the panel needs them.
> Have symposium deliberate this RFC, but run the whole panel on claude.
> Summarize the last symposium run in runs/.
Claude maps these to deliberate / deliberate_adaptive / get_run_summary and streams the debate back turn by turn. Under the hood:
| Tool | Does |
|---|---|
deliberate |
Run a debate, stream every turn live. The default. |
deliberate_adaptive |
Same, but generates new expert personas on demand (early-start + mid-run). |
*_muted variants |
Same result, no live streaming — just the final answer. |
get_run_status |
Poll a still-running debate for new turns. |
get_run_summary |
Outcome + metrics + replay check for a finished run. |
list_personas / generate_persona |
Inspect the built-in panel / design a new expert. |
get_version |
What's actually running (handy after a reinstall). |
Billing. Logged in with a Pro/Max or ChatGPT subscription? CLI turns spend subscription quota and rate limits, not metered API dollars. The real ceiling under
cli-autoismax_wallclock_seconds(default 1h) and your plan's rate limit — the token/cost caps are telemetry, not a hard budget. Only theanthropic/openaiHTTP adapters bill per token.
API keys: what's used, what isn't
| Provider | API key |
|---|---|
cli-auto (default), claude-cli, codex-cli |
None — reuses your local CLI login |
fake |
None — offline & deterministic |
anthropic |
ANTHROPIC_API_KEY (optional ANTHROPIC_BASE_URL) |
openai |
OPENAI_API_KEY (optional OPENAI_BASE_URL) |
ANTHROPIC_API_KEY / OPENAI_API_KEY are read only when you explicitly pick the metered anthropic / openai HTTP adapter. Every default path ignores them — and the CLI adapters actively scrub cross-vendor credentials before each spawn.
CLI commands
symposium run # run a session against any provider
symposium watch # live browser viewer (follows the newest run)
symposium replay # re-render a stored transcript; verify the digest
symposium execution-replay # re-run under the 10 pinning conditions; prove reproducibility
symposium validate # check an artifact against the v1.0.0 JSON Schemas
symposium metrics # tokens, cost, latency, branch depth — computed offline
To run real models from the CLI without a key, set provider: claude-cli (or codex-cli) on each agent in your config and drop the vendor key — the adapters are registered out of the box.
Use it as a library
from symposium.providers import default_registry
from symposium.scheduler import run_session
providers = default_registry().build_session_providers(config)
artifact = run_session(config, providers, runs_root="runs/")
print(artifact.outcome.kind) # "synthesis" or "termination"
print(artifact.transcript_digest) # 64-hex SHA-256 over the canonical transcript
How it's different
| Symposium | |
|---|---|
| Topology | One fixed shape — no arbitrary handoffs or nested supervisors. |
| Routing | Schema-validated direct_request only; inline @mentions are never routing (injection-resistant). |
| Who decides to stop | Deterministic runtime code — never the LLM coordinator. |
| Replay | Unconditional transcript replay and conditional re-execution, both spelled out. |
| Failure modes | Closed, enumerated — not "whatever the framework happened to do". |
The full rationale, and a comparison against AutoGen / CrewAI / LangGraph / OpenAI Agents SDK, lives in the specification.
Project layout
docs/specification.md— the normative protocol (language-independent) + 16 JSON Schemas underdocs/schemas/v1.0.0/.symposium/— the reference Python runtime (scheduler, providers, replay, viewer, MCP server, CLI).examples/,tests/— runnable configs and the conformance suite.
A conformant runtime in any language is just as valid as this one, as long as it matches the spec and validates against the schemas.
Contributing & status
The v1.0 spec is frozen (ratified 2026-05-26); the runtime ships as symposium-protocol on PyPI. Issues, errata, and PRs welcome — see CONTRIBUTING.md and ROADMAP.md.
pip install -e ".[test]" && pytest -q # run the suite
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file symposium_protocol-1.11.4.tar.gz.
File metadata
- Download URL: symposium_protocol-1.11.4.tar.gz
- Upload date:
- Size: 364.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
731a1297a37745936fd3faf565538f9f6740eae690f3ba4726a1adeaa5530d44
|
|
| MD5 |
24fea061992383b8ddd5c082ca3022f4
|
|
| BLAKE2b-256 |
61d6fbbeeff8a61f03d7fb9ebef4f1830a4c00d02b223862ffd38f829ef4f842
|
Provenance
The following attestation bundles were made for symposium_protocol-1.11.4.tar.gz:
Publisher:
release.yml on terrordrummer/symposium
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
symposium_protocol-1.11.4.tar.gz -
Subject digest:
731a1297a37745936fd3faf565538f9f6740eae690f3ba4726a1adeaa5530d44 - Sigstore transparency entry: 1662060079
- Sigstore integration time:
-
Permalink:
terrordrummer/symposium@700228faf837cca03d987c92bb4b50d36cc7372d -
Branch / Tag:
refs/tags/v1.11.4 - Owner: https://github.com/terrordrummer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@700228faf837cca03d987c92bb4b50d36cc7372d -
Trigger Event:
push
-
Statement type:
File details
Details for the file symposium_protocol-1.11.4-py3-none-any.whl.
File metadata
- Download URL: symposium_protocol-1.11.4-py3-none-any.whl
- Upload date:
- Size: 173.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de2d57347c6893e0a38d1337c47654b723f1b6ac31e2b22f410a2f2364a67854
|
|
| MD5 |
eb491a63a74c3dc797e396f7d9bd39bb
|
|
| BLAKE2b-256 |
c223d1e86c9777b0194d72e0af45827a9623c238044810061cf1300d06d39d9c
|
Provenance
The following attestation bundles were made for symposium_protocol-1.11.4-py3-none-any.whl:
Publisher:
release.yml on terrordrummer/symposium
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
symposium_protocol-1.11.4-py3-none-any.whl -
Subject digest:
de2d57347c6893e0a38d1337c47654b723f1b6ac31e2b22f410a2f2364a67854 - Sigstore transparency entry: 1662060287
- Sigstore integration time:
-
Permalink:
terrordrummer/symposium@700228faf837cca03d987c92bb4b50d36cc7372d -
Branch / Tag:
refs/tags/v1.11.4 - Owner: https://github.com/terrordrummer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@700228faf837cca03d987c92bb4b50d36cc7372d -
Trigger Event:
push
-
Statement type: