cerno — Python client
Three kinds of question about a piece of text, answered by a locally hosted model:
- noul — how likely is the answer yes
- choice — which one of up to 20 options
- score — where on a rubric of 2–10 levels
Each question is one forward pass, so answers come back in tens of milliseconds.
uv add cerno-sdk
from cerno import Client
client = Client("http://localhost:3000")
answers = (
client.systemone("Ticket: server room at 31C, rising, servers throttling.")
.noul("urgent", "Is this urgent?")
.choice("team", "Which team?", ["IT", "Facility", "HR"])
.score("sev", "How severe?", ["harmless", "minor", "moderate", "high", "critical"])
.send()
)
answers.noul("urgent") # 0.991
answers.choice("team") # "Facility"
answers.score("sev") # 5
answers.legend("sev") # "critical"
answers.confidence("team") # 0.939
Questions in one call share their state, so the text is sent and prefilled once.
Async
Same surface, await on send():
from cerno import AsyncClient
async with AsyncClient("http://localhost:3000") as client:
answers = await client.systemone(text).noul("spam", "Is this spam?").send()
Reading the answer honestly
Every answer carries the evidence it came from:
answers.label_mass("team") # 0.999 — share of the model's probability on the letters
answers.truncated("team") # some label fell outside the host's reporting window
answers.truncated_labels("team") # ("C",) — which ones; their raw_logprobs entry is a bound
answers["team"].raw_logprobs # {"A": -4.54, "B": -0.02, ...}
answers["team"].probabilities # per option, in request order
truncated is worth checking when you act on a probability rather than on the winner: it means
at least one option ranked below everything the host reported, so its probability is an upper
bound, not an observation.
label_mass is worth checking before trusting any answer at all: it is how much of the model's
own probability fell on the offered letters. The probabilities are normalised over the letters
alone, so they look just as decisive when the model was about to write something else and the
letters were far down its ranking. Well below 1, the answer was read off tokens the model was
not going to write.
To flatten an overconfident model, scale the logits before they are normalised:
client.systemone(text).calibration(2.5).noul("urgent", "Is this urgent?").send()
Above 1 flattens, below 1 sharpens, and raw_logprobs is unaffected either way.
Errors
from cerno import ApiError
try:
answers = client.systemone(text).choice("team", "Which?", options).send()
except ApiError as err:
err.code # "too_many_options" — branch on this, never on the message
err.question_id # "team"
UnexpectedResponse is raised instead when a body is not something cerno sends — a non-2xx
that is not a cerno error, or a 2xx that is not an answer — which usually means a proxy between
you and the service. TransportError means the service could not be reached or timed out; the
httpx exception is its __cause__. All three derive from CernoError.
The builder refuses two easy mistakes with a TypeError before anything is sent: a string where
the options belong (.choice("team", "Which team?") would otherwise ask about eleven single
letters), and a string or bool as a score rubric.
Metadata
Release files for cerno-sdk 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cerno_sdk-0.1.3.tar.gz | 19.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cerno_sdk-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.9 kB
Release files / cerno_sdk-0.1.3.tar.gz
| Download URL | cerno_sdk-0.1.3.tar.gz |
|---|---|
| Size | 19.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0748750ddc6d0e2925f977f67ccd6b95b09b9f5b0414a11497e841c744f057fb
|
|
BLAKE2b-256 checksum How to use checksums |
ab889d7a64affa53bcf484a1fe7285aa2f7f40c69106b4497135db5a53c2b18f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / cerno_sdk-0.1.3-py3-none-any.whl
| Download URL | cerno_sdk-0.1.3-py3-none-any.whl |
|---|---|
| Size | 8.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
18cfe3994605c7650873cf5519558e8c809fc67e5b9a4cd28372150c0a5fe0d9
|
|
BLAKE2b-256 checksum How to use checksums |
228ebf1290946c1a397f9460a235e635a11478e371875bff98a85d94f8ad4182
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|