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.2.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.2-py3-none-any.whl (34.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: langfence-0.1.2.tar.gz
  • Upload date:
  • Size: 24.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.2.tar.gz
Algorithm Hash digest
SHA256 5720cb463fcd9b1410c5f3101c4a2eed5c6d668e6daa2f16de1214daf67b8858
MD5 f5b05f32ea932589e7f61c54b0336166
BLAKE2b-256 02c060189e4ec842ebcf1b187ab7132b90ef7e1187bc255e45f2b2e57417c689

See more details on using hashes here.

File details

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

File metadata

  • Download URL: langfence-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 34.5 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 433a1b263dd35d773563238f69e24a50af2a5ed57bd5a29c82a2111f3adf0967
MD5 f81901f25ec7e57870022b3413beffa7
BLAKE2b-256 df69f506a980adf31204bd9d578e045b274f258e53bf9e366ad7cedcd08b11a9

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