Skip to main content

Strict JSON LLM outputs with multi-provider support (Anthropic / OpenAI / DeepSeek / Kimi / Google)

Project description

guarded-llm

Strict JSON output from any LLM, with retry + schema validation + multi-provider routing in one call.

Pre-release: not yet on PyPI; install from source.

What it does

LLMs hallucinate JSON. guarded-llm wraps a single call into a 4-layer defense:

  1. Strip markdown fences and locate the JSON envelope in chatty output.
  2. State-machine fix common drift: trailing commas, single quotes, NaN/Infinity, comments, unescaped interior quotes, BOM.
  3. Parse with json.loads.
  4. Validate against a schema (JSON Schema via LLMSchema, or any class exposing a .validate(d) -> (ok, err, instance) classmethod).

If any layer fails, the call is retried with the previous error injected back into the prompt as a hint. After max_retries, it returns a structured GuardrailResult with parsed, errors, attempts, and cost_usd.

Install

# From source (pre-release)
pip install git+https://github.com/dada8899/structural-isomorphism#subdirectory=packages/guarded-llm

# Once published
pip install guarded-llm

Optional extras for vendor SDKs (you don't need them — built-in adapters use plain HTTP via requests):

pip install guarded-llm[anthropic]   # if you want the official anthropic SDK
pip install guarded-llm[openai]      # if you want the official openai SDK
pip install guarded-llm[dev]         # pytest, ruff, mypy

Quickstart

from guarded_llm import guardrailed_llm_call, LLMSchema

schema = LLMSchema({
    "type": "object",
    "properties": {
        "verdict": {"type": "string", "enum": ["KEEP", "REJECT", "SPLIT", "MERGE"]},
        "confidence": {"type": "number", "minimum": 0, "maximum": 1},
    },
    "required": ["verdict", "confidence"],
})

result = guardrailed_llm_call(
    provider="deepseek",
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "Is gravity a self-organized criticality system?"}],
    schema=schema,
    max_retries=3,
    budget_cap_usd=0.05,
)

if result.ok:
    print(result.parsed)         # {"verdict": "REJECT", "confidence": 0.9}
    print(result.cost_usd)       # 0.0012
    print(result.attempts)       # 1
else:
    print("All retries failed:", result.errors)

Set DEEPSEEK_API_KEY in your env (or pass api_key= via **kwargs).

Features

  • Multi-provider out of the box — DeepSeek, Anthropic Claude, OpenAI, Kimi (Moonshot). All built-in adapters use plain HTTP — no vendor SDK required.
  • Pluggable — subclass BaseProvider + call register_provider("name", cls) to add anything else (OpenRouter, Together, Google Gemini, local Ollama, …).
  • Schema validation — bring your own JSON Schema via LLMSchema(...), or use the legacy dataclass schemas (Layer3CriticVerdict, Layer4Prediction, B3EnsembleReview) shipped from the structural-isomorphism V4 pipeline.
  • Automatic retry with error feedback — each retry's prompt includes the prior validation error so the model can self-correct.
  • Budget cap — pass budget_cap_usd= and a BudgetExceededError fires before you torch your wallet on a runaway loop.
  • Structured resultGuardrailResult exposes parsed, errors, attempts, cost_usd, and raw_outputs for debugging.
  • Drop-in compat — supports the legacy guardrailed_llm_call(prompt_fn, llm_caller, schema_cls, max_retries) signature for existing callers.

How it compares

Feature guarded-llm instructor outlines guidance
Multi-provider ✅ 4 built-in ✅ many partial (HF-first) partial
Works on closed-model APIs mostly local partial
JSON Schema input via Pydantic
State-machine fixer for drift retry only grammar-constrained grammar-constrained
No SDK lock-in (HTTP only) requires vendor SDK
Cost tracking
Budget cap
Footprint tiny (3 deps) medium large (torch optional) medium

guarded-llm's niche: closed-model APIs where you can't grammar-constrain the decoder, but you still want strict JSON without writing five layers of defensive parsing. If you're using local HF models, prefer outlines' grammar-level approach; if you're already deep in Pydantic, instructor is elegant.

Provider environment variables

Provider API key env Base URL env (optional)
deepseek DEEPSEEK_API_KEY DEEPSEEK_BASE_URL
anthropic ANTHROPIC_API_KEY ANTHROPIC_BASE_URL
openai OPENAI_API_KEY OPENAI_BASE_URL
kimi KIMI_API_KEY or MOONSHOT_API_KEY KIMI_BASE_URL

You can also pass api_key=, base_url= directly in the call.

License

MIT — see LICENSE.

Contributing

This package lives inside the structural-isomorphism monorepo at packages/guarded-llm/. PRs welcome — see the repo issues page.

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

guarded_llm-0.1.0.tar.gz (24.0 kB view details)

Uploaded Source

Built Distribution

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

guarded_llm-0.1.0-py3-none-any.whl (22.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for guarded_llm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 faef638f99eb80275e487dea7032c64579168d2ab067621062e35fe72708883d
MD5 3ea38622d60c480c7756f5ac43427407
BLAKE2b-256 7d077307fe294b991075b829a465afd504b80df18a7dc0653d11debef5dcd4c5

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for guarded_llm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d3e3de8a486346448bff327fc85d99766c6be51ccac066055398cf4c017eb62f
MD5 c4a8ee51181074d00ab39594f85e272b
BLAKE2b-256 867cc14d8d9f02d6a2ca97c2521b63dc4d9d0321885c5a7dbab43b373ec7ed04

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