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

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.4
File Size Uploaded
cerno_sdk-0.1.4.tar.gz 19.2 kB Details

Built distribution (wheel)

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

Total release size: 27.9 kB

Release files / cerno_sdk-0.1.4.tar.gz

Download URL cerno_sdk-0.1.4.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c643ebfd3ffa0763d76300fa0c5a249b7a1d4c98482d44330c57fb065d54b844
BLAKE2b-256 checksum
How to use checksums
0dafa5120b311e7d04e81db5e75001761b33bec26a226e066adbe52ac110fa19
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.4-py3-none-any.whl

Download URL cerno_sdk-0.1.4-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2aaac8c07d22ebb37d735febdff478f0f765528d24c08247cd97c474ceb66509
BLAKE2b-256 checksum
How to use checksums
4938dba3a0d8809365e3cc851d0f48a10474c2626dad9522cc68e5aea87490d0
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

This release

0.1.4 This release

2 release files

0.1.3

2 release files

0.1.2

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