deciding-with-confidence
Skill158 starsChanged 8 months agoMITView on GitHub
Routes, triages, flags and rates a piece of text with a probability for every option: which department or queue a ticket goes to, which intent a message expresses, whether a yes/no condition holds (is this tool call grounded, should the agent ask first, is the customer angry), and how severe or urgent it is on a rubric, each with a calibrated confidence. Runs Claude Haiku in the request and response shapes of OpenAI's Decisions API, for when no purpose-built decision model is at hand. Use for \"route this ticket\", \"triage these\", \"classify with a confidence\", \"give me a probability that\", \"rate the severity\", \"score against this rubric\", guardrail checks before a tool call, or \"a Decisions API without OpenAI\".
- Reads credentials
- Installs packages
In this repository113 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- accessing-github-reposSkill
- agent-routingSkill
- animating-with-codeSkill
- api-credentialsSkill
- asking-questionsSkill
- assessing-impactSkill
- atprotoingSkill
- bm25Skill
- browsing-blueskySkill
- building-github-indexSkill
- building-github-index-v2Skill
- categorizing-bsky-accountsSkill
- challengingSkill
- chartingSkill
- charting-vega-liteSkill
- check-toolsSkill
- cloning-projectSkill
- closing-issuesSkill
- coding-mojoSkill
- compiling-wgslSkill
- composing-htmlSkill
- configuringSkill
- container-layerSkill
- controlling-spotifySkill
- convening-expertsSkill
- converting-filesSkill
- crafting-instructionsSkill
- creating-bookmarkletsSkill
- creating-kbSkill
- creating-mcp-serversSkill
- creating-skillSkill
- creating-videoSkill
- declaring-invariantsSkill
- declaudingSkill
- delegating-with-contextSkill
- describing-productsSkill
- detecting-tips-zonesSkill
- developing-preactSkill
- dispatching-subagentsSkill
- down-skillingSkill
- drawing-videoSkill
- drawing-with-pycairoSkill
- dunking-anonymouslySkill
- exploring-codebasesSkill
- exploring-dataSkill
- extracting-keywordsSkill
- featuringSkill
- fetching-blocked-urlsSkill
- finding-skillsSkill
- flowingSkill
- forecasting-reversoSkill
- gatingSkill
- generating-patchesSkill
- generative-thinkingSkill
- githubbingSkill
- hallucinating-labelsSkill
- hello-demoSkill
- image-to-svgSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 91
Use the name the Agent tool lists: deciding-with-confidence:decider from the plugin, decider from .claude/agents/.
- Distinctive: line 118
Calibrate on your own labels: when you have 50 or more per question type:
- Distinctive: line 157
Run the tests, then one live request:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Deciding with confidence
scripts/decide.py takes an OpenAI Decisions API request (input plus
questions of type predicate, choice or score) and returns its response
shape: a probability per option, the chosen value or score, and confidence.
Claude Haiku 5.5 answers. Its logits are not exposed, so the distribution is
estimated: each of k parallel samples states a probability per option with the
options in a different order, the samples are averaged, and the average is
temperature-scaled from a labelled eval. Disagreement between samples lowers
confidence and shows up in diagnostics.agreement.
Expect about 85% of what a purpose-built decision model gets: on the bundled
104-item eval, accuracy 0.846 against Jev's 0.894, with a calibration error
(ECE 0.041) that matches it. The whole accuracy gap was on eight-way intent
questions; yes/no and rubric questions tied. Disagreement between samples is
the strongest warning sign. references/method.md has the numbers.
When NOT to use this skill
| Situation | Use instead |
| The label set is too large to list in a prompt (a taxonomy, hundreds of tags) | hallucinating-labels |
| The answer needs reasoning, multi-step work or a written explanation | a normal Claude call; this skill forbids explanation |
| You need extracted fields or free-form JSON | structured outputs on the Messages API |
A real decision model is reachable (OpenAI /v1/decisions, Strands Decider, Jev) and latency matters | that model: 0.1–0.3 s against ~0.7–4 s here |
| Picking which Claude tier runs a subagent | agent-routing |
| The evidence is an image | not supported; the transports send text only |
Abandon a run when diagnostics.agreement is below 1 on most of a batch: the
questions or option descriptions are ambiguous, and more samples will not fix
them. Rewrite the options (distinct, observable criteria) before sampling more.
Procedure
Write the request as JSON in the OpenAI shape. Give every question a unique
name. Options needdescriptions that say when each applies; add anotherchoice when the set is not exhaustive. Scorelevelsgo lowest first.{"input": "I was charged twice for my order.", "questions": [ {"type": "choice", "name": "department", "instructions": "Which department should handle this?", "choices": [{"value": "billing", "description": "Payments, invoices, refunds."}, {"value": "shipping", "description": "Delivery and tracking."}, {"value": "other", "description": "Anything else."}]}, {"type": "predicate", "name": "angry", "instructions": "Is the customer expressing anger?"}, {"type": "score", "name": "severity", "instructions": "How severe is this?", "levels": [{"label": "Cosmetic", "description": "No lost functionality."}, {"label": "Workaround", "description": "Fails, another way works."}, {"label": "Blocked", "description": "Fails with no workaround."}]}]}Pick the transport.
--transport auto(the default) takes the first that works:Transport Needs Wall time per request apipip install anthropicandANTHROPIC_API_KEYorANTHROPIC_AUTH_TOKEN~0.7 s expected (the API time measured inside claude -p)clithe claudeCLI, logged in~4 s, measured bedrockpip install anthropic,AWS_REGION, AWS credentials; explicit onlyas apiWith none of them, use the subagent path in step 3b.
Run it.
a. With a transport:
S=/mnt/skills/user/deciding-with-confidence/scripts # or wherever the skill lives python3 $S/decide.py run request.json # k=3 by default echo '{...}' | python3 $S/decide.py run -From Python:
sys.path.insert(0, S); import decide; decide.decide(req)returns the response dict, or None when no sample was usable.b. In a Claude Code session, the plugin's
decidersubagent is the cheaper path: it is pinned toclaude-haiku-5-5(the model the calibration was fitted on) and carries its instructions inline, so it answers without a tool call. Install thedeciding-with-confidenceplugin, or copyagents/decider.mdto.claude/agents/; agent definitions load at session start. Then:python3 $S/decide.py emit request.json -k 3 --agent deciding-with-confidence:decider > batch.jsonUse the name the Agent tool lists:
deciding-with-confidence:deciderfrom the plugin,deciderfrom.claude/agents/. Send eachsamples[i].promptverbatim as an Agent call with thatsubagent_type, all in one message. Collect the reply texts into a JSON list inreplies.json, thenpython3 $S/decide.py aggregate batch.json replies.json. Pool before acting: a single reply carries no agreement signal and no calibration.Without the agent installed, omit
--agent: the system prompt then rides inside each prompt for a stock general-purpose subagent withmodel: haiku. That works and costs about 58K tokens a sample against 9K.- Read the answer. Predicates give
probability(P true). Choices givechoice,probabilitiesandconfidence. Scores givescore(the probability-weighted level index, so 1.4 sits between levels 1 and 2),probabilitiesandconfidence. Every answer carriesdiagnostics:agreement,spread, the pre-calibrationrawpool andper_sample. - Act on it with thresholds, never on the top answer alone.
agreement < 1(the samples' top answers differ): escalate. On the bundled eval, unanimous answers were 92% right and split ones 44%.- Top probability under 0.7: escalate. Together with the split rule that sent 23 of 104 items onward and left 6 wrong, assuming the escalation target got every escalated item right. The 0.7 was chosen on the same data, so treat it as a starting point.
- Set the final thresholds from labelled examples of your own traffic, weighing the cost of a false positive against a false negative.
- Calibrate on your own labels when you have 50 or more per question type:
The bundledpython3 $S/decide.py eval my_labelled.jsonl --out results.jsonl # {id, input, questions, labels} python3 $S/decide.py calibrate results.jsonl --out my-cal.json export DECIDER_CALIBRATION=$PWD/my-cal.jsonassets/calibration.jsonfits onlychoice(T = 0.62, fitted through theclitransport). Predicate and score keep T = 1 until a type has 50 labels, because smaller sets swung between folds.
Earned exceptions
| Rule | Banned when | Earned when |
| k=3 samples | latency or cost is the constraint | always the default: parallel samples cost no wall time, and k=1 loses the agreement signal |
| Bundled calibration | your transport or domain differs from the eval's (cli, banking and support text) | you have not yet labelled 50 items of your own |
Escalate on agreement < 1 | nothing stronger sits behind it | a stronger model or a human can take the split items |
Common failure modes
decide: no usable sample; first error: TypeError: "Could not resolve authentication method..."→ theapitransport found no key. SetANTHROPIC_API_KEY, or pass--transport cli.decide: no transport→ no key and noclaudeon PATH. Use step 3b.diagnostics.samplesbelow k → some replies did not parse. Usually a transport timeout under heavy concurrency; lowerDECIDER_WORKERS(default 8) or raiseDECIDER_TIMEOUT(default 60 s).- Every answer near uniform (confidence around 0.1–0.2 throughout) → options without descriptions, or descriptions that overlap. Rewrite them so each has distinct, observable criteria; more samples will not help.
- A subagent reply with prose around the JSON →
aggregatetakes the outermost{...}and copes. A reply with no JSON at all counts as a failed sample. - Transcript text showing up as evidence in the subagent path → the
[no-context]line was dropped from the prompt. Send the emitted prompt verbatim.
Verification
Run the tests, then one live request:
python3 -m pytest /mnt/skills/user/deciding-with-confidence/tests -q # 39 pass, no network
echo '{"input":"Nobody can log in since the 2pm deploy.","questions":[{"type":"predicate","name":"outage","instructions":"Is a service down for users?"}]}' \
| python3 $S/decide.py run -The live answer should have probability above 0.9 and diagnostics.samples
equal to 3. A bad success is an answer with samples: 1 from a k=3 run:
it looks normal but has lost the agreement signal. Check samples when a
batch runs under load.
Diagnosed failures
- 2026-10-09, first eval: 14 of 520 samples were discarded because Haiku left the options it ruled out of 8-way choices. Missing keys now share the probability mass the sample left unassigned, and the re-run lost none. The prompt also asks for ruled-out options at 0.001.
- 2026-10-09:
claude -p --json-schemadoubled API time (2.2 s against 0.8 s) with a second turn and three times the output tokens. Theclitransport sends the JSON contract in the system prompt instead. - 2026-10-09: the claude-workspace PreToolUse hook that appends
parent-transcript chunks to Agent prompts would have put them in the
evidence.
emitappends[no-context], which that hook honours.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

