System 1: Teach a decision. Run it locally.
System 1 is not an LLM. Show it examples of a repeatable decision—such as which team should receive a message—then check the skill and reuse it locally. It uses small numerical decision heads: no language-model weights to download, no token generation, and no GPU required. Optional MLX support runs decision-head matrix operations on Apple Silicon.
Choose a decision → show examples → check answers → save and reuse → improve.
Performance · Start teaching · Automatic teachers · Evidence · Integrations · Documentation
Why it is fast
Small skills make fast local decisions. After teaching, System 1 applies a compact numerical decision head. Each request avoids a teacher API round trip and language-model token generation. The saved skill needs no language-model weights or model server.
| Benefit | Measured on our three public-data workloads |
|---|---|
| Sub-millisecond decisions | 0.34–0.44 ms median per local decision |
| Small, portable skills | 20.4–47.0 KiB saved .s1m files |
| Quick teaching | 0.23–1.77 seconds to teach and calibrate once labeled examples exist |
| No ongoing teacher calls | Zero teacher API calls during local evaluation |
These are NumPy CPU measurements on an Apple M4 Pro, excluding startup, receipt signing and downstream work. Skill-file sizes exclude the installed runtime and dependencies. Optional MLX supports Apple Silicon acceleration; its speed benefit depends on the workload. See the reproducible results and quality limits.
The payoff is useful for repeated routing, classification and structured choices. Quality depends on the taught task; uncertain answers still need review.
Quickstart
Use Python 3.11 or newer. To follow the editable lesson, start from a repository checkout:
git clone https://github.com/steph4n-gh/system1.git
cd system1
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
On Windows, activate the environment with .venv\Scripts\activate instead.
1. Choose one decision
We will choose between billing and support. Payment questions go to billing;
broken software goes to support. You decide the rule.
2. Show it examples
An example is an input paired with the answer you want. That answer is what “label” means:
| Message | Answer you want |
|---|---|
| Refund my payment | billing |
| Correct the invoice | billing |
| Fix a software crash | support |
The editable lesson file contains eight such pairs. Run it:
python examples/teach_skill.py
This teaches a small skill, saves .system1/support-route.s1m, reloads it and tries
“Please refund this payment.” No API key or teacher service is involved.
3. Check the answer
The starter prints:
Suggested team: billing
Needs review: True
billing is its best guess. Needs review means a person should still decide.
Eight examples show the process; they do not establish reliable automatic routing.
To judge a skill, check different messages: count both wrong answers and requests
for review. A saved file alone does not mean the skill is ready.
For a complete, larger demonstration with separate teaching, uncertainty checks
and final evaluation, run python examples/support_triage.py. It routes to four
departments and reports every result, including mistakes. The
first-skill walkthrough
explains how to do this with your own messages.
4. Reuse the saved skill
The file is the portable skill. Load it without reteaching or calling the teacher:
from system1 import CompiledSystemOneModel, System1Engine
skill = CompiledSystemOneModel.load(".system1/support-route.s1m")
engine = System1Engine(skill.schema, model=skill, strict_mode=True)
answer = engine.decide("Please refund this payment", record_receipt=False)
print(answer.values["team"])
print("Needs review:", answer.is_ambiguous)
The application honors the review flag before using an answer automatically. Saving and reloading preserves uncertainty; it does not turn the starter's uncertain answer into an approved one.
5. Improve with a correction
Copy the lessons and edit their answers or add varied real messages:
cp examples/teaching/first_skill.json .system1/my-lessons.json
python examples/teach_skill.py --lessons .system1/my-lessons.json --output .system1/candidate.s1m --prompt "The payment page crashes"
For that message, our desired answer is support: the issue is broken software.
If a lesson has the wrong answer, replace it. Rerun teaching, then check different
messages for both teams before adopting the candidate. This keeps the earlier
skill while you evaluate the revision. Follow the
worked correction
and teaching API guide
for your own output choices and separate checking data.
Observe a teacher, then take over
Once the lesson format makes sense, another source can supply the answers: a colleague, reviewed historical decisions, existing rules, a conventional classifier, Jev, Gemini or another API. JSON stores lessons; a teacher callback supplies them while a program runs. An LLM can teach a skill without the resulting skill becoming an LLM or inheriting the teacher's general knowledge.
python examples/observe_routing.py
This demonstrates the same journey automatically: observe answers, teach, validate, switch to local decisions, then save and reload. Its default teacher is an inspectable rule over synthetic tickets. An optional live Jev mode and custom callbacks use the same observation workflow.
The teacher stays responsible until the candidate qualifies. Local execution
can still request review. Promotion depends on evidence, not a promised number
of turns. Use PromotionPolicy(min_accepted_agreement=.95) when you need the
stronger accepted-agreement qualification added in 1.0.2; teacher agreement and
independent correctness are separate checks.
Benchmarks
The published public-data evaluation measures three fixed bounded tasks. These 1,301 cases were kept out of teaching and calibration in the original experiment:
| Explicitly taught skill | Answered without review | Correct among those answers | Median local decision |
|---|---|---|---|
| Banking support, three intents | 118/120 | 115/118 (97.5%) | 0.378 ms |
| Assistant commands, six intents | 173/180 | 172/173 (99.4%) | 0.344 ms |
| SMS spam triage | 980/1,001 | 957/980 (97.7%) | 0.444 ms |
The report includes original labels, fixed splits, every error and a classical TF-IDF/logistic-regression baseline. That baseline matched raw correctness on banking and assistant, scored lower on SMS, and ran faster locally on all three.
Automatic observation is measured separately. Under the original default policy, actual Jev and Gemini 2.5 Flash each enabled assistant takeover after 358 observations: 171/180 old official test requests accepted locally, 167/171 correct, with no further teacher calls. Saved/reloaded results matched. Recorded teacher responses can be replayed offline.
The 1.0.2 quality round uses stronger qualification and a fuller SMS stream: 2,961 observations, 954/980 correct accepted old-test decisions (97.3%). Banking and assistant remain deferred under that policy. Fresh authored SMS probes reach only 27/33 correct accepted answers (81.8%). New banking phrasing also reveals weaknesses, and a routing teaching candidate was not adopted after mixed results. The old tests are now regression evidence; the new authored probes are diagnostics, not independent customer evidence. These limitations remain visible.
To check the primary teaching examples and the recorded Jev comparison:
python benchmarks/quality/evaluate_release.py
This runs offline and fails if a primary demonstration misses its 95% accepted correctness / 80% acceptance point targets. See the quality index for all reproduction commands, confidence intervals and historical experiments.
Integrations
The project is packaged on PyPI as system1. To add it to an existing Python project:
python -m pip install system1
After checking the skill on your task, connect it to your application. The core supports choice, boolean, multi-choice and score outputs; uncertainty tells the application when to request review.
| Need | Next step |
|---|---|
| Teach a different task or use your own data | Teaching API and file formats |
| Learn by observing a running teacher | Teacher callbacks and automatic takeover |
| Use Apple Silicon decision-head operations | Install system1[metal]; see backend scope |
| Connect LangChain, MCP, ASGI or gRPC | Integration guide |
| Monitor local decisions | Metrics and tracing |
Policy guard
If a decision would execute a tool, add an explicit permission policy. The
executable guard quickstart
shows PolicyEngine, an enforcement guard and a durable ledger. Optional
software Ed25519 signatures (RFC 8032) and a SHA-256 hash-chained ledger provide
audit evidence. A classifier's suggested answer alone is not permission to act.
See deployment boundaries
for identity, network and enforcement responsibilities.
Examples and research
The example catalog links every teaching, observation, game and integration example with its scope. The architecture, technical brief and whitepaper explain the implementation and evidence. The papers are maintainer-authored, not peer-reviewed publications. Established numerical methods power the product; the practical value is the complete path from examples to a checked local skill.
Release and development
Version 1.0.2: clearer first-skill teaching, explicit accepted-decision
qualification, a fuller SMS observation run and transparent quality limits.
See the release report
and 1.0 migration guide.
The legacy reflex import namespace remains a compatibility alias.
python -m pip install -e '.[dev,langchain]'
python -m pytest tests/ -q
CI checks Linux/macOS tests, documentation, built distributions and real LangChain dispatch. See contributing and security reporting.
Metadata
Release files for system1 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| system1-1.0.2.tar.gz | 2.9 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| system1-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.0 MB
Release files / system1-1.0.2.tar.gz
| Download URL | system1-1.0.2.tar.gz |
|---|---|
| Size | 2.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
78b6a5e1f565793c54fca9a904017ea174d2566baed1b7517b8b9952d84b531e
|
|
BLAKE2b-256 checksum How to use checksums |
47e4597352fa98e7fe4c57f49d8bb7b41821bde46f72b5445b5364bf80ec328f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 20, 2026.
Transparency logRelease files / system1-1.0.2-py3-none-any.whl
| Download URL | system1-1.0.2-py3-none-any.whl |
|---|---|
| Size | 182.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8c8a5db6c786994c7b94eed2cc3c29bad08da20e5b2f71cb689d81d3fdbce461
|
|
BLAKE2b-256 checksum How to use checksums |
3d5714a223bcc9e614e3b0620a601eb82b28cab3829511a9234237aee46ec8b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 20, 2026.
Transparency log