Metadata-Version: 2.4
Name: sb-decision
Version: 0.2.0
Summary: SB Decision Model: score your own options for any text in one pass, with a trained-in ask. By Sarathi Balakrishnan.
Author: Sarathi Balakrishnan
License: Apache-2.0
Project-URL: Model, https://huggingface.co/sarathi-balakrishnan/browser-decision-model-base
Project-URL: Author, https://huggingface.co/sarathi-balakrishnan
Keywords: decision,routing,triage,classification,zero-shot,guardrail
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: torch>=2.2
Requires-Dist: transformers>=4.48
Requires-Dist: huggingface_hub>=0.24
Dynamic: license-file

# sb-decision

The SB Decision Model, by Sarathi Balakrishnan. Give it a text and your own list of options, each written as
`name: when to choose it`, and it returns a calibrated probability per option in one pass. Nothing is retrained per
use case: the option definitions are the policy. A reserved `ask` option is trained to win when the deciding fact is
missing from the text, so irreversible actions go to a person instead of being guessed.

Not an LLM. It never generates text. It is the router, guardrail, or triage layer in front of one.

## Install

```
pip install sb-decision
```

## Use

```python
from sb_decision import SBDecision

m = SBDecision.load()  # sarathi-balakrishnan/browser-decision-model-base
m.decide(
    "Package arrived broken, second time this month. I want a manager.",
    [
        "refund: customer wants money back for a damaged, wrong, or missing item",
        "replace: customer wants the product again",
        "escalate: angry, threatens to leave, or asks for a manager",
    ],
)
# {'decision': 'escalate', 'band': 'auto', 'scores': {'escalate': 0.90, 'ask': 0.09, 'refund': 0.01, 'replace': 0.01}}
```

`band` is `auto` when the top score is at or above `auto=0.7`, `review` at or above `review=0.4`, otherwise
`abstain`. If `ask` wins it is always `abstain`. Both thresholds are arguments; they are statements about the error
rate you accept, not model constants.

Independent tags, when several options can apply at once:

```python
m.decide(
    "Headache since morning and now my chest feels tight.",
    ["headache: pain in the head", "chest pain: pressure or tightness in the chest", "rash: skin redness or itching"],
    mode="multi",
)
# {'decision': 'chest pain', 'band': 'auto', 'tags': ['headache', 'chest pain'],
#  'scores': {'chest pain': 0.76, 'headache': 0.61, 'ask': 0.14, 'rash': 0.0}}
```

Many texts at once: `m.scores_many(texts, options)`. Command line:

```
sb-decision "It doesn't work on my machine." -o "crash: the app exits or hangs" -o "slow: works but takes too long" -o "question: asks how to do something"
```

## Access

The package is public; the weights are in private preview. `SBDecision.load()` raises `SBAccessError` with contact
details if your Hugging Face token does not have access. To try it on your own option set, contact Sarathi
Balakrishnan at https://huggingface.co/sarathi-balakrishnan .

## Writing options

- One line per option, saying when to choose it, with the boundary to its neighbours explicit.
- Describe what the text says, not what you will do about it. "chest pressure with sweating or arm tingling" scores;
  "tell the caller to call 911" does not.
- Keep `ask` in the list whenever the action is irreversible.
- Up to 12 options, 1,024 tokens, English. It decides from the text, not the world: no lookups, no arithmetic.

## Results

Measured on 4,745 messages from five domains never seen in training or validation.

| model | params | held-out top-1 vs teacher | ask recall | false ask | calibration error (ECE) |
|---|---|---|---|---|---|
| base | 151M | 0.765 | 0.752 | 0.024 | 0.030 |
| large | 399M | 0.796 | 0.822 | 0.021 | 0.072 |

The teacher's own self-agreement on the same messages is 0.883.

## License

Apache-2.0. See NOTICE.
