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

For most Python code, start with the LangFence facade:

from langfence import LangFence, LanguagePolicy

fence = LangFence(language=LanguagePolicy(include=["zh"], exclude=["en"], min_confidence=0.2))

result = fence.validate("这是一个中文回答。")
assert result.valid

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 LangFence, RegexConstraint

fence = LangFence(format=RegexConstraint(r"^(approved|rejected)$"))

client = fence.client(
    provider="openai-compatible",
    base_url="http://localhost:8000/v1",
    model="local-model",
    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:

import os

client = fence.client(
    provider="anthropic",
    base_url="https://api.anthropic.com/v1",
    model="claude-compatible",
    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.3.tar.gz (24.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.3-py3-none-any.whl (34.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for langfence-0.1.3.tar.gz
Algorithm Hash digest
SHA256 96405f5ee523bafc2050c1b51414ccfb893bcf9b8822025368156f23c22bf324
MD5 3f679b85c4c242d7edae1863dbcc21b8
BLAKE2b-256 b188931286cf0623315fcfe461319bd9c59bcbcbf65bfaa4594c64184265d098

See more details on using hashes here.

Provenance

The following attestation bundles were made for langfence-0.1.3.tar.gz:

Publisher: publish.yml on jianbo27/langfence

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

File details

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

File metadata

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

File hashes

Hashes for langfence-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b5f6f89a149524d9c66afa0729cbe8485e8b9334db62603c2de2ec82f52b7ed6
MD5 fc3d3639fc0b21a941d52c150f46cdc2
BLAKE2b-256 53b473eacc19c8a7f515a9c246ed4ae6336528a3ae9b80ccdf0da7fe2ac5d6cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for langfence-0.1.3-py3-none-any.whl:

Publisher: publish.yml on jianbo27/langfence

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