Causal-reasoning backbone for LLM agents — no fabricated effect sizes, structured audit trail, GapKind diagnostics
Project description
themis-causal
English README · 中文 README
A causal-reasoning backbone for LLM agents. When your agent receives a causal question — "Does X cause Y?" / "What's the effect of X on Y?" / "If we'd intervened on X, would Y have changed?" — Themis forces the agent to articulate the variables, the DAG, and the query as JSON, then runs Pearl-style identification, surfaces specific data gaps as named GapKinds with paper-level citations, and refuses to fabricate effect sizes when the data isn't there.
Why this exists
LLMs answering causal questions have three failure modes that don't go away with bigger models:
- Fabricated effect sizes — confident "X reduces Y by 20%" with no traceable source.
- Conflated mechanisms — mixing confounding with collider bias in the same paragraph.
- Soft caveats over hard "not identifiable" — papering over identification failures with "depends on many factors".
For AI agents whose causal claims will be acted on, audited, or cited — medical decision support, A/B test attribution, policy analysis, scientific research assistance — those failure modes are load-bearing risks.
Themis sits between the LLM and the answer. Mechanically:
- The kernel returns no number unless data was supplied — the LLM literally cannot output a fabricated effect size through this path.
- Every result carries a DAG, an identification formula, a
GapKindlist with citations (Pearl, Hernán, Manski, MacMahon, …), and a derivation chain. Auditable. - When identification fails, the kernel says
not_identifiableor returns Manski natural bounds — no soft fallback to a guessed number.
Quick start
pip install themis-causal
Then add the Themis MCP server to your Claude Code config (.mcp.json in your project, or ~/.claude/.mcp.json for user-level):
{
"mcpServers": {
"themis": {
"command": "themis-mcp"
}
}
}
Restart Claude Code. Your agent now has mcp__themis__* tools:
themis_run(program)— main entry: runs identification + emitsdata_gap_reportthemis_apply_patch_and_run(program, patches)— multi-turn fill-back loopthemis_verify(program, result)— independent V0-V5 re-checkthemis_estimate(program, csv_path)— numeric estimate with CSV datathemis_discover(csv_path, ...)— PC / FCI / LiNGAM DAG discoverythemis_list_resources()— schema + prompt URI catalog
Install the agent-integration Claude Skill
The package ships a Claude Skill that auto-triggers mcp__themis__* when the user asks a causal question. Install it user-level:
# Find where themis is installed:
python -c "import themis, os; print(os.path.dirname(themis.__file__))"
# Copy the skill (replace <INSTALL_DIR> with the path above):
mkdir -p ~/.claude/skills
cp -r <INSTALL_DIR>/claude_skills/themis-causal-check ~/.claude/skills/
After restart, when a user asks any causal question, Claude auto-loads the skill body and routes through Themis.
What you get vs. what you don't
Themis adds:
- A mechanical block on number-fabrication for causal claims (validated in the reverse benchmark — 0/3 vs 3/3 vanilla on Q1/Q2/Q3 effect-size hallucinations).
- A formal audit trail (DAG + identification formula +
GapKindlist + paper citations + bounds expressions) that downstream agents / reviewers / compliance can inspect. - A conservative default —
needs_investigationwith structured "what data would unblock this" instead of an answer with a vague caveat.
Themis does not:
- Make up data. No data → Manski natural bounds (or
[0, 1]if nothing is supplied). - Infer the causal DAG. The LLM proposes edges; the kernel checks identification on the proposed DAG. Garbage in = garbage out. (
themis_discoverexists for CSV-driven discovery as a separate, opt-in workflow.) - Replace strong base-LLM causal knowledge. Modern frontier models recognize Berkson's paradox and ill-defined-intervention concerns unaided — what Themis adds is forcing those recognitions into formal output, not knowing more.
Programmatic Python API (non-MCP path)
from themis import run, apply_patch_and_run, estimate, verify
# Main entry: JSON dict in, JSON dict out
out = run(program)
# Multi-turn fill-back
out2 = apply_patch_and_run(program, [filled_bundle])
# Numeric estimation with a DataFrame
estimated = estimate(program, df)
# Independent re-verification
verify(program, out["results"][0])
Boundary contract:
run/verifyare pure JSON — no network, no disk reads outside the package schemas.estimateaccepts apandas.DataFrame— a numeric estimation side-channel; doesn't alter kernel semantics.- KB adapters / external resource lookups happen in client code or sibling repos. Themis itself sends no requests.
MCP server note: the MCP server is a long-running process and does not auto-reload code changes. After upgrading themis-causal (e.g., pip install -U themis-causal), restart your MCP server (/mcp restart in Claude Code, or exit and reopen the session).
Reverse benchmark — what we measured
benchmarks/agent_integration/ contains a reproducible comparison: three real NL causal questions × (vanilla LLM with no tools vs. LLM + Themis-MCP + agent-integration prompt), scored against 5 binary rubric criteria. Latest run (2026-05-12):
| Vanilla LLM | LLM + Themis | |
|---|---|---|
| Q1 (running → waist, confounding + measurement error) | 1.5 / 5 | 5 / 5 |
| Q2 (smoking → cancer, Berkson collider) | 3 / 5 | 5 / 5 |
| Q3 (obesity → CHD, ill-defined intervention) | 2.5 / 5 | 5 / 5 |
| Total | 7 / 15 | 15 / 15 |
The decisive gaps are on (1) "didn't fabricate effect sizes" — vanilla failed all three — and (4) "audit trail" — vanilla produced free-text prose, Themis produced DAGs + GapKinds + bounds.
Full per-question rubric: benchmarks/agent_integration/findings_2026-05-12.md.
License
MIT. Author: Crows12138 (ucapxux@ucl.ac.uk).
Status
- 1943 passing tests
- 15 reproducible L3 case fixtures (each anchored to an authoritative causal-inference paper)
- 30+
GapKinds mapped to specific identification / measurement / framing failure modes
For deeper documentation in Chinese, see README.md and CORE_STATUS.md.
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 themis_causal-0.1.3.tar.gz.
File metadata
- Download URL: themis_causal-0.1.3.tar.gz
- Upload date:
- Size: 597.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccd73d33706fecc47d09a4ec38f814163e6527d6d0966c07882b08895b7c3bc1
|
|
| MD5 |
a6e6a7667b6b85d336b5ad2183090ddf
|
|
| BLAKE2b-256 |
d0ef14eafab95c4d9e50ef0488a0501405f314722f8be469538784b85ccfdd3d
|
File details
Details for the file themis_causal-0.1.3-py3-none-any.whl.
File metadata
- Download URL: themis_causal-0.1.3-py3-none-any.whl
- Upload date:
- Size: 436.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e5c1f5d2c22223884ce512d86abacacb6f0bd0ecfd5fa88066eaf78c3edde76
|
|
| MD5 |
5d676a8d9a2918ee9f5c17f48d095f94
|
|
| BLAKE2b-256 |
085ad98c3a1edd72f578ae21575d562eb20b605186dadbd3dea79873a67e1a4e
|