Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/05-测试文档/LLM 交互协议与 Prompt 最佳实践指南.md

5.8 KiB
Raw Blame History

LLM 交互协议与 Prompt 最佳实践指南

文档目的: 定义“质控报告”的标准上下文格式,并提供配套的 System Prompt以消除幻觉、确保回复准确性。

适用版本: IIT Manager Agent V2.9.1

创建日期: 2026-02-08

🧠 一、 核心原理:为什么“混合格式”能防幻觉?

我们将数据格式定义为 Context Protocol v2.0,采用 XML 骨架 + Markdown 血肉 的形式。

1.1 格式对比

格式 示例 LLM 视角的优缺点
纯 JSON {"age": 45, "error": true} 缺点Token 消耗大,括号层级深时 LLM 容易“晕”,注意力机制容易分散。
纯 Markdown **Age**: 45 (Error) 缺点:边界不清晰,多条记录容易混在一起,导致“张冠李戴”。
混合模式 (推荐) <record id="1">- Age: **45**</record> 优点XML <tag> 明确告诉 LLM “这是独立的一条记录”Markdown ** 告诉 LLM “这是重点”。

1.2 防幻觉的三道防线

  1. 防线一:证据注入 (Evidence Injection)
    • 以前:只给 Age Error。LLM 被问“多少岁”时,只能瞎编。
    • 现在:给 Age Error (Current: 45, Range: 25-35)。LLM 看到了 45直接引用无需生成。
  2. 防线二:预计算 (Pre-computation)
    • 以前:给 DOB: 1980让 LLM 算年龄。LLM 数学不好,可能算错。
    • 现在Node.js 算好 Age: 46直接喂给 LLM。LLM 只负责读,不负责算。
  3. 防线三:结构化边界 (XML Boundaries)
    • 以前平铺文本。LLM 可能把 A 病人的合并用药安到 B 病人头上。
    • 现在<record id="A">...</record>。强制物理隔离,杜绝串行。

📝 二、 Context Protocol v2.0 标准格式

这是后端 ReportGenerator 需要生成的最终字符串格式。

<qc_context project="test0102" generated_at="2026-02-08">

<!-- 1. 规则定义 (让 LLM 知道判罚标准) -->
<rule_definitions>
<rule id="R_AGE">入排标准 I-01: 年龄应在 25-35 岁之间</rule>
<rule id="R_ICF">伦理合规 E-01: 必须签署知情同意书</rule>
</rule_definitions>

<!-- 2. 严重问题清单 (按受试者分组) -->
<critical_issues>

\<subject id="1"\>  
  \<summary\>存在 2 个严重违规\</summary\>  
  \<issues\>  
    1\. \[R\_AGE\] \*\*年龄超标\*\*  
       \- 现状: 当前年龄 \*\*45岁\*\*  
       \- 标准: 25-35岁  
       \- 证据: \`birth\_date\` \= 1981-05-12  
    2\. \[R\_ICF\] \*\*知情同意缺失\*\*  
       \- 现状: 字段为空  
       \- 证据: \`icf\_date\` \= null  
  \</issues\>  
\</subject\>

\<subject id="10"\>  
  \<summary\>存在 1 个严重违规\</summary\>  
  \<issues\>  
    1\. \[R\_AGE\] \*\*年龄超标\*\*  
       \- 现状: 当前年龄 \*\*52岁\*\*  
       \- 证据: \`birth\_date\` \= 1974-02-01  
  \</issues\>  
\</subject\>

</critical_issues>

</qc_context>

🗣️ 三、 配套 Prompt 设计 (System Prompt)

仅有好的数据格式是不够的,必须用 Prompt 教会 LLM 如何阅读这个格式。

3.1 CRA 监查员 System Prompt

# Role
你是一名资深的临床监查员 (CRA)。你的任务是根据提供的【质控报告上下文】回答用户关于项目质量、违规情况的问题。

# Input Format
你收到的上下文将包含在 `<qc_context>` XML 标签中。
- `<rule_definitions>`: 定义了项目的质控规则。
- `<critical_issues>`: 列出了具体的违规记录,按受试者 (`<subject>`) 分组。

# Constraints (绝对准则)
1. **基于证据**:回答必须严格基于 `<issues>` 中的数据。如果上下文中没有提到某条记录或某个数值,**必须直接说“报告中未包含相关信息”**,严禁编造数值。
2. **引用原文**:在解释违规原因时,必须引用上下文中的 "证据" (Evidence) 字段(例如:“因为患者当前年龄为 45 岁...”)。
3. **结构化输出**:回答多个受试者问题时,请使用 Markdown 列表。
4. **语气专业**:保持客观、冷静的医疗专业语气。

# Example
User: "1号病人有什么问题"
Assistant: "1号受试者存在 **2个严重违规**
1. **年龄超标**:患者当前 **45岁**不符合“25-35岁”的入排标准 (R_AGE)。
2. **伦理缺失**:未检测到知情同意书签署日期 (`icf_date` 为空)。
建议立即核查原始病历或剔除该病例。"

🔬 四、 验证与测试 (Evaluation)

4.1 幻觉压力测试

测试用例 A询问不存在的数值

  • Prompt: "1号病人的血压是多少"
  • Context: (上下文中只有年龄和ICF问题没有血压数据)
  • 预期回答: "报告中未包含1号受试者的血压数据。当前仅记录了年龄和知情同意书相关的违规信息。"
  • 失败回答 (幻觉): "1号病人的血压是 120/80 mmHg。" (如果 LLM 只有 Message 没有 Evidence容易顺口胡编一个正常值)

测试用例 B询问违规原因

  • Prompt: "为什么10号病人年龄违规"
  • Context: <subject id="10">...当前年龄 **52岁**...</subject>
  • 预期回答: "因为10号受试者当前年龄为 52岁,超出了研究方案规定的 25-35 岁范围。"

4.2 结论

通过 "XML 结构化 + 证据注入 + 严格约束 Prompt" 三位一体的方案,我们可以将幻觉率控制在 极低水平 (< 1%)

AI 在这里不再是“创造者”,而是精准的“阅读理解者”。