Metis
Metis (μῆτις) — distributed cognitive layer over any LLM
Part of the alexar76 AI agent economy
Grab the star · watch it pulse and think · chat with Metis — open the live demo →
Multi-agent reasoning orchestrator — Understanding Council, DGPD depth gating, layered MoA, verifier, memory, search, economy metering, distributed cluster, MCP tools, and OpenAI-compatible API.
Quick start
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,distributed]"
ollama pull qwen3:8b
metis "Explain multi-agent systems" --model qwen3:8b --url http://localhost:11434/v1
Install
PyPI package name is aimarket-metis (the PyPI name metis is a different project). Import path and CLI stay metis, metis-serve, etc.
# PyPI
pip install aimarket-metis
pip install "aimarket-metis[dev,distributed]"
# GitHub release tag
pip install "aimarket-metis[distributed] @ git+https://github.com/alexar76/metis.git@v0.2.0"
# Clone / monorepo (editable)
git clone https://github.com/alexar76/metis.git && cd metis
pip install -e ".[dev,distributed]"
# Docker
docker compose up -d
Documentation index
| Resource | Link |
|---|---|
| Architecture | EN · RU · ES |
| API reference | EN · RU · ES |
| Deployment | EN · RU · ES |
| Security | EN · RU · ES |
| User guide | EN · RU · ES |
| Distributed | EN · RU · ES |
| Ecosystem | EN · RU · ES |
| Research | EN · RU · ES |
| Wiki | Home · Quick Start · FAQ |
| Landing page | Live demo · docs/landing/index.html · deploy guide |
| Changelog | CHANGELOG.md · RELEASE.md |
Ecosystem map
| Project | Role |
|---|---|
| Metis | Cognitive orchestration layer (this repo) |
| cognitive-runtime | OpenAI API wrapper with DGPD |
| ARGUS-3 | Demand-side reference agent + WARDEN MCP firewall |
| AIMarket Hub | Federated capability catalog and invoke API |
| aimarket-oracle-gateway | Verifiable oracle MCP services |
| aimarket-mcp | Shared MCP gateway — web fetch/search + Metis verify (Glama) |
| Ecosystem landing | Full AICOM map — Metis, MCP servers, oracles, ARGUS |
| HELIOS | Broadcast pipeline for ecosystem content |
| AICOM | AI-Factory — autonomous product pipeline |
CLI commands
| Command | Purpose |
|---|---|
metis |
Run a query through the cognitive stack |
metis-serve |
OpenAI-compatible API (/v1/chat/completions) |
metis-node |
Start a distributed worker node |
metis-coordinator |
Start the cluster coordinator |
metis-cluster |
Check cluster node health |
Architecture
flowchart LR
Q["Query"] --> M["Metis"]
M --> R["Router"]
R --> C["Council/MoA/Agent"]
C --> P["LLM Providers"]
C --> T["Tools + MCP"]
M --> E["Economy Meter"]
Jury verification (/v1/verify)
By default a /v1/verify verdict is written by one model and audited by one model — the
base model on fast, the MoA aggregator on council. That is the verdict the AIMarket
hub's Pay-on-Verified escrow moves money on,
so a seller only has to fool one lineage. A jury makes it a vote across vendors:
jury_default_for_verify: true # every /v1/verify goes to the jury; off → only route: "jury"
jury_min_vendors: 3 # and every seat must be a different vendor
jury_models:
- {model: deepseek-v4-pro, base_url: https://api.deepseek.com/v1, api_key_env: DEEPSEEK_API_KEY}
- {model: minimax/minimax-m3, base_url: https://openrouter.ai/api/v1, api_key_env: OPENROUTER_API_KEY}
- {model: z-ai/glm-5.3, base_url: https://openrouter.ai/api/v1, api_key_env: OPENROUTER_API_KEY}
Ready rosters for both courts are in deploy/prod.jury.example.yaml.
What the jury does, and what it promises:
- The caller's prompt goes to every juror unchanged, in parallel, at
jury_temperature(0.1). A juror slower thanjury_timeout_secondsabstains; it does not hold the jury. - A juror's vote counts only if it states
{"fulfils": bool, "score": 0–1}consistently at the caller's bar and — when the request carriesaudit_id— echoes that id. A juror that parroted a verdict planted in the audited text has not voted. - A side wins with a strict majority of the whole roster; abstentions count against
agreement.
verify_score= agreement × median confidence of the winning side (confidence in "fulfils" = score, in "does not fulfil" = 1 − score), so a confident unanimous conviction is a trusted audit. answeris one winning juror's verdict object on its own, so a consumer's parser reads it unchanged. A split carries no verdict object (indeterminate); every seat failing isstatus: "error"(retry), never a verdict.- The envelope adds
jury([{model, vendor, fulfils, score, latency_ms, abstained?}]),jury_outcome(pass|fail|split|unavailable),jury_agreementandinput_flags.injection_suspected. The trace resolves at/v1/traces/{trace_id}. - Injection-looking text is flagged, not blocked on this path: the audited text is written by the parties with money on the verdict, and a hard block would hand either of them an indeterminate outcome on demand.
Know the arithmetic before sizing a roster: at the hub's 0.7 bar a 3-seat jury settles only when unanimous (2/3 × anything < 0.7); five seats tolerate one confident dissent; an even roster only adds splits. The jurors are independent labs, not independent infrastructure — seats behind one gateway share its outages and its account.
The same change stops the capability gate from seating one model as both the writer and
the auditor of a verdict: with judge_distinct_vendor: true (default) the judge avoids the
vendors of the base model and the MoA aggregator, an explicit modules.judge that clears
min_aggregator_capability is honoured instead of silently overridden, and
min_unique_council_vendors extends the diversity check from (model, endpoint) pairs to
vendors, for the MoA seats as well as the council. metis validate warns when the judge
still shares a vendor with a writer.
Running a second instance as the appeal court
The hub's appeal path (AIMARKET_APPEAL_WINDOW_S) re-judges a disputed verdict on a
second, independent Metis. Independence is operational, so it has to be set up that way:
- Another host. Not the first instance's machine (shared failure, shared operator access) and not a host holding a hot wallet. Same image, its own container.
- A disjoint jury. The
metis_2roster indeploy/prod.jury.example.yamlshares no vendor withmetis_1(a test enforces it). Use a second OpenRouter key with its own spend cap — vendor-disjoint seats behind one key still share that key's quota. - Its own identity. Its own
METIS_API_KEY(setting it makes/v1/verifyrequire the Bearer), handed to the hub asAIMARKET_APPEAL_METIS_KEY; its ownAIMARKET_APPEAL_METIS_URL; and a distinctAIMARKET_APPEAL_VERIFIER_ID(e.g.metis.appeal@v1) so every envelope and receipt names which court decided. - Nothing from the first instance. It gets the stored intent and delivery, a fresh audit id and the appellant's fenced statement — never the first verdict, its score, its reasons or its trace. Do not point it at the first instance's trace store or knowledge store.
docker run -d --name metis-appeal --restart unless-stopped -p 127.0.0.1:8081:8080 \
-e METIS_API_KEY=<appeal-court key> -e OPENROUTER_API_KEY=<second, capped key> \
-v /opt/metis-appeal/prod.yaml:/app/config/prod.yaml:ro -v /opt/metis-appeal/data:/app/data \
metis:latest metis-serve --host 0.0.0.0 --port 8080 --config /app/config/prod.yaml
Production
export METIS_API_KEY=sk-...
metis-serve --config config.production.yaml --production --port 8080
Legacy env vars SUPERBRAIN_* and COGNITIVE_* are still read for one release cycle.
Docker
cp config/docker.env.example .env
docker compose up -d --build
Tests
pytest --cov=metis --cov-report=term-missing -v
Research citations
Design decisions are grounded in published work — see docs/en/RESEARCH.md for Yang et al. 2026 (heterogeneous agents), Wang et al. ICLR 2025 (layered MoA), and related citations with honest caveats.
MIT License
Metadata
Release files for aimarket-metis 0.2.3
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 |
|---|---|---|---|---|
| aimarket_metis-0.2.3.tar.gz | 196.7 kB | Without provenance | Details for aimarket_metis-0.2.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| aimarket_metis-0.2.3-py3-none-any.whl | Python 3 | none | any | Details for aimarket_metis-0.2.3-py3-none-any.whl |
Total release size: 367.4 kB
Release files / aimarket_metis-0.2.3.tar.gz
| Download URL | aimarket_metis-0.2.3.tar.gz |
|---|---|
| Size | 196.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5735a441f3a269aa86c7db260bcc7bb3376bd5f4a55b797fe8a0a3620960fc90
|
|
BLAKE2b-256 checksum How to use checksums |
f4c1b81d838ae456d9deb6f71dfdbf0f41a1cb4885460cb88c24e5ee8ee01240
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / aimarket_metis-0.2.3-py3-none-any.whl
| Download URL | aimarket_metis-0.2.3-py3-none-any.whl |
|---|---|
| Size | 170.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb503759acc16c543a1751b74e1b5e1555a37ff378b010d10168ba547e54d5ec
|
|
BLAKE2b-256 checksum How to use checksums |
2d45739d813b3e1cfe9c5577ad95ad6dc128cfb3755db56b12a1efaccab4aeed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Security for aimarket-metis 0.2.3
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.