¶ The Pilcrow — Python SDK
Deterministic AI governance for enterprise pipelines.
The Pilcrow is a compliance firewall for AI-generated text. Zero AI in the checker. Pure logic. Cryptographically auditable. Built for mass-quantity enterprise deployment.
pip install pilcrow
Quick Start
1. Check a piece of text
from pilcrow import PilcrowClient
client = PilcrowClient(api_key="pk_...", workspace_id="ws_...")
result = client.check("The patient should probably take this medication twice daily.")
print(result.verdict) # "REJECT"
print(result.score) # e.g. 72
print(result.repair_guidance) # ["Remove hedging language (probably...)"]
print(result.audit_token) # "pilcrow_sig_abc123..."
2. Self-healing guardrails — the Auto-Retry middleware
Wrap your existing LLM call with with_guardrails(). The SDK calls your LLM, runs the output through The Pilcrow, and automatically re-prompts with deterministic repair guidance until the response passes — or raises after max_retries.
import openai
from pilcrow import PilcrowClient
client = PilcrowClient(api_key="pk_...", workspace_id="ws_...")
def my_llm(prompt: str) -> str:
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
)
return response.choices[0].message.content
result = client.with_guardrails(
llm_callable=my_llm,
prompt="Write a medical discharge summary for patient Jane Doe.",
max_retries=3,
)
print(result.text) # Compliant output — guaranteed
print(result.attempts) # How many LLM calls it took (1 = first-pass)
print(result.audit_token) # Cryptographic attestation token
Works with any LLM — OpenAI, Anthropic, AWS Bedrock, LangChain, LlamaIndex, or any callable that takes a string and returns a string.
How with_guardrails() works
- Calls your LLM with the original prompt.
- Lints the output via
POST /pilcrow/check. - If
verdict == RELEASE→ returns immediately. - If
verdict == REJECT→ appends the deterministicrepair_guidanceto your prompt and calls your LLM again. - Repeats until RELEASE or
max_retriesis exhausted.
No secondary LLM judge. No regex heuristics. The same deterministic engine that generates the REJECT also generates the exact instructions to fix it.
Handling retries exhausted
from pilcrow import PilcrowClient, PilcrowMaxRetriesExceeded
client = PilcrowClient(api_key="pk_...")
try:
result = client.with_guardrails(
llm_callable=my_llm,
prompt="...",
max_retries=3,
)
except PilcrowMaxRetriesExceeded as e:
print(f"Failed after {e.attempts} attempts.")
print(f"Final verdict: {e.last_result.verdict}")
print(f"Guidance: {e.last_result.repair_guidance}")
# Route to human review, log to your audit system, etc.
Inspecting every attempt
result = client.with_guardrails(llm_callable=my_llm, prompt="...", max_retries=3)
for i, check in enumerate(result.check_results):
print(f"Attempt {i+1}: {check.verdict} (score {check.score})")
for finding in check.findings:
print(f" — [{finding.severity}] {finding.rule}: '{finding.matched}'")
API Reference
PilcrowClient(api_key, workspace_id, base_url, timeout, retry_delay)
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str | required | Your Pilcrow API key (pk_...) |
workspace_id |
str | None | Your workspace ID (ws_...) |
base_url |
str | https://pilcrow.entrustai.co |
Override for self-hosted deployments |
timeout |
int | 30 | HTTP timeout in seconds |
retry_delay |
float | 0.0 | Seconds to wait between guardrail retries |
client.check(text, *, protocols, banned_words, custom_rules, spec_reqs, protocol_version)
Returns a CheckResult. All keyword arguments are optional and override the workspace contract.
client.with_guardrails(llm_callable, prompt, *, max_retries, accept_review, ...)
Returns a GuardrailsResult. Raises PilcrowMaxRetriesExceeded if all retries are exhausted.
Exceptions
| Exception | When raised |
|---|---|
PilcrowAuthError |
Invalid or missing API key |
PilcrowContractError |
Workspace contract not in active state |
PilcrowAPIError |
HTTP error from the API |
PilcrowMaxRetriesExceeded |
All retries exhausted without RELEASE |
Requirements
- Python 3.9+
requests >= 2.28
License
Proprietary. Copyright 2026 Abraham Chachamovits / ENTRUST AI. All rights reserved.
Release files for pilcrow 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pilcrow-1.0.1.tar.gz | 9.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pilcrow-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.9 kB
Release files / pilcrow-1.0.1.tar.gz
| Download URL | pilcrow-1.0.1.tar.gz |
|---|---|
| Size | 9.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
00caa567a1e40236121d54cd190a435a35fb26e751cb84459e6589740be49b2a
|
|
BLAKE2b-256 checksum How to use checksums |
eade365333225ee84677730a9ac5be74157ef278489b7f935ed5c958caf58729
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.0
|
Release files / pilcrow-1.0.1-py3-none-any.whl
| Download URL | pilcrow-1.0.1-py3-none-any.whl |
|---|---|
| Size | 9.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6ae7c790b4b5615233d2958ed06437e53b6f1d27aa8316d459776ed70f5c8169
|
|
BLAKE2b-256 checksum How to use checksums |
11abcc5e353f5087b35e69b45afb81a036d102233f2f9fb8ab656917c5e4cf80
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.0
|