Skip to main content

The detection layer for LLM pipelines — per-step anomaly detection on tokens, latency, and cost

Project description

cernova

Python SDK for Cernova — the detection layer for LLM pipelines.

Automatically captures tokens, latency, and cost for every LLM call, and runs per-step anomaly detection to catch silent regressions before your users notice.

Installation

pip install cernova              # core — manual ingest()
pip install cernova[langchain]   # + LangChain callback handler (Anthropic, OpenAI, etc.)

LangChain (recommended)

Attach CernovaCallbackHandler to any LangChain LLM — every call is traced automatically:

from cernova import Tracer
from cernova.langchain import CernovaCallbackHandler
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

tracer  = Tracer(api_key="trace_...")
handler = CernovaCallbackHandler(tracer)

llm   = ChatAnthropic(model="claude-haiku-4-5-20251001", callbacks=[handler])
chain = ChatPromptTemplate.from_template("Summarize: {text}") | llm | StrOutputParser()
chain.invoke({"text": "..."})
# → shows up in your dashboard automatically

Works with any LangChain-compatible provider: Anthropic, OpenAI, Gemini, Cohere, and more.

Step naming

Pass step_name in config metadata to label steps in the dashboard:

chain.invoke(
    {"text": "..."},
    config={"metadata": {"step_name": "summarize"}}
)

Without a name, the step is labeled from the serialized model name (e.g. ChatAnthropic).

Multi-step pipelines

Steps inside a single chain.invoke() are automatically grouped into one run in the dashboard. Use RunnableLambda to wrap multi-step workflows:

from langchain_core.runnables import RunnableLambda
from langchain_core.messages import SystemMessage, HumanMessage

def pipeline(inputs, config):
    intent = llm.invoke(
        [SystemMessage(content="Classify as: billing, technical, general."),
         HumanMessage(content=inputs["message"])],
        config={**config, "metadata": {"step_name": "classify"}},
    )
    reply = llm.invoke(
        [SystemMessage(content="You are a support agent. Be concise."),
         HumanMessage(content=inputs["message"])],
        config={**config, "metadata": {"step_name": "generate"}},
    )
    return reply.content

chain = RunnableLambda(pipeline)
chain.invoke({"message": "..."}, config={"callbacks": [handler]})
# → both steps appear under one run_id in the dashboard

Manual ingest

For models outside LangChain, or to record any custom step:

import time, json

start    = time.monotonic()
response = my_model.generate(prompt)
latency  = int((time.monotonic() - start) * 1000)

tracer.ingest(
    run_id        = "my-run-id",
    step_name     = "generate",
    step_index    = 0,
    model         = "my-model",
    prompt        = json.dumps({"messages": [{"role": "user", "content": prompt}]}),
    input_tokens  = response.input_tokens,
    output_tokens = response.output_tokens,
    total_tokens  = response.total_tokens,
    latency_ms    = latency,
    cost          = 0.001,
    status_success= True,
    output_code   = response.text,
)

ingest() fires in a background thread and never blocks your application.

Configuration

import os
from cernova import Tracer

tracer = Tracer(
    api_key = os.environ["CERNOVA_API_KEY"],
    api_url = os.environ.get("CERNOVA_API_URL", "https://trace-production-940c.up.railway.app"),
)

For local dev, add to .env:

CERNOVA_API_KEY=trace_...
CERNOVA_API_URL=http://localhost:8000

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cernova-0.1.1.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cernova-0.1.1-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file cernova-0.1.1.tar.gz.

File metadata

  • Download URL: cernova-0.1.1.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for cernova-0.1.1.tar.gz
Algorithm Hash digest
SHA256 29ea60e638b81427d07432c34d33f511081092d966cfb7d9cd957872db5e0638
MD5 2bb9c6f4c99e99e2ed850f2e2f6b466f
BLAKE2b-256 8341e111d446632ba2a51c1ea6f249193e3584eca11603b80043fc58b8e0232e

See more details on using hashes here.

File details

Details for the file cernova-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: cernova-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for cernova-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 76602779a448d38d6d833b3314a1e359f2401ecafd150356d302436e7d38750f
MD5 8aa80882fb7b0b026691431195767393
BLAKE2b-256 49b3ac359995f6ffbc3f38ce11f1aa9827a405b312f2d4f3aafb684168183354

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page