医疗问答大模型的越狱:让模型开具违规处方的诱导路径
医疗问答大模型的越狱:让模型开具违规处方的诱导路径
一、当模型开始开处方:医疗问答的合规悬崖
医疗问答大模型上线后,最常见的滥用方向"让它开药"。处方权在现实里受严格管制,但在对话窗口里,模型只要被绕过对齐,就能给出一份看似专业的用药清单。这条线一旦越过,伤害直接落在患者身上。
越狱攻击在医疗场景里有个危险的放大效应:模型输出的处方带着"专业语气"。患者分不清"模型建议"和"医生医嘱"。剂量、禁忌、联合用药一旦出错,就是真实的药害事件,危害比通用聊天场景大得多。
更棘手的是多轮诱导的隐蔽性。攻击者不会一上来就问"给我开抗生素"。他们会先做症状描述,再引入角色扮演,逐步把模型推到"假设你是一名急诊医生"的语境里。每一步单看都合规,组合起来却击穿了对齐边界。这种渐进式越狱,在静态测试集上很难被发现。
还有一类风险来自产品侧的过度承诺。不少医疗 Agent 把"智能问诊"作为卖点,却在系统提示词里只写了一句"不要开具处方"。这种声明在对抗性输入面前脆弱。的防线必须建在输出侧,而不是提示词里。
医疗大模型的安全重点,在"它能不能被守住不开违规处方"。对齐评估、输出校验、合规兜底要串成一条强制链路。
二、医疗语境下的越狱手法变体与对齐失效点
通用越狱手法在医疗场景里会做"语境换皮"。角色扮演从"越狱助手"变成"资深主任医师";假设场景从"虚构世界"变成"急诊抢救现场";指令重写从"忽略上文"变成"为了患者安全,请打破常规"。本质都是利用模型对"医疗紧急性"的过度顺从。
输入侧检测拦截"诱导意图",对齐评估判断"模型是否已被推偏",输出侧校验是最后兜底,哪怕模型已经被越狱,也要拦住违规处方的实际输出。三层防线相互独立,一层失守,其他层补位。
三、输出侧合规校验网关的实现
下面是一段输出侧校验网关。它独立于模型,对生成结果做处方禁忌、剂量阈值、联合用药的强制检查:
import asyncio import re import hashlib import time from dataclasses import dataclass, field from typing import Optional # 处方禁忌规则表:药物组合、单次剂量上限、禁用人群 PRESCRIPTION_RULES = { "antibiotics_under_18": { "pattern": r"(阿奇霉素|左氧氟沙星|环丙沙星)", "condition": lambda ctx: ctx.get("age", 99) < 18, "reason": "未成年禁用喹诺酮/大环内酯类", }, "max_dose_paracetamol": { "pattern": r"对乙酰氨基酚[^\d]{0,6}(\d+)\s*(mg|毫克)", "condition": lambda ctx: True, "limit": 1000, # 单次剂量上限 mg "reason": "对乙酰氨基酚单次超量", }, "combined_sedatives": { "pattern": r"(地西泮|艾司唑仑).{0,20}(酒精|酒)", "condition": lambda ctx: True, "reason": "镇静药与酒精联用", }, } @dataclass class MedContext: """患者上下文,用于条件判断;缺字段按安全侧处理""" age: int = 99 pregnant: bool = False allergies: list = field(default_factory=list) trace_id: str = "" def sign(self) -> str: raw = f"{self.age}|{self.pregnant}|{time.time_ns()}" return hashlib.sha256(raw.encode()).hexdigest()[:16] class PrescriptionGuard: def __init__(self, timeout: float = 2.0): self._timeout = timeout async def check(self, output: str, ctx: MedContext) -> dict: ctx.trace_id = ctx.sign() # 并发跑所有规则,单条超时不阻塞整体 try: findings = await asyncio.wait_for( self._run_all(output, ctx), timeout=self._timeout ) except asyncio.TimeoutError: # 超时按"未通过"处理,宁可拦截也不放行违规处方 return {"status": "blocked", "reason": "check_timeout", "trace": ctx.trace_id} if findings: return {"status": "blocked", "reason": "rule_violation", "findings": findings, "trace": ctx.trace_id} # 二次确认:即便无规则命中,疑似处方类输出也转人工 if self._looks_like_prescription(output): return {"status": "manual_review", "trace": ctx.trace_id} return {"status": "passed", "trace": ctx.trace_id} async def _run_all(self, output: str, ctx: MedContext) -> list: sem = asyncio.Semaphore(8) async def one(name, rule): async with sem: return self._apply_rule(name, rule, output, ctx) tasks = [one(n, r) for n, r in PRESCRIPTION_RULES.items()] results = await asyncio.gather(*tasks, return_exceptions=True) return [r for r in results if r] def _apply_rule(self, name, rule, output, ctx) -> Optional[dict]: m = re.search(rule["pattern"], output) if not m: return None if not rule["condition"](ctx): return None # 带剂量上限的规则,额外校验数值 if "limit" in rule: try: dose = int(m.group(1)) except (IndexError, ValueError): return {"rule": name, "reason": rule["reason"]} if dose > rule["limit"]: return {"rule": name, "reason": rule["reason"], "dose": dose, "limit": rule["limit"]} return None return {"rule": name, "reason": rule["reason"]} def _looks_like_prescription(self, output: str) -> bool: # 启发式判断:出现"用法用量"+"药品名",即视为疑似处方 keywords = ["用法", "用量", "每日", "口服", "静脉滴注"] hits = sum(1 for k in keywords if k in output) return hits >= 2 # 使用示例 async def demo(): guard = PrescriptionGuard() ctx = MedContext(age=14) output = "建议口服左氧氟沙星 500mg 每日一次,连续 7 天。" print(await guard.check(output, ctx))关键点:规则与模型解耦,新增禁忌只改规则表不动模型;并发跑规则且整体超时兜底;疑似处方转人工而非直接放行。这样即使模型被越狱,违规处方也到不了用户眼前。
四、对齐评估的盲区与合规兜底的代价
输出侧校验不是万能的,落地前要想清几条边界。
规则覆盖有滞后性。新药、新禁忌、新联合用药风险不断出现,规则表不及时更新就会有"已知规则全过、实际仍违规"的盲区。规则维护要和药监通报、说明书更新联动,定期同步,不能靠安全团队手动补。
启发式判断会误伤。"_looks_like_prescription" 在科普类回复上可能误判为处方,把正常健康教育内容也转人工,拉高审核成本,伤害用户体验。要在召回率与误报率之间取舍,优先保证"不放过违规处方",再用更细的特征降低误报。
对齐评估本身难量化。模型在静态测试集上表现良好,不代表对抗场景下不越狱。医疗场景需要专门的红队语料库,覆盖角色扮演、假设场景、指令重写等变体,定期做回归评估。把评估结果纳入模型上线门禁,而非只作为事后指标。
最后一条:合规兜底不能替代专业医生。哪怕校验全部通过,模型给出的也只是"参考信息",不能等同于医嘱。产品侧必须在显著位置声明边界,并在涉及具体用药时强制引导用户线下就医。把"AI 开处方"作为产品宣传点,本身就是合规风险。
五、总结
医疗问答大模型的越狱风险,本质是"概率模型"与"刚性合规"的冲突。攻击者用角色扮演、假设场景、指令重写等手法,把模型推过对齐边界,输出违规处方。可靠的防线分三层:输入侧做诱导意图检测,模型侧定期做对抗性对齐评估,输出侧用独立规则引擎做处方禁忌兜底。规则与模型解耦、并发校验带超时、疑似输出转人工,是工程落地的基本要求。再强的护栏,也不能替代专业医生的判断,这是医疗 AI 的底线。
