Constitutional 规则引擎:声明式约束与修订 本节摘要:一条规则是「名字 + 谓词 + 解释」,缺一不是规则而是「感觉」。分类器覆盖可识别的失败,规则引擎覆盖契约性的:编码助手要「每个含代码的响应必须以可运行块或显式假设结尾」;客服机器人要「每次拒绝必须提供下一步」。这些不是天然分类器目标,而是对响应、对话、系统策略的谓词,且要让非工程师可读。本节用声明式 YAML 宪法文件(version control 里、独立评审流程),每规则有 / / / / ;引擎加载、对候选输出评估每规则、返回每触发规则的 ;用 / / 组合谓词表达「若响应含代码,必须以可运行块结尾且不引用内部专用库」。
本节摘要:一条规则是「名字 + 谓词 + 解释」,缺一不是规则而是「感觉」。分类器覆盖可识别的失败,规则引擎覆盖契约性的:编码助手要「每个含代码的响应必须以可运行块或显式假设结尾」;客服机器人要「每次拒绝必须提供下一步」。这些不是天然分类器目标,而是对响应、对话、系统策略的谓词,且要让非工程师可读。本节用声明式 YAML 宪法文件(version control 里、独立评审流程),每规则有
name/predicate/severity/explanation/fix;引擎加载、对候选输出评估每规则、返回每触发规则的Violation;用all_of/any_of/not_组合谓词表达「若响应含代码,必须以可运行块结尾且不引用内部专用库」。另一半是修订:只拦的规则引擎是半成品,提议修复的才操作上有用——起草响应、引擎标违规、修复器产修订响应、引擎二次确认修订满足规则,附逐行结构化 diff 供人工审计。读完本节,你能说清为什么规则须声明式(可读、可版本、可评审),以及为何「不讨论竞争对手定价」这类约束归规则引擎而非分类器。
对应原课程:Phase 19 · Lesson 86 ·
constitutional-rules-engine(原英文phases/19-capstone-projects/86-constitutional-rules-engine/docs/en.md)。本节属第 20 章「毕业项目」的安全赛道。
阅读完本节,你应当能够:
name + predicate(原子:contains_regex/not_contains_regex/ends_with_regex/starts_with_regex/max_words/min_words;组合:all_of/any_of/not_)+ severity + explanation + fix。applies_when,不适用记 not_applicable,否则评估 must 产 pass/violation。分类器覆盖可识别的失败,规则引擎覆盖契约性的。写编码助手的团队要约束「每个含代码的响应必须以可运行块或显式假设结尾」;跑客服机器人的团队要「每次拒绝必须提供下一步」。这些不是天然分类器目标,是对响应、对话、系统策略的谓词,且要让非工程师可读。
诚实表示是声明式文件。宪法住在 YAML 里,与代码并列、在版本控制里、有独立评审流程。每规则有 name、predicate、severity、explanation 模板。引擎加载文件、对候选输出评估每规则、返回每触发规则的结构化 Violation。本节的规则引擎用 all_of/any_of/not_ 组合谓词,使单规则可表达「若响应含代码,必须以可运行块结尾且不引用内部专用库」。
另一半是修订。只拦的规则引擎是半成品;提议修复的才操作上有用:助手起草响应、引擎标违规、修复器产修订、引擎确认修订满足规则。本节随附最小修复器(每规则正则替换)与结构化 diff(草稿与修订间的逐行 add/remove/edit)。
- name: end-with-runnable-or-assumption severity: medium applies_when: contains_regex: '```python' must: any_of: - ends_with_regex: '```\s*$' - contains_regex: 'assumption:' explanation: "含代码的响应必须以闭合围栏或显式假设结尾。" fix: append_if_missing: "\n\nAssumption: 示例输入有效。"
谓词原子:contains_regex、not_contains_regex、ends_with_regex、starts_with_regex、max_words、min_words。组合:all_of、any_of、not_。引擎先评估 applies_when,不适用则违规记 not_applicable;否则评估 must,产 pass 或 violation。
严重度 low/medium/high,镜像 85 节。下游门(87 节)把 high 规则违规等同于 high 分类器 verdict:block。
声明式操作列表:append_if_missing、prepend_if_missing、replace_regex。每操作按规则名映到一个变换。修复器故意限于局部编辑;结构性改写属单独的「拒绝并帮助」层(本节不覆盖)。diff 在原稿与修订间算,是 Change 记录列表,含 op(add/remove/edit)与相关文本,供人工评审长期审计修复器行为。
def eval_predicate(pred, text): if "contains_regex" in pred: return bool(re.search(pred["contains_regex"], text)) if "ends_with_regex" in pred: return bool(re.search(pred["ends_with_regex"] + "$", text)) if "all_of" in pred: return all(eval_predicate(p, text) for p in pred["all_of"]) if "any_of" in pred: return any(eval_predicate(p, text) for p in pred["any_of"]) if "not_" in pred: return not eval_predicate(pred["not_"], text) # ... max_words / min_words / starts_with_regex / not_contains_regex raise ValueError(f"未知谓词: {pred}") def evaluate_rule(rule, draft): if not eval_predicate(rule["applies_when"], draft): return Violation(rule["name"], status="not_applicable") return Violation(rule["name"], status="pass" if eval_predicate(rule["must"], draft) else "violation", severity=rule["severity"], explanation=rule["explanation"])
code/rules.yml 持宪法;code/main.py 的加载器接 YAML(PyYAML 可用时)或 JSON(内置);本节随附 rules.yml 被两路径都解析测过。main.py 定义 Engine、Fixer、diff;组合递归评估,any_of 短路。
no-empty-refusal(medium):拒绝必须含建议或重定向。end-with-runnable-or-assumption(medium):含代码响应必须干净收尾。no-pii-in-examples(high):示例数据不得含邮箱或电话形。cite-when-asserting-fact(low):以「据」开头的行必须含括号引用。no-internal-library-leak(high):输出不得出现 internal-only、policybot-internal。bounded-length(low):响应不得超 800 词。业界对比:Anthropic 的 Constitutional AI(规则作为批评与修订的种子)、NeMo Guardrails 的 Colang 规则、Llama Guard 的策略提示、Guardrails AI 都把契约约束做成声明式规则。它们的共识与本节一致:规则须名字+谓词+解释、声明式可版本可评审、严重度对齐分类器、修复器+diff 让约束操作上有用。差别在谓词语言(本节正则+组合 vs Colang 的对话脚本 vs CA 的自然语言批评),但「规则即数据、引擎即评估器」形状一致。
outputs/rules_report.json:草稿经引擎、修复、diff 的全报告,87 节安全门 post-gen 阶段消费。code/rules.yml(宪法即数据):六条规则,加规则即加 YAML 条目,经独立评审流程。Engine + Fixer + diff:可独立用于任何「谓词约束 + 修订 + 审计」场景。运行 python3 main.py:demo 跑三条草稿响应过引擎、打印违规、跑修复器、打印 diff、写 outputs/rules_report.json;一条固定样例有不适用的规则(草稿无代码块),报告对该规则显式记 not_applicable,让团队看到引擎显式评估了它。
下一节是本赛道与全书的收官:「端到端安全门」——把 82~86 节的部件组装成 pre-gen/during-gen/post-gen 三检查点的门,一个聚合表、每请求一条审计轨迹;其过渡段做全书从第 1 章到第 20 章的完整收尾。