Skip to main content

Output contracts and language policies for vLLM, SGLang, LiteLLM, and compatible LLM APIs.

Project description

LangFence

LangFence puts a small, explicit contract around LLM output.

It compiles format constraints into the strongest request fields a provider supports, adds language guidance when useful, and validates the returned text locally. The goal is not to pretend natural language can be perfectly constrained. The goal is to make format and language expectations visible, testable, and easy to use with local or OpenAI-compatible serving stacks.

What It Supports

  • vLLM and SGLang, out of the box
  • LiteLLM and generic OpenAI-compatible /chat/completions endpoints
  • Anthropic-compatible /messages endpoints
  • Python API, CLI, and an optional OpenAI-compatible sidecar proxy
  • JSON Schema, regex, choice, grammar/EBNF, and structural tag contracts
  • Language include/exclude policies, checked after generation
  • Redacted CLI/service diagnostics by default

Install

pip install langfence

For local development:

pip install -e ".[dev,all]"

Python API

Use compile_request when you only want the provider payload:

from langfence import JsonSchemaConstraint, LanguagePolicy, OutputContract, compile_request

contract = OutputContract(
    format=JsonSchemaConstraint(
        name="answer",
        schema={
            "type": "object",
            "properties": {"answer": {"type": "string"}, "language": {"enum": ["zh"]}},
            "required": ["answer", "language"],
            "additionalProperties": False,
        },
    ),
    language=LanguagePolicy(include=["zh"], exclude=["en"], min_confidence=0.2),
)

compiled = compile_request(
    "vllm",
    [{"role": "user", "content": "用中文解释 constrained decoding。"}],
    contract,
    base_payload={"model": "Qwen/Qwen2.5-7B-Instruct"},
)

Use LangFenceClient when you want request, retry, extraction, and validation in one place:

from langfence import LangFenceClient, RegexConstraint, OutputContract
import os

contract = OutputContract(format=RegexConstraint(r"^(approved|rejected)$"))

client = LangFenceClient(
    provider="openai-compatible",
    base_url="http://localhost:8000/v1",
    model="local-model",
    contract=contract,
    max_retries=1,
)

result = client.chat([{"role": "user", "content": "Return approved or rejected."}])
assert result.ok
print(result.text)

Provider names accepted by the client:

  • vllm
  • sglang
  • openai or openai-compatible
  • litellm
  • anthropic or anthropic-compatible

For Anthropic-compatible endpoints, use the Messages API base URL:

client = LangFenceClient(
    provider="anthropic",
    base_url="https://api.anthropic.com/v1",
    model="claude-compatible",
    contract=contract,
    api_key=os.environ["ANTHROPIC_API_KEY"],
)

CLI

Compile a request payload:

langfence compile --provider vllm --contract examples/contract.zh.yaml
langfence compile --provider sglang --contract examples/contract.zh.yaml

Call a model and validate its output:

langfence chat \
  --provider vllm \
  --base-url http://localhost:8000/v1 \
  --model local-model \
  --contract examples/contract.zh.yaml \
  --prompt "用中文回答。"

Use --api-key-env OPENAI_API_KEY or --api-key-env ANTHROPIC_API_KEY to read keys from the environment. CLI output redacts model text by default; add --show-sensitive only in a trusted local shell.

Validate saved output:

langfence validate --contract examples/contract.zh.yaml --input output.txt

Run the optional OpenAI-compatible proxy:

pip install "langfence[service]"
langfence proxy --provider vllm --base-url http://localhost:8000/v1

Provider Behavior

Provider Format handling Language handling
vLLM Uses vLLM structured output fields where available Prompt guidance + local validation
SGLang Uses SGLang regex/JSON/EBNF/structural fields where available Prompt guidance + local validation
OpenAI-compatible Uses standard JSON Schema response_format; other formats are validated after generation Prompt guidance + local validation
LiteLLM Same portable OpenAI-compatible behavior Prompt guidance + local validation
Anthropic-compatible Uses Messages system guidance; validation runs after generation Prompt guidance + local validation

LangFence does not log prompts, outputs, or provider responses. HTTP error bodies are hidden by default because providers may echo request content.

LangFence validates text returned to the caller. It cannot inspect or constrain hidden reasoning traces or internal chain-of-thought that a provider does not expose. If a local reasoning model returns a leading visible block such as <think>...</think>, LangFence strips that block before validation by default and checks the final answer. This keeps reasoning-model output quality intact: no extra constrained decoding or prompt pressure is added just to control the language of private reasoning.

Development

pytest
ruff check .
mypy src/langfence

See docs/architecture.md for design notes and docs/privacy.md for privacy rules.

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

langfence-0.1.1.tar.gz (33.9 kB view details)

Uploaded Source

Built Distribution

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

langfence-0.1.1-py3-none-any.whl (32.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for langfence-0.1.1.tar.gz
Algorithm Hash digest
SHA256 cd389231f1a929b01bfda9de3a1dd579f862a89d679310aec6dd3c286ab451d5
MD5 cdc996c4c1438c04d19c6e12fa62f1ba
BLAKE2b-256 edf3ca2f7419ae450692b25660e3c0216e3e68766df00f96c0ca313fc7c556c0

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for langfence-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5fb04c8de28e153b21e2c2440ddbf2a74d7d356bc76339409d5f9bb59c3ca179
MD5 e3f09eceb8db76c7470f7e1351377da1
BLAKE2b-256 daab2a2262688685d70105cee4a3e6551a72f0ed45ed54b18542d7e862d72a5a

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