<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>架构 on WYF 的技术博客</title><link>https://saflyer.cn/tags/%E6%9E%B6%E6%9E%84/</link><description>Recent content in 架构 on WYF 的技术博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 14 Sep 2026 10:03:15 +0800</lastBuildDate><atom:link href="https://saflyer.cn/tags/%E6%9E%B6%E6%9E%84/index.xml" rel="self" type="application/rss+xml"/><item><title>模型安全检测 03：JoySafety 技术架构与业务模块分析</title><link>https://saflyer.cn/posts/joysafety-arch-analysis/</link><pubDate>Mon, 14 Sep 2026 10:03:15 +0800</pubDate><guid>https://saflyer.cn/posts/joysafety-arch-analysis/</guid><description>&lt;img src="https://saflyer.cn/posts/joysafety-arch-analysis/cover.webp" alt="Featured image of post 模型安全检测 03：JoySafety 技术架构与业务模块分析" /&gt;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;前置阅读&lt;/strong&gt;：安全编排框架-4（Mac 本地部署实操笔记）——部署视角的容器清单和两个时期划分&#10;&lt;strong&gt;日期&lt;/strong&gt;：2026-09-13&#10;&lt;strong&gt;素材来源&lt;/strong&gt;：JoySafety 源码通读（safety/ 目录全模块）&#10;&lt;strong&gt;读者定位&lt;/strong&gt;：已部署成功、想理解&amp;quot;它到底是怎么跑起来的&amp;quot;的读者；后续要写自定义策略、自定义能力的读者&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="一张图看懂全局"&gt;&lt;a href="#%e4%b8%80%e5%bc%a0%e5%9b%be%e7%9c%8b%e6%87%82%e5%85%a8%e5%b1%80" class="header-anchor"&gt;&lt;/a&gt;〇、一张图看懂全局&#10;&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-0-1"&gt;&lt;a class="lnlinks" href="#hl-0-1"&gt; 1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-2"&gt;&lt;a class="lnlinks" href="#hl-0-2"&gt; 2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-3"&gt;&lt;a class="lnlinks" href="#hl-0-3"&gt; 3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-4"&gt;&lt;a class="lnlinks" href="#hl-0-4"&gt; 4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-5"&gt;&lt;a class="lnlinks" href="#hl-0-5"&gt; 5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-6"&gt;&lt;a class="lnlinks" href="#hl-0-6"&gt; 6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-7"&gt;&lt;a class="lnlinks" href="#hl-0-7"&gt; 7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-8"&gt;&lt;a class="lnlinks" href="#hl-0-8"&gt; 8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-9"&gt;&lt;a class="lnlinks" href="#hl-0-9"&gt; 9&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-10"&gt;&lt;a class="lnlinks" href="#hl-0-10"&gt;10&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-11"&gt;&lt;a class="lnlinks" href="#hl-0-11"&gt;11&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-12"&gt;&lt;a class="lnlinks" href="#hl-0-12"&gt;12&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-13"&gt;&lt;a class="lnlinks" href="#hl-0-13"&gt;13&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-14"&gt;&lt;a class="lnlinks" href="#hl-0-14"&gt;14&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-15"&gt;&lt;a class="lnlinks" href="#hl-0-15"&gt;15&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-16"&gt;&lt;a class="lnlinks" href="#hl-0-16"&gt;16&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-17"&gt;&lt;a class="lnlinks" href="#hl-0-17"&gt;17&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-18"&gt;&lt;a class="lnlinks" href="#hl-0-18"&gt;18&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-19"&gt;&lt;a class="lnlinks" href="#hl-0-19"&gt;19&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-20"&gt;&lt;a class="lnlinks" href="#hl-0-20"&gt;20&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-21"&gt;&lt;a class="lnlinks" href="#hl-0-21"&gt;21&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-22"&gt;&lt;a class="lnlinks" href="#hl-0-22"&gt;22&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-23"&gt;&lt;a class="lnlinks" href="#hl-0-23"&gt;23&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-24"&gt;&lt;a class="lnlinks" href="#hl-0-24"&gt;24&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-25"&gt;&lt;a class="lnlinks" href="#hl-0-25"&gt;25&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-26"&gt;&lt;a class="lnlinks" href="#hl-0-26"&gt;26&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-27"&gt;&lt;a class="lnlinks" href="#hl-0-27"&gt;27&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────────────────────┐&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 配置期（写配置） │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ quickstart 脚本 / 运维人员 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ▼ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ safety-admin (8006, Java/SpringBoot) │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 原子能力/业务/DAG策略/敏感词/知识库 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ 写入（版本化状态机） │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ▼ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ MySQL ──────────┐ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────────────────┼──────────────────┘&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ① api 每 60s HTTP 轮询 admin&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 拉取 online 配置（不直连 MySQL！）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────┼──────────────────┐&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 执行期（跑审核） ▼ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 业务方 ──HTTP/HMAC-SHA1──► safety-api (8007, Java/SpringBoot) │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ DAG 引擎逐节点执行 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌───────────┬─────┴──────┬───────────────┐ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ▼ ▼ ▼ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ safety-keywords safety-bert safety-knowledge (fasttext)│&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ AC自动机敏感词 BERT分类 知识库/RAG代答/多轮 默认未启用 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ▼ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ MySQL Vearch向量库 + 本地bge embedding │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ + OpenAI兼容LLM │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Redis: 会话历史 / free_taxi任务队列 / 分布式锁 / 结果缓存 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────────────────┘&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;三条最重要的架构认知&lt;/strong&gt;（后面所有细节都围绕这三条）：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;admin 不在请求链路上&lt;/strong&gt;。它只负责&amp;quot;配置期&amp;quot;写库和下发配置，挂了对线上审核零影响。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;api 不直连 MySQL&lt;/strong&gt;。safety-api 通过 HTTP 轮询 admin 的 &lt;code&gt;/config/defense/api/conf&lt;/code&gt; 接口拿全量 online 配置（默认 60s 一次），这是&amp;quot;改配置不生效、重启 api 才行&amp;quot;（笔记-4 坑 5）的根因。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;skill 服务全部无状态、HTTP 解耦&lt;/strong&gt;。bert/keywords/knowledge 只是&amp;quot;会干活的工具人&amp;quot;，编排逻辑全在 safety-api 的 DAG 引擎里。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="一模块全景表"&gt;&lt;a href="#%e4%b8%80%e6%a8%a1%e5%9d%97%e5%85%a8%e6%99%af%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;一、模块全景表&#10;&lt;/h2&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;模块&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;语言/框架&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;角色&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;一句话职责&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-basic&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;纯 Java 库（无 Spring）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;核心 jar&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DAG 引擎抽象（Function/Router/Node）、会话上下文、签名工具，被 api/admin 依赖&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-api&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Java / Spring Boot 2.0.9&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;执行层&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;对外审核接口、DAG 构建与执行、free_taxi 异步任务体系、配置动态加载&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-admin&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Java / Spring Boot + MyBatis&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;管理层&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;配置 CRUD + 版本化状态机 + 配置下发 API&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-keywords&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Java / Spring Boot&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;能力层&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;敏感词检测（AC 自动机 + 正则倒排加速）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-bert&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Python / Tornado 多进程&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;能力层&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;BERT 分类模型推理（HF transformers）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-fasttext&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Python / Flask+gunicorn&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;能力层&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;FastText 分类（&lt;strong&gt;默认不启用&lt;/strong&gt;，不在根 compose 里）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-knowledge&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Python / Tornado（20 进程）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;能力层&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;知识库向量检索、RAG 代答、多轮对话检测&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;safety-demo&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Python/Go/Java&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;示例&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;三种语言调 Defense API 的签名示例&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;example/&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Python 脚本&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;初始化&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;一次性灌演示数据（建向量库→知识入库→注册能力→建业务→配策略）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;strong&gt;批注&lt;/strong&gt;：Java 侧用的是 Spring Boot 2.0.9（2018 年的版本）+ Jedis 2.5.2 + fastjson 混用，技术栈偏老旧，二开时依赖升级是个工程量。Python 侧反而现代：Tornado 多进程、onnxruntime、HF transformers。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="二safety-basicdag-引擎的抽象层"&gt;&lt;a href="#%e4%ba%8csafety-basicdag-%e5%bc%95%e6%93%8e%e7%9a%84%e6%8a%bd%e8%b1%a1%e5%b1%82" class="header-anchor"&gt;&lt;/a&gt;二、safety-basic：DAG 引擎的抽象层&#10;&lt;/h2&gt;&lt;p&gt;包根 &lt;code&gt;com.jd.security.llmsec.core&lt;/code&gt;，是整个框架的&amp;quot;定义层&amp;quot;：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;子包&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;关键类&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;职责&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;engine&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Function&lt;/code&gt; 接口、&lt;code&gt;AbstractFunction&lt;/code&gt;（模板方法）、&lt;code&gt;Node&lt;/code&gt;、&lt;code&gt;Router&lt;/code&gt; 接口&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DAG 的三要素抽象&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;engine.routers&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;7 种 Router 实现&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;groovy / stupid_end / simple_next / keyword / risk_end / user_end / robot_end&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;session&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;SessionContext&lt;/code&gt;、&lt;code&gt;ResponseMode&lt;/code&gt;、&lt;code&gt;CheckConf&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;一次审核的会话上下文（groovy 脚本里的 &lt;code&gt;ctx&lt;/code&gt; 就是它）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;check&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;RiskCheckType&lt;/code&gt; 枚举 + 各 &lt;code&gt;RiskCheckResult&lt;/code&gt; 子类&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;检测结果类型体系（keyword/single_label_pred/rag_answer/parallel…）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;conf&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;NodeConfig&lt;/code&gt;、&lt;code&gt;FunctionConfig&lt;/code&gt;、&lt;code&gt;RouterConfig&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DAG 节点的配置 POJO（YAML 反序列化目标）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;auth&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;AuthRequest.basicCheck()&lt;/code&gt;、&lt;code&gt;AuthControlConf&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;鉴权模型&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;util&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;SignUtil&lt;/code&gt;（HMAC-SHA1）、&lt;code&gt;GroovyHelper&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;签名、groovy 引擎工厂&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;strong&gt;核心抽象就三个&lt;/strong&gt;：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-1-1"&gt;&lt;a class="lnlinks" href="#hl-1-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-2"&gt;&lt;a class="lnlinks" href="#hl-1-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-3"&gt;&lt;a class="lnlinks" href="#hl-1-3"&gt;3&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SessionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RiskCheckResult&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 干活：调模型/查词库/问知识库&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SessionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;下一个&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;或&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;链路结束&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NodeConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 节点 = 配置 + 能力 + 路由&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键认知：它名义上叫 DAG，实际是&amp;quot;链式逐跳&amp;quot;&lt;/strong&gt;。节点之间没有 Edge 实体类——边由 Router 返回的下一个 nodeId 隐式表达；执行就是 &lt;code&gt;while (curNode != null) { curNode.run(ctx); curNode = curNode.next(ctx); }&lt;/code&gt;。真正的并行只存在于 &lt;code&gt;parallel&lt;/code&gt; 虚拟节点&lt;strong&gt;内部&lt;/strong&gt;（一个节点里并发跑多个 Function 再归约），不存在图上并发分支的汇合调度。理解这点对写策略很重要：&lt;strong&gt;分支逻辑全靠 groovy 脚本里的 if-else 返回不同 nodeId&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="三safety-api请求链路与执行引擎"&gt;&lt;a href="#%e4%b8%89safety-api%e8%af%b7%e6%b1%82%e9%93%be%e8%b7%af%e4%b8%8e%e6%89%a7%e8%a1%8c%e5%bc%95%e6%93%8e" class="header-anchor"&gt;&lt;/a&gt;三、safety-api：请求链路与执行引擎&#10;&lt;/h2&gt;&lt;h3 id="31-入口与处理链"&gt;&lt;a href="#31-%e5%85%a5%e5%8f%a3%e4%b8%8e%e5%a4%84%e7%90%86%e9%93%be" class="header-anchor"&gt;&lt;/a&gt;3.1 入口与处理链&#10;&lt;/h3&gt;&lt;p&gt;唯一对外接口：&lt;code&gt;DefenseApiV2Controller&lt;/code&gt;（&lt;code&gt;safety-api/.../contoller/DefenseApiV2Controller.java:33&lt;/code&gt;）&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-2-1"&gt;&lt;a class="lnlinks" href="#hl-2-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-2"&gt;&lt;a class="lnlinks" href="#hl-2-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;POST /llmsec/api/defense/v2/{accessKey}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;POST /llmsec/api/defenseResult/v2/{accessKey} ← 主动拉异步结果&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;一次请求的处理链：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-3-1"&gt;&lt;a class="lnlinks" href="#hl-3-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-2"&gt;&lt;a class="lnlinks" href="#hl-3-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-3"&gt;&lt;a class="lnlinks" href="#hl-3-3"&gt;3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-4"&gt;&lt;a class="lnlinks" href="#hl-3-4"&gt;4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-5"&gt;&lt;a class="lnlinks" href="#hl-3-5"&gt;5&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;checkParams（参数校验）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → rateLimited（Guava RateLimiter，按 accessKey+accessTarget 内存级限流）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → verify（HMAC-SHA1 验签）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → preProcess（OpenAI 格式解析、7000 字截断）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 按 responseMode 分派：sync / free_taxi / http / mq&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="32-鉴权hmac-sha1"&gt;&lt;a href="#32-%e9%89%b4%e6%9d%83hmac-sha1" class="header-anchor"&gt;&lt;/a&gt;3.2 鉴权：HMAC-SHA1&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;签名字符串：&lt;code&gt;accessKey=..&amp;amp;accessTarget=..&amp;amp;requestId=..&amp;amp;timestamp=..&amp;amp;plainText=..&lt;/code&gt;，用业务的 &lt;code&gt;secretKey&lt;/code&gt; 做 HmacSHA1 → Base64（&lt;code&gt;safety-basic/.../core/util/SignUtil.java:36&lt;/code&gt;）&lt;/li&gt;&#10;&lt;li&gt;secretKey 存在 admin 的 &lt;code&gt;business_info.secret_key&lt;/code&gt;，api 通过配置轮询拿到&lt;/li&gt;&#10;&lt;li&gt;timestamp 超过业务配置的 &lt;code&gt;expireSeconds&lt;/code&gt; 直接拒绝（防重放）&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;特赦&lt;/strong&gt;：accessKey 以 &lt;code&gt;test&lt;/code&gt; 开头跳过验签（&lt;code&gt;DefenseApiV2Controller.java:74&lt;/code&gt;）——这就是演示业务能免签名调通的原因&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="33-dag-的构建与执行"&gt;&lt;a href="#33-dag-%e7%9a%84%e6%9e%84%e5%bb%ba%e4%b8%8e%e6%89%a7%e8%a1%8c" class="header-anchor"&gt;&lt;/a&gt;3.3 DAG 的构建与执行&#10;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;构建&lt;/strong&gt;（&lt;code&gt;FunctionChainBuilderImpl.java:73&lt;/code&gt;）：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-4-1"&gt;&lt;a class="lnlinks" href="#hl-4-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-2"&gt;&lt;a class="lnlinks" href="#hl-4-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-3"&gt;&lt;a class="lnlinks" href="#hl-4-3"&gt;3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-4"&gt;&lt;a class="lnlinks" href="#hl-4-4"&gt;4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-5"&gt;&lt;a class="lnlinks" href="#hl-4-5"&gt;5&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;YAML 节点数组 → 先建全部 Node → 逐个节点：&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ① FunctionUtil.doMerge() 合并 ref 引用的原子能力模板（map 递归深合并）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ② 反射实例化 Function（查 FunctionRegistry.FUNC_MAP）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ③ 按 Router.ROUTER_MAP 反射构造 Router（注入 nodeMap）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ root 节点存 rootMap，按业务名索引&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;执行&lt;/strong&gt;（&lt;code&gt;FunctionExecutorImpl.doExecute():289&lt;/code&gt;）：就是从 root 开始的 while 循环逐跳，每轮先检查整体超时，节点异常按 &lt;code&gt;ignoreError&lt;/code&gt; 决定抛出或跳过，router 返回 null 即结束。router 脚本通常直接改写 &lt;code&gt;ctx.curResult&lt;/code&gt; 后 return null 终结链路。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;parallel 并行节点&lt;/strong&gt;（&lt;code&gt;ParallelFunction.java:41&lt;/code&gt;）：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;静态线程池：200 线程 / 队列 1 / CallerRunsPolicy（满了让调用线程自己跑，变相背压）&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;doRun()&lt;/code&gt; 把各子 Function submit 后，&lt;strong&gt;按各自的 &lt;code&gt;timeoutMilliseconds&lt;/code&gt; 逐个 &lt;code&gt;Future.get(timeout)&lt;/code&gt; 收取&lt;/strong&gt;，剩余预算递减——这就是笔记-4 坑 4&amp;quot;两层超时&amp;quot;里第①层的实现位置&lt;/li&gt;&#10;&lt;li&gt;归约策略三选一：&lt;code&gt;no_reduce&lt;/code&gt; / &lt;code&gt;first_risk&lt;/code&gt; / &lt;code&gt;groovy_script&lt;/code&gt;（脚本 bindings：&lt;code&gt;ctx/conf/retMap&lt;/code&gt;）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="34-三层超时体系笔记-4-坑-4-的完整答案"&gt;&lt;a href="#34-%e4%b8%89%e5%b1%82%e8%b6%85%e6%97%b6%e4%bd%93%e7%b3%bb%e7%ac%94%e8%ae%b0-4-%e5%9d%91-4-%e7%9a%84%e5%ae%8c%e6%95%b4%e7%ad%94%e6%a1%88" class="header-anchor"&gt;&lt;/a&gt;3.4 三层超时体系（笔记-4 坑 4 的完整答案）&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;层&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;位置&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;默认值&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;超时后果&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;整体 DAG&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;业务配置的 &lt;code&gt;userCheckConf/robotCheckConf.timeoutMilliseconds&lt;/code&gt;，主循环每节点前检查&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1000ms&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;抛 exec_timeout&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;单 Function HTTP&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;function 配置 &lt;code&gt;timeoutMilliseconds&lt;/code&gt; → OkHttp callTimeout&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;注册时定（2000）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;该节点结果丢弃&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;parallel 内部&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Future.get(剩余预算)&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同上&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;该子项结果丢弃&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Mac 上 BERT 推理 ~1.7s（并行争抢 CPU 时 3.3s），三层默认值全部不够——所以坑 4 要同时改两层。&lt;/p&gt;&#10;&lt;h3 id="35-四种-responsemode-与-free_taxi-详解"&gt;&lt;a href="#35-%e5%9b%9b%e7%a7%8d-responsemode-%e4%b8%8e-free_taxi-%e8%af%a6%e8%a7%a3" class="header-anchor"&gt;&lt;/a&gt;3.5 四种 responseMode 与 free_taxi 详解&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;模式&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;行为&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;适用&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;sync&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同步跑完整 DAG 返回结果&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;输入审核（发出去之前拦）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;free_taxi&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;投递异步任务后立即返回&lt;strong&gt;该会话之前累积&lt;/strong&gt;的检测结果（&amp;ldquo;搭便车&amp;rdquo;）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;流式输出审核（不阻塞 token 输出）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;http&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;只投递不返回，客户端调 defenseResult 接口拉结果&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;异步批量&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;mq&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;预留，开源版是&lt;strong&gt;空实现 stub&lt;/strong&gt;（&lt;code&gt;MessageQueueServiceImpl.java:32&lt;/code&gt;）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;需自行实现&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;strong&gt;free_taxi 的完整机制&lt;/strong&gt;（代码与 docs/ABOUT_FREE_TAXI.md 一致）：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-5-1"&gt;&lt;a class="lnlinks" href="#hl-5-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-2"&gt;&lt;a class="lnlinks" href="#hl-5-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-3"&gt;&lt;a class="lnlinks" href="#hl-5-3"&gt;3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-4"&gt;&lt;a class="lnlinks" href="#hl-5-4"&gt;4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-5"&gt;&lt;a class="lnlinks" href="#hl-5-5"&gt;5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-6"&gt;&lt;a class="lnlinks" href="#hl-5-6"&gt;6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-7"&gt;&lt;a class="lnlinks" href="#hl-5-7"&gt;7&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 投递：lpush 全局任务队列(sessionId) + lpush 该会话新消息队列(请求JSON) [Redis pipeline 原子执行]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 分发：单分发线程 rpop 任务队列 → 提交到 200 线程池&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 抢占：对该 sessionId 抢 Redis 分布式锁（setnx+expire 10s）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - 抢到：循环批量 rpopN 取新消息（batch=checkNum，即&amp;#34;滑动窗口&amp;#34;）→ 每批跑完整 DAG → 结果 lpush 进会话结果队列&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - 没抢到：直接放弃（等客户端下次请求再触发）→ 天然的多实例互斥&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 取结果：下一次请求进来时 fetchResult() rpopN 取走之前的结果；&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 会话结束发 sync 请求（content=&amp;#39;$&amp;#39;）收尾，等 200ms 取全量剩余结果&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;设计精髓：&lt;strong&gt;把&amp;quot;检测&amp;quot;从请求的同步路径上摘掉，用下一次请求顺带带回上一次的检测结果&lt;/strong&gt;。代价是结果滞后一条消息，靠收尾请求兜底。会话历史同时写 Redis list，供 multi_turn_detect 取上下文。&lt;/p&gt;&#10;&lt;h3 id="36-配置加载与缓存坑-5-的完整答案"&gt;&lt;a href="#36-%e9%85%8d%e7%bd%ae%e5%8a%a0%e8%bd%bd%e4%b8%8e%e7%bc%93%e5%ad%98%e5%9d%91-5-%e7%9a%84%e5%ae%8c%e6%95%b4%e7%ad%94%e6%a1%88" class="header-anchor"&gt;&lt;/a&gt;3.6 配置加载与缓存（坑 5 的完整答案）&#10;&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-6-1"&gt;&lt;a class="lnlinks" href="#hl-6-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-6-2"&gt;&lt;a class="lnlinks" href="#hl-6-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-6-3"&gt;&lt;a class="lnlinks" href="#hl-6-3"&gt;3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-6-4"&gt;&lt;a class="lnlinks" href="#hl-6-4"&gt;4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-6-5"&gt;&lt;a class="lnlinks" href="#hl-6-5"&gt;5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-6-6"&gt;&lt;a class="lnlinks" href="#hl-6-6"&gt;6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-6-7"&gt;&lt;a class="lnlinks" href="#hl-6-7"&gt;7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-6-8"&gt;&lt;a class="lnlinks" href="#hl-6-8"&gt;8&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;admin 侧：只有调 online/upgrade 接口才更新 lastChangeTimestamp&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ api 侧 DynamicConfigService：&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ @PostConstruct 首载 + @Scheduled(fixedRate=60000) 每分钟轮询&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ /config/defense/api/conf → 按 lastChangeTimestamp 判断变更&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;变更后：全量替换 volatile 配置 Map → 回调 listener 重建所有业务的 DAG&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; （重新编译 groovy 脚本、重建 OkHttp client、重新注册 warmup）&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;所以配置变更最长滞后约 60s；实践中原子能力超时这类变更重建不彻底，需要 &lt;code&gt;docker restart safety-api&lt;/code&gt;（笔记-4 坑 5 的经验结论与此机制吻合）。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Redis 在 api 侧的四个用途&lt;/strong&gt;：会话历史、free_taxi 任务/结果队列、分布式锁、&lt;strong&gt;识别结果缓存&lt;/strong&gt;（user 且单条时按 业务+内容MD5 缓存 15 分钟——这就是笔记-4 说&amp;quot;重试要改动一两个字&amp;quot;的原因）。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="四safety-admin配置中心与版本化状态机"&gt;&lt;a href="#%e5%9b%9bsafety-admin%e9%85%8d%e7%bd%ae%e4%b8%ad%e5%bf%83%e4%b8%8e%e7%89%88%e6%9c%ac%e5%8c%96%e7%8a%b6%e6%80%81%e6%9c%ba" class="header-anchor"&gt;&lt;/a&gt;四、safety-admin：配置中心与版本化状态机&#10;&lt;/h2&gt;&lt;h3 id="41-管理域与接口"&gt;&lt;a href="#41-%e7%ae%a1%e7%90%86%e5%9f%9f%e4%b8%8e%e6%8e%a5%e5%8f%a3" class="header-anchor"&gt;&lt;/a&gt;4.1 管理域与接口&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;管理域&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;路径前缀&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;动作&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;原子能力 function&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/config/defense/manage/function&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;new / get / newVersion / update / online / offline / upgrade / active / allActive&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;业务 business&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/config/defense/manage/business&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同上&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DAG 策略&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/config/defense/manage/dag&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同上 + &lt;code&gt;newDagWithYaml / dagUpdateYaml / activeYaml&lt;/code&gt;（YAML 导入）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;配置下发&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/config/defense/api/conf&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;给 api 轮询的全量 online 配置&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;敏感词&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/data/sensitive_words&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;upsert / queryByWord / online / offline&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;红线知识库&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/data/redline_knowledge&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CRUD&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;平台字典&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/platform/dict&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CRUD&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="42-版本化状态机所有配置通用"&gt;&lt;a href="#42-%e7%89%88%e6%9c%ac%e5%8c%96%e7%8a%b6%e6%80%81%e6%9c%ba%e6%89%80%e6%9c%89%e9%85%8d%e7%bd%ae%e9%80%9a%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;4.2 版本化状态机（所有配置通用）&#10;&lt;/h3&gt;&lt;p&gt;状态枚举 &lt;code&gt;NormalStatus&lt;/code&gt;：&lt;code&gt;init → edit → (audit / rejected 预留未用) → online ⇄ offline&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;核心规则（&lt;code&gt;FunctionConfigServiceImpl.java&lt;/code&gt; 为代表）：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;唯一键 &lt;code&gt;(name, group, version)&lt;/code&gt;，&lt;code&gt;newVersion&lt;/code&gt; 基于当前 online 版本复制、版本号 +1&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;online 状态的记录禁止 update&lt;/strong&gt;——只能复制出新版本改，保证线上配置不可变&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;upgrade&lt;/code&gt; = 旧版本置 offline + 新版本置 online，原子切换&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;这就是笔记-4 附录 C 那条流水线的代码实现：&lt;code&gt;active → newVersion → update → upgrade&lt;/code&gt;。&lt;/p&gt;&#10;&lt;h3 id="43-数据表6-张safety-admindocstablessql"&gt;&lt;a href="#43-%e6%95%b0%e6%8d%ae%e8%a1%a86-%e5%bc%a0safety-admindocstablessql" class="header-anchor"&gt;&lt;/a&gt;4.3 数据表（6 张，&lt;code&gt;safety-admin/docs/tables.sql&lt;/code&gt;）&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;表&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;要点字段&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;function_conf&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;conf 为 JSON（url、超时、模型参数都在里面）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;business_info&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;secret_key&lt;/code&gt;、&lt;code&gt;access_targets&lt;/code&gt;、&lt;code&gt;qps_limit&lt;/code&gt;、user/robot 检测配置&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;execute_dag_conf&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;root_id&lt;/code&gt; + conf JSON 节点数组&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;sensitive_words&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;match_type&lt;/code&gt;: contain/equal/regex/compound；&lt;code&gt;handle_strategy&lt;/code&gt;: black/white/gray/exclude&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;red_line_knowledge&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;question/answer/metadata&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;platform_dict&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;字典&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;每张表都带 &lt;code&gt;version + status + editor/auditor/release&lt;/code&gt; 审计字段。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="五safety-skills四个原子能力服务"&gt;&lt;a href="#%e4%ba%94safety-skills%e5%9b%9b%e4%b8%aa%e5%8e%9f%e5%ad%90%e8%83%bd%e5%8a%9b%e6%9c%8d%e5%8a%a1" class="header-anchor"&gt;&lt;/a&gt;五、safety-skills：四个原子能力服务&#10;&lt;/h2&gt;&lt;h3 id="51-safety-keywordsjava8005敏感词"&gt;&lt;a href="#51-safety-keywordsjava8005%e6%95%8f%e6%84%9f%e8%af%8d" class="header-anchor"&gt;&lt;/a&gt;5.1 safety-keywords（Java，8005）——敏感词&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;匹配算法：&lt;strong&gt;AC 自动机&lt;/strong&gt;（&lt;code&gt;org.ahocorasick.trie.Trie&lt;/code&gt;），不是 DFA&lt;/li&gt;&#10;&lt;li&gt;数据源：MySQL &lt;code&gt;sensitive_words&lt;/code&gt; 表（只取 online），每 60s 轮询，先查 &lt;code&gt;max(update_time)&lt;/code&gt; 判断有无变更再全量重建&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;双引擎&lt;/strong&gt;（线程池并行，150ms 总预算）：&#10;&lt;ul&gt;&#10;&lt;li&gt;contain/equal 词 → 直接进 AC Trie；命中后按业务场景过滤、按优先级排序；&lt;code&gt;black&lt;/code&gt; 短路返回、&lt;code&gt;exclude&lt;/code&gt; 忽略（白名单机制）&lt;/li&gt;&#10;&lt;li&gt;regex 词 → &lt;strong&gt;正则倒排加速&lt;/strong&gt;：正则按元字符切 token 建 Trie + token→规则倒排索引，query 先 AC 粗筛出候选正则再精匹配，避免全量正则扫文本（这个设计很值得单独写一篇）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;all&lt;/code&gt; 业务下的敏感词对所有业务生效&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="52-safety-bertpythontornado8003"&gt;&lt;a href="#52-safety-bertpythontornado8003" class="header-anchor"&gt;&lt;/a&gt;5.2 safety-bert（Python/Tornado，8003）&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;Tornado &lt;code&gt;bind_sockets&lt;/code&gt; + multiprocessing 多进程（进程数可配）&lt;/li&gt;&#10;&lt;li&gt;模型加载：HuggingFace &lt;code&gt;BertForSequenceClassification.from_pretrained()&lt;/code&gt;，CPU/GPU 可配，max_length=512，softmax argmax&lt;/li&gt;&#10;&lt;li&gt;接口：&lt;code&gt;POST /v1/bert/{model_name}&lt;/code&gt;，body &lt;code&gt;text_list&lt;/code&gt;，返回每条 riskCode/probability/全标签分布&lt;/li&gt;&#10;&lt;li&gt;模型即配置：每个模型一个目录（config 声明 name/路径/labels 的 riskCode↔风险文案映射），现有三个：&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;bert_20250916&lt;/code&gt;：14 类内容风险（涉政/暴恐/涉黄/辱骂…）&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;bert_prompt_injection_20250828&lt;/code&gt;：提示词注入二分类&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;bert_prompt_injection_20251118&lt;/code&gt;：注入三分类（正常/明确攻击/疑似），红蓝军对抗训练的新版&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="53-safety-knowledgepythontornado8004默认-fork-20-进程功能最重"&gt;&lt;a href="#53-safety-knowledgepythontornado8004%e9%bb%98%e8%ae%a4-fork-20-%e8%bf%9b%e7%a8%8b%e5%8a%9f%e8%83%bd%e6%9c%80%e9%87%8d" class="header-anchor"&gt;&lt;/a&gt;5.3 safety-knowledge（Python/Tornado，8004，默认 fork 20 进程）——功能最重&#10;&lt;/h3&gt;&lt;p&gt;路由：&lt;code&gt;/knowledge/upsert|delete|search&lt;/code&gt;、&lt;code&gt;/knowledge/answer&lt;/code&gt;、&lt;code&gt;/dialog&lt;/code&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;知识库检索&lt;/strong&gt;：Vearch Python SDK（连 router :9001）+ 本地 &lt;strong&gt;bge-small-zh-v1.5 ONNX 模型&lt;/strong&gt;生成 512 维向量（onnxruntime CPU，启动预热 10 次）；&lt;code&gt;_id=md5(text)&lt;/code&gt;；支持标量 IN 过滤 + min_score 阈值&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;RAG 代答&lt;/strong&gt;：检索 Top1 分数 ≥ same_threshold → 直接返回知识库 &lt;code&gt;safeChat&lt;/code&gt; 字段；否则拼 prompt（参考答案+输入）调 &lt;strong&gt;OpenAI 兼容 LLM API&lt;/strong&gt;，生成后&lt;strong&gt;再用 bge 余弦相似度校验答案与参考知识一致性&lt;/strong&gt;（阈值 0.7），不一致则答案置空、进 backup——双保险防代答胡说&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;multi_turn_detect 多轮检测&lt;/strong&gt;：把 history 拼进审核细则 prompt 发给 LLM，要求返回 &lt;code&gt;{label, reason}&lt;/code&gt; JSON，正则抽取解析&lt;/li&gt;&#10;&lt;li&gt;依赖：Vearch + OpenAI 兼容 LLM + 本地 ONNX embedding；&lt;strong&gt;不依赖 Redis&lt;/strong&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="54-safety-fasttextflaskgunicorn8002"&gt;&lt;a href="#54-safety-fasttextflaskgunicorn8002" class="header-anchor"&gt;&lt;/a&gt;5.4 safety-fasttext（Flask+gunicorn，8002）&#10;&lt;/h3&gt;&lt;p&gt;默认不在根 compose 里、初始化脚本也没注册它。定位是&amp;quot;轻量预筛&amp;quot;（对应 ABOUT_DAG.md 纵深防御里的第一层：keyword+fasttext 粗筛 → BERT 精检）。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="六example-初始化脚本演示环境的装配线"&gt;&lt;a href="#%e5%85%adexample-%e5%88%9d%e5%a7%8b%e5%8c%96%e8%84%9a%e6%9c%ac%e6%bc%94%e7%a4%ba%e7%8e%af%e5%a2%83%e7%9a%84%e8%a3%85%e9%85%8d%e7%ba%bf" class="header-anchor"&gt;&lt;/a&gt;六、example 初始化脚本：演示环境的装配线&#10;&lt;/h2&gt;&lt;p&gt;safety-example-init 容器按序执行（对应笔记-4 的启动时序图）：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;脚本&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;动作&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;vearch_manage.py&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;建库 db0、建 space（HNSW 512 维 InnerProduct 向量索引 + 标量索引），自测 upsert/search&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;index_all.py&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;直连 MySQL 分批读 &lt;code&gt;red_line_knowledge&lt;/code&gt; → POST 到 knowledge &lt;code&gt;/knowledge/upsert&lt;/code&gt; 向量化入库&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;skills_init.py&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;注册 6 个原子能力（keyword、2 个 bert、kb_search、rag_answer、multi_turn_detect）并 online&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;business_init.py&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;建 test 业务（secretKey=123456、qpsLimit=20）并 online&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;strategy_init.py&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;strategy_example.yml → dagUpdateYaml → online&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="演示-dag-逐节点解读strategy_exampleyml纵深防御教科书案例"&gt;&lt;a href="#%e6%bc%94%e7%a4%ba-dag-%e9%80%90%e8%8a%82%e7%82%b9%e8%a7%a3%e8%af%bbstrategy_exampleyml%e7%ba%b5%e6%b7%b1%e9%98%b2%e5%be%a1%e6%95%99%e7%a7%91%e4%b9%a6%e6%a1%88%e4%be%8b" class="header-anchor"&gt;&lt;/a&gt;演示 DAG 逐节点解读（strategy_example.yml，纵深防御教科书案例）&#10;&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-7-1"&gt;&lt;a class="lnlinks" href="#hl-7-1"&gt; 1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-2"&gt;&lt;a class="lnlinks" href="#hl-7-2"&gt; 2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-3"&gt;&lt;a class="lnlinks" href="#hl-7-3"&gt; 3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-4"&gt;&lt;a class="lnlinks" href="#hl-7-4"&gt; 4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-5"&gt;&lt;a class="lnlinks" href="#hl-7-5"&gt; 5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-6"&gt;&lt;a class="lnlinks" href="#hl-7-6"&gt; 6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-7"&gt;&lt;a class="lnlinks" href="#hl-7-7"&gt; 7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-8"&gt;&lt;a class="lnlinks" href="#hl-7-8"&gt; 8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-9"&gt;&lt;a class="lnlinks" href="#hl-7-9"&gt; 9&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-10"&gt;&lt;a class="lnlinks" href="#hl-7-10"&gt;10&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-7-11"&gt;&lt;a class="lnlinks" href="#hl-7-11"&gt;11&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;start（dummy 节点，groovy router）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 按 ctx.curReq[0].fromRobot() 分流&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 机器人输出 → from_robot_test1：keyword → stupid_end（机器人侧只查敏感词）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 用户输入 → from_user_test1：parallel(keyword)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ groovy router：命中黑(bwgLabel=1)直接出风险；命中白(2)直接放行&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from_user_test_bert2：parallel(bert_20250916, bert_prompt_injection_20250828)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ groovy router：按 riskCode 差异化概率阈值表判定&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ （如 1003涉黄 0.85、1004涉赌 0.996、201注入 0.99）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 都不达标 → MixedCheck.noRisk()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;所有节点 &lt;code&gt;ignoreError: true&lt;/code&gt;（单个能力挂了不阻断整体）。ABOUT_DAG.md 里还有更进阶的打法：&lt;code&gt;parallel(rag_answer + bert)&lt;/code&gt; 红线代答与模型&lt;strong&gt;双证&lt;/strong&gt;（riskCode 一致且概率 &amp;gt; 0.5 才判风险，防误杀）。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="七值得学习的设计点-vs-开源版的坑博客素材库"&gt;&lt;a href="#%e4%b8%83%e5%80%bc%e5%be%97%e5%ad%a6%e4%b9%a0%e7%9a%84%e8%ae%be%e8%ae%a1%e7%82%b9-vs-%e5%bc%80%e6%ba%90%e7%89%88%e7%9a%84%e5%9d%91%e5%8d%9a%e5%ae%a2%e7%b4%a0%e6%9d%90%e5%ba%93" class="header-anchor"&gt;&lt;/a&gt;七、值得学习的设计点 vs 开源版的坑（博客素材库）&#10;&lt;/h2&gt;&lt;h3 id="71-设计亮点"&gt;&lt;a href="#71-%e8%ae%be%e8%ae%a1%e4%ba%ae%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;7.1 设计亮点&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;编排与能力彻底分离&lt;/strong&gt;：skill 服务无状态、HTTP 解耦，新增能力 = 起一个服务 + admin 注册 + DAG 引用，不动一行 Java 代码&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;配置版本化 + 不可变线上配置&lt;/strong&gt;：online 禁改、upgrade 原子切换，天然支持灰度回滚（AB 机制还能按 dagVersion 指定版本实时构建）&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;free_taxi 模式&lt;/strong&gt;：把检测从流式输出的同步路径上摘掉，业界少见的工程化解法&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;纵深防御策略&lt;/strong&gt;：词库粗筛 → 轻模型 → 重模型 → 知识库双证，每层都有成本和准确率权衡&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;groovy 脚本做 router&lt;/strong&gt;：策略逻辑不用发版就能改（虽然要重启 api 才彻底生效）&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;正则倒排加速、RAG 代答一致性校验&lt;/strong&gt;：细节处的工程功底&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="72-开源版的坑--局限"&gt;&lt;a href="#72-%e5%bc%80%e6%ba%90%e7%89%88%e7%9a%84%e5%9d%91--%e5%b1%80%e9%99%90" class="header-anchor"&gt;&lt;/a&gt;7.2 开源版的坑 / 局限&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;mq responseMode 是空 stub&lt;/strong&gt;，要用得自己实现 &lt;code&gt;MessageQueueService&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;文档超前于代码&lt;/strong&gt;：ABOUT_DAG.md 里 &lt;code&gt;executedNodes/nodeCosts&lt;/code&gt; 等 ctx 字段实际不存在&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;MySQL/Redis/Vearch 全都没挂数据卷&lt;/strong&gt;（笔记-4 已踩：&lt;code&gt;docker compose down&lt;/code&gt; 即丢全部配置）&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;DAG 热更新不彻底&lt;/strong&gt;：60s 轮询 + 部分变更需重启 api，离 README 宣称的&amp;quot;分钟级热更新&amp;quot;有差距&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;groovy eval 全局 synchronized&lt;/strong&gt;：ScriptEngine 非线程安全，所有脚本串行执行，高并发下是瓶颈&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;技术栈老旧&lt;/strong&gt;：Spring Boot 2.0.9 / Jedis 2.5.2 / fastjson 1.x 2.x 混用&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&amp;ldquo;DAG&amp;rdquo; 实为链式逐跳&lt;/strong&gt;：没有真正的图拓扑调度，并行只在 parallel 节点内部&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;fasttext 默认缺席&lt;/strong&gt;：README 能力清单里有，compose 和初始化脚本都没有&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="八关键源码坐标速查"&gt;&lt;a href="#%e5%85%ab%e5%85%b3%e9%94%ae%e6%ba%90%e7%a0%81%e5%9d%90%e6%a0%87%e9%80%9f%e6%9f%a5" class="header-anchor"&gt;&lt;/a&gt;八、关键源码坐标速查&#10;&lt;/h2&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;主题&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;位置&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DAG 主执行循环&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/src/main/java/com/jd/security/llmsec/engine/FunctionExecutorImpl.java:289&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;并行节点&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../engine/functions/ParallelFunction.java:41&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Function 注册表&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../engine/FunctionRegistry.java:20&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;groovy router&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-basic/.../core/engine/routers/GroovyRouter.java:27&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;SessionContext（ctx 结构）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-basic/.../core/session/SessionContext.java:21&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;审核入口&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../contoller/DefenseApiV2Controller.java:33&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HMAC-SHA1&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-basic/.../core/util/SignUtil.java:36&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;free_taxi 任务执行&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../task/TaskExecutorImpl.java:78&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;配置轮询&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../service/DynamicConfigService.java:45&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;版本化状态机&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-admin/.../service/business/FunctionConfigServiceImpl.java:236&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;AC 自动机敏感词&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-skills/safety-keywords/.../service/data/SensitiveWordDetector.java&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;建表 SQL&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-admin/docs/tables.sql&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;演示策略&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;docs/strategy_example.yml&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;注：Java 源码里 controller 目录拼写为 &lt;code&gt;contoller&lt;/code&gt;（原仓库笔误），检索时注意。&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;</description></item><item><title>模型安全检测 12：三层防护体系串联（网关 × 脱敏 × JoySafety）</title><link>https://saflyer.cn/posts/joysafety-three-layer-defense/</link><pubDate>Mon, 14 Sep 2026 10:03:15 +0800</pubDate><guid>https://saflyer.cn/posts/joysafety-three-layer-defense/</guid><description>&lt;img src="https://saflyer.cn/posts/joysafety-three-layer-defense/cover.webp" alt="Featured image of post 模型安全检测 12：三层防护体系串联（网关 × 脱敏 × JoySafety）" /&gt;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;状态&lt;/strong&gt;：✅ 已完成&#10;&lt;strong&gt;前置阅读&lt;/strong&gt;：01~11 全部（尤其 03 架构分析），以及 maas-safe-doc 仓库的三篇网关侧笔记：&#10;&lt;code&gt;../../maas-safe-doc/安全护栏/poc/网关安全插件-1-基础功能验证.md&lt;/code&gt;、&#10;&lt;code&gt;网关安全插件-2-高级能力验证以及存在的问题分析.md&lt;/code&gt;、&#10;&lt;code&gt;网关脱敏插件实现原理分析-ai-data-masking-脱敏与还原.md&lt;/code&gt;&#10;&lt;strong&gt;日期&lt;/strong&gt;：2026-09-14&#10;&lt;strong&gt;素材来源&lt;/strong&gt;：JoySafety 源码核实（路径均逐一 Read/Grep 验证）+ Higress 插件侧引用自上述脱敏原理笔记&#10;&lt;strong&gt;读者定位&lt;/strong&gt;：要把&amp;quot;网关插件 / 脱敏插件 / JoySafety&amp;quot;三条线组装成一套生产方案的读者。本篇以架构图和决策表为主，源码坐标用于支撑每个机制结论&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="一句话总览"&gt;&lt;a href="#%e4%b8%80%e5%8f%a5%e8%af%9d%e6%80%bb%e8%a7%88" class="header-anchor"&gt;&lt;/a&gt;〇、一句话总览&#10;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;网关插件管&amp;quot;流量&amp;quot;，脱敏插件管&amp;quot;数据&amp;quot;，JoySafety 管&amp;quot;内容&amp;quot;。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-0-1"&gt;&lt;a class="lnlinks" href="#hl-0-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-2"&gt;&lt;a class="lnlinks" href="#hl-0-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-3"&gt;&lt;a class="lnlinks" href="#hl-0-3"&gt;3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-4"&gt;&lt;a class="lnlinks" href="#hl-0-4"&gt;4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-5"&gt;&lt;a class="lnlinks" href="#hl-0-5"&gt;5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-6"&gt;&lt;a class="lnlinks" href="#hl-0-6"&gt;6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-7"&gt;&lt;a class="lnlinks" href="#hl-0-7"&gt;7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-8"&gt;&lt;a class="lnlinks" href="#hl-0-8"&gt;8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-0-9"&gt;&lt;a class="lnlinks" href="#hl-0-9"&gt;9&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 流量层 数据层 内容层&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────┐ ┌──────────────────┐ ┌──────────────────────────┐&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 网关安全插件 │ │ ai-data-masking │ │ JoySafety │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ WAF/IP名单/ │ │ 敏感词拦截 │ │ 敏感词/BERT/知识库/多轮 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ QPS/TPM 限流 │ │ PII 脱敏与还原 │ │ DAG 编排 + free_taxi │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ &amp;#34;谁来、来多少&amp;#34; │ │ &amp;#34;数据出不出域&amp;#34; │ │ &amp;#34;内容合不合规&amp;#34; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────┘ └──────────────────┘ └──────────────────────────┘&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 微秒~毫秒级 毫秒级（WASM 本地） 毫秒~秒级（模型推理）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 规则匹配 分词+正则 语义理解&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;类比：机场安检——网关是&lt;strong&gt;入口闸机&lt;/strong&gt;（验票、限流、黑名单），脱敏是&lt;strong&gt;行李打包&lt;/strong&gt;（贵重物品封存、凭条可取回），JoySafety 是&lt;strong&gt;安检仪+人工复检&lt;/strong&gt;（X 光粗筛、开包精检、专家会诊）。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="一三层各自的定位"&gt;&lt;a href="#%e4%b8%80%e4%b8%89%e5%b1%82%e5%90%84%e8%87%aa%e7%9a%84%e5%ae%9a%e4%bd%8d" class="header-anchor"&gt;&lt;/a&gt;一、三层各自的定位&#10;&lt;/h2&gt;&lt;h3 id="11-定位对照表"&gt;&lt;a href="#11-%e5%ae%9a%e4%bd%8d%e5%af%b9%e7%85%a7%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;1.1 定位对照表&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;维度&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;网关安全插件（Higress）&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;脱敏插件（ai-data-masking）&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;JoySafety&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;防护对象&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;流量入口&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;敏感数据（PII/密钥）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;内容语义风险&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;核心问题&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;谁来访问、来多少、是不是 Web 攻击&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;数据出不出域、能不能还原&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;文本合不合规、有没有注入&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;技术形态&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Envoy/Higress 插件（WAF=ModSecurity+CRS）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Rust 编译 WASM，网关内嵌运行&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;独立部署的 Java/Python 微服务集群&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;检测手段&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;规则匹配（CRS 规则集、IP 名单、计数器）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;结巴分词+HashSet、Grok/正则、HMAC-SHA256&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;AC 自动机、BERT 分类、向量检索、LLM 多轮&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;单次开销&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;微秒~毫秒&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;毫秒（本地 WASM，无网络调用）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;词库 ~40ms，BERT 生产 ~200ms（见 02 篇实测）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;策略载体&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关控制台 YAML&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同左（&lt;code&gt;replace_roles&lt;/code&gt;/&lt;code&gt;system_deny&lt;/code&gt;）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MySQL 版本化配置 + DAG YAML&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;拦截粒度&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;请求级（403/429）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;词级（替换）或请求级（deny）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;词/句/会话级，riskCode 细分 14+ 类&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;失败倾向&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;拒绝服务（fail-close 基因）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;可配（deny/replace 两档）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ignoreError&lt;/code&gt; 可配，默认容错（fail-open 基因）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="12-为什么需要三层而不是一层"&gt;&lt;a href="#12-%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81%e4%b8%89%e5%b1%82%e8%80%8c%e4%b8%8d%e6%98%af%e4%b8%80%e5%b1%82" class="header-anchor"&gt;&lt;/a&gt;1.2 为什么需要三层而不是一层&#10;&lt;/h3&gt;&lt;p&gt;三道防线对应三种&lt;strong&gt;成本—能力&lt;/strong&gt;曲线，缺一不可：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;网关层最便宜也最快&lt;/strong&gt;，但只能做模式匹配。SQL 注入、XSS、IP 封禁、QPS/TPM 限流在这里拦，一次拦截成本几乎为零——POC 验证 6 项 WAF 用例全部 403 拦截（网关安全插件-1，TC01~TC04）。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;脱敏层解决的是&amp;quot;内容合规管不了&amp;quot;的问题&lt;/strong&gt;。JoySafety 没有脱敏替换能力（网关安全插件-2 第 4.2 节实测确认：&amp;ldquo;缺少 Higress 脱敏插件的脱敏替换功能&amp;rdquo;），身份证/手机号/API Key 必须在出域前由脱敏插件替换或哈希。脱敏插件源码证实其三档机制：&lt;code&gt;DenyWord&lt;/code&gt;（结巴分词+HashSet 拦截，&lt;code&gt;deny_word.rs:63-70&lt;/code&gt;）、&lt;code&gt;replace&lt;/code&gt;（正则替换为固定值）、&lt;code&gt;hash&lt;/code&gt;（HMAC-SHA256 可逆脱敏，&lt;code&gt;ai_data_masking.rs:431-486&lt;/code&gt;）。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;JoySafety 解决的是&amp;quot;规则看不懂&amp;quot;的问题&lt;/strong&gt;。变体辱骂、暗示性暴恐、祖母漏洞式提示词注入，规则引擎无解，必须上模型和知识库。02 篇实测：BERT 对&amp;quot;哪里有卖枪支的&amp;quot;判 riskCode=1002（置信度 0.9989），对祖母漏洞判 riskCode=201（置信度 0.994）——这两类网关层完全拦不住。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="13-各层在本系列姊妹篇中的出处"&gt;&lt;a href="#13-%e5%90%84%e5%b1%82%e5%9c%a8%e6%9c%ac%e7%b3%bb%e5%88%97%e5%a7%8a%e5%a6%b9%e7%af%87%e4%b8%ad%e7%9a%84%e5%87%ba%e5%a4%84" class="header-anchor"&gt;&lt;/a&gt;1.3 各层在本系列/姊妹篇中的出处&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;层&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;深入笔记&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关插件&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关安全插件-1（基础功能 POC）、-2（高级能力与问题分析）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;脱敏插件&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关脱敏插件实现原理分析（Rust/WASM 源码级）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;本系列 03（架构）、04（DAG）、05（free_taxi）、06（敏感词）、07（知识库）、08（注入攻防）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="二完整请求链路设计"&gt;&lt;a href="#%e4%ba%8c%e5%ae%8c%e6%95%b4%e8%af%b7%e6%b1%82%e9%93%be%e8%b7%af%e8%ae%be%e8%ae%a1" class="header-anchor"&gt;&lt;/a&gt;二、完整请求链路设计&#10;&lt;/h2&gt;&lt;h3 id="21-全链路时序图"&gt;&lt;a href="#21-%e5%85%a8%e9%93%be%e8%b7%af%e6%97%b6%e5%ba%8f%e5%9b%be" class="header-anchor"&gt;&lt;/a&gt;2.1 全链路时序图&#10;&lt;/h3&gt;&lt;p&gt;一条 LLM 对话请求穿过三层防线的完整旅程（入向审核采用 JoySafety &lt;code&gt;sync&lt;/code&gt; 模式，在调用模型&lt;strong&gt;之前&lt;/strong&gt;拦；出向采用 &lt;code&gt;free_taxi&lt;/code&gt; 模式，不阻塞流式输出）：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-1-1"&gt;&lt;a class="lnlinks" href="#hl-1-1"&gt; 1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-2"&gt;&lt;a class="lnlinks" href="#hl-1-2"&gt; 2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-3"&gt;&lt;a class="lnlinks" href="#hl-1-3"&gt; 3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-4"&gt;&lt;a class="lnlinks" href="#hl-1-4"&gt; 4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-5"&gt;&lt;a class="lnlinks" href="#hl-1-5"&gt; 5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-6"&gt;&lt;a class="lnlinks" href="#hl-1-6"&gt; 6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-7"&gt;&lt;a class="lnlinks" href="#hl-1-7"&gt; 7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-8"&gt;&lt;a class="lnlinks" href="#hl-1-8"&gt; 8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-9"&gt;&lt;a class="lnlinks" href="#hl-1-9"&gt; 9&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-10"&gt;&lt;a class="lnlinks" href="#hl-1-10"&gt;10&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-11"&gt;&lt;a class="lnlinks" href="#hl-1-11"&gt;11&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-12"&gt;&lt;a class="lnlinks" href="#hl-1-12"&gt;12&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-13"&gt;&lt;a class="lnlinks" href="#hl-1-13"&gt;13&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-14"&gt;&lt;a class="lnlinks" href="#hl-1-14"&gt;14&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-15"&gt;&lt;a class="lnlinks" href="#hl-1-15"&gt;15&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-16"&gt;&lt;a class="lnlinks" href="#hl-1-16"&gt;16&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-17"&gt;&lt;a class="lnlinks" href="#hl-1-17"&gt;17&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-18"&gt;&lt;a class="lnlinks" href="#hl-1-18"&gt;18&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-19"&gt;&lt;a class="lnlinks" href="#hl-1-19"&gt;19&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-20"&gt;&lt;a class="lnlinks" href="#hl-1-20"&gt;20&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-21"&gt;&lt;a class="lnlinks" href="#hl-1-21"&gt;21&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-22"&gt;&lt;a class="lnlinks" href="#hl-1-22"&gt;22&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-23"&gt;&lt;a class="lnlinks" href="#hl-1-23"&gt;23&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-24"&gt;&lt;a class="lnlinks" href="#hl-1-24"&gt;24&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-25"&gt;&lt;a class="lnlinks" href="#hl-1-25"&gt;25&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-26"&gt;&lt;a class="lnlinks" href="#hl-1-26"&gt;26&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-27"&gt;&lt;a class="lnlinks" href="#hl-1-27"&gt;27&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-1-28"&gt;&lt;a class="lnlinks" href="#hl-1-28"&gt;28&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;客户端 网关插件层 脱敏插件 JoySafety LLM&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ①POST /v1/chat/completions │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├────────────────►│ WAF(CRS规则) │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ IP黑名单 │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ QPS/TPM限流 │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ ──拦截→403/429 │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├────────────────►│ ②请求侧脱敏 │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ jieba+HashSet拦截 │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ ──命中→deny_message │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ Grok/正则替换PII │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ sk-* → hash(存map) │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ ├────────────────────►│ ③输入审核 sync │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ 鉴权HMAC-SHA1 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ DAG: keyword→BERT 并行 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ ──命中→riskCode≠0 拦截 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ ├─────────────────────────►│&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ │ ④推理&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ │ ⑤SSE 流式输出&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │◄─────chunk 累积投递──────┤&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ ⑥free_taxi 异步检测 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ (不占输出路径，结果搭 │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │ 下次请求便车带回) │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ ⑦响应侧 │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ 流式敏感词检测 │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ mask_map 还原hash │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ⑧SSE 透传给客户端 │ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │◄────────────────┴──────────────────┤ │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 会话结束发 sync(content=&amp;#39;$&amp;#39;) 收尾，取走剩余检测结果 │ │&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;设计说明（与提纲出入处）&lt;/strong&gt;：提纲原文把&amp;quot;JoySafety 输入审核&amp;quot;放在 LLM 之后。实际方案将其放在 LLM &lt;strong&gt;之前&lt;/strong&gt;——输入审核的意义就是在token消耗发生前拦截（命中即不再调模型，省钱省延迟），这与 JoySafety &lt;code&gt;sync&lt;/code&gt; 模式的定位一致：&amp;ldquo;同步跑完整 DAG 返回结果，适用输入审核（发出去之前拦）&amp;quot;（03 篇 3.5 节）。提纲中的顺序在&amp;quot;先过模型再回头审输入&amp;quot;的反模式里没有意义，本篇以实际代码语义为准做了修正。&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;h3 id="22-joysafety-侧的两个视角回顾详见-03-篇"&gt;&lt;a href="#22-joysafety-%e4%be%a7%e7%9a%84%e4%b8%a4%e4%b8%aa%e8%a7%86%e8%a7%92%e5%9b%9e%e9%a1%be%e8%af%a6%e8%a7%81-03-%e7%af%87" class="header-anchor"&gt;&lt;/a&gt;2.2 JoySafety 侧的两个视角回顾（详见 03 篇）&#10;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;配置流转&lt;/strong&gt;（配置期）：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-2-1"&gt;&lt;a class="lnlinks" href="#hl-2-1"&gt;1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-2"&gt;&lt;a class="lnlinks" href="#hl-2-2"&gt;2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-3"&gt;&lt;a class="lnlinks" href="#hl-2-3"&gt;3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-4"&gt;&lt;a class="lnlinks" href="#hl-2-4"&gt;4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-5"&gt;&lt;a class="lnlinks" href="#hl-2-5"&gt;5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-6"&gt;&lt;a class="lnlinks" href="#hl-2-6"&gt;6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-7"&gt;&lt;a class="lnlinks" href="#hl-2-7"&gt;7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-8"&gt;&lt;a class="lnlinks" href="#hl-2-8"&gt;8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-2-9"&gt;&lt;a class="lnlinks" href="#hl-2-9"&gt;9&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;运维&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="err"&gt;控制台&lt;/span&gt; &lt;span class="err"&gt;──►&lt;/span&gt; &lt;span class="n"&gt;safety&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8006&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;──写入──►&lt;/span&gt; &lt;span class="n"&gt;MySQL&lt;/span&gt;&lt;span class="err"&gt;（版本化状态机：&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="n"&gt;edit&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="n"&gt;online&lt;/span&gt;&lt;span class="err"&gt;⇄&lt;/span&gt;&lt;span class="n"&gt;offline&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;safety&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="err"&gt;每&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="err"&gt;轮询&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;defense&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt; &lt;span class="err"&gt;◄─────┘（不直连&lt;/span&gt; &lt;span class="n"&gt;MySQL&lt;/span&gt;&lt;span class="err"&gt;！）&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DynamicConfigService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loadConf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Scheduled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fixedRate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="n"&gt;safety&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/.../&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;DynamicConfigService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;按&lt;/span&gt; &lt;span class="n"&gt;lastChangeTimestamp&lt;/span&gt; &lt;span class="err"&gt;判断有无变更（同文件&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;142&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;144&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;无变更&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;配置无变更&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;直接返回（&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;76&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt; &lt;span class="err"&gt;有变更&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;全量替换&lt;/span&gt; &lt;span class="n"&gt;volatile&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="err"&gt;）→&lt;/span&gt; &lt;span class="err"&gt;回调&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="err"&gt;重建所有业务&lt;/span&gt; &lt;span class="n"&gt;DAG&lt;/span&gt;&lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;106&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;请求流转&lt;/strong&gt;（执行期），入口 &lt;code&gt;DefenseApiV2Controller&lt;/code&gt;（&lt;code&gt;safety/safety-api/src/main/java/com/jd/security/llmsec/contoller/DefenseApiV2Controller.java:31-33&lt;/code&gt;）：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-3-1"&gt;&lt;a class="lnlinks" href="#hl-3-1"&gt; 1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-2"&gt;&lt;a class="lnlinks" href="#hl-3-2"&gt; 2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-3"&gt;&lt;a class="lnlinks" href="#hl-3-3"&gt; 3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-4"&gt;&lt;a class="lnlinks" href="#hl-3-4"&gt; 4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-5"&gt;&lt;a class="lnlinks" href="#hl-3-5"&gt; 5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-6"&gt;&lt;a class="lnlinks" href="#hl-3-6"&gt; 6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-7"&gt;&lt;a class="lnlinks" href="#hl-3-7"&gt; 7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-8"&gt;&lt;a class="lnlinks" href="#hl-3-8"&gt; 8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-9"&gt;&lt;a class="lnlinks" href="#hl-3-9"&gt; 9&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-3-10"&gt;&lt;a class="lnlinks" href="#hl-3-10"&gt;10&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// DefenseApiV2Controller.java，处理链关键节点（行号为实测）&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;checkParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// :46 参数校验&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;defenseService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rateLimited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;// :59 Guava RateLimiter 内存级限流（按 accessKey）&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;accessKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// :74 test 开头特赦&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;defenseService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;// :75 HMAC-SHA1 验签（SignUtil.java:36 拼串、:62 加密）&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;defenseService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;preProcess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;// :78 OpenAI 格式解析 + 7000 字截断（GlobalConf.java:49）&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// :97 按 responseMode 分派&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// :100 同步跑 DAG&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;free_taxi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// :107 只投递&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fetchResult&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// :108 顺带取回历史结果&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;随后进入 DAG 主循环 &lt;code&gt;FunctionExecutorImpl.doExecute()&lt;/code&gt;（&lt;code&gt;FunctionExecutorImpl.java:289&lt;/code&gt;）——&lt;code&gt;while (curNode != null)&lt;/code&gt; 逐跳执行，每轮先查整体超时（:297-299），节点异常按 &lt;code&gt;ignoreError&lt;/code&gt; 决定抛出还是跳过（:312-323），router 返回 null 即终结。&lt;/p&gt;&#10;&lt;h3 id="23-出向为什么必须是-free_taxi"&gt;&lt;a href="#23-%e5%87%ba%e5%90%91%e4%b8%ba%e4%bb%80%e4%b9%88%e5%bf%85%e9%a1%bb%e6%98%af-free_taxi" class="header-anchor"&gt;&lt;/a&gt;2.3 出向为什么必须是 free_taxi&#10;&lt;/h3&gt;&lt;p&gt;流式输出场景，同步检测意味着&amp;quot;攒完整段再返回&amp;rdquo;，首 token 延迟直接报废。JoySafety 的解法是 &lt;code&gt;free_taxi&lt;/code&gt;（03 篇 3.5 节、&lt;code&gt;TaskExecutorImpl.java:78&lt;/code&gt;）：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;请求侧只做 &lt;code&gt;submit&lt;/code&gt;（Redis lpush 投递）立即返回，&lt;strong&gt;检测从同步路径上摘掉&lt;/strong&gt;；&lt;/li&gt;&#10;&lt;li&gt;200 线程池消费（&lt;code&gt;TaskExecutorImpl.java:56-63&lt;/code&gt;），按 sessionId 抢 Redis 分布式锁（&lt;code&gt;storageService.lock&lt;/code&gt;，:88，锁 10 秒，:75）实现多实例互斥；&lt;/li&gt;&#10;&lt;li&gt;检测结果 lpush 进会话结果队列，&lt;strong&gt;下一次请求搭便车带回&lt;/strong&gt;（&lt;code&gt;DefenseApiV2Controller.java:108&lt;/code&gt;）；&lt;/li&gt;&#10;&lt;li&gt;会话结束发 &lt;code&gt;sync&lt;/code&gt; 请求（content=&lt;code&gt;'$'&lt;/code&gt;）收尾取全量。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;代价是&lt;strong&gt;结果滞后一条消息&lt;/strong&gt;，且跨 chunk 的 unsafe 内容识别能力有限（网关安全插件-2 第 4.1 节明确指出该短板，并建议与脱敏插件的滑动窗口机制结合）——这正是三层互补的典型场景：出向的实时底线由脱敏插件的流式敏感词检测（MsgWindow 累积缓冲区检测）兜住，深度语义检测由 free_taxi 异步补齐。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="三职责边界与不重复建设"&gt;&lt;a href="#%e4%b8%89%e8%81%8c%e8%b4%a3%e8%be%b9%e7%95%8c%e4%b8%8e%e4%b8%8d%e9%87%8d%e5%a4%8d%e5%bb%ba%e8%ae%be" class="header-anchor"&gt;&lt;/a&gt;三、职责边界与不重复建设&#10;&lt;/h2&gt;&lt;h3 id="31-放哪层的决策表"&gt;&lt;a href="#31-%e6%94%be%e5%93%aa%e5%b1%82%e7%9a%84%e5%86%b3%e7%ad%96%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;3.1 放哪层的决策表&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;检测项&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;放哪层&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;理由（成本/准确率/延迟权衡）&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;SQL 注入/XSS/路径穿越/命令注入&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关 WAF&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CRS 规则成熟、微秒级、与 LLM 语义无关。POC 实测 5 类攻击全部 403&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Content-Type 校验、空 UA&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关/前置 Nginx&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;纯协议层检查，不重复建设（POC 明确&amp;quot;不在 WAF 层重复配置&amp;quot;）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;IP 黑白名单&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;连接级信息，越靠前越省资源。注意 POC 发现黑白名单互斥、白名单≠跳过审核&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;租户 QPS/TPM 限流&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;需要全局计数（Redis 集群级限流插件），JoySafety 的 RateLimiter 是单实例内存级（03 篇 3.1），只作兜底&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;PII（身份证/手机/邮箱/IP）脱敏&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;脱敏插件&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety 无替换能力；正则微秒级，放模型层是纯浪费&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;API Key/密钥出域&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;脱敏插件（hash+restore）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;可逆需求只有 mask_map 机制能满足&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;粗粒度敏感词（涉政/赌博黑词）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;两层都放&lt;/strong&gt;（见 3.2）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关侧拦截成本≈0 先挡一波；JoySafety 词库做黑白灰精细化管理&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;变体辱骂/暗示性违规&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety BERT&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;语义问题，规则无解&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;提示词注入（祖母漏洞等）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety 注入模型&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;需要红蓝军对抗训练的专门模型（08 篇）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;红线问题代答&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety RAG&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;需要知识库+一致性校验双保险（07 篇）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;多轮上下文风险&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety multi_turn_detect&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;需要会话历史（Redis），网关无状态做不了&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;业务级 HMAC 鉴权&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety（审核接口）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关管租户身份，JoySafety 管业务 accessKey/secretKey，各管一段&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="32-重叠能力的分工敏感词两层都放但不重复"&gt;&lt;a href="#32-%e9%87%8d%e5%8f%a0%e8%83%bd%e5%8a%9b%e7%9a%84%e5%88%86%e5%b7%a5%e6%95%8f%e6%84%9f%e8%af%8d%e4%b8%a4%e5%b1%82%e9%83%bd%e6%94%be%e4%bd%86%e4%b8%8d%e9%87%8d%e5%a4%8d" class="header-anchor"&gt;&lt;/a&gt;3.2 重叠能力的分工：敏感词两层都放，但不重复&#10;&lt;/h3&gt;&lt;p&gt;三层在&amp;quot;敏感词&amp;quot;上有能力重叠（网关安全插件-2 第五章有完整对比表），分工原则是&lt;strong&gt;网关挡子弹、JoySafety 做手术&lt;/strong&gt;：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;维度&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;脱敏插件内置词库&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;JoySafety 敏感词服务&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;匹配方式&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;结巴分词+HashSet，contains&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;AC 自动机（&lt;code&gt;SensitiveWordDetector.java:14-15&lt;/code&gt;，ahocorasick Trie），支持 contain/equal/regex/compound 四种（&lt;code&gt;safety-admin/docs/tables.sql:9&lt;/code&gt;）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;处置策略&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;拦截（deny）或替换（replace/hash）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;黑白灰名单+exclude（&lt;code&gt;tables.sql:10&lt;/code&gt;），白名单命中直接放行短路&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;词库运营&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;静态内置+配置自定义&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MySQL 持久化，admin 动态增删，keywords 服务定时轮询重建（&lt;code&gt;SensitiveWordsManageServiceImpl.java:194&lt;/code&gt; &lt;code&gt;@Scheduled&lt;/code&gt;）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;定位&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;出域底线（数据不走）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;内容风控（语义判定）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;实操建议：网关侧只放&lt;strong&gt;零容忍、无歧义&lt;/strong&gt;的短词黑名单（错了代价高的放这里，fail-close）；JoySafety 侧放全量词库+黑白灰策略，承接需要场景过滤、优先级排序的精细判定（06 篇）。&lt;/p&gt;&#10;&lt;h3 id="33-脱敏与内容审核的数据流衔接"&gt;&lt;a href="#33-%e8%84%b1%e6%95%8f%e4%b8%8e%e5%86%85%e5%ae%b9%e5%ae%a1%e6%a0%b8%e7%9a%84%e6%95%b0%e6%8d%ae%e6%b5%81%e8%a1%94%e6%8e%a5" class="header-anchor"&gt;&lt;/a&gt;3.3 脱敏与内容审核的数据流衔接&#10;&lt;/h3&gt;&lt;p&gt;关键决策：&lt;strong&gt;先脱敏还是先审核？&lt;/strong&gt; 推荐顺序&amp;quot;脱敏请求侧 → JoySafety 输入审核&amp;quot;（即 2.1 图的顺序），理由与代价：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;✅ PII 不进 JoySafety 的日志/会话历史/结果缓存——JoySafety 会把会话历史写 Redis、按内容 MD5 缓存结果 15 分钟（03 篇 3.6），明文手机号进去就是二次泄露面；&lt;/li&gt;&#10;&lt;li&gt;⚠️ 代价：审核看到的是脱敏后文本（手机号→&lt;code&gt;*****&lt;/code&gt;），对&amp;quot;报出自己手机号求回拨&amp;quot;这类语义判定有轻微影响。可接受——PII 本身不是内容风险，语义审核本来就不需要知道号码是多少；&lt;/li&gt;&#10;&lt;li&gt;❌ 反序（先审后脱敏）的问题：审核链路成为明文 PII 的新出口，且脱敏替换可能把黑词切成两段逃逸审核（如正则替换恰好切分敏感词），必须在审核&lt;strong&gt;之前&lt;/strong&gt;完成文本改写。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;出向衔接：JoySafety free_taxi 检测的是&lt;strong&gt;脱敏态&lt;/strong&gt;的输出流（hash 串不影响语义判定），脱敏插件在最后一个环节做 mask_map 还原——还原发生在审核之后，审核结果不受还原影响。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="四每层故障的兜底策略"&gt;&lt;a href="#%e5%9b%9b%e6%af%8f%e5%b1%82%e6%95%85%e9%9a%9c%e7%9a%84%e5%85%9c%e5%ba%95%e7%ad%96%e7%95%a5" class="header-anchor"&gt;&lt;/a&gt;四、每层故障的兜底策略&#10;&lt;/h2&gt;&lt;h3 id="41-fail-open-vs-fail-close-决策表"&gt;&lt;a href="#41-fail-open-vs-fail-close-%e5%86%b3%e7%ad%96%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;4.1 fail-open vs fail-close 决策表&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;故障场景&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;默认行为&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;建议取向&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;理由&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关 WAF/限流插件异常&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关层故障通常表现为整个入口不可用&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;fail-close&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;入口挂了等于服务下线，不存在&amp;quot;放过去&amp;quot;选项；重点是多副本+健康检查&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;脱敏插件异常（WASM panic/配置错误）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;请求中断&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;fail-close&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;它的职责是&amp;quot;数据不出域&amp;quot;，放行=明文 PII 直送外部 LLM，宁可误伤不可泄露&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety 单 skill 挂（bert/keywords/knowledge）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;fail-open&lt;/strong&gt;：DAG 节点 &lt;code&gt;ignoreError: true&lt;/code&gt; 时异常被吞掉继续走（&lt;code&gt;FunctionExecutorImpl.java:319-323&lt;/code&gt;），演示策略全部节点都是 &lt;code&gt;ignoreError: true&lt;/code&gt;（&lt;code&gt;docs/strategy_example.yml:23,65,107,114&lt;/code&gt;）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;看节点角色&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;词库节点挂了fail-open可接受（后面还有模型）；&lt;strong&gt;最后一道模型节点挂了必须告警&lt;/strong&gt;，否则等于裸奔&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety 单 skill 慢（超时）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;fail-open&lt;/strong&gt;：parallel 内 &lt;code&gt;Future.get(curTimeout)&lt;/code&gt; 超时丢弃该子项结果（&lt;code&gt;ParallelFunction.java:130-136&lt;/code&gt;）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;fail-open + 阈值监控&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;02 篇坑 4 的教训：超时丢弃是静默的，必须靠耗时分布监控发现（该拦没拦且耗时诡异停在 2s 就是信号）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety 整体挂（api 不可达）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;业务方调审核接口失败&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;建议 fail-close，配额降级&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;输入审核 fail-close 拦不了就拒答；出向 free_taxi 本来就是异步，api 挂了影响的是检测结果回流，可短窗 fail-open&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;admin 挂了&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;天然 fail-open&lt;/strong&gt;：admin 不在请求链路上，api 靠内存缓存继续跑（03 篇认知 1）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;fail-open（架构自带）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;只是不能再改配置；且 &lt;code&gt;shouldUpdate&lt;/code&gt; 有保底：拉取失败/配置为空时保留旧配置不丢（&lt;code&gt;DynamicConfigService.java:116-119&lt;/code&gt; 注释&amp;quot;防止出现异常时丢失配置&amp;quot;）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MySQL/Redis/Vearch 挂&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;api 不直连 MySQL 无影响；Redis 挂=free_taxi/会话历史/结果缓存全瘫；Vearch 挂=知识库能力瘫&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Redis 必须高可用&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;开源版全部没挂数据卷（03 篇 7.2 坑 3），&lt;code&gt;docker compose down&lt;/code&gt; 即丢全部配置——生产化第一项改造（11 篇）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="42-兜底策略的三条元规则"&gt;&lt;a href="#42-%e5%85%9c%e5%ba%95%e7%ad%96%e7%95%a5%e7%9a%84%e4%b8%89%e6%9d%a1%e5%85%83%e8%a7%84%e5%88%99" class="header-anchor"&gt;&lt;/a&gt;4.2 兜底策略的三条元规则&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;数据类故障（脱敏、密钥）一律 fail-close&lt;/strong&gt;，内容类故障可按业务容忍度选 fail-open——泄露不可逆，误拦可申诉。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;fail-open 必须配监控&lt;/strong&gt;，否则就是&amp;quot;静默裸奔&amp;quot;。JoySafety 的失败全部是静默的：超时丢结果（&lt;code&gt;ParallelFunction.java:132-135&lt;/code&gt; 只打 error 日志+计数）、异常忽略（&lt;code&gt;FunctionExecutorImpl.java:320&lt;/code&gt; 同样只打日志）。好在框架内置了 &lt;code&gt;MonitorAlarmService&lt;/code&gt; 计数（如 &lt;code&gt;parallelIncr&lt;/code&gt;、&lt;code&gt;functionIncr&lt;/code&gt;、&lt;code&gt;apiPlanIncr&lt;/code&gt;），把这些计数接入告警是生产化的必修课。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;降级不等于关闭&lt;/strong&gt;：JoySafety 挂了可以临时降级为&amp;quot;只过网关词库&amp;quot;（网关侧词表保持一份最小黑名单的意义就在这里）；脱敏挂了没有降级方案，只能拒答——所以脱敏插件的规则集要刻意保持小而稳。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="五统一审计与运营"&gt;&lt;a href="#%e4%ba%94%e7%bb%9f%e4%b8%80%e5%ae%a1%e8%ae%a1%e4%b8%8e%e8%bf%90%e8%90%a5" class="header-anchor"&gt;&lt;/a&gt;五、统一审计与运营&#10;&lt;/h2&gt;&lt;h3 id="51-三层日志汇集"&gt;&lt;a href="#51-%e4%b8%89%e5%b1%82%e6%97%a5%e5%bf%97%e6%b1%87%e9%9b%86" class="header-anchor"&gt;&lt;/a&gt;5.1 三层日志汇集&#10;&lt;/h3&gt;&lt;p&gt;三层各有一套&amp;quot;拦截证据&amp;quot;，格式完全不同，统一审计的第一步是&lt;strong&gt;用 requestId 贯穿&lt;/strong&gt;：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;层&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;拦截证据&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;关键字段&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;WAF 审计日志、限流 429 日志&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;命中规则 id（如 CRS 942/930）、租户、IP&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;脱敏&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关日志中的 deny_message 返回、替换计数&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;命中词/规则、是否 restore&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;审核响应 + &lt;code&gt;MonitorAlarmService&lt;/code&gt; 计数&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;riskCode&lt;/code&gt;（1002 暴恐/1006 辱骂/201 注入…）、&lt;code&gt;riskCheckType&lt;/code&gt;（keyword/single_label_pred/rag_answer）、&lt;code&gt;hitWord&lt;/code&gt;、置信度（02 篇实测响应样例）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;落地方案：网关和脱敏在入口生成/透传 &lt;code&gt;X-Request-Id&lt;/code&gt;，JoySafety 请求体自带 &lt;code&gt;requestId&lt;/code&gt; 且参与 HMAC 签名（&lt;code&gt;SignUtil.java:45&lt;/code&gt;），三层日志按 requestId join 进同一个 OLAP/ES 索引。&lt;/p&gt;&#10;&lt;h3 id="52-拦截事件归因"&gt;&lt;a href="#52-%e6%8b%a6%e6%88%aa%e4%ba%8b%e4%bb%b6%e5%bd%92%e5%9b%a0" class="header-anchor"&gt;&lt;/a&gt;5.2 拦截事件归因&#10;&lt;/h3&gt;&lt;p&gt;收到一条拦截告警后的归因决策树：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-4-1"&gt;&lt;a class="lnlinks" href="#hl-4-1"&gt; 1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-2"&gt;&lt;a class="lnlinks" href="#hl-4-2"&gt; 2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-3"&gt;&lt;a class="lnlinks" href="#hl-4-3"&gt; 3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-4"&gt;&lt;a class="lnlinks" href="#hl-4-4"&gt; 4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-5"&gt;&lt;a class="lnlinks" href="#hl-4-5"&gt; 5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-6"&gt;&lt;a class="lnlinks" href="#hl-4-6"&gt; 6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-7"&gt;&lt;a class="lnlinks" href="#hl-4-7"&gt; 7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-8"&gt;&lt;a class="lnlinks" href="#hl-4-8"&gt; 8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-9"&gt;&lt;a class="lnlinks" href="#hl-4-9"&gt; 9&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-10"&gt;&lt;a class="lnlinks" href="#hl-4-10"&gt;10&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-11"&gt;&lt;a class="lnlinks" href="#hl-4-11"&gt;11&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-4-12"&gt;&lt;a class="lnlinks" href="#hl-4-12"&gt;12&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;拦截事件&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 状态码 403 + WAF 规则 id？ → 网关层，查 CRS/自定义规则误报率&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 状态码 429？ → 网关限流，查租户配额是否该扩&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 返回体是 deny_message？ → 脱敏层词库命中（注意：可能是 PII 规则误伤正常数字串）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ code=0 且 riskCode≠0？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ riskCheckType=keyword → JoySafety 词库，看 bwgLabel（1黑/2白/3灰）与 hitWord&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ riskCheckType=single_label_pred → BERT，看置信度是否贴着阈值线（阈值表见&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ docs/strategy_example.yml:94-95，如 1003涉黄 0.85、1004涉赌 0.996）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ riskCheckType=rag_answer/… → 知识库代答/多轮，查知识命中分数&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ &amp;#34;该拦没拦&amp;#34;（漏报）？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 耗时诡异停在超时值附近 → 超时丢结果（02 篇坑 4，ParallelFunction.java:130）&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 跨 chunk 内容逃逸 → free_taxi/滑动窗口的固有边界（网关安全插件-2 第 3.2/4.1 节）&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="53-策略分层维护节奏"&gt;&lt;a href="#53-%e7%ad%96%e7%95%a5%e5%88%86%e5%b1%82%e7%bb%b4%e6%8a%a4%e8%8a%82%e5%a5%8f" class="header-anchor"&gt;&lt;/a&gt;5.3 策略分层维护节奏&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;层&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;策略载体&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;变更方式&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;建议节奏&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;生效延迟&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关 WAF&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;控制台 YAML&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;先 &lt;code&gt;DetectionOnly&lt;/code&gt; 观察 1-3 天再切 &lt;code&gt;On&lt;/code&gt;（POC 建议）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;月级/随 CRS 升级&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;秒级&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关限流&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;控制台 YAML&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;直接改&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;随业务活动（大促前压测调整）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;秒级&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;脱敏规则&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;控制台 YAML&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;新增规则先小流量灰度；规则集刻意保持小（4.2 条 3）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;季度级，谨慎&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;秒级&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety 词库&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MySQL（admin API）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;upsert→online，走黑白灰策略&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;周级/舆情驱动&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;~60s（keywords 轮询，&lt;code&gt;SensitiveWordsManageServiceImpl.java:194&lt;/code&gt;）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety DAG/能力&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MySQL 版本化状态机&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;active→newVersion→update→upgrade（03 篇 4.2，online 禁原地改）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;按需，灰度可用 AB 按 dagVersion 指定版本&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;最长 ~60s（api 轮询，&lt;code&gt;DynamicConfigService.java:65&lt;/code&gt;；原子能力类变更实践上需重启 api，02 篇坑 5）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JoySafety 模型&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HuggingFace 模型目录&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;换模型目录+重建容器&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;跟随官方模型迭代（如注入模型二分类→三分类）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;重启级&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="六系列总结与展望"&gt;&lt;a href="#%e5%85%ad%e7%b3%bb%e5%88%97%e6%80%bb%e7%bb%93%e4%b8%8e%e5%b1%95%e6%9c%9b" class="header-anchor"&gt;&lt;/a&gt;六、系列总结与展望&#10;&lt;/h2&gt;&lt;h3 id="61-12-篇知识地图回顾"&gt;&lt;a href="#61-12-%e7%af%87%e7%9f%a5%e8%af%86%e5%9c%b0%e5%9b%be%e5%9b%9e%e9%a1%be" class="header-anchor"&gt;&lt;/a&gt;6.1 12 篇知识地图回顾&#10;&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-5-1"&gt;&lt;a class="lnlinks" href="#hl-5-1"&gt; 1&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-2"&gt;&lt;a class="lnlinks" href="#hl-5-2"&gt; 2&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-3"&gt;&lt;a class="lnlinks" href="#hl-5-3"&gt; 3&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-4"&gt;&lt;a class="lnlinks" href="#hl-5-4"&gt; 4&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-5"&gt;&lt;a class="lnlinks" href="#hl-5-5"&gt; 5&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-6"&gt;&lt;a class="lnlinks" href="#hl-5-6"&gt; 6&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-7"&gt;&lt;a class="lnlinks" href="#hl-5-7"&gt; 7&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-8"&gt;&lt;a class="lnlinks" href="#hl-5-8"&gt; 8&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-9"&gt;&lt;a class="lnlinks" href="#hl-5-9"&gt; 9&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-10"&gt;&lt;a class="lnlinks" href="#hl-5-10"&gt;10&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-11"&gt;&lt;a class="lnlinks" href="#hl-5-11"&gt;11&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-12"&gt;&lt;a class="lnlinks" href="#hl-5-12"&gt;12&lt;/a&gt;&#10;&lt;/span&gt;&lt;span class="lnt" id="hl-5-13"&gt;&lt;a class="lnlinks" href="#hl-5-13"&gt;13&lt;/a&gt;&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;入门篇 01 功能验证 ──────── 跑通四个官方案例，建立&amp;#34;它能干什么&amp;#34;的直觉&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 02 Mac 本地部署 ──── 跑起来 + 6 个踩坑（Rosetta/超时/缓存），故障决策树&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;架构篇 03 技术架构分析 ──── 配置期/执行期分离、admin 不在链路上、api 不直连 MySQL&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 04 DAG 编排引擎 ──── Function/Router/Node 三要素，名义 DAG 实为链式逐跳&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 05 FreeTaxi 模式 ─── 流式场景的工程化解法：Redis 队列+会话锁+结果搭便车&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;能力篇 06 敏感词服务 ────── AC 自动机+正则倒排，黑白灰四策略&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 07 知识库与 RAG ──── Vearch+bge，代答一致性校验双保险&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 08 提示词注入 ────── 二分类→三分类，红蓝军对抗&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;实战篇 09 自定义原子能力 ── 起服务→注册→DAG 引用，不改一行 Java&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 10 业务接入全流程 ── accessKey/secretKey/HMAC-SHA1/QPS&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;生产篇 11 生产化改造清单 ── 数据卷、mq stub 补实现、热更新、监控&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 12 三层防护体系串联（本篇）── JoySafety×网关×脱敏 组装成方案&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;番外篇 13 方案横评 / 14 模型横评 / 15 红队评测（待写）&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;一句话收束整个系列：&lt;strong&gt;JoySafety 的内核是&amp;quot;配置版本化 + DAG 编排 + 无状态 skill&amp;quot;三板斧，把它放进三层防护体系里，它负责的是最需要智能、也最贵的那一段。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h3 id="62-官方-roadmap-展望readmemd346-353-计划-一节原文摘录转述"&gt;&lt;a href="#62-%e5%ae%98%e6%96%b9-roadmap-%e5%b1%95%e6%9c%9breadmemd346-353-%e8%ae%a1%e5%88%92-%e4%b8%80%e8%8a%82%e5%8e%9f%e6%96%87%e6%91%98%e5%bd%95%e8%bd%ac%e8%bf%b0" class="header-anchor"&gt;&lt;/a&gt;6.2 官方 roadmap 展望（README.md:346-353 &amp;ldquo;📅计划&amp;rdquo; 一节，原文摘录转述）&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;方向&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;官方表述要点&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;对三层体系的意义&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;安全审核大模型&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HuggingFace 已开源部分模型 &lt;code&gt;JSL-joysafety-v1&lt;/code&gt;（README.md:349），后续 JoySafety 集成该系列实现大模型风险合规审计&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;内容层从&amp;quot;BERT 小模型分类&amp;quot;升级到&amp;quot;审核专用大模型&amp;quot;，语义判定能力质变；对网关/脱敏层无影响，接口层不变&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;大模型安全评测&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;覆盖《生成式人工智能服务安全基本要求》5 大类 31 小类风险类型（README.md:351）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;给三层体系提供&lt;strong&gt;量化验收标准&lt;/strong&gt;——每层拦哪几小类、漏哪几小类，可以按国标口径出报告（本系列 15 篇红队评测的对接点）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Agent 安全防护&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;身份与权限管理、数据与记忆防护、工具与执行安全、MCP 代码安全检测、供应链与协议安全（README.md:353）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;三层体系的前瞻缺口：Agent 场景下&amp;quot;工具调用参数&amp;quot;和&amp;quot;MCP 协议&amp;quot;既不是纯流量也不是纯文本内容，现有三层都罩不全，是下一个架构演进点&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="63-留给实践的开放问题"&gt;&lt;a href="#63-%e7%95%99%e7%bb%99%e5%ae%9e%e8%b7%b5%e7%9a%84%e5%bc%80%e6%94%be%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;6.3 留给实践的开放问题&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;free_taxi 的跨 chunk 漏检与脱敏插件滑动窗口如何组合（网关安全插件-2 第 4.1 节的方向），需要一次联合实验；&lt;/li&gt;&#10;&lt;li&gt;脱敏插件流式响应&amp;quot;拦截后 finish 时吐出剩余内容&amp;quot;的疑似 Bug（网关安全插件-2 第 3.1 节）需要上游修复或规避，出向兜底策略据此调整；&lt;/li&gt;&#10;&lt;li&gt;Agent 安全防护落地时，三层模型的&amp;quot;流量/数据/内容&amp;quot;划分需要扩展第四层&amp;quot;行为/工具&amp;quot;——这是官方 roadmap 给出明确信号、但开源代码尚未覆盖的领域。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="附本篇引用的源码坐标汇总"&gt;&lt;a href="#%e9%99%84%e6%9c%ac%e7%af%87%e5%bc%95%e7%94%a8%e7%9a%84%e6%ba%90%e7%a0%81%e5%9d%90%e6%a0%87%e6%b1%87%e6%80%bb" class="header-anchor"&gt;&lt;/a&gt;附：本篇引用的源码坐标汇总&#10;&lt;/h2&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;机制&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;位置&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;审核入口/限流/验签/模式分派&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/src/main/java/com/jd/security/llmsec/contoller/DefenseApiV2Controller.java:31-120&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HMAC-SHA1 签名&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-basic/src/main/java/com/jd/security/llmsec/core/util/SignUtil.java:36,62&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Guava RateLimiter 内存级限流&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../service/RateLimitServiceImpl.java:7,30,69&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;识别结果缓存 15 分钟（user 且单条）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../service/execute/FunctionExecutorImpl.java:247,253-254,275-287&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;配置 60s 轮询/变更判断/保底不丢配置&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../service/DynamicConfigService.java:65,142-144,116-119&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DAG 主循环/超时检查/ignoreError&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../service/execute/FunctionExecutorImpl.java:289,297-299,312-323&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;parallel 超时丢弃/线程池/归约&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../service/execute/functions/ParallelFunction.java:87-92,130-136,142-172&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;free_taxi 任务执行/会话锁&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../service/task/TaskExecutorImpl.java:56-63,78-110&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;AC 自动机敏感词&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-skills/safety-keywords/.../service/data/SensitiveWordDetector.java:14-15&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;敏感词定时轮询重建&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-skills/safety-keywords/.../service/data/SensitiveWordsManageServiceImpl.java:194&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;四种 match_type/黑白灰策略/QPS 字段&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-admin/docs/tables.sql:9,10,41&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;7000 字截断&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;safety/safety-api/.../config/GlobalConf.java:49&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;演示 DAG（阈值表/ignoreError）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;docs/strategy_example.yml:23,65,94-95,107,114&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;官方 roadmap&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;README.md:346-353&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;脱敏插件机制（Rust/WASM，源码不在本仓库）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;引自 &lt;code&gt;../../maas-safe-doc/安全护栏/poc/网关脱敏插件实现原理分析-ai-data-masking-脱敏与还原.md&lt;/code&gt;（其中 &lt;code&gt;ai_data_masking.rs:431-486&lt;/code&gt;、&lt;code&gt;deny_word.rs:63-70&lt;/code&gt; 等坐标为该笔记核实结果）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网关插件能力与问题清单&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;引自 &lt;code&gt;../../maas-safe-doc/安全护栏/poc/网关安全插件-1-基础功能验证.md&lt;/code&gt;、&lt;code&gt;-2-高级能力验证以及存在的问题分析.md&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;</description></item></channel></rss>