
------基于临床自然语言处理的工程视角:从大型语言模型演示到院内可运营临床系统的实现路径
摘要
病历自动生成与临床文档改进(CDI)/国际疾病分类(ICD)编码是医疗人工智能落地应用的关键场景。当前研究多集中于模型算法本身的优化,然而在真实临床环境中,系统的成功部署与长期运营更依赖于系统性工程范式的构建。本文指出,此类任务的核心挑战并非单纯追求模型性能指标的提升,而在于如何在强合规性、高可靠性、全程可追溯的刚性约束下,将自动化生成与智能建议能力无缝、安全地嵌入现有的临床工作流。因此,其实际落地成效主要取决于推理服务架构、质量门禁流水线、证据链闭环设计以及全链路治理机制等系统性工程范式的建立。本文从工程实践视角出发,系统剖析了病历生成与质控编码任务固有的系统性约束,构建了一个融合在线服务、混合调度、检索增强生成(RAG)与审计追溯能力的可治理推理系统框架,并详细阐述了关键组件的设计范式与具体实施路径,旨在为医疗人工智能系统的工程化落地提供具备参考价值的解决方案。
关键词:医疗人工智能;临床自然语言处理;病历生成;质控编码;系统工程;检索增强生成;推理服务;质量门禁
1. 引言:从算法优化到系统范式的必然性
在医疗领域,病历文书自动生成与CDI/ICD编码的自动化辅助,长期以来被视为自然语言处理(NLP)的典型应用场景。常见的研究路径是采用更强大的模型、更多的参数、更优质的微调数据集,以期提升BLEU、ROUGE或编码准确率等指标。然而,在真实的临床部署环境中,这些单纯的"模型指标"往往无法直接转化为"可上线、可运营的服务能力"。
究其原因在于,医疗应用场景存在以下三重刚性约束,决定了它不是一个"单一模型、单一指标"的算法问题,而是一个典型的"端到端系统 + 工作流闭环 + 持续治理"的工程范式问题。
1.1 三重刚性约束(决定"更偏工程范式")
- 工作流约束:临床操作具有强时序性、高交互性,并对延迟极其敏感(临床医生通常无法接受超过数秒的等待)。系统必须具备低延迟、高并发、弹性调度的基础能力。
- 风险约束:系统输出直接关联诊疗决策、医保支付与法律证据,必须从根本上杜绝低概率但后果严重的高危错误。质量保障必须实现制度化与流程化。
- 合规约束:数据安全、全程可追溯、结果可复现是硬性要求。每一次系统输出都必须能够回放、解释与审计。
结论 :
病历生成与编码任务的最终落地成效,决定性因素往往并非"模型性能的强弱",而在于系统是否构建了一套可治理、可运营的工程范式,其核心包括:健壮的推理服务架构、多层质量门禁、完整的证据链、严格的审计追溯与持续的运营改进机制。
2. 核心系统性约束剖析
2.1 在线化服务的负载特性:调度与弹性成为基础能力
临床工作流天然产生峰谷特征显著的请求负载:
- 门诊场景:短文本请求、高并发、极低延迟(P95延迟是关键指标)
- 住院场景:长上下文、多轮生成与编辑、整体吞吐量更为重要
- 夜间场景:批处理编码或归档任务,强调高吞吐与低成本
因此,系统架构必须内建以下核心能力:
- 请求队列管理与优先级调度机制
- 动态批处理以提升硬件利用率
- KV缓存与前缀缓存(针对病历模板重复率高的特点非常关键)
- 流式响应以支持实时交互
- 熔断、限流与服务降级策略(如降级至模板填充或抽取式摘要)
这些能力属于推理系统工程范式的范畴,无法通过简单地"更换模型"来解决。
2.2 高风险内容的质控需求:质量门禁必须流水线化
医疗文本生成的风险核心特征是:低概率发生但危害性极高的错误 。
因此,评估不能仅关注"平均质量",而必须系统性地回答以下问题:
- 同一输入重复生成,输出是否稳定?(一致性)
- 生成的事实是否与已有的结构化字段对齐?(事实性)
- 关键临床主张是否都有对应的证据支持?(证据覆盖率)
- 是否对幻觉进行有效监控与拦截?(幻觉监控)
工程上必须借鉴持续集成/持续交付的理念,构建流水线式的质量门禁体系:
- 离线阶段:回归测试集、一致性测试、事实对齐检查、人工量表评分
- 在线阶段:实时幻觉监控、定期抽样检查、临床医生反馈闭环、数据漂移检测
质量保障应从"事后评估"转变为"事前拦截 + 事中监控"的主动治理范式。
2.3 合规审计的刚性要求:可追溯性与可复现性是系统属性
面对医疗争议与质控抽查,系统必须能够清晰回答:
- 当时使用了哪个提示模板和哪个模型版本?
- 检索到了哪些证据?这些证据事后是否被修改过?
- 解码参数是什么?为何今天的输出与之前不同?
- 临床医生修改了哪些内容?为何进行修改?
为此,系统必须强制记录:
- 提示模板与版本锁定
- 模型与版本锁定
- 证据快照(检索结果的冻结状态)
- 系统输出与人工修改的差异对比
- 贯穿全链路的追踪标识符
这并非简单的"增加日志记录",而是需要在系统设计之初就内建的治理能力。
3. 任务特性与对应工程范式映射
3.1 病历生成:推理系统范式与内容安全范式的结合
病历生成任务面临典型的工程矛盾:
- 高频推理需求与高峰值负载(临床工作流强依赖)
- 高风险内容输出与必须可审计(医疗文书是法律证据)
因此,系统架构必须兼顾两个方面:
推理侧:在线服务化与性能工程
- 动态批处理以提升GPU利用率
- KV缓存与前缀缓存以降低重复计算成本
- 流式输出使医生能够"边生成边修改"
- 熔断与降级机制保证"服务永不中断"
内容侧:多层质量门禁体系
- 强制结构化输出(遵循JSON Schema或Pydantic模型)
- 事实与结构化字段对齐校验(诊断、药物、检验值等)
- 关键句证据覆盖检查
- 输出一致性测试(多次采样语义漂移检测)
- 幻觉实时监控(对关键禁忌症、确定性措辞进行拦截)
病历生成系统的上线标准 :
系统服务水平目标(包括P95延迟、可用性、吞吐量、成本) + 内容质量门禁(量表评分/抽检/一致性/幻觉监控) + 审计追溯能力(提示、证据、版本、编辑链的完整记录)。
3.2 质控编码:以闭环工作流范式驱动的人机协同系统
CDI/ICD编码任务更接近一个"人机协作的闭环系统",而非"全自动预测"问题。
系统必须围绕 建议 → 证据 → 解释 → 交互 → 反馈 这一核心流程进行构建:
- 证据链是前提:没有证据支持的编码建议几乎无法被采纳。
- 工作流引擎是关键:需支持批处理与在线协同两种模式并存。
- 反馈闭环是进化动力:编码员的采纳、驳回、修改行为应回流系统,形成持续改进的数据飞轮。
CDI/ICD编码系统的关键评估指标并非单纯的Top-1准确率,而应包括 :
建议采纳率、驳回原因分布、查询补全效率、证据可核查率、历史编码一致性。
4. 可治理的推理系统架构设计(统一支撑病历生成与编码)
以下提出一套"可落地、可运营、可审计"的统一架构方案,可作为医疗领域大型语言模型系统工程的参考蓝图。
4.1 总体架构模块图(在线、批处理与治理一体化)
编排器是系统大脑;LLM服务是发动机;质量门禁是安全闸门;审计日志是黑匣子。
队列与工作器层
数据与审计层
质量与安全层
推理层
检索增强生成层
编排层
API网关与安全层
临床应用层
电子病历系统界面
CDI/ICD编码系统
API网关\n身份认证/授权\n限流
Web应用防火墙/数据防泄漏
编排器\n上下文构建器\n策略引擎
功能开关\n灰度/AB测试
索引器\nETL+去标识化+分块
向量数据库
关键词/SQL检索
重排序器
引用构建器\n证据快照
模型路由\n成本/延迟策略
LLM服务\n动态批处理\nKV缓存
工具服务\n规则引擎/ICD映射
质量门禁\n一致性\n事实性\n安全性
幻觉监控\n事实核查
不可变审计日志\n提示+证据+版本
可观测性\n追踪+指标+日志
结果存储\n文书/编码+差异
优先级队列
工作器\n批处理/异步任务
批处理调度器\n夜间编码任务
4.2 核心组件设计范式(工程可执行)
编排器:策略驱动的核心编排器(系统"大脑")
- 上下文构建器:整合结构化字段、原始文本、历史修改记录。
- 策略引擎:根据任务类型、敏感性、延迟预算选择模型、是否启用RAG、是否触发降级。
- 提示构建器:模板化、版本化、哈希值固定。
- 工具调用:集成规则引擎、ICD映射表、各类校验器。
- 证据快照:检索证据的冻结存储(保障可复现性与可核验性)。
RAG层:检索增强与证据链闭环
- 文本分块:结构优先,支持片段级证据引用。
- 混合检索:结合向量检索、BM25关键词检索与结构化过滤。
- 重排序:提升临床关键证据的命中优先级。
- 引用生成:记录文档ID、版本、偏移量、原文引用及哈希值。
- 快照机制:根据风险等级选择轻量级或重量级证据快照策略。
质量门禁:流水线式的质量检查(类似持续集成流水线)
- 模式验证:确保输出格式符合预定模式。
- 事实对齐:检查与已有结构化字段的冲突。
- 证据覆盖:确保关键句具备引用。
- 一致性漂移检测:对同一输入多次生成的语义漂移设定阈值。
- 安全过滤:拦截禁忌词、过度确定性措辞、无依据的建议。
- 失败处理策略:重试、降级或转人工审核。
审计日志:不可篡改的黑匣子(一次写入,多次读取)
记录内容包括:追踪ID、提示版本、模型版本、证据快照、解码参数、原始输出、质量评分、人工修改差异。
5. RAG与证据链接的实现细化(分块策略、引用粒度、冻结快照)
本章节是决定临床可用性的关键环节。实现越扎实,系统上线可行性越高,抗审计能力越强。
5.1 分块策略:结构优先,语义兜底(两级索引)
为何不能仅使用滑动窗口分块?
因为临床文书是强结构文本(如主诉、现病史、体格检查、诊疗计划等)。滑动窗口切分会导致"证据引用失去上下文",临床医生无法定位来源。
推荐方案:两级索引
- 第一级:段落/小节级分块(以高召回率为目标)
- 第二级:句子/短语级分块(以精确引用为目标)
分块大小建议
- 病历生成任务:小节级350--800词元;片段级60--180词元。
- CDI/ICD编码任务:片段级40--120词元(要求更精准);小节级250--600词元。
分块元数据必须包含结构与定位信息
- 文档类型、所属章节、事件时间、作者角色。
- 就诊ID、患者ID、租户ID。
- 字符起始与结束位置(证据追溯的根基)。
5.2 引用粒度:可核查、可追责、不影响医生工作流
建议支持三种引用粒度:
- 粒度一:文档级(提供背景参考)
- 粒度二:章节级 + 偏移量(默认推荐)
- 粒度三:片段级 + 原文引用(关键事实与ICD编码必须使用)
必须使用粒度三引用的关键信息类型
- 诊断结论、用药剂量、关键检验值、关键时间线、影像/病理报告印象、编码直接证据。
5.3 冻结快照:证据快照(审计回放的核心)
若无快照,证据会随原始文书的更新而漂移,导致审计无法复盘。
建议支持两种快照策略:
- 轻量快照(默认):保存文档ID、文档版本、偏移量、原文引用及文本哈希。
- 重量快照(高风险场景):保存全文哈希,并将文档版本加密存储于合规仓库。
最佳实践:默认启用轻量快照;针对手术记录、争议病例、结算关键文书等高风险场景启用重量快照。
5.4 证据链接:两种实现路径
路径A:生成时强制引用(推荐)
要求大型语言模型在输出结构中即包含引用标识符。
优点:稳定、成本低,不依赖复杂的后处理对齐算法。
路径B:生成后对齐(作为兜底方案)
适用于:调用外部模型、旧版本模型或医生编辑后需要补全引用的文本。
实现方式:句子嵌入 → 检索相关证据Top-K → 计算相似度并设定阈值 → 对未达标部分标记"需复核"。
6. 关键接口与数据流设计(可直接落地)
6.1 病历生成API(强结构、带引用、版本化)
POST /v1/notes/generate
请求示例:
json
{
"encounter_id": "E123",
"note_type": "DISCHARGE_SUMMARY",
"inputs": {
"structured": { "diagnoses": ["I10"], "labs": [{"name":"HbA1c","value":8.1}] },
"free_text": "主诉:头晕3天..."
},
"rag": { "enabled": true, "top_k": 12 },
"options": { "stream": true, "deterministic": true, "temperature": 0.2 }
}
响应示例(包含引用与快照):
json
{
"note_id": "N789",
"model_version": "model-x.y",
"prompt_version": "note_v3.2",
"content": { "sections": [{"title":"现病史","text":"..."}] },
"citations": [{"section":"现病史","doc_id":"D1","offset":[120,245]}],
"quality": { "passed": true, "scores": {"factuality":0.93,"consistency":0.89} },
"trace_id": "T-abc"
}
6.2 编码建议API(建议、证据、解释与查询)
POST /v1/coding/suggest
请求示例:
json
{
"encounter_id": "E123",
"scope": ["ICD10"],
"rag": { "enabled": true, "top_k": 20 },
"options": { "max_candidates": 30, "explain": true }
}
6.3 统一数据流(管道化治理)
请求 → 身份鉴权 → 上下文构建 → RAG检索 → 模型推理 → 质量门禁 → 审计存储 → 响应
管道化设计确保每个处理环节都可测试、可控制、可回放。
7. 关键伪代码示例(工程团队可直接参考复用)
7.1 编排器主流程(病历生成)
python
def generate_note(request, user):
trace_id = generate_trace_id()
authorize_user(user, request.encounter_id)
context = ContextBuilder().build(request.encounter_id, request.inputs)
evidence_list = []
if request.rag.enabled:
evidence_list = rag_retrieve(context.query_text(), top_k=request.rag.top_k)
evidence_snapshot = freeze_evidence(trace_id, evidence_list)
policy = PolicyEngine().decide(task="note_generation", latency_budget_ms=1200)
selected_model = ModelRouter().select(policy)
prompt = PromptBuilder(version="note_v3.2").render(context, evidence_snapshot)
raw_output = LLMClient(selected_model).generate(prompt, temperature=policy.temperature, seed=policy.seed)
parsed_output = OutputParser(schema=NOTE_SCHEMA).parse(raw_output)
quality_result = QualityGate().run(parsed_output, context, evidence_snapshot)
if not quality_result.passed:
fallback_output = FallbackStrategy().apply(parsed_output, context, quality_result)
AuditLog.write(trace_id, request, selected_model, prompt, evidence_snapshot, fallback_output, quality_result)
return fallback_output
saved_note_id = ResultStore.save(parsed_output)
AuditLog.write(trace_id, request, selected_model, prompt, evidence_snapshot, parsed_output, quality_result)
return {"note_id": saved_note_id, "content": parsed_output, "quality": quality_result, "trace_id": trace_id}
7.2 质量门禁(事实对齐与证据覆盖检查)
python
class QualityGate:
def run(self, generated_note, clinical_context, evidence_snapshot):
if not validate_schema(generated_note, NOTE_SCHEMA):
return QualityResult(passed=False, issue="schema_validation_failed")
conflict_list = []
conflict_list += check_lab_alignment(generated_note, clinical_context.structured["labs"])
conflict_list += check_medication_alignment(generated_note, clinical_context.structured["meds"])
uncovered_ratio = calculate_citation_coverage(generated_note, evidence_snapshot)
drift_score = ConsistencyProxy().estimate(generated_note, clinical_context)
passed = (len(conflict_list) == 0 and uncovered_ratio < 0.1 and drift_score < 0.2)
return QualityResult(passed=passed, issues=conflict_list, scores={"uncovered_ratio": uncovered_ratio, "drift_score": drift_score})
8. 工程化实施与评估范式(离线持续集成与在线治理结合)
8.1 离线评测流水线(上线前强制通过)
- 一致性测试:同一输入多次生成的语义漂移。
- 事实性测试:与金标准结构化字段的冲突率。
- 证据覆盖测试:关键句无引用支持的比例。
- 人工量表评分与抽样检查。
- 任何指标未达预设阈值,则阻止进入灰度发布流程。
8.2 在线监控与持续改进(保障系统长期稳定运营)
系统层面服务水平目标监控:
- P95/P99延迟、服务可用性、错误率、队列深度、GPU利用率、推理成本。
内容层面关键绩效指标监控:
- 事实冲突告警频率。
- 引用覆盖率趋势。
- 幻觉被拦截次数。
- 临床医生按章节的编辑比例。
- 编码建议采纳率、驳回原因分类统计。
反馈数据回流机制:
- 采纳、驳回操作及编辑差异自动进入数据仓库。
- 形成高质量的训练样本与回归测试集。
- 持续迭代提示模板、模型参数与业务规则,驱动系统进化。
9. 部署范式:中心化服务与院内一体机(边界不同,核心组件一致)
- 范式A:中心化服务(云或私有云部署)
强调弹性伸缩、动态批处理、统一治理与集中监控。 - 范式B:院内私有化/一体机部署
强调数据不出院、支持离线批处理、满足本地合规审计要求,对外仅暴露最小化API接口。
重要洞察 :
两种部署范式仅在网络与物理边界上存在差异,其核心系统组件与治理范式保持高度一致。这进一步印证了此类任务"更偏向工程范式"的论点。
10. 常见工程陷阱与风险项(提前识别以备评审)
- 仅存储文档ID而未记录字符偏移量 → 导致引用无法精确定位核查。
- 未存储文档版本号 → 原始文书更新后,原有证据引用失效。
- 仅使用向量检索 → 导致包含具体数值、缩写术语的查询召回失败(必须采用混合检索)。
- 检索时未应用权限标签过滤 → 可能召回越权访问的文书,引发合规事故。
- 引用原文片段过长 → 带来患者隐私泄露风险及存储成本激增。
- 未实施输出一致性测试 → 线上服务输出漂移,导致临床医生对系统失去信任。
- 缺乏用户反馈闭环设计 → 系统性能停留在演示水平,无法持续改进。
11. 讨论与结论:系统"智能"持续演进,治理范式长期沉淀
本文论证了病历生成与CDI/ICD编码任务从本质上更偏向于一个系统工程范式问题,而非单纯的算法优化问题。其成功落地的关键,在于能否构建一个适应临床工作流特性、内嵌多层质量与安全管控机制、并能满足严格合规与审计要求的系统性工程框架。
我们所提出的"可治理推理系统"范式,通过以下核心设计实现了这一目标:
- 编排层进行统一调度与策略决策(策略驱动的编排器)。
- RAG层固化证据链条并确保可追溯(证据快照与精细化引用)。
- 质量门禁层实现风险的事前拦截与事中监控(事实对齐、一致性检查、幻觉监控)。
- 审计层保障全流程的可追溯与可复现(遵循一次写入多次读取原则的黑匣子日志)。
该框架为高风险医疗人工智能应用提供了一个具备高度可复用性的工程蓝图。
展望未来,随着医疗领域大型语言模型能力的持续演进,系统的"智能"核心将不断升级。然而,支撑其实现安全、可靠、合规落地的系统性工程治理范式将保持相对稳定并持续深化。推动医疗人工智能从实验室走向临床日常,必须坚持"算法创新"与"工程治理"双轮驱动的战略。
附录
附录A:证据快照输入规范
核心原则:模型只能引用快照中提供的 citation_id。
确保引用"可核查、可追责、可复现"。
A.1 证据快照结构示例(由RAG层生成并传递给模型)
json
{
"snapshot_id": "SNP-20260109-001",
"retrieval_metadata": {
"query": "E11 HbA1c metformin discharge summary",
"top_k": 12,
"ranker_version": "rerank-v2"
},
"items": [
{
"citation_id": "C1",
"doc_id": "D123",
"doc_version": "v7",
"doc_type": "lab_report",
"section": "Results",
"char_start": 120,
"char_end": 245,
"quote": "HbA1c 8.1% (H)...",
"time": "2026-01-08T10:23:00Z",
"integrity": { "text_hash": "sha256:..." }
},
{
"citation_id": "C2",
"doc_id": "D456",
"doc_version": "v3",
"doc_type": "progress_note",
"section": "Assessment",
"char_start": 800,
"char_end": 910,
"quote": "继续二甲双胍...",
"time": "2026-01-08T11:00:00Z",
"integrity": { "text_hash": "sha256:..." }
}
]
}
附录B:病历生成提示模板(生产可用)
采用三层模板结构:
- 系统提示:定义基础角色与硬性约束,在模型服务端固定。
- 开发者提示:定义任务规则与输出格式要求,便于版本化管理。
- 用户提示:由编排器动态拼装,包含具体的患者上下文与证据快照。
B.1 系统提示(强约束:输出必须为JSON)
text
你是一个临床文档生成组件。你必须遵守以下规则:
1) 你只能使用输入中提供的"患者上下文"和"证据快照"中的信息。
2) 你必须严格输出符合指定JSON Schema的JSON对象,不得包含任何额外的解释、Markdown标记或代码块。
3) 所有关键的临床主张(诊断、用药、检验值、时间线、计划)必须附带citation_ids,且这些ID只能来源于Evidence Snapshot中的items。
4) 如果无法从证据中支持某个主张,必须在对应句子的flags中标记"NO_EVIDENCE"或"NEEDS_REVIEW",并避免使用确定性陈述。严禁编造信息。
5) 对于任何不确定的信息,必须使用不确定的措辞,并在flags中标记"UNCERTAIN"。
6) 不得提供治疗建议或做出超出证据的推断。你的输出仅作为临床记录草稿,需经医生审核。
B.2 开发者提示(任务规则与章节要求)
text
任务:为{note_type}类型的临床文书生成草稿,并按指定章节输出。
输出要求:
- 输出JSON必须通过NOTE_JSON_SCHEMA校验。
- content.sections[].sentences[].citation_ids中的每个ID必须存在于Evidence Snapshot中。
- 以下信息类型的句子必须有citation_ids(否则其flags必须包含NO_EVIDENCE):
(a) 诊断结论或鉴别诊断。
(b) 药物名称、剂量、频次。
(c) 关键的检验值、单位及其是否异常的判断。
(d) 手术、操作名称及关键日期。
(e) 影像或病理报告的印象结论。
(f) 出院带药或随访计划中涉及药物或关键风险提示的语句。
- 对于"总结性、模板性、非事实性"的句子(如"患者耐受良好"),可不引用证据,但必须避免包含具体的数值、诊断或药物等事实细节。
- 如果证据之间存在冲突(例如不同版本的检验值),必须标记"CONFLICT"并说明冲突点(但仍需引用相关证据)。
- 必须输出质量自检字段quality.self_check,包含:
* uncovered_claims_count(无证据支持的关键主张数量)
* conflict_claims_count(存在证据冲突的主张数量)
* risky_phrases(发现的过度确定性措辞列表)
- 不得输出患者身份信息。即使输入中出现,也必须脱敏为[REDACTED]。
B.3 用户提示(动态填充)
text
任务标识: {trace_id}
【患者上下文(结构化部分)】
{structured_context_json}
【患者上下文(非结构化文本)】
{free_text}
【文书类型】
{note_type}
【证据快照(仅可引用以下citation_id)】
{evidence_snapshot_json}
【输出章节要求】
{sections_requirement_json}
请生成符合NOTE_JSON_SCHEMA的JSON。
附录C:病历生成JSON Schema(严格可校验)
json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.org/schemas/clinical_note.schema.json",
"title": "临床文书输出",
"type": "object",
"additionalProperties": false,
"required": ["meta", "content", "citations_used", "quality"],
"properties": {
"meta": {
"type": "object",
"additionalProperties": false,
"required": ["note_type", "language", "model_version", "prompt_version", "snapshot_id", "trace_id"],
"properties": {
"note_type": { "type": "string" },
"language": { "type": "string", "enum": ["zh-CN", "en-US", "mixed"] },
"model_version": { "type": "string" },
"prompt_version": { "type": "string" },
"snapshot_id": { "type": "string" },
"trace_id": { "type": "string" }
}
},
"content": {
"type": "object",
"additionalProperties": false,
"required": ["sections"],
"properties": {
"sections": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["title", "sentences"],
"properties": {
"title": { "type": "string" },
"sentences": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["text", "citation_ids", "flags"],
"properties": {
"text": { "type": "string", "minLength": 1 },
"citation_ids": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
},
"flags": {
"type": "array",
"items": {
"type": "string",
"enum": ["OK", "NO_EVIDENCE", "NEEDS_REVIEW", "UNCERTAIN", "CONFLICT", "PHI_REDACTED"]
},
"uniqueItems": true
}
}
}
}
}
}
}
}
},
"citations_used": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true,
"description": "文书中引用的所有唯一citation_id集合"
},
"quality": {
"type": "object",
"additionalProperties": false,
"required": ["self_check"],
"properties": {
"self_check": {
"type": "object",
"additionalProperties": false,
"required": ["uncovered_claims_count", "conflict_claims_count", "risky_phrases"],
"properties": {
"uncovered_claims_count": { "type": "integer", "minimum": 0 },
"conflict_claims_count": { "type": "integer", "minimum": 0 },
"risky_phrases": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
}
}
}
}
}
}
}
附录D:编码建议提示模板与JSON Schema
编码建议任务对证据的要求更为严格:每个建议的编码必须附带证据,否则不具备可用性。
D.1 系统提示(编码任务)
text
你是一个临床编码建议组件。
约束:
1) 输出必须是符合指定JSON Schema的JSON对象,且只能是JSON。
2) 每一条编码建议必须包含至少一条evidence,且evidence.citation_ids只能来自Evidence Snapshot。
3) 你必须在rationale字段中解释编码依据,但不得编造信息。
4) 如果证据不足以确定编码的特异性,必须在actions中输出CDI_QUERY,并在flags中标记NEEDS_REVIEW。
5) 不得输出患者身份信息;所有身份信息需脱敏为[REDACTED]。
D.2 开发者提示(编码任务)
text
任务:为本次就诊生成{scope}编码的候选建议列表。
输出要求:
- 必须通过CODING_JSON_SCHEMA校验。
- 每个candidate必须包含:
* code, label, confidence (0~1)
* evidence: 至少一条(引用citation_ids)
* rationale: 简短逻辑说明
* actions: 若缺乏特异性,则包含CDI_QUERY
- 若evidence之间存在冲突,flags必须包含CONFLICT,并在rationale中提示冲突点。
- 若候选编码高度不确定,flags应包含UNCERTAIN或NEEDS_REVIEW。
D.3 编码建议JSON Schema
json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.org/schemas/coding_suggestion.schema.json",
"title": "编码建议输出",
"type": "object",
"additionalProperties": false,
"required": ["meta", "candidates", "citations_used", "quality"],
"properties": {
"meta": {
"type": "object",
"additionalProperties": false,
"required": ["scope", "model_version", "prompt_version", "snapshot_id", "trace_id"],
"properties": {
"scope": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
"model_version": { "type": "string" },
"prompt_version": { "type": "string" },
"snapshot_id": { "type": "string" },
"trace_id": { "type": "string" }
}
},
"candidates": {
"type": "array",
"minItems": 0,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["code", "label", "confidence", "evidence", "rationale", "flags", "actions"],
"properties": {
"code": { "type": "string" },
"label": { "type": "string" },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"evidence": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["citation_ids", "summary"],
"properties": {
"citation_ids": { "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true },
"summary": { "type": "string", "minLength": 1 }
}
}
},
"rationale": { "type": "string", "minLength": 1 },
"flags": {
"type": "array",
"items": { "type": "string", "enum": ["OK", "NO_EVIDENCE", "NEEDS_REVIEW", "UNCERTAIN", "CONFLICT", "PHI_REDACTED"] },
"uniqueItems": true
},
"actions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["type", "text"],
"properties": {
"type": { "type": "string", "enum": ["NONE", "CDI_QUERY"] },
"text": { "type": "string" }
}
}
}
}
}
},
"citations_used": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"quality": {
"type": "object",
"additionalProperties": false,
"required": ["self_check"],
"properties": {
"self_check": {
"type": "object",
"additionalProperties": false,
"required": ["no_evidence_candidates", "conflict_candidates"],
"properties": {
"no_evidence_candidates": { "type": "integer", "minimum": 0 },
"conflict_candidates": { "type": "integer", "minimum": 0 }
}
}
}
}
}
}
附录E:防幻觉与乱引用的强制约束策略
以下是生产环境中最为关键的几条"硬规则",建议在编排器或质量门禁层实现。
E.1 引用合法性校验(必须实现)
- 对输出中的每个
citation_id,必须验证其存在于evidence_snapshot.items[].citation_id中。 citations_used字段应由服务端重新计算,确保是输出中所有引用ID的去重集合。
伪代码示例:
python
def validate_citations(output_json, evidence_snapshot):
allowed_ids = {item["citation_id"] for item in evidence_snapshot["items"]}
used_ids = collect_all_citation_ids(output_json) # 从输出中提取所有citation_id
illegal_ids = [cid for cid in used_ids if cid not in allowed_ids]
if illegal_ids:
raise ValidationError(f"发现非法引用标识符: {illegal_ids}")
E.2 "关键句必须引用"规则检测(必须实现)
针对病历生成任务:
- 如果句子包含诊断、药物、剂量、检验值、关键日期等实体,则必须有对应的citation_ids。
- 否则,该句子的flags必须被打上
NO_EVIDENCE或NEEDS_REVIEW标签。
(可通过轻量级规则引擎结合命名实体识别实现)
E.3 "编造事实"的快速拦截(建议实现)
- 将结构化字段(检验、药物、诊断)作为事实来源。
- 若输出中出现了结构化字段中不存在的药物、数值或诊断,则触发
FACT_CONFLICT警报。 - 触发后执行策略:降级为模板填充、要求人工复核、或阻止写回电子病历系统。
附录F:强约束提示片段
F.1 禁止输出非JSON内容
text
重要:你的输出必须是单一的JSON对象。不要输出任何解释性文字、前缀、后缀、Markdown标记或代码块标记。
如果无法完成任务,也必须输出符合Schema的JSON,并在相关flags中标记NEEDS_REVIEW。
F.2 强制引用约束
text
你只能引用Evidence Snapshot中出现的citation_id。
严禁捏造citation_id,或引用不存在的证据。
如果没有证据支持某个句子,请使用flags标记NO_EVIDENCE或NEEDS_REVIEW,并使用"可能"、"考虑"等不确定措辞。
F.3 防止过度确定性措辞
text
避免使用"明确"、"肯定"、"必然"、"排除"等过度确定性的措辞。
如果证据不足或存在冲突,请标记UNCERTAIN或CONFLICT,并在句子中使用"考虑"、"可能"、"倾向于"等表述。
附录G:输出示例(合格与不合格对比)
G.1 合格示例(病历句子带正确引用)
json
{
"meta": {
"note_type": "DISCHARGE_SUMMARY",
"language": "zh-CN",
"model_version": "model-x.y",
"prompt_version": "note_v3.2",
"snapshot_id": "SNP-20260109-001",
"trace_id": "T-abc"
},
"content": {
"sections": [
{
"title": "诊疗计划",
"sentences": [
{
"text": "考虑2型糖尿病控制不佳(HbA1c 8.1%)。",
"citation_ids": ["C1"],
"flags": ["OK"]
},
{
"text": "出院继续二甲双胍治疗,具体剂量请由医生确认。",
"citation_ids": ["C2"],
"flags": ["NEEDS_REVIEW"]
}
]
}
]
},
"citations_used": ["C1", "C2"],
"quality": {
"self_check": {
"uncovered_claims_count": 0,
"conflict_claims_count": 0,
"risky_phrases": []
}
}
}
G.2 不合格示例
- 引用了不存在的
C99。 - 使用"明确诊断"等措辞但未提供引用。
➡️ 此类输出必须被质量门禁拦截。
附录H:实战建议
为确保"严格引用"成为系统可靠能力(而非依赖模型的自觉性),提出三个工程化落地点:
- 服务端重写citations_used字段:不直接信任模型输出的汇总字段,由服务端根据解析后的实际引用重新计算。
- 非法引用快速失败:发现非法citation_id时立即失败,可重试一次,若仍失败则触发降级或转人工复核流程。
- 服务端二次检查关键句引用 :即使模型漏引,也能通过服务端规则进行补救(例如为无引用的关键事实句自动添加
NEEDS_REVIEW标记)。