从 0 到 1 开源:基于 FastAPI 和本地大模型打造一个提示词安全网关

背景:大模型时代的"黑产"与痛点

随着生成式 AI 的爆发,大模型开始接管企业核心业务。但随之而来的,是 OWASP 提出的 LLM Top 10 威胁------其中最致命的,就是提示词注入(Prompt Injection)和越狱(Jailbreak)。

作为一个入门小手,我调研了市面上现有的防护方案,发现都有明显的痛点:

  • 传统 WAF:只懂正则,不懂语义,稍微换个近义词或者加个 base64 编码就能绕过。
  • 云端 API 护栏:语义理解强,但企业核心数据要求不出域,合规风险直接拉满。
  • 开源护栏(如 LLM Guard) :部署太重。而且最大的问题是,绝大多数开源护栏在遇到自身组件故障(断网、模型宕机)时,为了业务可用性,默认选择 Fail-Open(静默放行)。这对于安全产品来说,是致命的灾难。

为了解决这些问题,我开发并开源了 PromptGuard ------ 一个纯本地化、零配置的轻量级提示词安全网关。


核心架构:三级融合检测 + 终极自省

系统的核心设计思路是"纵深防御",我把检测链路分成了三层:

  1. 规则层(正则匹配):微秒级响应,拦截低级显式攻击。
  2. 相似度层(TF-IDF):提取字符级 N-gram,计算余弦相似度,拦截变体绕过。
  3. 语义层(本地 LLM):调用本地 Ollama 轻量模型,输出 JSON 判定,拦截极度隐晦的越狱。

💡 关于语义层模型选择的建议: 老实说,受限于我本地的算力,为了能跑通演示,当前项目默认选用的是较弱的轻量级模型(qwen2.5:3b)。但系统底层我做了彻底的模型解耦,只需要改一个环境变量,就能换成更强大的模型。非常建议大家拉取代码后,换成本地更大参数量的模型(如 14B、72B),或者直接接上 GPT-4 的 API 试试。 换了更强的脑子,你会发现它拦长上下文注入的能力直线飙升,代码一行都不用改。

但真正让这套系统与众不同的,是我在工程层面的两个设计:Fail-Closed 状态机 和 正交可观测性审计。


亮点一:Fail-Closed 状态机(拒绝静默放行)

安全产品的底线应该是:"宁可错杀,绝不漏放"。 当 PromptGuard 检测到语义模型不可达(degraded)或者模型输出了乱码(fault)时,系统绝不会默认放行。

核心代码逻辑如下:

python 复制代码
def _llm_score(llm):
    # 如果检测器故障,强制赋予高兜底风险分 0.7
    if (llm or {}).get("status") in ("degraded", "fault"):
        return DEGRADED_SCORE 
    risk = (llm or {}).get("risk", "low")
    return {"high": 0.9, "medium": 0.5, "low": 0.0}.get(risk, 0.0)

0.7 的分数会直接越过审查阈值(0.5),将请求强制拉入 review(人工审查)状态,并直接短路跳过生成阶段(节省算力且防止二次注入)。


亮点二:正交可观测性(解决排障痛点)

传统的日志往往一锅粥,报错了只记一个 error。运维根本分不清是"被黑客攻击了"还是"系统自己挂了"。 所以我把审计日志拆成了三个完全独立(正交)的维度:

  • llm_status:检测链路状态(success / degraded / fault)
  • gen_status:生成链路状态(success / timeout / skipped)
  • action:最终准入判决(allow / review / block)

来看看 Streamlit 界面的四色审计看板:

当黄色(环境降级)事件激增时,运维可以一秒定位是检测模型超时了,还是后端接口挂了。这种微服务级别的链路追踪思维,在轻量级安全工具中极其少见。


避坑探讨:大模型在安全检测中的"局限性"

在实际开发中,我发现把大模型作为安全网关的一环,并非"银弹"。以下是我们在 PromptGuard 中直面的三大局限性:

  1. 模型的"幻觉"与非标准输出 :本地部署的轻量级模型在指令遵循上不如大模型稳定,有时会输出中文的"安全"而不是要求的 high/low。 解法 :除了强约束的 Prompt,底层还写了极严格的类型校验。一旦模型不按套路出牌,系统直接判定为 fault,留存 raw_llm_output 作为案发现场,绝不强行解析。
  2. 长上下文导致的"注意力稀释" :这是我们漏报那 3.4% 的主要原因。攻击者铺垫大量废话把越狱指令藏在最后,小模型容易误判。 解法 :这就是为什么不能只依赖大模型。前置的规则和相似度层能兜底拦截。下一步计划在网关中引入滑动窗口切片检测。
  3. 算力成本与延迟的博弈 :本地小模型单次推理约 4 秒,这对高并发网关是致命的。 解法 :设计了生成阶段成本控制 。高危请求直接 block,完全短路大模型调用。只有"拿不准"的才交给大模型裁决。

工程细节:平滑迁移与离线测试

除了核心架构,项目还内置了许多企业级工程细节:

  • SQLite 平滑迁移 :系统升级时,利用 PRAGMA table_info 自动检测缺失字段并 ALTER TABLE 补全,历史审计数据零丢失。
  • 14 项离线故障注入测试 :基于 pytest 和 unittest.mock,不依赖真实网络,2.4 秒跑完断网、超时、乱码等极端场景,主动证明降级策略的可靠性。
python 复制代码
# 一个典型的故障注入测试
with patch("app.llm_client.httpx.post", side_effect=httpx.ConnectError("err")):
    result = process("今天天气怎么样")
assert result["action"] == "review" # 证明 Fail-Closed 生效

🚀 从 MVP 到企业级:未来的演进路线

目前 PromptGuard 是一个轻量级的 MVP,为了做到"开箱即用",我选用了 SQLite 和本地小模型。但如果要真正落地到高并发的企业私有化环境,可以参考如下:

  1. 存储层:SQLite 演进为 MySQL / PostgreSQL 当前单机文件级数据库在读写并发上有上限。后续会将审计模块的数据库驱动抽象出来,无缝切换到 MySQL 集群。写入时引入消息队列(如 Redis / Kafka)做异步削峰,防止高并发下日志写入阻塞主链路。
  2. 算力层:轻量模型演进为高精模型 / 异构算力集群 只需修改环境变量,即可从 3B 模型切换到企业私有化部署的百亿参数安全大模型;或对接大厂的云端内容风控 API。
  3. 部署架构:单机演进为 K8s Sidecar 将 PromptGuard 打包成 Docker 镜像,以 Sidecar(边车)模式 挂载到业务 Pod 旁边。业务代码无需任何改动,网络流量自动经过网关过滤,实现真正的"安全与业务解耦"。

测试数据与开源地址

在自建的 59 条高覆盖测试集上,PromptGuard 的检测准确率达到了 96.6%。而且我们没有伪造完美的 100%,剩下 3.4% 的漏报精准暴露了长上下文诱导的盲区,这也是未来的迭代方向。

项目已完全开源,包含详细的 README、部署手册和全套测试代码: 🔗 GitHub 地址: github.com/zhni1314/pr...

欢迎各位大佬体验、提 Issue,或者点个 Star 支持一下!如果你也在做大模型安全相关的业务,欢迎在评论区交流探讨!

相关推荐
mr_g2 小时前
一个注解搞定 AGI,两个注解搞定 AMI —— SmartCall 让 Java 对接 Asterisk 简单到离谱
github
sbjdhjd5 小时前
从签名重放到 Agent Harness:一堂安全课程如何把前端逆向、MCP 与工程约束串起来
网络安全·ai·github·agent·webshell·mcp·harness
逛逛GitHub6 小时前
火了两周的 30 万 Star 逆向 GitHub 开源神器,网友都用它来干啥?
github
wflynn8 小时前
GitHub 日榜趋势速报 | 2026-10-18
开源·github
疯狂敲代码的老刘8 小时前
d2r-mobile:3.2千星开源暗黑破坏神2 iOS兼容层,3天冲上GitHub日榜
ios·github
高频因子挖掘机9 小时前
多股票行情为什么容易对不齐?用 Pandas MultiIndex 管理标的、日期与缺失值
后端·github·api
miofly9 小时前
GitHub 日榜趋势速报 | 2026-10-19
开源·github
高频因子挖掘机9 小时前
Python 量化数据接口设计实战:用数据契约解决字段混乱与回测不一致
后端·github·api
u13013018 小时前
GitHub 热榜项目:日榜(2026-10-17)
人工智能·github