Skip to main content

Capture LLM call/response snapshots and validate them against the ModelGenius snapshot format — locally, with no network calls.

Project description

modelgenius-sdk

CI PyPI Python License

Capture your production LLM calls as local snapshot files, and validate them against the ModelGenius snapshot format — entirely on your machine, with zero network calls and zero telemetry.

ModelGenius answers "is it safe to switch LLM models, and is it worth it?" by replaying your real production requests against candidate models and comparing quality, cost, and latency. The input to that analysis is a set of snapshots: your requests, the parameters they ran with, and (ideally) the responses your current model actually produced. This SDK is the capture side. It has one runtime dependency (jsonschema) and never imports openai, anthropic, or litellm — it duck-types your existing client objects.

Two ways to adopt it:

  1. Wrap your client — one line at startup; every call is spooled to local JSONL as it happens, with real outputs, token usage, and latency attached.
  2. Bring your own logs — if you already log LLM traffic, write it in the snapshot format and use modelgenius-sdk validate to check it before uploading.

Install

pip install modelgenius-sdk

Quickstart

OpenAI (sync or async client; streaming supported):

import modelgenius_sdk
from openai import OpenAI

client = modelgenius_sdk.wrap_openai(OpenAI(), workflow_name="support_ticket_triage")
# use `client` exactly as before — every chat.completions call is snapshotted locally

Anthropic (sync or async client; messages.create streaming supported):

import modelgenius_sdk
from anthropic import Anthropic

client = modelgenius_sdk.wrap_anthropic(Anthropic(), workflow_name="math_tutoring")

LiteLLM (success callback):

import litellm
import modelgenius_sdk

litellm.success_callback.append(modelgenius_sdk.make_litellm_callback(workflow_name="ap_automation"))

Validate what you captured (or logs you wrote yourself):

modelgenius-sdk validate ./modelgenius_snapshots

The wrapper returns the same client object and never changes call behavior: your arguments pass through untouched, return values and exceptions propagate unchanged, and any internal capture error is swallowed (logged once), never raised into your app.

What gets captured

One JSON object per call, appended to a local JSONL spool file: the request (messages, model, temperature, tools, response_format, and the rest of the request parameters), plus a captured_output block with the real response — output text, tool calls, token usage, latency, and, via the LiteLLM callback, cost. See docs/snapshot_format.md for the full format, and examples/ for validated sample files.

The more you capture, the more the analysis can do:

You provide You unlock
captured_output Baseline scored from real production outputs — no baseline replay, real latency/cost preserved
usage + cost_usd Honest savings baseline from actual spend
workflow_name + call_name (or workflow_id) Precise workflow grouping instead of content-based inference
tools / response_format Deterministic output-contract checks on every candidate
model Automatic baseline identification

Full table with grouping precedence: docs/snapshot_format.md.

Configuration

Everything can be set in code via CaptureConfig, or via environment variables:

from modelgenius_sdk import CaptureConfig, wrap_openai

config = CaptureConfig(
    spool_dir="/var/log/myapp/snapshots",
    workflow_name="support_ticket_triage",
    call_name="classify_ticket",
    sample_rate=0.25,          # capture 25% of calls
)
client = wrap_openai(OpenAI(), config)
Environment variable Effect Default
MODELGENIUS_CAPTURE Set to 0, false, or no (case-insensitive) to disable capture entirely — the kill switch enabled
MODELGENIUS_CAPTURE_DIR Spool directory for snapshot files ./modelgenius_snapshots
MODELGENIUS_CAPTURE_SAMPLE_RATE Fraction of calls to capture, 0.01.0 1.0
MODELGENIUS_CAPTURE_DEBUG Set to 1 to make internal capture errors raise instead of being swallowed (for tests/debugging) off

Explicit CaptureConfig values win over environment variables. The sampling decision is made once per call, before dispatch, so a streamed response is either fully captured or not at all.

Redaction and filtering

You stay in control of what lands on disk:

def redact(record: dict):
    # Called with the full record just before it is written.
    for message in record.get("messages", []):
        if isinstance(message.get("content"), str):
            message["content"] = scrub_pii(message["content"])
    if record.get("metadata", {}).get("tenant_tier") == "enterprise":
        return None  # returning None drops the record entirely
    return record

def only_prod_traffic(request_kwargs: dict) -> bool:
    # Called with the request kwargs before capture is attempted.
    return request_kwargs.get("user") != "internal-smoke-test"

config = CaptureConfig(
    workflow_name="support_ticket_triage",
    redact=redact,
    request_filter=only_prod_traffic,
    sample_rate=0.1,
)

Spool files and rotation

Records are appended to <spool_dir>/snapshots-<YYYYMMDD>-<pid>-<seq>.jsonl — one JSON object per line, flushed after every write, safe across processes (each PID writes its own file). When the current file exceeds max_file_bytes (default 64 MiB) the writer rotates to the next sequence number. The spool directory is created lazily on first write. Point modelgenius-sdk validate (or the ModelGenius upload step) at the directory when you are ready.

Trust posture

  • Local-only. The library makes no network calls of its own — the only network traffic is your unmodified provider call. Uploading snapshots to ModelGenius is a separate, deliberate step you take elsewhere.
  • No telemetry. Nothing is phoned home. Ever.
  • Fail-open. Capture errors never raise into your application and never alter the provider call, its return value, or its exceptions.
  • You control the data. Redaction hook, request filter, sampling, and a one-variable kill switch (MODELGENIUS_CAPTURE=0).
  • Small and auditable. A handful of modules, one dependency, no provider SDK imports — read the whole thing in one sitting.

CLI

modelgenius-sdk validate PATH [--json] [--strict] [--quiet]
modelgenius-sdk version

validate accepts a .jsonl file, a .json file (object or array), or a directory of both. Exit code 0 means every record is accepted by the same semantics as the ModelGenius upload path; warnings point out optional fields that would unlock capability. --strict turns warnings into failures (useful in CI — this repo validates its own examples/ on every push).

Limitations (v0)

  • Failed provider calls are not captured (only successful responses).
  • OpenAI: chat.completions only; the responses API surface is not wrapped yet.
  • Anthropic: messages.create (including stream=True) is captured; the messages.stream() helper is not yet.
  • LiteLLM: the callback is sync-only (litellm accepts sync callbacks for async paths).

Roadmap

  • Direct upload client (modelgenius-sdk push) as an explicit, opt-in step
  • Continuous monitoring mode (rolling capture windows + scheduled re-evaluation)
  • TypeScript SDK
  • OpenAI responses surface and Anthropic messages.stream() capture

License

Apache-2.0.

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

modelgenius_sdk-0.1.0.tar.gz (71.2 kB view details)

Uploaded Source

Built Distribution

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

modelgenius_sdk-0.1.0-py3-none-any.whl (50.5 kB view details)

Uploaded Python 3

File details

Details for the file modelgenius_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: modelgenius_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 71.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for modelgenius_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e68c031dfeb52cbddb9879394249ff253ef8c571fe30be1169ea4288db5583ad
MD5 738eb9e0e6a88107185eec7a8b49542c
BLAKE2b-256 a630c4eb81fcf057bad532eef4e1622d5916331e1fc74451535fa785bd8c6968

See more details on using hashes here.

Provenance

The following attestation bundles were made for modelgenius_sdk-0.1.0.tar.gz:

Publisher: release.yml on modelgenius/modelgenius-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file modelgenius_sdk-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for modelgenius_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dde7aa73c52697580a79e559d3702662d5003014dcd6ebf442800977b7e05d4f
MD5 9e75d470caf25f4997428a94ce649c39
BLAKE2b-256 9d1697dc39d29e8163093e10aa77545840265f2a5f7c2ace508986876999ab40

See more details on using hashes here.

Provenance

The following attestation bundles were made for modelgenius_sdk-0.1.0-py3-none-any.whl:

Publisher: release.yml on modelgenius/modelgenius-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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