外观
安全过滤
安全过滤在 AI 链路中优先级最高。当前系统同时存在四类安全机制:Chat 输入安全过滤、RAG 内部安全短路、评估红黄绿规则引擎、处方结构安全检查。它们覆盖的场景不同,不应混写成一个“模型安全提示”。
安全层次
| 层次 | 入口 | 主要文件 | 输出 |
|---|---|---|---|
| Chat 内容安全 | SendChatMessageUseCase.execute() | app/core/safety_filter.py | SafetyCheckResult、安全免责声明、可选 suggested_response。 |
| RAG 内部安全短路 | RAGEngine.safe_search_and_generate() | app/core/rag_engine.py + safety_filter.py | 高风险时跳过检索并返回安全建议。 |
| 评估红黄绿规则 | /api/assessment/safety-check、/api/safety/risk-assessment | safety_engine.py、safety_rules.py、safety_policy.py | GREEN / YELLOW / RED 与 action。 |
| 处方安全检查 | PrescriptionGenerationService | safety_filter.check_prescription_safety() | 处方风险等级、warnings、是否需要 human review。 |
Chat 输入安全
SafetyFilter.check_content_safety(...) 会扫描用户输入和可选用户上下文:
| 风险类型 | 典型触发 | 风险等级 | 系统行为 |
|---|---|---|---|
| 医疗诊断 | 症状或疾病 + “是不是 / 诊断 / 确诊 / 什么病”等诊断意图 | MEDIUM / HIGH | 添加诊断边界;高风险时给出不能诊断的建议文本。 |
| 危险运动 | 极限运动、大重量、倒立、跳跃、冲击、爆发力等 | MEDIUM,特殊年龄或病史可升高 | 加入危险运动 warning。 |
| 紧急症状 | 胸痛、呼吸困难、昏厥、大出血、抽搐等 | CRITICAL | 要求停止运动并就医,requires_human_review=true。 |
| 药物建议 | 药物、剂量、胰岛素、降压药、副作用、禁忌等 | HIGH | 添加药物咨询边界。 |
| 自残倾向 | 自杀、轻生、结束生命等表达 | CRITICAL | 返回危机支持建议,requires_human_review=true。 |
SendChatMessageUseCase 的处理规则:
- 先调用 safety filter。
- 若
is_safe=false且存在suggested_response,直接返回安全建议。 - 该路径不调用 RAG,也不调用 LLM。
- 返回中
requires_acknowledgment=true,rag_context=["安全检查"]。 - 如果不是高危短路,但属于健康建议语境,会追加泛化安全提示。
RAG 安全短路
RAG 内部也会执行 safety check,避免绕过 Chat use case 的调用方直接进入检索生成。契约测试覆盖以下行为:
| 条件 | 行为 |
|---|---|
高风险且有 suggested_response | 不执行 hybrid pipeline。 |
| 返回字段 | 保留 query、suggested_response、knowledge_context=""、sources=[]、safety_check。 |
| 免责声明 | 根据 flags 或泛化规则生成 safety_disclaimer。 |
| 人工复核 | safety_check.requires_human_review=true 时向上游保留该字段。 |
这层保护确保后续新增 RAG 调用方时,高风险输入仍有本地拦截能力。
评估红黄绿规则
safety_engine.evaluate(...) 使用规则表判断运动前安全检查结果:
| 规则 | 条件 | 等级 | 行为 |
|---|---|---|---|
G1 发热 | 发热或不确定 | RED | 建议先就医或确认感染控制后再运动。 |
G2 急性期/不稳定期 | 急性期、不稳定或不确定 | RED | 暂不生成运动康复方案。 |
G3 心肺危险症状 | 胸痛、气短等危险信号或不确定 | RED | 建议立即就医排除风险。 |
G4 严重副作用 | 严重不能耐受治疗副作用 | RED | 先处理副作用。 |
G5 极度虚弱 | 极度疲劳或虚弱 | RED | 建议线下评估。 |
G6 医嘱禁忌 | 医生明确禁止或不确定 | RED | 遵医嘱暂停运动。 |
M1 术后伤口 | 术后/恢复期且伤口异常或不确定 | RED | 暂缓运动。 |
M2 跌倒风险 | 高龄或相关风险上下文,且有跌倒风险 | YELLOW | 限制为坐姿/卧姿运动。 |
M3 贫血 | 治疗相关上下文且 Hb < 80 或贫血不确定 | RED | 确认后再运动或禁止运动。 |
最终 action:
| 等级 | action_required |
|---|---|
RED | consult_doctor |
YELLOW | conservative_mode |
GREEN | null |
处方安全检查
check_prescription_safety(...) 针对生成后的处方结构做二次检查:
| 检查项 | 行为 |
|---|---|
| 高强度运动 | 对 高 / high / 剧烈 强度加入 warning,风险至少为 MEDIUM。 |
| 年龄 | 年龄大于 70 时加入高龄运动风险提示。 |
| 心血管病史 | 心脏、心血管、高血压相关条件会提升到 HIGH。 |
| 骨关节问题 | 骨折、关节、脊椎相关条件会提升风险。 |
| 糖尿病 | 提醒运动时监测血糖。 |
| 安全字段缺失 | 缺少 safety_guidelines 或 contraindications 时加入 warning。 |
| 无运动项目 | 风险至少为 MEDIUM。 |
风险为 HIGH 或 CRITICAL 时,返回 requires_human_review=true。
非诊断边界
AI 回复和运动处方均不能替代医生诊断。系统允许提供一般运动健康建议、知识库证据解释和风险提示,但遇到以下内容必须收缩:
| 内容 | 边界 |
|---|---|
| 诊断判断 | 不判断“是不是某病”,建议咨询医生。 |
| 急症信号 | 不继续运动建议,先停止运动并就医。 |
| 药物剂量 | 不给药物剂量或替代用药方案。 |
| 高风险运动 | 只给安全边界,不鼓励挑战极限。 |
| 处方生成 | 模型生成结果必须通过结构校验与安全检查后再保存。 |
测试入口
| 测试 | 覆盖点 |
|---|---|
tests/test_safety_filter.py | 医疗诊断、急症、危险运动、药物、自残、免责声明。 |
tests/test_safety_logic.py | G/M 红黄绿规则。 |
tests/use_cases/test_send_chat_message_use_case.py | Chat 高风险短路、RAG suggested response、免责声明追加。 |
tests/test_rag_hybrid_contract.py | RAG 高风险输入不进入 hybrid pipeline。 |
tests/core/test_safety_policy_contract.py | Safety policy 公共契约。 |
来源锚点
- Content safety:
apps/backend_service/app/core/safety_filter.py - Rules:
apps/backend_service/app/core/safety_rules.py - Policy data:
apps/backend_service/app/core/safety_policy.py - Safety engine:
apps/backend_service/app/core/safety_engine.py - Chat use case:
apps/backend_service/app/use_cases/chat/send_message.py - Prescription generation:
apps/backend_service/app/core/rag/prescription_generation.py - API:
apps/backend_service/app/api/safety.py、apps/backend_service/app/api/assessment.py