atliq/guardex-ai

GitHub: atliq/guardex-ai

一个 Python SDK,为 LLM 应用提供进程内的内容安全分类、PII 检测与 Prompt 注入防御等护栏功能,无需外部 API。

Stars: 5 | Forks: 0

GuardEx

# GuardEx: AI 护栏

PyPI Python CI License

GuardEx 是一个 Python SDK,用于筛查 LLM 的输入和输出中是否存在不安全内容、PII、prompt injection 以及可选的 grounding 检查。所有操作均在进程内运行,无需外部 API。只需大约十行代码,即可将其插入到任何 LLM 调用之前。 ## 快速开始 ``` pip install 'guardex-ai[local]' # adds in-process ML engines ``` 或者从源码安装: ``` git clone https://github.com/atliq/guardex-ai.git cd guardex-ai pip install -e '.[local]' ``` ``` from guardex import Guard guard = Guard() # zero-config, models download on first use result = guard.screen("How do I reset my password?", gate="input") if result.blocked: print(f"Blocked: {result.classify.category} - {result.classify.description}") else: if result.pii.has_pii: print(f"PII detected ({len(result.pii.entities)} entities), masked text:") print(result.text) ``` 首次调用 `Guard()` 会下载约 250 MB 的模型到 `~/.cache/guardex/` 和 `~/.cache/huggingface/hub/`。随后的调用将直接使用已加载的缓存。 三个适配 Colab 的 [notebooks](docs/notebooks/) 演示了快速入门流程、PII 检测和内容安全。 如需完整的 S1-S14 安全分类,请通过 Ollama 运行 LlamaGuard(参见下方的说明)。如果未安装 Ollama,GuardEx 将使用 ONNX 快速网关。Grounding 为可选功能,需额外下载约 700 MB 的 NLI 模型;请参阅[配置](#configuration)以更改这两项的默认设置。 ## 异步 ``` import asyncio from guardex import Guard async def main(): async with Guard() as guard: result = await guard.ascreen("What's your refund policy?", gate="input") print(result.action, result.classify.category) asyncio.run(main()) ``` 每个同步方法都有对应的异步版本(`ascreen`、`ascreen_batch`、`acheck_grounding`、`ascreen_grounded`、`astream`)。在本地模式下,它们通过 `asyncio.to_thread` 桥接到同步执行,因此您无需部署服务器。 ## PII 保险库(可逆 token 化) 当 LLM 需要将个人数据回显给用户时(例如“向...发送确认信息”),掩码并不是合适的工具。Vault token 可以将占位符映射回原始值: ``` from guardex import Guard, PIIVault guard = Guard() vault = PIIVault() text = "Send a confirmation to alice@example.com" r = guard.screen(text, gate="input") # vault_text 原地修改 `vault` vaulted_text, _ = vault.vault_text(text, r.pii) # vaulted_text == "Send a confirmation to {{pii:email:a3f9b2...}}" # 将 vaulted_text 与 LLM 一起使用;模型永远不会看到该 email。 llm_reply = call_my_llm(vaulted_text) # 在展示给用户之前进行恢复。 final_reply = vault.restore(llm_reply) ``` 对于流式响应,请使用 `Guard.astream(..., vault=vault, restore_mode="buffered")` 以便在数据块边界处正确还原 token。流式输出网关默认不会对 PII 进行掩码处理;如有需要,请传入 `mask_output_pii=True`。 ## 策略 `GuardExPolicy` 是单一的配置对象。常用的配置项如下: ``` from guardex import Guard, GuardExPolicy, TopicScope policy = GuardExPolicy( blocked_categories=["S1", "S3", "S4", "S9", "S11"], # default-blocked set block_on_unsafe_input=True, block_on_unsafe_output=True, pii_enabled=True, pii_action="mask", # or "block" pii_threshold=0.85, topic_scope=TopicScope( topics=["customer support", "product help"], scope_width="moderate", ), audit_logging=True, ) guard = Guard(policy=policy) ``` 从 YAML 加载策略: ``` policy = GuardExPolicy.from_yaml("guardex_policy.yaml") ``` `from_yaml` 会读取一个扁平的策略文件(`pii_action`、`blocked_categories`、 `topic_scope`、`safety_routes` 等)。这是一个**与** `guardex.yaml` **不同的文件**, 后者用于配置本地 ML 引擎(模型仓库、缓存目录),并且会从您的项目根目录自动加载。 `guardex.yaml.example` 是它的模板。有关这两者的说明,请参阅 [configuration.md](docs/guides/configuration.md)。 需要特定领域的 PII 实体(如病历号、员工 ID)? `GuardExPolicy(pii_custom_regex={...})` 可以添加您自定义的标签 → 正则表达式规则, 这在本地和服务器模式下均可用。请参阅 [PII 检测:自定义正则表达式模式](docs/guides/pii-detection.md#custom-regex-patterns)。 ## 功能 | 功能 | 描述 | 延迟(热启动) | |---|---|---| | 安全分类 | 二元毒性网关(ONNX,默认开启);通过 LlamaGuard 3 支持完整的 S1-S14 类别(需可选的 Ollama) | ~20 ms / ~500 ms | | PII 检测与掩码 | 涵盖 5 大类别的 31 种实体类型(GLiNER) | ~15 ms | | Prompt injection 防御 | 客户端正则表达式(31 种模式) | ~1 ms | | 幻觉检测 | NLI + embedding 混合模式,支持断言分解(需主动开启) | ~50-200 ms | | 主题范围限制 | 基于 embedding 的主题过滤 | ~5 ms | | 流式传输支持 | 缓冲 + 流安全的 Vault 还原 | 按数据块 | | 多轮对话感知 | `ConversationGuard` 可检测跨轮次的冲突升级 | 按对话轮次 | | 自定义安全路由 | 通过示例话语定义用户自定义的黑名单类别 | ~5 ms | 默认情况下,ONNX 快速网关会做出二元的安全/有毒判定:它能可靠地捕获有毒语言,但无法识别措辞中性的有害请求(例如“我该如何制作武器”)。若要实现基于 S1-S14 类别的详细判定并覆盖此类请求,需要通过 Ollama 启用可选的 LlamaGuard 层(请参阅“快速开始”下的说明)。延迟数据是在 Apple M2 上测得的;冷启动会增加模型下载时间(未启用 grounding 时约 250 MB,启用时约 950 MB)。 ## 集成示例 ### Gemini ``` pip install google-genai ``` ``` from google import genai from guardex import Guard, GuardExViolation guard = Guard() client = genai.Client() # reads GEMINI_API_KEY user_msg = "How do I reset my password?" try: input_text = guard.screen_or_raise(user_msg, gate="input") except GuardExViolation as e: print(f"Refused at input gate: {e.category}") raise response = client.models.generate_content( model="gemini-2.5-flash", contents=input_text, ) try: safe_output = guard.screen_or_raise(response.text, gate="output") except GuardExViolation as e: print(f"Refused at output gate: {e.category}") raise print(safe_output) ``` 这种双层网关模式适用于任何提供商——只需替换模型调用,保留护栏即可。 ### 带有幻觉检测的 RAG Grounding 是可选功能——设置 `GUARDEX_GROUNDING_ENABLED=1` 或将 `grounding_mode=` 传递给 `screen_grounded`。 ``` from guardex import Guard guard = Guard() screen_result, grounding = guard.screen_grounded( response_text=llm_response, sources=retrieved_chunks, gate="output", grounding_mode="accuracy", ) if screen_result.blocked: return "I can't help with that." if grounding.hallucinated: print(f"Faithfulness {grounding.faithfulness_score:.0%}; flagging for human review.") for s in grounding.hallucinated_sentences: print(f" - {s.sentence}") ``` ### 对话护栏(升级检测) ``` from guardex import Guard from guardex.conversation import ConversationGuard guard = Guard() cg = ConversationGuard(guard, window=6) result = cg.screen_turn("user", user_message) if result.blocked: return guard.policy.refusal_messages.get( result.classify.category, "I can't help with that.", ) llm_reply = call_llm(user_message) cg.screen_turn("assistant", llm_reply) ``` ## 服务器模式 未带 `api_key` 或 `base_url` 的 `Guard()` 会在进程内运行模型(本地 模式)。传入其中任意一个,SDK 就会转而通过 HTTP 与 GuardEx 服务器通信: ``` guard = Guard(base_url="http://your-host:8001") # your self-hosted server ``` SDK 内置了一个参考服务器——与 FastAPI 背后的本地 pipeline 相同: ``` pip install 'guardex-ai[local,server]' guardex-server --host 0.0.0.0 --port 8001 ``` 模型在启动时加载;一旦 pipeline 准备就绪,服务器便开始接收流量。 它没有内置身份验证:请在私有网络中运行,或者在前面加上 您自己的身份验证代理。仅当您的部署在 endpoint 前设置了身份验证时, 才需要传入 `api_key=`;目前没有 GuardEx 托管的云服务。 ## 架构 ``` Guard() | | in-process v LocalRunner pipeline | +-- Input validation (length / repetition / character flood) +-- Keyword gate (zero-latency hard blocks for passive ideation) +-- Text normalization (homoglyph + invisible-char removal) +-- Safety classifier | +-- Layer 0: ONNX fast gate | +-- Layer 1: LlamaGuard 3 via Ollama (optional, ~500 ms) +-- PII detection (GLiNER, 31 entity types) +-- Topic scope (sentence-transformers embedding) +-- Custom safety routes (user-defined blocklist categories) +-- Grounding / hallucination (DeBERTa NLI + embedding hybrid, opt-in) +-- Prompt injection (client-side regex, 31 patterns) ``` ## 安全类别 GuardEx 原样使用了标准的 LlamaGuard 3 / MLCommons 分类体系(`S1`-`S14`), 并增加了由输入验证器发出的 GuardEx 专用 `S0`。默认拦截的集合如下: | 代码 | 类别 | |---|---| | S1 | 暴力犯罪 | | S3 | 性犯罪 | | S4 | 儿童性剥削 | | S9 | 无差别武器 | | S11 | 自杀与自残 | 有关完整的 S0-S14 对照表以及如何更改被拦截的类别,请 参阅 [safety-categories.md](docs/guides/safety-categories.md)。 ## 配置 您可以通过环境变量(`GUARDEX_*`)或项目根目录下的 `guardex.yaml` 来覆盖默认设置。有关其支持的本地引擎设置,请参见 `guardex.yaml.example`。常见的覆盖配置如下: ``` export GUARDEX_CASCADE_MODE=speed # skip LlamaGuard, use ONNX only export GUARDEX_GROUNDING_ENABLED=1 # enable NLI grounding (~700 MB) export GUARDEX_CACHE_DIR=/data/guardex # custom model cache export GUARDEX_ONNX_USE_GPU=1 # CUDA for ONNX classifier ``` ## 本 SDK 不涵盖的功能 - 图像、音频或视频审核 - 角色/权限模型(无内置 RBAC) - 跨语言安全分类(仅限英语模式) - 托管的云服务(在进程内运行或自行托管参考服务器) - 从远程存储实时热加载策略(请使用 YAML + 重启的方式) ## 贡献 欢迎提交 Bug 报告、功能请求和 Pull Request。在提交 PR 之前,请阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 以了解开发 环境设置、分支策略和代码风格要求。对于安全问题, 请遵循 [SECURITY.md](SECURITY.md) 中的负责任的披露流程。 请勿就安全漏洞发布公开的 issue。 ## 许可证 Apache 2.0。详情请参阅 [LICENSE](LICENSE)。
标签:AI安全, AI风险缓解, Chat Copilot, Clair, CNCF毕业项目, Naabu, PII检测, Python SDK, 内容安全, 提示词注入防御, 逆向工具