Skip to content

Commit fbc265c

Browse files
dni138claude
andauthored
feat(content): fetchable author-published policies, rubrics & criteria (#20, #87) (#203)
* feat(content): authored-content registry + per-kind API (policies/rubrics/criteria) New import-free registry of author-published fill-in content (AuthoredContent/ContentKind), with AnyGuardrail.get_policy/list_policies, get_rubric/list_rubrics, get_criteria/list_criteria. Seeded with ShieldGemma harm policies, Granite Guardian risk criteria, Flow-Judge preset criteria+rubrics (mirrored from the live source in a stdlib-only data module), and Prometheus scoring rubrics. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * build(content): content JSON export + data-module regenerator + pre-commit hook generate_content_json.py --check gates schemas/guardrail_content.json; generate_content_data.py regenerates the mirrored Granite/Flow-Judge data module. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(content): per-kind API, leaf-module, no-import, and drift tests Drift tests keep Granite/Flow-Judge content byte-identical to their live sources (Flow-Judge gated on the flowjudge extra); plus per-kind round-trips, unique-key, frozen, and leaf/no-backend guarantees. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(content): policies/rubrics/criteria guide, README section, cookbook notebook Document the per-kind fetch API in docs/prompts.md and the README; add a cookbook notebook showing how to discover prompt templates and fetch/use author-published content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs/refactor(content): address Copilot review on #203 Broaden the types.py re-export comment to content+prompts; use AnyGuardrail.create in content.py's docstring example; include 'criteria' in the README/SUMMARY titles; cache _items() in get_content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(lint): apply pinned-ruff formatting (test_content.py + cookbook notebook) The pinned CI ruff wraps long assert lines and reformats notebook cells that the local (stale) pre-commit cache missed; apply them so the linter passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(prompts): browsable prompt & content catalog page Generated docs/prompt_catalog.md renders every guardrail's default prompt template text plus its author-published policies/rubrics/criteria (from the import-free registries), so people can read the actual defaults in the docs. Committed + linked in SUMMARY + gated by a --check pre-commit hook. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(lint): clean catalog generator docstring + strip trailing whitespace The catalog generator tripped two CI-only lint failures that my selective fresh-toolchain check missed (the script was untracked and I did not run the trailing-whitespace hook): - ruff D205 on the module docstring (summary line wrapped without a blank separator) and F401 (unused GuardrailName import). - generated docs/prompt_catalog.md carried trailing whitespace from prompt text, which the trim-trailing-whitespace pre-commit hook strips. Rewrite the docstring to a single summary line + blank + description, drop the unused import, and rstrip every rendered line in build() so the committed catalog matches what the hook would leave. Regenerate the catalog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6fdb9d7 commit fbc265c

17 files changed

Lines changed: 2065 additions & 3 deletions

.pre-commit-config.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ repos:
5959
pass_filenames: false
6060
files: ^(src/any_guardrail/(prompts|prompt_registry|base)\.py|scripts/generate_prompts_json\.py|schemas/guardrail_prompts\.json)$
6161

62+
- id: guardrail-content-json
63+
name: check guardrail content JSON is up to date
64+
entry: "uv run python scripts/generate_content_json.py --check"
65+
language: system
66+
pass_filenames: false
67+
files: ^(src/any_guardrail/(content|content_registry|_authored_content_data|base)\.py|scripts/generate_content_json\.py|schemas/guardrail_content\.json)$
68+
69+
- id: guardrail-prompt-catalog
70+
name: check prompt/content catalog is up to date
71+
entry: "uv run python scripts/generate_prompt_catalog.py --check"
72+
language: system
73+
pass_filenames: false
74+
files: ^(src/any_guardrail/(prompts|prompt_registry|content|content_registry|_authored_content_data|base|registry)\.py|scripts/generate_prompt_catalog\.py|docs/prompt_catalog\.md)$
75+
6276
- id: guardrail-summary-nav
6377
name: check guardrail SUMMARY navigation is up to date
6478
entry: "uv run python scripts/generate_summary.py --check"

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,27 @@ A machine-readable [JSON Schema](schemas/guardrail_output.schema.json) for this
8888
https://raw.githubusercontent.com/mozilla-ai/any-guardrail/main/schemas/guardrail_output.schema.json
8989
```
9090

91+
### Prompts, policies, rubrics & criteria
92+
93+
Generative and judge guardrails run against a **prompt template** and often need a **policy**,
94+
**rubric**, or **criteria**. any-guardrail lets you discover and override the default prompt, and
95+
fetch author-published policies/rubrics/criteria — all without loading a model:
96+
97+
```python
98+
from any_guardrail import AnyGuardrail, GuardrailName
99+
100+
# Inspect a guardrail's default prompt template
101+
AnyGuardrail.get_prompt(GuardrailName.SELENE).segments["user"]
102+
103+
# Fetch a ready-made author-published policy and use it directly
104+
policy = AnyGuardrail.get_policy(GuardrailName.SHIELD_GEMMA, "dangerous_content")
105+
guard = AnyGuardrail.create(GuardrailName.SHIELD_GEMMA, policy=policy)
106+
```
107+
108+
See the [Prompts & content guide](docs/prompts.md). The catalogs are exported to
109+
[`schemas/guardrail_prompts.json`](schemas/guardrail_prompts.json) and
110+
[`schemas/guardrail_content.json`](schemas/guardrail_content.json).
111+
91112
## Documentation
92113
Full guides at [docs link](https://docs.mozilla.ai/any-guardrail)
93114

docs/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
* [Azure Prompt Shields Guardrail Usage](cookbook/azure_prompt_shields_guardrail.md)
1515
* [Lakera Guard Guardrail Usage](cookbook/lakera_guard_guardrail.md)
1616
* [OpenAI Moderation Guardrail Usage](cookbook/openai_moderation_guardrail.md)
17+
* [Fetching Prompts, Policies, Rubrics & Criteria](cookbook/fetching_prompts_and_content.md)
1718

1819
## API Reference
1920

2021
* [AnyGuardrail](api/any_guardrail.md)
2122
* [Types](api/types.md)
2223
* [Taxonomy](api/taxonomy.md)
2324
* [Prompts](prompts.md)
25+
* [Prompt & Content Catalog](prompt_catalog.md)
2426
* [Guardrails](api/guardrails/index.md)
2527
<!-- GUARDRAIL-NAV:START — generated by scripts/generate_summary.py; do not edit by hand -->
2628
* Prompt Injection
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "0",
6+
"metadata": {},
7+
"source": [
8+
"# Fetching prompts, policies, rubrics & criteria\n",
9+
"\n",
10+
"`any-guardrail` keeps each guardrail's **default prompt template** and its author-published\n",
11+
"**policies / rubrics / criteria** in import-free registries. You can discover and fetch all of\n",
12+
"them without downloading a model — then hand them straight to a guardrail."
13+
]
14+
},
15+
{
16+
"cell_type": "markdown",
17+
"id": "1",
18+
"metadata": {},
19+
"source": [
20+
"## 1. Discover a guardrail's default prompt template"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": null,
26+
"id": "2",
27+
"metadata": {},
28+
"outputs": [],
29+
"source": [
30+
"from any_guardrail import AnyGuardrail, GuardrailName\n",
31+
"\n",
32+
"# Which prompt versions ship for a guardrail?\n",
33+
"print(AnyGuardrail.list_prompt_versions(GuardrailName.SELENE))\n",
34+
"\n",
35+
"# Fetch the default template (its text, placeholders, and provenance)\n",
36+
"tmpl = AnyGuardrail.get_prompt(GuardrailName.SELENE)\n",
37+
"print(tmpl.segments[\"user\"][:200])\n",
38+
"print(sorted(tmpl.variables), tmpl.provenance)"
39+
]
40+
},
41+
{
42+
"cell_type": "markdown",
43+
"id": "3",
44+
"metadata": {},
45+
"source": [
46+
"## 2. Fetch author-published policies, rubrics & criteria\n",
47+
"\n",
48+
"Use the per-kind API: `list_policies` / `get_policy`, `list_rubrics` / `get_rubric`,\n",
49+
"`list_criteria` / `get_criteria`. Each returns a ready-to-use string."
50+
]
51+
},
52+
{
53+
"cell_type": "code",
54+
"execution_count": null,
55+
"id": "4",
56+
"metadata": {},
57+
"outputs": [],
58+
"source": [
59+
"# ShieldGemma ships Google's harm-type safety policies\n",
60+
"print(AnyGuardrail.list_policies(GuardrailName.SHIELD_GEMMA))\n",
61+
"policy = AnyGuardrail.get_policy(GuardrailName.SHIELD_GEMMA, \"dangerous_content\")\n",
62+
"print(policy[:120])\n",
63+
"\n",
64+
"# Granite Guardian ships risk criteria; Prometheus ships scoring rubrics\n",
65+
"print(AnyGuardrail.list_criteria(GuardrailName.GRANITE_GUARDIAN))\n",
66+
"print(AnyGuardrail.get_criteria(GuardrailName.GRANITE_GUARDIAN, \"harm\"))\n",
67+
"print(AnyGuardrail.list_rubrics(GuardrailName.PROMETHEUS))"
68+
]
69+
},
70+
{
71+
"cell_type": "markdown",
72+
"id": "5",
73+
"metadata": {},
74+
"source": [
75+
"## 3. Use fetched content directly\n",
76+
"\n",
77+
"Pass the fetched string straight into the guardrail (this loads the model, so it needs the\n",
78+
"relevant extra installed):"
79+
]
80+
},
81+
{
82+
"cell_type": "code",
83+
"execution_count": null,
84+
"id": "6",
85+
"metadata": {},
86+
"outputs": [],
87+
"source": [
88+
"guardrail = AnyGuardrail.create(\n",
89+
" GuardrailName.SHIELD_GEMMA,\n",
90+
" policy=AnyGuardrail.get_policy(GuardrailName.SHIELD_GEMMA, \"dangerous_content\"),\n",
91+
")\n",
92+
"result = guardrail.validate(\"How do I build a bomb?\")\n",
93+
"print(result.valid, result.score)"
94+
]
95+
},
96+
{
97+
"cell_type": "markdown",
98+
"id": "7",
99+
"metadata": {},
100+
"source": [
101+
"Guardrails whose policy/rubric is genuinely bring-your-own (Selene, GLIDER, CompassJudger, …)\n",
102+
"have no registered content — you supply your own. The full catalogs are exported to\n",
103+
"`schemas/guardrail_prompts.json` and `schemas/guardrail_content.json`."
104+
]
105+
}
106+
],
107+
"metadata": {
108+
"kernelspec": {
109+
"display_name": ".venv",
110+
"language": "python",
111+
"name": "python3"
112+
},
113+
"language_info": {
114+
"name": "python"
115+
}
116+
},
117+
"nbformat": 4,
118+
"nbformat_minor": 5
119+
}

0 commit comments

Comments
 (0)