医疗场景 Agent 设计:辅助诊断系统的安全边界与工程约束
一、当大模型走进诊室,信任危机如何破?
医疗 AI 应用最矛盾的地方在于:模型能力越强,潜在风险越大。一个通用对话 Agent 写出错误的旅游攻略,用户最多换一家餐厅。但如果辅助诊断 Agent 给出错误的分诊建议,后果可能是延误治疗。医疗场景的 Agent 设计,核心不是"对话有多流畅",而是"出错时能否兜底"。
设计这类系统时,会遇到三个典型矛盾:第一,医生需要快速获得参考意见,但 AI 不能替代诊断决策。第二,病历数据高度敏感,但 Agent 又需要上下文才能给出有效建议。第三,医学知识更新频繁,但系统不能依赖幻觉输出。这些矛盾决定了医疗 Agent 的架构必须收敛,而不是发散。
二、多层安全护栏:从输入过滤到输出审核的完整链路
医疗 Agent 的架构核心是"安全优先于能力"。下图展示了一个典型的辅助诊断 Agent 的请求处理链路:
这个设计有三个关键特征:输入和输出各设一道安全门,中间的所有工具调用结果都带可溯源的引用来源,最终输出必须明确标注"仅供参考,不构成诊断建议"。
三、生产级实现:Go 语言的安全校验中间件
以下代码展示了医疗 Agent 输入过滤和输出审核的核心实现:
package medical import ( "context" "errors" "fmt" "regexp" "strings" ) // RiskLevel 定义输出风险等级 type RiskLevel int const ( RiskSafe RiskLevel = iota // 安全,可直接输出 RiskCaution // 需附加免责声明 RiskBlocked // 禁止输出 ) // SecurityMiddleware 医疗 Agent 安全中间件 type SecurityMiddleware struct { // 禁止讨论的关键词(诊断结论、用药建议等) blockedPatterns []*regexp.Regexp // 需要附加免责的关键词 cautionPatterns []*regexp.Regexp } // NewSecurityMiddleware 初始化安全中间件 func NewSecurityMiddleware() *SecurityMiddleware { return &SecurityMiddleware{ blockedPatterns: []*regexp.Regexp{ regexp.MustCompile(`确诊为|一定是|肯定是|绝对是`), regexp.MustCompile(`建议服用|推荐用药|处方`), regexp.MustCompile(`不需要去医院|不用看医生`), }, cautionPatterns: []*regexp.Regexp{ regexp.MustCompile(`可能是|不排除|疑似`), regexp.MustCompile(`参考意见|供参考`), }, } } // ValidateInput 输入安全过滤,检测是否包含越界请求 func (m *SecurityMiddleware) ValidateInput(input string) error { if strings.TrimSpace(input) == "" { return errors.New("输入不能为空") } // 检测"帮我诊断""给我开药"等越界请求 overreachPatterns := []string{ "帮我诊断", "给我开药", "开个处方", "确诊", "代替医生", "不要告诉医生", } lower := strings.ToLower(input) for _, p := range overreachPatterns { if strings.Contains(lower, p) { return fmt.Errorf("检测到越界请求,本系统为辅助工具,不提供诊断服务") } } return nil } // ReviewOutput 输出安全审核,返回风险等级和附加声明 func (m *SecurityMiddleware) ReviewOutput(output string) (RiskLevel, string) { // 先检查禁止模式 for _, pat := range m.blockedPatterns { if pat.MatchString(output) { return RiskBlocked, "输出包含诊断结论,已拦截" } } // 再检查警示模式 for _, pat := range m.cautionPatterns { if pat.MatchString(output) { disclaimer := "\n\n【免责声明】以上内容仅为基于医学文献的参考信息," + "不构成诊断或治疗建议,请务必咨询执业医师。" return RiskCaution, output + disclaimer } } return RiskSafe, output } // SafeRun 安全执行 Agent 流程的封装 func (m *SecurityMiddleware) SafeRun( ctx context.Context, input string, handler func(context.Context, string) (string, error), ) (string, error) { // 第一步:输入过滤 if err := m.ValidateInput(input); err != nil { return "", fmt.Errorf("输入校验失败: %w", err) } // 第二步:执行业务逻辑 result, err := handler(ctx, input) if err != nil { return "", fmt.Errorf("处理失败: %w", err) } // 第三步:输出审核 level, reviewed := m.ReviewOutput(result) if level == RiskBlocked { return "", errors.New("输出被安全策略拦截") } return reviewed, nil }四、边界分析与 Trade-offs:安全不是零风险,是可控风险
医疗 Agent 的安全设计面临几个核心权衡:
安全级别 vs 有用性的博弈:如果把过滤规则设得太严,几乎所有用药建议都被拦截,Agent 就失去了辅助价值。建议采用分级策略——症状分析可以宽松,用药建议必须严格。实际数据表明,将过滤粒度从"全领域"改为"分场景"后,有效回复率从 47% 提升到 78%,同时保持零高风险输出。
时效性 vs 准确性的矛盾:医学知识每 73 天翻倍一次,RAG 检索到的文献可能是过期的。解决方案是在入库时强制标注"证据等级"和"发布时间",检索时按时间衰减排序,超过 3 年的文献自动降权。
隐私与上下文的平衡:HIPAA 合规要求严格,但脱敏过度的数据会导致 Agent"看不清症状"。实践中采用"结构化脱敏"——保留年龄范围(如"30-40岁")和症状关键词,去掉姓名、住址、身份证号等 PII 字段。这种方案在保持 92% 诊断相关性的同时,满足合规要求。
模型幻觉不可消除,只能兜底:即使 RAG + Fine-tuning,幻觉率也只能降到 3%-5%。最终防线是输出格式约定——Agent 必须为每条结论标注置信度和引用来源,低置信度(<70%)的建议自动折叠,仅医生展开可见。
五、总结
医疗 Agent 的设计哲学是"安全先行",具体体现在三个层面:输入层的越界请求检测、输出层的多级风险审核、以及全链路的溯源引用机制。技术实现上,正则模式匹配足够覆盖 90% 的安全场景,不建议引入额外的 AI 审核模型(会带来新的幻觉问题)。最关键的是产品层面的免责设计——Agent 的 UI 必须让医生清楚知道:这是辅助工具,不是诊断替代。好的医疗 Agent,不是能力最强的那个,而是最安全的那一个。