Skip to main content

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.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cerno-sdk 0.1.2
File Size Uploaded
cerno_sdk-0.1.2.tar.gz 19.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cerno-sdk 0.1.2
File Interpreter ABI Platform
cerno_sdk-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 27.9 kB

Release files / cerno_sdk-0.1.2.tar.gz

Download URL cerno_sdk-0.1.2.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
114f2c5b3dad6822d6601679ea4a11f2082e722ddf4309716722e094e25e701a
BLAKE2b-256 checksum
How to use checksums
5fae592d1342fa7ceef1d3d091d7e3650f7f75758959401d2d1a831210a18d12
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.2-py3-none-any.whl

Download URL cerno_sdk-0.1.2-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
081d5262809f70370e1c5cb521d3625fb30645b0e03d0533c56f854c6fb0db8b
BLAKE2b-256 checksum
How to use checksums
516a5f14ca35a3bade4a835b783f1123f4b1d0352f1b37540f0c5633a7754a88
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 history Release notifications | RSS feed

0.1.4

2 release files

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page