Second Thought
Does your model's confidence number actually mean anything?
Quickstart · How it works · Proof · Dashboard · Contributing
Real screenshot of secondthought serve — not a mockup.
We ran this against a real model on a real GPU and it found a real problem: 87.5% accuracy, but an ECE of 0.62 — high accuracy, badly calibrated confidence. See the receipts →
The problem
A new class of model — TypeSafe's Jev, the open-weight Laya, and others — answers
questions with a probability instead of a paragraph: choice, score, or noul (yes/no), plus a
confidence number. The whole pitch of these models is "trust the number, act automatically above a
threshold, route to a human below it."
Nobody checks if that number is actually honest. And if you do have a human reviewing decisions, nothing tells you which ones are worth their time.
The fix
Second Thought captures every decision, measures whether its probabilities are really calibrated, picks the ones most worth a human reviewing, and turns their corrections into a dataset you can fine-tune on.
capture → store → select (most uncertain first) → review (CLI or web) → export → evaluate → watch for drift
Works with any model that returns a probability — Laya, a capture-only Jev adapter, or your
own classifier in one line (FunctionProvider). Laya and Jev just happen to be the two this
project has actually tested against.
Quickstart
pip install -e ".[dev]"
from second_thought import Store, capture, select, correct, export
from second_thought.adapters import FunctionProvider # or LayaProvider, JevProvider, your own
provider = FunctionProvider("my-model", my_predict_fn) # wraps any predict(state, questions) call
store = Store(".secondthought/store.db")
result = provider.predict(state, questions)
capture(store, result, provider=provider.name, state=state, questions=questions)
top = select(list(store.query()), budget=25)[0] # the decision most worth reviewing
correct(store, top.event.id, top.question_id, value="refund")
export(list(store.query()), "dataset/") # fine-tune-ready, leak-free
Or skip Python entirely: secondthought init | select | review | export | evaluate | serve.
(Not on PyPI yet — install from source. Release process →)
The proof
Every number here comes from a script in this repo. Run it yourself, don't take our word for it.
- Real model, real GPU, real bug found. Live Laya, 24 tickets: 87.5% accuracy, ECE
0.62. The uncertainty queue caught 3 of 3 real mistakes while reviewing only a third of
the tickets.
examples/laya_customer_service/ - Smart review beats random review, measured. +0.106 accuracy gain from 75 corrections
picked by uncertainty vs. +0.060 from 75 picked at random — 1.8× more improvement per
correction, consistent across 3 seeds.
examples/toy_typed_decisions/ - Not a Laya-only trick. Same SDK, zero GPU, zero Laya, zero Jev — a plain scikit-learn
text classifier.
examples/generic_provider/ - We show our failures too. The active-learning strategy loses to random at large batch
sizes — five real fix attempts tried, none worked, all written up instead of buried.
docs/research/wedge-and-mvp-spec.md - 72 tests,
mypy --strict,ruffclean, CI green on Linux + Windows, Python 3.11–3.13. See for yourself
How does it compare to TensorZero, Evidently, Snorkel, etc.? (full 19-tool matrix)
| Second Thought | LLM-ops (TensorZero, Langfuse) |
ML monitoring (Evidently, WhyLabs) |
Weak supervision (Snorkel, Cleanlab) |
|
|---|---|---|---|---|
| Stores the full probability distribution | ✅ | ❌ | partial | ✅ |
| Calibration error (ECE) | ✅ | ❌ | ❌ | ❌ |
| ECE tracked over time, with drift alerts | ✅ | ❌ | ❌ | ❌ |
| Uncertainty-based review queue | ✅ | ❌ | ❌ | ✅ |
| Correction → fine-tune dataset export | ✅ | ✅ | ❌ | partial |
| Local web review UI, no terminal | ✅ | varies | varies | varies |
| Typed-decision native (not LLM-text) | ✅ | ❌ | ✅ | ✅ |
No single tool surveyed does the whole row. Full 19-tool breakdown, sourced from each tool's own
docs: docs/research/competitive-matrix.md.
How it works
SystemOneProvider is a two-method interface (predict(), model_info()). FunctionProvider
wraps any plain function that returns {"model", "answers"} — no subclassing needed. Everything
downstream (storage, selection, correction, export, evaluation) is model-agnostic; it only ever
touches that one shape.
Dashboard and drift monitoring
secondthought serve— the local web UI in the screenshot above. A review queue that doesn't need a terminal, plus a calibration chart per workflow.second_thought.drift— the same calibration check, bucketed over time and flagged with a standard control chart when it degrades. Most tools check calibration once; this watches it.second_thought.protocol— the request/response shape, published as JSON Schema plus a conformance checker, so anyone building a System One model can check their API against it.
All three are thin layers over the same Store/select/correct/evaluate functions above — no
parallel implementation. Background and the ecosystem research behind this:
docs/research/decision-control-plane.md.
Laya vs. Jev
Laya (Apache-2.0, open-weight) is the one model this project fine-tunes end-to-end. Jev decisions
can be captured for your own observability, but TypeSafe's license forbids training on Jev's
output — so export() hard-blocks Jev in code, not just in a docs warning. Bring your own
model via FunctionProvider and it's just as fine-tunable as Laya. Details →
What this deliberately does not build
Not a prompt manager, not a generic LLM observability platform, not a generic annotation tool, not
a model registry, not distributed infrastructure. The dashboard is scoped to this SDK's own loop —
not general tracing or prompt playgrounds. Full reasoning for each cut:
docs/research/wedge-and-mvp-spec.md.
Status
v0.1.0, alpha. Real, tested, run against a real model — see The proof. Not on PyPI yet. API may still move before v1.
Contributing
Young project, young category — there's real ground still uncovered. Start with
CONTRIBUTING.md. Bringing your own System One model is one of the
highest-leverage contributions there is.
Discussions for questions · Issues for bugs and feature requests.
License
Metadata
Release files for second-thought 0.1.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 | |
|---|---|---|---|
| second_thought-0.1.0.tar.gz | 114.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| second_thought-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 170.9 kB
Release files / second_thought-0.1.0.tar.gz
| Download URL | second_thought-0.1.0.tar.gz |
|---|---|
| Size | 114.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b15a1c77f3b7a3713ac8f26c4aedcd926f74fb4290f0e8bce5e0f50cb8796a1d
|
|
BLAKE2b-256 checksum How to use checksums |
d4e180d84d79d020040bd2754ba2e84ea842fa98d957e756712c21cee1853e29
|
| 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 23, 2026.
Transparency logRelease files / second_thought-0.1.0-py3-none-any.whl
| Download URL | second_thought-0.1.0-py3-none-any.whl |
|---|---|
| Size | 56.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f0d52cc0056799c96dfacb19b2eb183838406db156338e077c2fe9e4522d7231
|
|
BLAKE2b-256 checksum How to use checksums |
119a2b560833fd401525f32559572685ae8d75d116afab1f49fad1612750400e
|
| 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 23, 2026.
Transparency log