先说结论别等大模型把脏东西吐出来才慌得在它和用户之间架一层出口闸——命中敏感词就拦、就替换、就兜底回一句安全话术。我自己踩完坑给的最实用做法是DFA 多模式匹配做识别再配一套兜底文案做替换最后留一个模型也可能漏判的二次复核。下面按 问题→分析→方案 三段讲带步骤和我自己的踩坑。一、问题模型嘴上没把门业务背锅我做的是一个客服性质的问答小助手给一个卖家居用品的客户用的。上线第三天就出事了——有个用户故意问你们这破枕头是不是垃圾竞品XX牌是不是更好模型挺老实地把竞品名字、还有一句带情绪的评价原样夹在回答里发出去了。客户截图发我问号脸。问题不止这一个政治、涉黄涉暴这种红线词模型大部分时候会拒答但总有 5% 左右的边角 case 漏出来尤其用户用谐音、拆字、空格分隔绕的时候竞品品牌名、内部代号、还没公开的活动价这些不是违法但客户不想让 AI 嘴里出现模型偶尔会自己脑补一个客服热线号码编得有鼻子有眼这个比说脏话还麻烦。说白了大模型的安全是它训练时的安全不等于你这个业务的合规。业务规则它根本不知道。二、分析拦在哪一层怎么拦我前后试过三个位置记一下对比省得你也绕拦截位置做法我的体感改 Prompt在 system 里写禁止提及竞品/脏话能压一部分但模型说漏就漏不可控靠概率不靠谱模型自带安全开关厂商的内容安全 API红线词管用但管不了竞品名这种业务私有词出口做后置过滤回答生成完发给用户前再过一道最稳规则在我手里想加词就加词结论很直接Prompt 约束 出口后置过滤两道一起上。Prompt 负责把大头压下去出口过滤负责兜那漏网的 5%。后置过滤的核心是个匹配效率问题。敏感词表我手上这份有 4000 多个词一条回答几百字要是拿正则一个个if in去撞几千个词循环下来响应明显卡。所以识别得用DFA确定有限状态机把词表预编译成一棵字典树一次扫描过完全文O(n) 复杂度n 是文本长度跟词表多大基本无关。三、方案DFA 过滤 兜底替换分四步步骤 1把敏感词建成 DFA 字典树不用上来就装第三方库Python 拿 dict 嵌套就能搭几十行class SensitiveFilter: def __init__(self, words): self.root {} for w in words: node self.root for ch in w: node node.setdefault(ch, {}) node[_end_] True # 词尾标记 def find_all(self, text): hits [] for i in range(len(text)): node, j self.root, i while j len(text) and text[j] in node: node node[text[j]] if _end_ in node: hits.append((i, j, text[i:j1])) j 1 return hits词表我分了几类放不同文件red.txt红线命中直接拦、brand.txt竞品/品牌命中替换成某品牌、internal.txt内部词命中删掉。分类的好处是不同类走不同兜底策略下一步说。步骤 2命中后分级处理别一刀切全拦def guard(text, filters): # 红线整条回答作废换安全话术 if filters[red].find_all(text): return 这个问题我不太方便回答要不咱们聊点别的 # 品牌词替换不删句 for s, e, w in filters[brand].find_all(text): text text.replace(w, 某同类产品) # 内部词直接抹掉 for s, e, w in filters[internal].find_all(text): text text.replace(w, ) return text兜底文案这块我吃过亏第一版我让命中红线就回您的问题包含敏感内容已被拦截结果用户更炸毛觉得被当坏人了。后来改成上面那种软话术把球踢回对话流投诉立刻少了。文案得当人话写别像报警器。步骤 3堵谐音和拆字绕过纯字符匹配挡不住枕*头枕 头这种插符号、加空格的。处理也简单——匹配前先把文本里的特殊符号、多余空格洗掉再过 DFAimport re def normalize(text): return re.sub(r[\s\*\.·\-_], , text)谐音比如用拼音首字母、同音字代替这层我没死磕投入产出比太低靠后面第 4 步的模型二次复核去捞工程上认怂有时候是对的。步骤 4上一层语义复核兜最后的底DFA 只认字面词认不出你们老板是不是跑路了这种没有敏感词、但语义有风险的句子。这层我没自己训模型直接挂了个现成大模型当二次裁判把过滤后的回答连同一句判断这段话是否涉及法律/政治/对公司的负面指控只回 safe 或 risk丢给它返回 risk 就走兜底话术。这套二次复核我是搭在一个零代码就能配智能体的平台上做的——拖个节点、挂上知识库、把上面这套过滤逻辑接成一个处理环节不用我自己起服务部署模型。说实话第一次见到不写后端就能把识别→复核→兜底串成一条能跑的链路我还挺意外的。缺点也有这种语义复核每条多花一次模型调用响应慢个三五百毫秒高并发场景我只对客服投诉类会话开普通寒暄不开省点是点。整套上线后漏网率从我抽样的 5% 压到了千分之几剩下的基本是谐音绕过那种长尾认了。最大的体会是合规这事别指望模型自觉闸门攥在自己手里才踏实——DFA 管字面、语义复核管意思、兜底文案管体验三层各干各的。你们给 Agent 做合规过滤是怎么处理谐音绕过的评论区蹲一个更狠的方案。二次复核那层的模型我走的是讯飞星辰MaaS现成 API 调没自己部署算力省了一台 GPU 机的钱。