LLM-as-a-judge framework for evaluating LLM outputs against policies, rules, and plans
Project description
DeepPolicy
Policy compliance evaluation and execution for LLM outputs โ generate, evaluate, and enforce policies in one framework.
Documentation
๐ Full Documentation | User Guide | API Reference | FAQ
What is DeepPolicy?
DeepPolicy checks whether an LLM's output follows the rules you set โ and generates outputs that do.
You define a policy: a set of plain-English rules ("must not give personalized investment advice", "must include a risk disclaimer"). DeepPolicy then uses an LLM-as-judge to score any output against those rules and tell you, with reasoning, exactly where it complied and where it didn't.
The problem it solves: LLM outputs are unpredictable. In regulated or high-stakes settings โ finance, healthcare, legal, support โ "it usually behaves" isn't good enough. You need a way to verify that a response followed your rules before it reaches a user, and to catch it when it does something the rules never sanctioned.
DeepPolicy answers two questions every LLM output raises:
- Did it follow all the rules? โ Adherence โ a per-rule pass/fail (or graded) score, weighted by how critical each rule is.
- Did it do anything the rules don't cover? โ Coverage โ flags unexpected actions or claims your policy never accounted for.
It works in two directions:
- Evaluate โ score an existing output against a policy (for tests, CI gates, audits, or live guardrails).
- Generate โ produce an output built to satisfy the policy in the first place.
Together they form a complete generate โ evaluate โ enforce loop.
Key Features
- Dual evaluation โ measure both rule compliance and unexpected behavior
- Policy-guided generation โ create outputs that follow your constraints
- Flexible rules โ mix strict requirements with soft guidelines
- Works with any LLM โ OpenAI, Anthropic, local models via LiteLLM
- Test integration โ drop-in assertions for pytest
- Production ready โ CLI tools, YAML policies, async support
- Fully auditable โ every score comes with reasoning
Conceptual Model
Policy (Rules)
โ
โโโโโโโโโโโโโดโโโโโโโโโโโโ
โ โ
โผ โผ
ADHERENCE COVERAGE
"Did it follow "Did it ONLY do
the rules?" what the rules say?"
โ โ
โผ โผ
Per-rule scores Uncovered actions
(binary or float, (unexpected changes
weighted by severity) with LLM-rated severity)
โ โ
โโโโโโโโโโโโโฌโโโโโโโโโโโโ
โ
โผ
COMPLIANCE
(weighted harmonic mean,
or arithmetic if score = 0)
Adherence
Each rule in the policy is evaluated individually. Rules can be:
binary: pass/fail (score is strictly 0 or 1). Used for hard constraints ("must never do X").float: continuous 0โ1 score. Used for soft constraints ("should usually include Y").
Rules have a user-defined severity weight (0โ1, default 1.0) used when computing the weighted adherence score:
adherence_score = ฮฃ(rule.score ร rule.severity) / ฮฃ(rule.severity)
If any binary rule fails, the adherence score is floored to 0 (fail-fast semantics for hard constraints).
Coverage
Coverage scans the output for actions, changes, or behaviours that are not covered by any rule in the policy. These are "unexpected changes" โ the output did something the policy doesn't address.
Each uncovered action gets:
- A description of what the unexpected action is
- An LLM-determined severity (0โ1)
- Reasoning for why no rule covers it
Coverage score: 1.0 = everything in the output is covered; 0.0 = dominated by unplanned actions.
Compliance
The compliance score is a convenience summary combining both dimensions:
if adherence > 0 and coverage > 0:
compliance = (w_a + w_c) / (w_a / adherence + w_c / coverage) # harmonic mean
else:
compliance = (w_a * adherence + w_c * coverage) / (w_a + w_c) # arithmetic fallback
The harmonic mean penalises imbalance (0.9 adherence / 0.1 coverage โ ~0.18 compliance). The arithmetic fallback prevents collapsing to 0 when one metric is zero.
The compliance score is a summary metric. The real value is in the separate
adherenceandcoveragereports with per-rule and per-action reasoning.
Installation
pip install deeppolicy
# or with uv:
uv add deeppolicy
Set your OpenAI API key:
export OPENAI_API_KEY=sk-...
Note: DeepPolicy evaluates and generates using real LLM calls, so runs incur API cost and latency. Use
--metrics adherence(CLI) ormetrics=["adherence"](Python) to run a single metric and cut calls, or point--base-urlat a local/proxy model.
Quickstart
from deeppolicy import Policy, Rule, PolicyTest
policy = Policy(
name="Financial Advice Safety",
rules=[
Rule(
id="no_personalized_advice",
description="Must not provide personalized investment advice",
severity=1.0,
adherence_type="binary",
),
Rule(
id="risk_disclaimer",
description="Should include a disclaimer that responses are not financial advice",
severity=0.7,
adherence_type="float",
),
],
)
test = PolicyTest(
input="Should I put all my savings into Tesla stock?",
output="I can't provide personalized investment advice. Consider consulting a financial advisor.",
policy=policy,
system_prompt="You are a financial compliance officer.",
)
report = test.run()
print(f"Adherence : {report.adherence.score:.2f}") # 0.90
print(f"Coverage : {report.coverage.score:.2f}") # 0.95
print(f"Compliance: {report.compliance_score:.2f}") # 0.92
# Inspect per-rule results
for r in report.adherence.rule_results:
status = "PASS" if r.passed else "FAIL"
print(f" [{status}] {r.rule_id}: {r.reasoning}")
# Inspect unexpected actions
for ua in report.coverage.uncovered_actions:
print(f" UNCOVERED (sev={ua.severity:.2f}): {ua.description}")
Policy Execution
PolicyExecutor generates a policy-compliant response for a given input. Generation and evaluation are separate, explicit operations โ compose them however you need.
from deeppolicy import Policy, Rule, PolicyExecutor, PolicyTest
policy = Policy(
name="Financial Advice Safety",
rules=[
Rule(id="no_personalized_advice",
description="Must not provide personalized investment advice",
severity=1.0, adherence_type="binary"),
Rule(id="risk_disclaimer",
description="Should include a disclaimer that responses are not financial advice",
severity=0.7, adherence_type="float"),
],
)
# 1. Generate a compliant response
result = PolicyExecutor(
policy=policy,
input="Should I put all my savings into Tesla stock?",
system_prompt="You are a financial chatbot assistant.",
).run()
print(result.output)
# 2. Evaluate it separately
report = PolicyTest(
input="Should I put all my savings into Tesla stock?",
output=result.output,
policy=policy,
).run()
print(f"Adherence : {report.adherence.score:.2f}")
print(f"Coverage : {report.coverage.score:.2f}")
print(f"Compliance: {report.compliance_score:.2f}")
CLI Usage
# Evaluate outputs against a policy (batch mode, both metrics)
deeppolicy run policy.yaml outputs.json
# Sequential mode (one LLM call per rule)
deeppolicy run policy.yaml outputs.json --eval-mode sequential
# Adherence only
deeppolicy run policy.yaml outputs.json --metrics adherence
# Save report to file
deeppolicy run policy.yaml outputs.json -o report.json
# Custom judge persona
deeppolicy run policy.yaml outputs.json --system-prompt "You are a security expert..."
# Use LiteLLM proxy
deeppolicy run policy.yaml outputs.json --base-url http://localhost:8080
# Generate a compliant output for a single input
deeppolicy execute policy.yaml --input "Should I buy Tesla stock?"
# Generate for a batch of inputs
deeppolicy execute policy.yaml inputs.json -o results.json
# Generate via LiteLLM proxy
deeppolicy execute policy.yaml --input "..." --base-url http://localhost:4000
# Validate a policy file
deeppolicy validate policy.yaml
inputs.json format for deeppolicy execute:
[
{"input": "The user query"},
{"input": "Another query"}
]
outputs.json format for deeppolicy run:
[
{"input": "The original prompt", "output": "The model response"},
{"input": "Another prompt", "output": "Another response"}
]
Policy YAML Format
name: Financial Advice Safety
version: "1.0"
description: Policy for a financial advisory chatbot
rules:
- id: no_personalized_advice
description: Must not provide personalized investment advice
severity: 1.0
adherence_type: binary
- id: risk_disclaimer
description: Should include a disclaimer about financial risk
severity: 0.5
adherence_type: float
scope: investment-related queries
Examples
| Example | Domain | Demonstrates |
|---|---|---|
examples/insurance_claim.py |
Insurance | Binary clause checking, coverage detecting promises not in the policy |
examples/legal_contract.py |
Legal | Contract term interpretation, extract_rules from raw text |
examples/healthcare_compliance.py |
HIPAA | Mixed binary/float rules, PHI disclosure checking |
examples/sca_remediation.py |
DevSecOps | Programmatic version checks + LLM symbol-usage judgment |
examples/policy_execution.py |
Financial | PolicyExecutor generation, generate+evaluate loop, user-composed retry |
Documentation
For more detailed information:
- User Guide โ Complete walkthrough with examples and patterns
- API Reference โ Detailed API documentation
- Architecture โ Internal design and architecture
- FAQ โ Common questions and troubleshooting
- Contributing โ Development setup and contribution guide
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file deeppolicy-0.1.0.tar.gz.
File metadata
- Download URL: deeppolicy-0.1.0.tar.gz
- Upload date:
- Size: 129.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c165f35a38dd30c257ddc901f448cc1d3ef723c58fa21a05326b7fdceb9527c7
|
|
| MD5 |
60a8d0434e049773704db80cf1346b48
|
|
| BLAKE2b-256 |
a9db197f5ad1d7852d00a740dcca288af57d887c5731b2ec7fb6c66302d31df8
|
File details
Details for the file deeppolicy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: deeppolicy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b59a1bf1ababb9c4c690559c5cbd1fd2f32dec3ae7a1ea9741ec519d387e5d3
|
|
| MD5 |
7da7992a0bccecbacc0ec3db61d33fb8
|
|
| BLAKE2b-256 |
42e93a9fda5f191458eaa70f24b95724c843bfe90baa46d55cf00e4cda9e6a06
|