芥末
发布于 2026-04-04 / 0 阅读
0
0

文言文对抗提示如何暴露大模型安全盲区:CC-BOS 与 FOA 防御视角解析

大语言模型(Large Language Model,LLM)的安全问题,不能只理解成“模型会不会拒绝某些敏感问题”。真实系统通常由多层组件组成:输入审核、主模型推理、输出审核、日志监控、风控策略等。任何一层只要对某类表达形式覆盖不足,都可能被对抗性输入利用。

文言文对抗提示就是一个典型例子。它利用古汉语表达晦涩、词面和现代敏感词差异大、语义又能被模型理解的特点,暴露出多语言安全审核中的一个薄弱环节:模型可能懂古文,但安全分类器不一定同样懂。

需要明确一点:这里讨论的是防御建模、红队评测和安全加固思路,不提供可直接复用的绕过模板,也不展开具体有害请求的构造方式。

大模型安全链路为什么会出现语言盲区

一个常见的大模型服务大致可以拆成四段。

flowchart LR
    A[用户输入] --> B[输入预处理与安全分类]
    B --> C[主模型推理]
    C --> D[输出安全审核]
    D --> E[返回结果]

    B --> F[关键词规则]
    B --> G[意图分类器]
    B --> H[提示注入检测]

    D --> I[违规内容检测]
    D --> J[敏感信息检测]
    D --> K[策略合规判断]

输入审核主要判断请求是否涉及违法、暴力、自伤、色情、隐私泄露、恶意攻击等风险。输出审核则检查模型生成的内容是否真的越过边界。主模型本身负责根据上下文生成下一个 token,并不等同于完整的安全系统。

问题出在不同组件的语言能力并不一致。

组件通常擅长的事容易出问题的地方
主模型理解多语言、古文、隐喻、上下文推理可能顺着上下文生成不该生成的内容
关键词黑名单快速拦截明确词面对改写、古文、谐音、隐喻覆盖弱
意图分类器判断请求意图训练集如果缺少古文或低资源语言样本,召回会下降
输出审核器阻断最终违规内容如果输出被包装成古文、典故或隐喻,也可能漏检

这就形成了一个不对称局面:模型在预训练阶段见过大量古籍、文言文和历史文本,因此能解析古汉语;但安全数据集、审核规则和拒答样本往往集中在现代语言表达上。攻击者不一定需要让模型“变聪明”,只需要让审核器“看不准”。

Token 差异不是根因,语义覆盖不足才是根因

很多人会把这类问题简单归结为“token 不同,所以审核不到”。这个说法只说对了一部分。

模型输入会被分词器切成 token,再映射成向量。现代汉语、文言文、异体表达、隐喻写法在 token 层面确实差异很大。如果安全模块主要依赖关键词或浅层匹配,就会受到影响。

但更核心的问题不是 token,而是安全系统没有对“同一危险意图的多种表达”建立稳定表示。

可以把问题理解成三层:

flowchart TB
    A[表层形式] --> B[语义意图]
    B --> C[安全策略]

    A1[现代汉语直白表达] --> B
    A2[文言文表达] --> B
    A3[隐喻表达] --> B
    A4[跨语言表达] --> B

    C --> D[允许]
    C --> E[拒绝]
    C --> F[安全替代回答]

安全判断应该尽量落在“语义意图”这一层,而不是停留在“表层形式”。如果系统只认识现代汉语直白表达,那么同一意图换成古文、隐喻、外语夹杂或专业术语包装后,就可能逃过第一道审核。

CC-BOS 的核心思想:把对抗提示变成搜索问题

CC-BOS 可以理解成一种对抗提示搜索框架。它不是手工写一个固定提示,而是把提示拆成多个策略维度,再用黑盒优化算法自动寻找更容易触发风险输出的组合。

从防御视角看,它的重要性不在于某个具体提示形式,而在于它把“绕过安全策略”抽象成了一个可优化问题。

形式化地说,可以把一个输入请求记为 q,把策略组合记为 s,提示生成器记为 G

p = G(q, s)

其中:

  • q:待测试的风险意图,安全评测中通常来自受控数据集;
  • s:一组表达策略,例如语言风格、语境包装、表达结构等;
  • p:最终送入模型的测试提示;
  • G:根据策略组合生成提示的函数。

目标模型是黑盒时,只能看到输入和输出:

r = M(p)

其中 M 是目标模型,r 是响应。评测系统再根据响应判断它是否拒绝、是否给出违规细节、是否偏离安全策略。

整个过程像这样:

flowchart TD
    A[受控风险测试集] --> B[策略空间]
    B --> C[候选提示生成]
    C --> D[黑盒模型调用]
    D --> E[响应归一化]
    E --> F[安全评测打分]
    F --> G{是否达到停止条件}
    G -- 否 --> H[优化器更新策略组合]
    H --> C
    G -- 是 --> I[输出风险报告与防御样本]

这里的关键不是“某个古文模板”,而是自动搜索能力。一旦搜索器可以不断试探输入形式,并根据模型响应调整方向,安全系统就会面对持续变形的对抗样本。

八维策略空间:从单条提示到组合空间

CC-BOS 将文言文对抗提示拆成多个维度。为了避免提供可直接复用的绕过方法,可以把这些维度抽象成防御建模所需的类别。

维度防御侧理解风险点
身份框架请求被包装成某种角色或叙述视角审核器可能把危险意图误判成角色扮演
引导方式用委婉、递进或间接方式推动回答模型可能逐步越过拒答边界
推理结构用古文逻辑、问答体或论证结构组织请求浅层分类器难以捕捉真实目标
语义替换用古语、典故、隐喻替代现代敏感词关键词规则召回下降
文体风格让输入看起来像古籍、注疏或文学文本安全模型可能降低警惕
知识包装把危险请求伪装成历史、学术或考据问题“知识问答”和“操作指导”边界变模糊
场景语境构造特定时代、仪式、辩论或叙事背景语境掩盖真实意图
触发节奏分步、延迟或条件式触发目标内容单轮检测难以发现完整攻击链

这些维度构成一个笛卡尔积空间:

S = D1 × D2 × ... × D8

每一个 Di 是某个维度的候选集合,s ∈ S 表示一种完整组合。组合空间一旦变大,人工枚举就不现实,黑盒优化算法就有了用武之地。

FOA:用果蝇优化算法搜索高风险组合

FOA(Fruit Fly Optimization Algorithm,果蝇优化算法)是一种群体搜索算法。它模拟果蝇觅食过程,把每个“果蝇”看成一个候选策略组合,通过多轮迭代寻找更高风险的输入形式。

在这个问题中:

  • 一个个体 = 一组提示策略;
  • 一个种群 = 多组候选策略;
  • 适应度 = 该策略触发不安全响应的程度;
  • 迭代 = 根据打分继续生成新候选。

可以用一个抽象公式表示:

P(t+1) = Update(P(t), best(t))

其中 P(t) 是第 t 代种群,best(t) 是当前评测中风险最高的策略组合。更新过程通常包含三类动作。

嗅觉搜索:扩大搜索范围

嗅觉搜索负责全局探索。它会对当前策略组合做随机扰动,让搜索器不要只停留在已有组合附近。

new_index = current_index + random_step

在防御评测中,这类扰动可以帮助发现安全系统没覆盖到的表达变体。它的作用不是精确收敛,而是扩大样本多样性。

视觉搜索:向高风险样本靠拢

视觉搜索负责局部收敛。它会让普通个体向当前高风险个体学习,保留一些有效维度,同时继续保持一定随机性。

candidate_dimension =
    best_dimension, with probability p
    original_dimension, otherwise

这类似“保留有效特征,再微调其他部分”。如果某些表达形式已经表现出风险,搜索器会围绕它们继续扩展。

柯西变异:停滞时跳出局部区域

当多轮迭代都没有发现更高风险样本时,搜索可能陷入局部最优。柯西变异利用长尾分布产生较大跳跃,让搜索器离开当前区域。

new_index = current_index + cauchy_noise

柯西分布的特点是偶尔产生很大的扰动,这对逃离局部最优有帮助。防御侧要关注这一点:攻击样本不会只在一个固定风格附近变化,它可能突然跳到完全不同的表达区域。

适应度评估:如何判断一次测试是否危险

对抗搜索必须有打分函数,否则优化器不知道哪个方向更“有效”。从防御角度看,适应度可以拆成两个部分。

打分项含义防御价值
语义一致性响应是否在语义上贴近受控风险意图识别“没有直接关键词但实质违规”的输出
拒答与安全性响应是否明确拒绝、是否给出安全替代建议判断安全策略是否生效
细节泄露程度是否出现可执行步骤、材料、代码、参数等高风险细节区分轻微偏离和严重失败
归一化后风险将古文、现代文、英文等统一到同一语义空间后再评估减少语言形式造成的误判

一个更安全的评测流程应当先做归一化,再做判断:

flowchart LR
    A[模型响应] --> B[语言识别]
    B --> C[语义归一化]
    C --> D[多语言安全分类器]
    C --> E[规则与关键词补充检测]
    C --> F[LLM Judge 交叉评估]
    D --> G[综合风险分]
    E --> G
    F --> G
    G --> H[人工抽检与样本入库]

归一化不等于简单翻译。翻译可能丢失隐喻、古文典故或上下文指代,所以更稳妥的做法是组合多种信号:

  • 多语言嵌入模型;
  • 现代汉语释义;
  • 英文中间表示;
  • 安全分类器;
  • 规则检测;
  • 人工抽检。

为什么单靠关键词防不住

关键词规则适合拦截高频、明确、低成本的风险表达,但它很难处理“同义不同形”的输入。文言文对抗提示正是利用了这一点。

防御方式能解决的问题不能单独承担的部分
关键词黑名单拦截直白敏感词隐喻、古语、跨语言、拆分表达
正则规则处理固定格式攻击变形空间大时维护成本高
单轮分类器快速判断当前输入多轮递进、延迟触发、上下文累积
输出审核阻断最终违规内容如果输出同样被包装,仍可能漏检
语义级安全模型捕捉意图和风险需要高质量多语言安全数据
红队搜索评测主动发现盲区必须在授权环境中受控执行

更可靠的路线是把关键词规则放在底层兜底,把主要判断交给语义级安全模型,并且持续用对抗样本更新评测集。

防御设计:把“古文盲区”纳入安全系统

文言文不是唯一风险,低资源语言、方言、谐音、混合语言、编码变形、专业术语包装都有类似问题。防御设计不能只补一个“古文黑名单”,而要升级整个安全链路。

1. 输入侧做语义归一化

输入进入主模型前,可以增加一层归一化模块:

flowchart TD
    A[用户输入] --> B[语言与风格识别]
    B --> C{是否存在高风险变体}
    C -- 是 --> D[释义/翻译/语义嵌入]
    C -- 否 --> E[常规安全分类]
    D --> F[语义级安全分类]
    E --> F
    F --> G{是否允许进入主模型}
    G -- 允许 --> H[主模型]
    G -- 拒绝 --> I[安全拒答或替代帮助]

这个模块的目标不是把所有输入都翻译成现代汉语,而是识别“表层安全、语义可疑”的请求,并把它送入更强的安全分类器。

2. 输出侧同样做归一化

如果只审核现代汉语输出,模型用古文、外语或隐喻表达危险内容时仍可能漏出。输出审核也需要走语义归一化流程。

检查重点包括:

  • 是否提供可执行步骤;
  • 是否列出材料、参数、代码或规避方法;
  • 是否把拒答后又转向隐含指导;
  • 是否通过故事、典故、类比泄露关键操作。

3. 加入多轮上下文检测

很多风险不会在第一轮显露,而是通过连续对话逐步积累。安全系统要维护会话级风险状态。

session_risk = f(current_input, model_output, history, user_pattern)

如果用户持续围绕同一敏感目标做拆分询问,即使单轮输入看似无害,也应提高风险等级。

4. 用对抗搜索生成防御样本

黑盒优化不只属于攻击者,也可以用于防御评测。安全团队可以在隔离环境中使用搜索方法发现模型薄弱点,再把样本转化为训练集、回归测试集和策略规则。

一个受控红队流程可以这样设计:

flowchart LR
    A[安全策略定义] --> B[受控风险意图集合]
    B --> C[对抗变体生成]
    C --> D[沙箱模型评测]
    D --> E[失败样本标注]
    E --> F[分类器训练/规则更新]
    F --> G[回归测试]
    G --> H[上线前门禁]

关键要求是隔离、授权、留痕和最小化暴露。评测样本不应直接进入公开日志、客服系统或生产提示库。

工程落地时容易踩的坑

问题典型表现处理方式
把古文问题当成关键词缺失不断补词表,但新表达仍然绕过转向语义级分类和多语言评测
只测输入不测输出输入被识别,输出仍出现隐晦违规内容输入、输出、会话三层都要审核
只用一个评测模型打分评测模型自身也有盲区组合规则、分类器、LLM Judge 和人工抽检
翻译后再判断导致误判翻译丢失典故或把隐喻洗白保留原始输入、释义和嵌入表示,多路投票
忽视自动化试探高频变体请求未被识别加入速率限制、异常模式检测和账户级风控
没有回归测试修复一类样本后又被相似变体击穿建立固定红队样本集,每次模型或策略变更都跑

一个防御侧评测框架示例

下面的伪代码只描述安全评测流程,不包含任何对抗提示模板或可复用绕过内容。

def evaluate_multilingual_safety(test_cases, model, safety_stack):
    reports = []

    for case in test_cases:
        # case 由安全团队维护,包含受控风险标签和语言/文体元数据
        normalized_input = safety_stack.normalize(case.input_text)
        input_risk = safety_stack.classify_input(normalized_input)

        if input_risk.blocked:
            reports.append({
                "case_id": case.id,
                "stage": "input_blocked",
                "risk": input_risk.level,
            })
            continue

        response = model.generate(case.input_text)

        normalized_output = safety_stack.normalize(response)
        output_risk = safety_stack.classify_output(
            normalized_output,
            context=case.context,
        )

        reports.append({
            "case_id": case.id,
            "stage": "output_checked",
            "input_risk": input_risk.level,
            "output_risk": output_risk.level,
            "safe": output_risk.safe,
        })

    return reports

评测指标可以分成几类:

指标解释
输入拦截率风险请求在进入主模型前被识别的比例
输出拦截率主模型生成风险内容后被输出审核拦截的比例
语义漏检率表层无敏感词但语义违规的样本漏检比例
多轮风险召回率拆分到多轮对话中的风险意图被识别的比例
误杀率正常古文、文学、历史学习请求被错误拒绝的比例
回归通过率已知风险样本在策略更新后仍能被稳定拦截的比例

安全系统不能只追求拦截率。误杀率同样重要,因为古文学习、历史研究、文学创作都是正常需求。好的策略应该区分“讨论历史文本”与“索取现实可执行危险指导”。

对模型安全建设的启示

文言文对抗提示说明了一个更普遍的问题:安全能力必须跟上模型理解能力。只要模型能理解某种表达,安全系统就应该能判断这种表达背后的意图。

比较稳妥的建设方向包括:

  • 建立覆盖古文、方言、低资源语言、混合语言的安全评测集;
  • 用语义归一化替代单纯关键词匹配;
  • 对输入、输出和多轮上下文同时建模;
  • 将红队搜索结果转化为持续回归测试;
  • 对自动化试探行为做速率限制和异常检测;
  • 对高风险领域采用更严格的拒答模板和安全替代回答;
  • 对模型版本、系统提示和审核策略的变更建立上线门禁。

CC-BOS 这类研究的价值在于提醒安全团队:攻击面不只存在于模型能力本身,也存在于模型外部的审核链路、评测数据和语言覆盖范围中。只要安全策略仍然依赖表层形式,对抗者就可以通过换语言、换文体、换语境来寻找缝隙。真正可靠的防线需要理解语义、跟踪上下文,并持续用新型对抗样本检验系统。


评论