Skip to main content

LLM relay reality check — a CLI that audits whether an API relay actually serves the model it claims (货不对板检测).

Project description

zing — LLM relay reality check

English · 中文

CI License: Apache-2.0 Python 3.10+

zing is a local-first CLI that audits whether an API relay (中转站 / reseller / proxy) actually serves the model it claims to — or quietly substitutes a cheaper one, truncates your context window, fakes streaming, or inflates token billing (货不对板检测). It speaks both OpenAI Chat Completions and the Anthropic Messages API (auto-detected, or forced with --api).

You point it at a relay endpoint and the model it advertises; zing runs a battery of black-box probes, compares the observed behavior against a bundled knowledge base of 85 native model profiles across 7 platforms, and prints a clear, evidence-backed verdict — for a human, or as JSON for another tool / LLM to read.

zing reports black-box evidence of divergence and risk, not cryptographic proof of fraud. See Responsible use.


Why

The relay-key market is full of "GPT-4o for 1/10th the price" offers. Many are honest. Some are not — and the dishonest ones are hard to catch by eye:

  • You ask for gpt-4o; you're quietly served gpt-4o-mini or an open model.
  • The relay advertises a 1M-token context but silently truncates to 32K.
  • "Streaming" is the full response buffered and re-chunked, with no latency win.
  • Reported usage tokens are inflated, so your balance burns faster than it should.
  • A model that should support tool-calling / JSON mode quietly doesn't.

zing turns "this feels off" into a reproducible report.

Install

Requires Python 3.10+.

# from PyPI
pip install zing-audit          # the `zing` command

# or from source
git clone https://github.com/cenbonew/zing
cd zing
pip install -e .

(Maintainers: see docs/PUBLISHING.md for the release process.)

Optional: install the tokenizers extra for accurate OpenAI-family token counting in the billing audit:

pip install -e '.[tokenizers]'

Quick start

# 1) audit a relay against what it claims (model id + provider hint)
export ZING_API_KEY=sk-your-relay-key
zing check \
  --base-url https://relay.example.com/v1 \
  --api-key env:ZING_API_KEY \
  --model gpt-4o \
  --suite standard

# 2) the strongest check: compare against a trusted baseline of the same model
export OPENAI_API_KEY=sk-your-openai-key
zing compare \
  --target-base-url https://relay.example.com/v1 --target-api-key env:ZING_API_KEY --target-model gpt-4o \
  --baseline-base-url https://api.openai.com/v1 --baseline-api-key env:OPENAI_API_KEY --baseline-model gpt-4o \
  --suite deep

# 3) audit an Anthropic-native (Messages API) relay — protocol is auto-detected
#    from the base_url/model, or force it with --api anthropic
zing check --base-url https://relay.example.com/v1 --model claude-opus-4-8 \
  --api-key env:ZING_API_KEY --api anthropic

# 4) confirm a suspected substitution: audit the relay's REAL model id against the
#    profile it's sold as (here: a Doubao model passed off as deepseek-v4-flash)
zing check --base-url https://relay.example.com/v1 --api-key env:ZING_API_KEY \
  --model doubao-seed-2-0-lite --claimed-model deepseek-v4-flash

# 5) inspect the bundled knowledge base
zing kb            # all 85 models
zing kb deepseek   # one provider

# 6) generate a config you can commit
zing init          # writes zing.yaml
zing check -c zing.yaml

As a tool for an LLM / agent

zing is built to be driven by another program or model. Everything goes to stdout as JSON, errors included, and the exit code is the gate.

# lean, agent-friendly verdict (~5x smaller than --json: no bulky evidence)
zing check --base-url ... --model gpt-4o --compact | jq .verdict.risk

# full structured report when you need every finding's evidence
zing check --base-url ... --model gpt-4o --json

# budget first: which detectors run + estimated API calls, WITHOUT making any
zing check --base-url ... --model gpt-4o --suite deep --dry-run --json

# gate on the exit code (1 if risk >= medium); config/usage errors exit 2 as JSON
zing check --base-url ... --model gpt-4o --compact --fail-on-risk medium

# machine-readable discovery
zing kb --json                 # the whole knowledge base
zing models --base-url ... --json   # what an endpoint advertises

In --json/--compact mode a bad config prints {"error": {...}} (exit 2) instead of a human message, so a pipeline can parse failures uniformly.

What it checks

zing scores nine dimensions. The three that most directly reveal 货不对板 (model identity, real context window, capability claims) carry the most weight.

Dimension What it catches
model_identity Silent model downgrade/substitution — self-identification, knowledge-cutoff, tokenizer fingerprints, the echoed model field
context_window Silent context truncation (claim 1M, recall fails at 32K) and lost-in-the-middle from cheap RAG/summarization shims, via needle-in-a-haystack + binary search
capability Tool-calling / JSON-mode / json-schema / max-output claims that aren't actually delivered (or over-delivered, hinting at a substitute)
billing Token/usage inflation and missing/unverifiable usage accounting, via an independent tokenizer estimate
streaming Fake streaming (buffer-then-chunk) detected from chunk count and inter-chunk timing
protocol OpenAI-compatibility conformance: multi-turn, stop sequences, response shape, error schema — and a determinism sub-check for response caching that ignores temperature/seed
reliability Concurrent success rate and latency (HTTP 429 throttling bucketed separately)
connectivity Endpoint reachability and the advertised /v1/models list
security Transport (HTTPS), header hygiene, secret echo; hidden injected system prompt (fixed input-token overhead + leak), in-flight response/tool-call tampering via known-answer canaries (URL/package substitution), and prompt-prefix caching (timing)

See docs/METHODOLOGY.md for the technique behind each check, which relay trick it maps to, and its false-positive caveats.

Two detection modes

  • Pure code (default): every deterministic probe — fingerprints, context sweep, billing math, streaming timing. No second model needed; fully reproducible.
  • Code + LLM hybrid (--judge): additionally consults a trusted judge model (configured separately, never the target) to assess fuzzy signals like quality and reasoning depth that pure code can't decide. Powers the quality_judge detector.
zing check --base-url ... --model gpt-4o --suite deep --judge \
  --judge-base-url https://api.openai.com/v1 --judge-api-key env:OPENAI_API_KEY --judge-model gpt-4o-mini

Suites

Suite Detectors Cost
smoke connectivity, security very low
standard + protocol, model_identity, capability, streaming, billing, reliability low–medium
deep + context_window, determinism, injected_prompt, integrity, prompt_cache, quality_judge (if --judge) higher (long-context & timing probes cost tokens)
full everything highest

The context-window probe is bounded by --max-context-tokens (default 200K) so auditing a 1M-token model stays affordable.

Example verdict

╭─ ✗ HIGH RISK — Strong evidence the relay does not deliver the claimed model… ─╮
│ Target : my-relay · model gpt-4o · provider openai                            │
│ Mode   : check · suite deep                                                   │
│ Score  : 53.5/100 (rating F) · confidence medium                             │
│                                                                               │
│ Overall health score 53.5/100. Findings: 3 high. …                            │
╰───────────────────────────────────────────────────────────────────────────────╯
  • Self-identifies as a rival brand (anthropic) under the claimed model id gpt-4o
  • Real context window ~8000 << declared 128000 (silent truncation suspected)
  • Reported prompt tokens far exceed independent estimate

Reports are written to reports/ as JSON, Markdown, and HTML.

Knowledge base

Profiles live in zing/knowledge/data/ as editable YAML — one per provider (OpenAI, Anthropic, Google Gemini, DeepSeek, Qwen, GLM, Moonshot). Each model carries its native context window, max output, tokenizer, capability flags, identity keywords, and behavioral fingerprints. Add or override profiles without forking:

zing check --kb-dir ./my-profiles ...     # or set ZING_KB_DIR

Responsible use

zing is a black-box auditing aid. It cannot prove:

  • that a provider stores or trains on your prompts,
  • that it always routes to one exact model (relays can route probabilistically),
  • billing fraud beyond what independent token estimation can suggest.

Use reports for your own due diligence. Do not publicly accuse a vendor based on a single run without reviewing sample size, cost settings, and local law. Run zing compare against a trusted baseline before drawing strong conclusions.

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

zing_audit-0.4.0.tar.gz (162.8 kB view details)

Uploaded Source

Built Distribution

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

zing_audit-0.4.0-py3-none-any.whl (147.8 kB view details)

Uploaded Python 3

File details

Details for the file zing_audit-0.4.0.tar.gz.

File metadata

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

File hashes

Hashes for zing_audit-0.4.0.tar.gz
Algorithm Hash digest
SHA256 527f5d9db217de62c2c4cddc45e01d8ca5f36b298cfe36040daf98de6f4eb958
MD5 5bed4dd2f17a2be0b89e89848acca065
BLAKE2b-256 5f8b15e865236527d63a0d984ddf1f919a100ab61af0eed5e09cffbb651d7dd1

See more details on using hashes here.

Provenance

The following attestation bundles were made for zing_audit-0.4.0.tar.gz:

Publisher: release.yml on cenbonew/zing

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

File details

Details for the file zing_audit-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: zing_audit-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 147.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zing_audit-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9d141731f70373b0d8d8cb8db5dfbf273caa25e55245cdddb0c7d659afd9d845
MD5 9f74369814aec27d86b395e58e422769
BLAKE2b-256 b8eb110cdc7f568dc59ba1283b6dde9d8642c192b55a5a5ceaa6b3167ab94e47

See more details on using hashes here.

Provenance

The following attestation bundles were made for zing_audit-0.4.0-py3-none-any.whl:

Publisher: release.yml on cenbonew/zing

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