Skip to main content

A unified contract layer for LLM agents — declarative, parameterizable contract templates enforced by deterministic checks and LLM judgment.

Project description

Ratify

A unified contract layer for LLM agents.

Declare what an agent must do as a parameterizable contract — then enforce it with deterministic checks and fuzzy LLM judgment, verify runs offline, or guard them live.

CI Python License: MIT Ruff Typed


Why Ratify

Every agent framework tells you how to run an agent. Almost none let you declare what it must and must not do — and enforce that consistently across frameworks.

The 2025–2026 "agent contracts" wave (relari agent-contracts, agentcontract/spec, AgentAssert/ABC, ToolGate, FORGE) each nailed one slice: resource governance, or tool-level pre/postconditions, or policy enforcement, or behavioral invariants. Ratify unifies them into one declarative object and adds the two things production teams actually need:

Axis What it means Values
🎯 Scope what aspect of the agent a clause governs input · output · behavioral · tool · resource · policy · trajectory
⚙️ Enforcement how a clause is decided hard (code) · judge (LLM) · proof (strict gate)
⏱️ Lifecycle when a clause runs pre · post · invariant · on_tool · on_step

Plus: parameterizable templates (one contract → many scenarios), composition (reuse a base policy everywhere), probabilistic satisfaction ((p, δ, k) — run a judge k times, require a pass rate), pathconditions (constrain the trajectory, not just the output), and budget conservation (a delegated child budget can never exceed its parent).

Ratify has zero required dependencies, is strictly typed, and is hermetically testable — the LLM judge is a pluggable protocol, so the whole test suite runs offline.

Install

pip install ratify-agents            # core, zero deps
pip install "ratify-agents[schema]"  # + JSON-Schema checks
pip install "ratify-agents[openai]"  # + OpenAI judge adapter

60-second example

import ratify
from ratify import checks, Scope, Lifecycle

# 1. Declare a contract — a reusable template with a parameter.
support = (
    ratify.Contract("support-reply", version="1.0")
    .param("brand", type=str)
    # HARD: deterministic, runs on the output, no LLM needed
    .hard("no-pii", "Must not leak an email address.",
          scope=Scope.OUTPUT, check=checks.excludes("@"))
    .hard("bounded", "Reply is at most 600 chars.",
          scope=Scope.OUTPUT, check=checks.max_length(600))
    # JUDGE: fuzzy, an LLM scores the natural-language criterion
    .judge("on-brand", "The reply mentions {brand} and stays positive.",
           scope=Scope.BEHAVIORAL, threshold=0.6)
    # TRAJECTORY: a "pathcondition" on how the agent worked
    .hard("used-kb", "Must consult the knowledge base before answering.",
          scope=Scope.TRAJECTORY, check=checks.used_tool("search_kb"))
)

# 2. Specialize the same template for a specific client.
acme = support.bind(brand="Acme")

# 3. Enforce it live around your agent.
from ratify import KeywordJudge  # deterministic stand-in; swap for a real model
judge = KeywordJudge(required=["Acme"])

@ratify.guard(acme, judge=judge)
def agent(question: str) -> str:
    return "Thanks for reaching out to Acme — happy to help!"

print(agent("How do I reset my password?"))

If a blocking clause fails, ContractViolation is raised with a full report; switch to mode="monitor" to log instead of raise.

Three ways to enforce

# a) Offline verification (CI, eval harnesses, replaying traces)
report = ratify.evaluate(acme, output=answer, trajectory=traj, judge=judge)
assert report.passed, report.summary()

# b) Decorator (function-style agents)
@ratify.guard(acme, judge=judge, mode="monitor")
def my_agent(q): ...

# c) Context manager (imperative loops)
with ratify.guarded(acme, prompt, judge=judge) as box:
    box.record(agent.run(prompt), trajectory=traj)

Probabilistic satisfaction — (p, δ, k)

LLM judgments are noisy. A clause can require that a criterion hold across k samples:

contract.judge(
    "grounded", "Every claim is supported by the retrieved context.",
    scope=Scope.OUTPUT,
    threshold=0.7,   # a single judgment "passes" at score ≥ 0.7
    samples=5,       # k: run the judge 5 times
    pass_rate=0.8,   # p: at least 4/5 must pass
)

Budget conservation for multi-agent delegation

from ratify import ResourceBudget

root = ResourceBudget(tokens=100_000, cost_usd=5.0, label="orchestrator")
worker = root.child(label="researcher", tokens=40_000)   # ✅ fits
root.child(label="rogue", tokens=200_000)                # ❌ BudgetExceeded

A child budget that would exceed the parent's remaining headroom is rejected at creation — runaway spend becomes structurally impossible, not merely discouraged.

Integrations

The generic adapter ratifies any callable(input) -> output, so it works with every framework today:

from ratify.adapters import wrap
safe_agent = wrap(my_agent.run, contract, judge=judge)

Framework guides (LangChain / LangGraph, CrewAI, AutoGen, OpenAI Agents SDK, Pydantic-AI, Anthropic + MCP) with copy-paste snippets live in docs/INTEGRATION.md.

Documentation

  • Integration guide — per-framework wiring
  • Concepts — the scope × enforcement × lifecycle model, prior art, and design rationale
  • examples/ — runnable end-to-end scripts

Status & honesty

0.1.0, beta. The core engine, checks, judge protocol, resources, trajectory, and the generic adapter are fully unit-tested (see tests/, run pytest). Framework-specific adapters are provided as documented, import-light patterns; those requiring a third-party package are labeled as such and are not exercised in the default hermetic test run. Contributions and real-world reports welcome.

License

MIT © 2026 Duc Nguyen

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

ratify_agents-0.1.0.tar.gz (38.4 kB view details)

Uploaded Source

Built Distribution

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

ratify_agents-0.1.0-py3-none-any.whl (29.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for ratify_agents-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3c8a2552db2b5a2612c72bc8bf6d4d69f4320ba5588719428b9cc5b14a89e12a
MD5 618648251eecfc8b3322d3c739080fd3
BLAKE2b-256 95ec4118d3a2e3828a314474ad931bf11f78a98935eeabb94c9fce08ea04e824

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for ratify_agents-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a615b36b1156aba7cd6096cef971440d2c60cdeec3c26f412de2ac83aa345d2f
MD5 156e36664a569ae547f65afe49a20999
BLAKE2b-256 790ed6c67ca6bb23edefda8d77c81b268169f45343322dd2c06704b12896120a

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