Red Flag 症状检测:医疗 AI 的安全底线
医疗 AI 应用中的安全检测设计:通过关键词模式匹配检测危险症状(剧烈疼痛、神经症状、外伤等),在 LLM 回复前提前推送安全警告。
#type / concept
#status / growing
#tech / ai
[!info] related notes
- 并列安全系统: RAG Faithfulness 校验
- 应用: 咨询 Agent 工作流
- 事件推送: 多服务 SSE 管道
Red Flag 症状检测:医疗 AI 的安全底线
核心问题
用户说”疼得睡不着”,AI 不能只说”做做拉伸”。用户说”手指麻木无力”,AI 必须建议就医。这些危险信号必须在 LLM 生成回复之前就检测出来。
为什么不能依赖 LLM 自己判断:
- LLM 可能漏判(特别是症状描述模糊时)
- 用户需要在看到 LLM 回复之前就看到安全警告
- 安全检测必须是确定性的,不能是概率性的
设计原则
- 先于 LLM 执行 — 检测结果在 LLM 回复之前到达前端
- 确定性 — 关键词存在就命中,不存在就不命中,没有”可能”
- 可审计 — 每条规则都可以人工审查
- 不阻断对话 — 检测到 red flag 后继续正常对话,只是额外推送警告
检测范围
| 类别 | 关键词示例 | 风险 |
|---|---|---|
| 剧烈疼痛 | 剧烈疼痛、无法忍受、疼得睡不着 | 可能有严重损伤 |
| 放射痛 | 放射到手臂、串到腿、触电感 | 可能神经受压 |
| 神经症状 | 麻木无力、肌肉萎缩、走路不稳 | 神经功能异常 |
| 外伤 | 摔倒、骨折、车祸 | 需要影像排除 |
| 进行性加重 | 越来越严重、休息也不缓解 | 可能在恶化 |
| 感染征象 | 发热、红肿热痛 | 需要抗感染 |
| 全身症状 | 体重下降、夜间盗汗 | 可能全身性疾病 |
检测实现
RED_FLAG_PATTERNS = [
{
"category": "severe_pain",
"keywords": ["剧烈疼痛", "严重疼痛", "无法忍受", "疼得睡不着"],
"message": "您描述的疼痛程度较为严重,建议尽快就医。",
},
# ...
]
def detect(extracted_info, conversation_text):
flags = []
for pattern in RED_FLAG_PATTERNS:
for keyword in pattern["keywords"]:
if keyword in conversation_text:
flags.append(RedFlag(
category=pattern["category"],
message=pattern["message"],
matched_text=keyword,
))
break # 每个类别只报一次
return RedFlagResult(has_red_flags=len(flags) > 0, flags=flags)
执行时机
用户消息 → Red Flag 检测(<1ms)
↓
如果有 red flag → 立即推送 red_flag SSE 事件
↓
继续正常流程:意图分类 → RAG → LLM 生成 → 推送回复
Red flag 事件在 LLM 回复之前到达前端。
与 LLM 安全判断的对比
| 维度 | 关键词检测 | LLM 判断 |
|---|---|---|
| 方法 | 模式匹配 | 模型推理 |
| 速度 | <1ms | 1~3s |
| 可靠性 | 100% 命中 | 有概率漏判 |
| 覆盖面 | 只覆盖预定义模式 | 可识别新模式 |
| 可审计 | 规则明确 | 黑盒 |
两者互补:关键词检测做硬性兜底,LLM 做柔性判断。
设计要点
- 检测范围要覆盖已知和语言 — 不同语言需要不同的关键词表
- 误报比漏报好 — 宁可多报一个 false positive,也不能漏掉真正的危险
- 每个类别只报一次 — 避免用户被重复警告淹没
- 可以加 LLM 二次确认 — 关键词命中后让 LLM 判断是否真有风险(减少误报)
局限性
- 只支持预定义语言的关键词
- 无法理解语义:“不疼了” 也会命中 “疼”
- 误报:描述他人的症状也会触发
- 覆盖不全:新的危险表述需要手动添加