跳到主要内容

04 · 扩展、集成、边界与代码地图

本章讲怎么给 LlamaFirewall 加自己的扫描器、怎么接进现有 agent 框架、它有哪些巧妙处和硬边界, 最后给一张可 grep 的代码地图。

1. 写一个自定义扫描器

三步:继承 Scanner → 实现 scan → 用装饰器注册。注册后就能在策略表里用字符串名引用它。

# 示意,基于 examples/demo_customized_scanner_via_open_guardrails.py:32
from llamafirewall import Scanner, ScanResult, ScanDecision, register_llamafirewall_scanner

@register_llamafirewall_scanner("demo_scanner") # 注册名
class DemoScanner(Scanner):
def __init__(self, block_threshold: float = 1.0) -> None:
super().__init__("demo_scanner", block_threshold)

async def scan(self, message, past_trace=None) -> ScanResult:
# 你的检测逻辑;返回统一的 ScanResult
return ScanResult(decision=ScanDecision.ALLOW, reason="ok", score=0.0)

# 之后在策略里用字符串引用:
# LlamaFirewall(scanners={Role.USER: ["demo_scanner"]})

注册机制: register_llamafirewall_scanner(llamafirewall.py:32)是个装饰器工厂,把你的类塞进 模块级 custom_scanner_registry(llamafirewall.py:29),并校验它确实是 Scanner 子类。工厂函数 create_scanner优先查这张表(llamafirewall.py:47)——所以字符串名能覆盖/扩展内置类型。

如果你的检测靠 LLM:继承 CustomCheckScanner

想「让某个大模型按你的 prompt 打分」而不必自己写 API 调用,就继承 CustomCheckScanner (custom_check_scanner.py:23)。它已经封装好:

  • 传入 system_prompt + output_schema(Pydantic 模型)。
  • _evaluate_with_llmLLMClient(utils/base_llm.py:20,底层是 OpenAI 兼容 SDK 的 beta.chat.completions.parse,做结构化输出)。
  • 你只需实现 _get_default_error_response(出错时的兜底)和 _convert_llm_response_to_score (结构化输出 → 0~1 分)。

AlignmentCheck 和 PIICheck 就是这么来的(见第 2 章)。默认后端是 Together API 的 Llama-4-Maverick(custom_check_scanner.py:35-37),但 model_name / api_base_url / api_key_env_var 都能改,所以可以指向任何 OpenAI 兼容端点

2. 接进现有 agent 框架

项目自带两类集成示例(LlamaFirewall/examples/):

集成做法示例文件
OpenAI Agents SDKfirewall.scan_async 包进一个 @input_guardrail,BLOCK 时触发 tripwiredemo_openai_guardrails.pydemo_customized_scanner_via_open_guardrails.py
LangChain / LangGraph在 agent 流程里插入扫描demo_langchain_agent.pydemo_langchain_misaligned.py

OpenAI 集成的关键就一行:tripwire_triggered = (lf_result.decision != ScanDecision.ALLOW) (demo_customized_scanner_via_open_guardrails.py:72)——把 LlamaFirewall 的裁决翻译成框架的护栏信号。

3. 巧妙之处(可借鉴)

  • 角色驱动的策略表:安全策略被压成一张 Role → [Scanner] 的普通 dict,可读、可改、可预设 (config.py)。把「信任级别」建模成「消息来源」,很干净。
  • 懒加载 + 工厂:重依赖(torch / transformers / codeshield / openai)全部按需 import (llamafirewall.py:46scanners/__init__.py:29),装了哪个扫描器才拉哪个依赖。
  • 三档裁决:HUMAN_IN_THE_LOOP_REQUIRED 让「拿不准」有了正式出口,而不是被迫二选一 (llamafirewall_data_types.py:22)。
  • Fail-closed 默认:AlignmentCheck 的审计 LLM 出错时按「疑似被劫持」处理 (alignmentcheck_scanner.py:113)——安全组件该有的保守默认。
  • 抗空格绕过的归一化:PromptGuard 先删空白再按 token 边界补回,压制 i g n o r e 式绕过 (promptguard_utils.py:79)。
  • CodeShield 的 greedy fast 模式:regex 命中即停、semgrep 预扫闸门,为实时压延迟 (insecure_code_detector.py:126,295)。

4. 边界与局限(诚实)

  • 护栏强度 = 你配的策略。默认表里 SYSTEMMEMORY 不扫(llamafirewall.py:93,95); 很多扫描器要你显式配到对应角色才生效。装了库不等于安全。
  • 强依赖外部模型/服务:
    • PromptGuard 要下载 HF 模型(promptguard_utils.py:38);
    • AlignmentCheck / PIICheck 要 TOGETHER_API_KEY,否则 LLMClient 直接抛错 (utils/base_llm.py:48)。这也意味着这两者有网络延迟且把内容发给第三方 API
  • 每次 scan 重建扫描器实例(llamafirewall.py:117):对要加载模型的扫描器,高吞吐下可能反复 重载,库本身不做实例缓存/池化(inferred)。
  • CodeShield 语言靠猜:它对所有支持语言并行试扫(code_shield_scanner.py:57),不做语言识别; 且并非所有语言都有 semgrep(部分只 regex,insecure_code_detector.py:36)。
  • 同步 scan() 不特判 HITL:多扫描器汇总只把 BLOCK 当一票否决,HITL 只能靠分数胜出 (llamafirewall.py:144,见第 1 章 §4)。
  • 实验性组件:AlignmentCheck、PIICheck 在 scanners/experimental/ 下,接口可能变。
  • Regex 默认表很基础:注入模式只匹配 ignore previous/all instructions 一类字面量 (regex_scanner.py:23),真实注入远不止这些——它是补充,不是主防线。

5. 横向对比(evals-observability 货架内)

LlamaFirewall 在本货架里的定位是**「实时护栏 / guardrail」**,和「离线评测 / 可观测」类项目取舍不同:

  • 在线拦截 vs. 离线评测:它跑在请求路径上、要低延迟、给 allow/block 裁决;而评测类项目 (跑基准、算指标)是离线批处理。同仓的 CybersecurityBenchmarks(CyberSec Eval)就是评测那一派。
  • 规则/小模型 vs. LLM-as-judge:它两派都占——PromptGuard/CodeShield 属前者,AlignmentCheck/ PIICheck 属「用 LLM 当裁判」,和很多 LLM-eval 框架用 LLM 打分是同一思路,只是用在在线护栏上。
  • 与 CodeShield 的关系:CodeShield 本是独立静态分析包,LlamaFirewall 把它收编成一个扫描器, 体现「护栏 = 编排既有安全能力」的组合思路。

(链接到总库对应原理与兄弟子库 doc 时,按本货架 INDEX 补全。)

6. 代码地图(导航索引)

主题文件路径关键符号
策略引擎 / 汇总裁决LlamaFirewall/src/llamafirewall/llamafirewall.pyLlamaFirewallscanscan_asyncscan_replay
扫描器工厂 / 懒加载LlamaFirewall/src/llamafirewall/llamafirewall.pycreate_scannerregister_llamafirewall_scannercustom_scanner_registry
数据模型LlamaFirewall/src/llamafirewall/llamafirewall_data_types.pyMessageRoleTraceScanResultScanDecision
策略配置 / 预设LlamaFirewall/src/llamafirewall/config.pyConfigurationUseCasePREDEFINED_USE_CASES
扫描器基类LlamaFirewall/src/llamafirewall/scanners/base_scanner.pyScannerscan
PromptGuardLlamaFirewall/src/llamafirewall/scanners/prompt_guard_scanner.pyPromptGuardScanner
PromptGuard 模型/预处理LlamaFirewall/src/llamafirewall/scanners/promptguard_utils.pyPromptGuardget_jailbreak_score_preprocess_text_for_promptguard
AlignmentCheckLlamaFirewall/src/llamafirewall/scanners/experimental/alignmentcheck_scanner.pyAlignmentCheckScannerSYSTEM_PROMPT_pick_user_input
PIICheckLlamaFirewall/src/llamafirewall/scanners/experimental/piicheck_scanner.pyPIICheckScanner
LLM 打分基类LlamaFirewall/src/llamafirewall/scanners/custom_check_scanner.pyCustomCheckScanner_evaluate_with_llm
LLM 客户端LlamaFirewall/src/llamafirewall/utils/base_llm.pyLLMClientcall
CodeShield 扫描器壳LlamaFirewall/src/llamafirewall/scanners/code_shield_scanner.pyCodeShieldScanner_execute_icd
CodeShield 引擎CodeShield/insecure_code_detector/insecure_code_detector.pyanalyze_regex_analyze_semgrep_analyze_is_semgrep_scan_recommended
Regex 扫描器LlamaFirewall/src/llamafirewall/scanners/regex_scanner.pyRegexScannerDEFAULT_REGEX_PATTERNS
HiddenASCII 扫描器LlamaFirewall/src/llamafirewall/scanners/hidden_ascii_scanner.pyHiddenASCIIScanner_decode_hidden_ascii
CLI 配置助手LlamaFirewall/src/llamafirewall/cli/configure.pyrun_configurecheck_model_availability
OpenAI 集成示例LlamaFirewall/examples/demo_customized_scanner_via_open_guardrails.pyllamafirewall_input_guardrail
对齐检查端到端示例LlamaFirewall/examples/demo_alignmentcheck.pyrun_alignment_checkget_sample_traces