# CRA 智能质控 Agent — 四大工具工作原理说明 > **文档用途**:面向临床专家、PI(主要研究者)及项目管理人员,说明 CRA 智能质控 Agent 背后的四个核心工具是如何工作的。 > **最后更新**:2026-02-25 --- ## 一、整体工作方式 CRA 智能质控 Agent 是一个基于大语言模型(LLM)的 AI 助手,专门用于 IIT 临床研究项目的质量监控。当用户在对话框中提问时,AI **不是凭空回答**,而是通过调用 4 个专用工具获取真实数据后,再基于数据生成回答。 ### 工作流程 ``` 用户提问(如:"当前通过率是多少?") ↓ AI 分析问题,自动选择合适的工具 ↓ 工具执行,获取真实数据 ↓ AI 基于工具返回的数据,生成自然语言回答 ↓ 用户看到回答(如:"当前整体通过率为 92.9%,14 条记录中 13 条通过...") ``` ### 核心原则 - **所有回答必须基于真实数据**,AI 不会编造临床数据 - **只读不写**:AI 不会修改任何临床数据,如果被要求修改数据会拒绝 - **优先使用报告**:80% 的问题通过预计算的质控报告直接回答,保证速度和一致性 --- ## 二、四个工具详解 ### 工具 1:`read_report` — 质控报告查阅 **一句话说明**:查阅预先生成好的质控报告,是最常用的工具。 #### 什么时候使用? 用户问以下类型的问题时,AI 会调用此工具: - "目前通过率是多少?" - "有哪些严重问题?" - "3 号受试者有什么质控问题?" - "哪个表单通过率最低?" - "最近质控发现了什么趋势?" #### 报告包含哪些内容? | 报告章节 | 包含信息 | |---------|---------| | **概览(summary)** | 总记录数、已完成记录数、通过率、严重问题数、警告数、最后质控时间 | | **严重问题(critical_issues)** | 每个有问题的受试者具体违反了哪条规则、实际值是什么、标准应该是什么 | | **警告(warning_issues)** | 非致命性的数据异常提醒 | | **表单统计(form_stats)** | 每张 CRF 表单的通过率 | | **问题排名(trend)** | 哪些规则被违反最多,影响了多少人 | #### 报告示例 以下是 AI 实际读取的报告格式(修复后的真实报告): ```xml - 状态: 1/14 记录存在严重违规 (7% Fail) - 通过率: 92.9% - 严重问题: 1 | 警告: 0 - Top 1 问题: 1. 排除标准检查 (1人) **严重违规 (1项)**: 1. [exc_001] **排除标准检查**: 当前值 **1** (标准: 应为0) ``` #### 报告数据从哪里来? ``` 质控报告 ← 数据库中的质控日志(qc_logs 表) ↓ 每个受试者 × 每个访视事件,取最新一条质控记录 ↓ 按受试者+规则去重,避免重复计数 ↓ 通过率 = 按受试者级别计算(每个受试者取所有访视中最严重的状态) ``` #### 缓存机制 报告生成后会缓存 **24 小时**。在缓存有效期内,多次提问不会重复计算,保证了响应速度。执行"一键全量质控"后会自动刷新报告缓存。 #### 常见问题 **Q:报告里只有质控问题,不包含录入的原始数据吗?** A:对。`read_report` 只包含质控结论(通过/不通过、违规详情)。如果要看具体患者的原始录入数据(如年龄、实验室指标),AI 会自动调用下面的 `look_up_data` 工具。 --- ### 工具 2:`look_up_data` — 查询原始临床数据 **一句话说明**:从 REDCap 系统实时拉取患者的原始录入数据。 #### 什么时候使用? 用户问以下类型的问题时,AI 会调用此工具: - "3 号受试者的年龄是多少?" - "帮我查一下 5 号患者的实验室检查结果" - "这个患者的知情同意日期是什么时候?" #### 工作流程 ``` AI 调用 look_up_data(受试者编号=3, 查询字段=[年龄, 性别]) ↓ 系统将中文字段名翻译为 REDCap 内部字段名(如:年龄 → age) ↓ 通过 REDCap API 实时查询该患者数据 ↓ 如果是纵向研究(多次访视),自动合并所有访视的数据 ↓ 返回给 AI:{ record_id: "3", age: "28", gender: "1" } ↓ AI 组织成自然语言回答用户 ``` #### 关键特性 - **实时查询**:每次调用都从 REDCap 获取最新数据,不使用缓存 - **支持中文查询**:用户可以说"帮我查年龄",系统会自动翻译为 REDCap 字段名 `age` - **纵向数据自动合并**:同一患者在不同访视(筛选期、基线、随访等)中录入的数据会自动合并为一条完整记录 - **只读操作**:只查询数据,绝不修改 #### 数据来源 直接通过 REDCap REST API 从 REDCap 数据库实时获取,数据路径为: ``` AI → REDCap API(http://REDCap服务器/api/)→ REDCap 数据库 → 返回记录 ``` --- ### 工具 3:`check_quality` — 即时质控检查 **一句话说明**:对患者数据立即执行质控规则检查,可以检查单个患者或全部患者。 #### 什么时候使用? 用户**明确要求重新检查**时,AI 才会调用此工具: - "帮我重新检查一下 3 号受试者" - "现在执行一次全量质控" - "数据刚更新了,帮我跑一下质控" > **注意**:如果用户只是问"通过率是多少"这样的查询性问题,AI 会使用 `read_report` 而不是 `check_quality`,因为报告中已有预计算的结果。 #### 两种检查模式 ##### 模式 A:单患者检查 ``` AI 调用 check_quality(record_id="3") ↓ 从 REDCap 拉取 3 号患者的最新数据 ↓ 加载项目配置的所有质控规则(如:年龄范围检查、排除标准检查等) ↓ 逐条规则执行: - 字段缺失?→ 跳过该规则(不算失败) - 字段有值?→ 用 JSON Logic 规则引擎判定通过/失败 ↓ 返回结果: 整体状态: FAIL 通过 8 / 9 条规则 违规: 排除标准检查 — 当前值为 1(应为 0) ``` ##### 模式 B:全量批量检查 ``` AI 调用 check_quality()(不传受试者编号) ↓ 从 REDCap 拉取所有患者的所有访视数据 ↓ 基线数据合并:将基线访视的数据(如年龄、性别)合并到后续访视中 ↓ 逐个 受试者 × 访视 执行规则引擎 ↓ 结果写入数据库(追加新记录,不覆盖历史) ↓ 返回汇总: 总计: 42 条检查 通过: 39 条 未通过: 3 条 通过率: 92.9% 问题受试者: [3号 - 排除标准检查违规] ``` #### 质控规则引擎说明 系统使用 **JSON Logic 规则引擎** 执行质控检查。目前配置的规则包括: | 规则类别 | 示例规则 | 说明 | |---------|---------|------| | **纳入标准** | 年龄范围检查(16-35岁) | 不在范围内则标记为严重问题 | | **纳入标准** | 知情同意检查 | 必须已签署知情同意 | | **排除标准** | 排除标准符合性检查 | 符合任何排除标准则标记为严重问题 | **缺失数据处理策略**(V3.2 修复后): - 如果某个字段在当前访视中没有录入(如随访期没有"年龄"字段),该规则**自动跳过**,不算失败 - 只有字段有值但不符合规则时,才判定为失败 --- ### 工具 4:`search_knowledge` — 知识库检索 **一句话说明**:在项目文档(研究方案、CRF、伦理批件等)中搜索信息。 #### 什么时候使用? 用户问以下类型的问题时,AI 会调用此工具: - "纳入标准是什么?" - "研究方案中对随访间隔是怎么规定的?" - "主要疗效指标是什么?" - "知情同意的要求有哪些?" #### 工作流程 ``` AI 调用 search_knowledge(query="纳入标准是什么") ↓ 查找该项目关联的知识库 ↓ 将用户问题转化为向量(语义表示) ↓ 在知识库中进行语义相似度搜索(不是简单的关键词匹配) ↓ 返回最相关的 5 个文档片段: 1. 研究方案V2.0.pdf(相关度 87.3%) 内容:"纳入标准:1. 年龄16-35岁 2. 确诊为..." 2. ICF知情同意书.pdf(相关度 72.1%) 内容:"..." ↓ AI 综合这些文档片段,生成回答 ``` #### 关键特性 - **语义搜索**:不是简单的关键词匹配,而是理解问题含义后搜索。比如问"入组条件"也能找到"纳入标准"的内容 - **文档来源标注**:每个搜索结果都标注来自哪个文档,方便追溯 - **相关度评分**:只返回相关度 ≥ 30% 的结果,过滤无关内容 - **支持多种文档**:研究方案、CRF 说明、伦理批件、操作手册等上传到知识库的文档均可搜索 #### 知识库管理 知识库中的文档需要通过项目管理界面上传。上传后,系统会自动: 1. 解析文档内容(支持 PDF、Word 等格式) 2. 将文档分块(每块约 500-1000 字) 3. 为每个文档块生成向量嵌入(用于语义搜索) 4. 存入向量数据库 --- ## 三、工具协作示例 以下是一个典型的多工具协作场景: ### 场景:用户问"3 号受试者有什么问题?详细说明一下" ``` 第 1 轮:AI 调用 read_report(section="critical_issues", record_id="3") → 获取质控报告中 3 号受试者的问题列表 → 发现:排除标准检查失败,实际值为 1 第 2 轮:AI 调用 look_up_data(record_id="3", fields=["exclusion_criteria"]) → 从 REDCap 获取原始数据确认 → 确认 exclusion_criteria 字段值确实为 1 AI 最终回答: "3 号受试者存在 1 项严重违规:排除标准检查未通过。 该受试者的排除标准字段值为 1(应为 0,即不符合任何排除标准)。 建议核实该受试者是否确实符合入组条件。" ``` ### 场景:用户问"纳入标准中年龄范围是多少?有没有超龄的患者?" ``` 第 1 轮:AI 调用 search_knowledge(query="纳入标准年龄范围") → 从研究方案中找到:"纳入标准第1条:年龄16-35岁" 第 2 轮:AI 调用 read_report(section="critical_issues") → 检查是否有年龄相关的质控问题 → 当前无年龄违规记录 AI 最终回答: "根据研究方案,纳入标准规定年龄范围为 16-35 岁。 当前质控报告显示,所有已录入受试者的年龄均在合规范围内, 未发现超龄问题。" ``` --- ## 四、总结对比 | 工具 | 核心用途 | 数据来源 | 实时性 | 使用频率 | |------|---------|---------|--------|---------| | **read_report** | 查阅质控报告 | 数据库(预计算报告) | 缓存 24 小时 | ~80% | | **look_up_data** | 查询原始数据 | REDCap 实时 API | 实时 | ~10% | | **check_quality** | 执行质控检查 | REDCap + 规则引擎 | 实时执行 | ~5% | | **search_knowledge** | 搜索文档知识 | 项目知识库(向量搜索) | 准实时 | ~5% | ### 设计理念 **报告优先,工具兜底**(Report-first, Tools-fallback) - 绝大多数质控问题通过预计算的报告直接回答,保证响应速度(秒级) - 只在需要查看具体原始数据或重新执行质控时,才调用其他工具 - AI 会根据问题类型自动选择最合适的工具,无需用户干预 --- ## 附录:技术架构简图 ``` ┌──────────────────────────────────────────────────────────────────┐ │ 用户对话界面 │ │ (Web / 微信公众号) │ └──────────────────────┬───────────────────────────────────────────┘ │ 用户提问 ▼ ┌──────────────────────────────────────────────────────────────────┐ │ ChatOrchestrator(对话编排器) │ │ │ │ System Prompt(角色定义 + 工具选择策略) │ │ ↓ │ │ LLM(DeepSeek-V3)← Function Calling 循环(最多 3 轮) │ │ ↓ │ │ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ ┌───────────┐ │ │ │ read_report │ │look_up_data │ │check_quality │ │search_ │ │ │ │ │ │ │ │ │ │knowledge │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬───────┘ └─────┬─────┘ │ └─────────┼───────────────┼───────────────┼───────────────┼────────┘ │ │ │ │ ▼ ▼ ▼ ▼ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ QcReport │ │ REDCap │ │ REDCap │ │ pgvector │ │ Service │ │ REST API │ │ REST API │ │ 向量搜索 │ │ (数据库) │ │ (实时) │ │ + 规则引擎 │ │ (知识库) │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ ```