医疗人工智能的Harness Engineering:面向安全、可控与合规的大模型系统工程(八) 第八章 医疗 AI 评测体系:可量化、可重复、可防护的 Evaluation Harness8.1 引言:没有评测的 Harness 只是空壳如果说护栏是 Harness 的防御盾牌,那么评测体系(Evaluation Harness)就是检验盾牌厚度和模型质量的测量仪。在医疗 AI 生命周期的每一刻——从初次集成、模型微调、提示词修改到知识库更新、依赖升级——都必须回答同一个问题:这个系统是更安全了吗?还是悄悄变危险了?单靠手工抽检几张截图或几段对话,无法给出可重复的答案,也无法提交给监管机构。Evaluation Harness 正是为了解决这一问题的专门子系统:它自动化地运行大量预定义的测试用例,量化系统的准确性、安全性、公平性和鲁棒性,并生成可归档的评测报告。在 Martin Fowler 的 Harness 分析框架中,评测体系横跨确定性传感器(deterministic sensors)与推理性传感器(inferential sensors)两大类别。单元测试、断言检查、指标计算属于确定性范畴,它们输出无歧义的是/否或分数;而 LLM-as-judge、医生人工评审则属于推理性范畴,它们提供概率性的质量判断。成熟的 Evaluation Harness 必须将两者有机编织:确定性部分充当第一道质量门禁,推理性部分填补语义鸿沟,共同构成对 AI 行为的全景评估。医疗领域对评测提出了更高的要求。安全性不是可选的加分项,而是临床准入的基线;公平性不是政治正确,而是关乎患者生命——一个在不同人种间敏感性差异显著的皮肤癌检测模型,可能会导致某些群体的漏诊率飙升。传统的 MLOps 评测关注准确率、F1 分数,而医疗 AI 评测必须拓展至校准度、决策曲线、亚组公平性、OOD 检测、风险分层等维度。更为关键的是,评测不能是一次性的“论文实验”,而必须嵌入持续集成(CI)管道,成为每次变更的安全门禁——未通过评测的模型或配置变更,绝对不能上线。Rust 在 Evaluation Harness 中的角色是多重的。首先,评测执行引擎需要高性能地批量处理数百条测试用例,调用推理服务、计算指标、汇总结果——这正是一个 CPU 密集且需要确定性行为的任务,Rust 的零成本抽象和并发能力使其成为理想选择。其次,评测数据的定义(测试用例 schema、指标定义)可以通过强类型系统表达,确保不同版本评测之间的格式一致性,防止解析错误导致评测结果误报。第三,评测结果需要防篡改地归档,这与第七章的审计基础设施自然衔接,可利用相同的AuditedT模式和加密存储。本章将设计并实现一个完整的 Evaluation Harness 子系统。我们将从测试用例的类型安全定义入手,构建一套可扩展的指标计算引擎,引入风险分层的回归测试套件,最终将评测集成到 CI/CD 管道中,形成“变更 → 评测 → 门禁”的自动化闭环。8.2 评测设计原则与医疗特殊性在设计 Evaluation Harness 之前,我们明确几条指导原则:可重复性:对同一模型版本、同一测试集,多次运行应得到完全一致的结果。这要求固定随机种子、冻结依赖版本、并确保外部服务调用的确定性(或 mock 掉外部依赖)。Rust 的cargo锁定文件和std::hash的确定性在此是优势。覆盖面:测试用例必须涵盖正常场景、边界场景、高风险场景、对抗性场景,以及不同的患者人口统计分组(年龄、性别、种族)以评估公平性。分层评估:不是所有用例都同等权重。应该根据临床风险对测试用例进行分级(低/中/高),并设置不同的通过阈值。高风险用例不允许任何失败。自动化与人工编排:确定性指标全自动执行;推理性评估(如 LLM-as-judge)可以半自动运行,但最终判定需有人工评审的接口。评测报告应标记出需要人工审核的条目。可追溯:每次评测运行必须记录:测试集版本、模型版本、Harness 配置版本、运行的准确时间、所有指标数值。这些记录作为审计的一部分,证明系统在某个时间点的性能。在医疗场景中,评测不能只看模型输出的表面准确性,还要检查过程合规性:是否引用了正确的知识来源?是否在不确定时表达了不确定性?是否在高风险时触发了升级建议?这要求评测指标从单纯的结果比对扩展到过程质量评估。8.3 测试用例的强类型定义与管理测试用例是评测的原子单元。一个医疗问答评测用例可能包含:输入:患者背景、问题、期望的行为类别(如“给出鉴别诊断”)参考输出:金标准回答(可选)风险标签:低、中、高、急诊评估参数:是否检查引用、是否允许模糊表达、关键实体列表(必须出现或禁止出现的词汇)公平性分组:患者年龄组、性别、种族等(用于亚组分析)我们使用 Rust 结构体和枚举来定义这些概念,并借助serde实现 JSON/YAML 序列化,使得测试用例可以存储在版本控制的文件中。#[derive(Debug, Clone, Serialize, Deserialize)]pubstructTestCase{pubid:String,pubdescription:String,pubscenario:ClinicalScenario,pubinput:TestInput,pubexpected:TestExpectation,pubrisk_level:RiskLevel,pubfairness_tags:HashMapString,String,pubtags:VecString,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructClinicalScenario{pubpatient_age_range:OptionAgeRange,pubpatient_gender:OptionAdministrativeGender,pubchief_complaint:String,pubmedical_history:VecString,pubcurrent_medications:VecString,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructTestInput{pubuser_query:String,pubexpected_task:OptionClinicalTask,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructTestExpectation{/// 金标准参考回答,可选pubreference_answer:OptionString,/// 模型输出必须包含的关键词(如“可能”、“建议进一步检查”)pubrequired_keywords:Vec