“临床研究行业有个公开的尴尬:文档堆积如山,数据入口无数,但真正能把‘查资料’和‘查数据’串起来完成一件具体工作的工具几乎为零。”这句话我在这两年反复对同行讲。写方案的研究者要翻 GCP 指导原则、历史试验方案、药物说明书,同时还要核对入组进度和不良事件数量;做数据管理的同事要查 EDC 里的逻辑核查结果,又要去翻监查报告里的原始问题;监查员想确认某个中心是否有漏报事件,得同时看数据库导出表和传真的 SAE 报告。所有环节都在重复同一个动作:先找文档,再查数据,然后人工拼装答案。
这个项目做的就是一个面向临床研究场景的 AI Agent 平台,底层挂了两件核心资产——知识库和数据服务平台。知识库管非结构化文档,包括指南、SOP、方案、药物说明书、历史项目资料;数据服务平台管结构化数据,包括受试者人口学信息、检查检验结果、不良事件记录、入组进度和随访状态。Agent 在这两层之上负责拆解问题、决定调哪个知识库检索、调哪个数据服务接口,最后生成带引用的回答。谁适合看这篇文章?想给临床试验信息化做顶层设计的人、正在做医疗大模型应用落地的工程师、以及每天被文档和数据来回折腾的临床运营和医学事务同事。下面把我踩过的坑、试出来的做法,按一个完整项目的方式拆开讲。
1. 项目总体拆解:Agent 平台不是做出来,是“组装”出来的
这个项目最容易被误解的地方是:大家以为重点是选一个大模型,然后所有问题就解决了。实际恰恰相反。在临床研究场景里,大模型是被两个底座养着的上层应用。知识库决定它“从哪里找依据”,数据服务平台决定它“从哪里拿数字”,Agent 编排层决定前两者如何被正确调用。三者之间是组装关系,不是替代关系。
1.1 临床研究场景里最值得先做的几个应用点
做项目规划的第一件事,不是招算法专家,而是去业务部门听需求。我按频率和复杂度筛了一遍,临床研究里有四个场景在“文档+数据”上卡得最厉害,也是 Agent 最能产生实际价值的切口。
第一个是方案与合规问答。研究者和 CRC 在日常工作中会高频遇到“这个不良事件要不要按 SAE 报”“方案偏离算不算重大偏离”“筛选失败但签了知情同意书的受试者数据怎么保留”这类问题。过去答案是靠人记得,记得不准就翻几十份文档,效率极低。这个场景的知识源明确,答案相对确定,很适合做成一个能引用原文出处的问答 Agent。
第二个是受试者数据智能查询。项目组经常要回答“某个中心目前入组了多少”“有多少受试者白细胞计数在外周血检查中超过正常值上限”“最近一周有没有新发的非预期不良事件”。这类问题本质是结构化数据查询,你给大模型一份 API 清单和字段说明,它能把自然语言翻译成查询条件,关键是底层数据服务要稳。
第三个是文档生成辅助。写临床试验总结报告、年度进展报告、会议纪要时,大量工作是摘抄方案中的关键设计点、统计相关的历史数据、核对入组和随访的表。这类工作重复性强,但要求输出的每个数字都有出处,正好是“检索增强生成”擅长的长项。
第四个是数据质控提示。比如某中心某个访视窗口的检查项目缺失率明显偏高,或某研究者上报的 AE 用词不规范,这类跨文档、跨数据的模式识别,人工做非常费时,Agent 可以做线索生成,再由数据管理团队复核。
这四个场景不是平均用力。我给的建议是:第一个和第二个先做,因为知识边界清晰、验收标准明确、用户感知最强。文档生成辅助放在第二阶段,数据质控提示放在第三阶段,因为后者涉及统计模型和业务规则,前两步的数据资产还没打通时硬上,会变成“看起来会分析,实际不可信”。
1.2 为什么知识库和数据服务必须拆成两层
我一开始的直觉是把所有资料都塞进一个向量数据库,然后让大模型去检索,数据也想办法转成文本索引进去。做了一轮 POC 之后发现这条路走不通,至少有三个致命问题。
第一是上下文的“熵”太大。向量检索返回的是语义相似的片段,但临床问题的正确答案往往要求精确的数值、严格的限定条件和角色权限。把“三年前某个版本的方案查一下”和“现在执行的方案查一下”混在一个索引里,模型很容易给出一个“听起来对但版本不对”的答案。
第二是权限和追溯没法做。一个医学文档可能只有研究者角色能看全文,数据记录可能只对授权用户开放,如果全部塞进同一个向量库,权限粒度极难控制。更麻烦的是审计要求,临床研究行业要对“谁在什么时间基于什么数据得出结论”做完整追溯,单一向量库做不到。
第三是数据和文档的生命周期完全不一样。文档是版本化、低频变更的,数据是高频写入、及时更新的。知识库一周更新一次可以接受,入组人数和数据质控结果必须实时准。如果两者共用一个检索通道,要么实时性牺牲,要么每隔几分钟就要重建一次向量索引,成本不可控。
所以架构上我把它们拆成了两层。知识库解决的是“依据在哪、依据是什么、依据哪个版本”,数据服务平台解决的是“数是多少、数可不可信、数从哪里来”。Agent 层只做编排:识别意图、决定工具、拼接答案。DocA:这样每个组件的边界清楚,出问题也好排查,是典型的“先解耦,再组装”思路。
2. 知识库建设:把医学文档变成可检索、可引用、可追溯的知识资产
知识库听起来简单,实际上一个临床研究知识库的建设周期占整个项目的一半以上。老话说“Garbage in, garbage out”,医学领域更是如此。你喂给知识库的内容质量,直接决定 Agent 回答的可信度。知识库建设可以拆成三条线:文档采集与预处理、分块与检索策略、权限与版本管理。
2.1 医学文档的采集与预处理:解析管线是第一个隐形难点
临床研究知识库的文档来源非常杂。一套完整的试验方案可能是几十页的 PDF,其中还夹着大量表格;SOP 可能是 Word 版本改了很多遍;药物说明书可能是扫描件;监管指南甚至可能是中英双语对照版。把这些格式全部统一进知识库,需要一个可扩展的文档解析管线。
我采用的管线分四步走。
第一步是格式识别与转档。PDF 用内容解析引擎按页转成结构化文本,尽量保留标题层级;Word 文档直接提取段落和表格;扫描件先做 OCR,医学文档的 OCR 要比通用文档更谨慎,因为“0”和“O”、“I”和“l”在药品名和 ID 里经常混淆,需要准备一个医学词表做后纠错,把常见错误分词纠正回来。
第二步是版面分析与去噪。页眉页脚、页码、水印、批注这些都要剔掉,否则检索时会出现大量无意义片段。表格要单独识别成结构化数据,因为临床方案中的入组排除标准经常是长表格,如果你把表格拍平成纯文本,关键的“或”“且”条件很容易在语义上被模型误解。
第三步是结构化抽取。给每个文档打上元数据标签,包括文档类型、版本号、生效日期、适用项目、涉及药物或器械、编写单位等。这个步骤是后来做权限和版本过滤的基础,一定要在入库前完成,不要等检索时才去判断。
第四步是入库前的人工抽检。每次新增大批量文档时,我习惯让临床数据管理员抽看 5% 到 10% 的解析结果,确认关键数字和表格没有被识别错。这个环节省不了,因为 AI 模型生成答案时,引用一个被 OCR 识别错的数字,比不引用更危险。
有一个容易忽略的细节:知识库要保留原始文件和解析后的文本的对应关系。Agent 回答问题时如果引用了一段内容,用户需要能一键打开原始文件的对应页,否则“有引用”只是形式正确,追溯链还是断的。我在数据库里给每个文本块都存了 file_id、page_no、block_id,这个看似不起眼的设计,在临床团队的信任建立上起了很大作用。
2.2 分块策略、向量化与混合检索:不是所有片段都适合直接喂给模型
文本分块是知识库检索效果的分水岭。临床文档的特点是专业术语密集、逻辑链条长、条件限定多。固定按 512 或 1024 个字符硬切,很容易把“排除标准第 3 条”和它的例外条款切到两个块里,检索时要么漏上下文,要么召回一堆重复内容。
我用的分块策略是“结构优先、规则辅助”。先把文档按标题层级拆成章节,再把章节里的每个段落和每个表格单独成块;超长段落再按语义边界切,比如按句号、分号、逗号层级做二次切分。医学文档中“剂量调整规则”“不良事件分级标准”这类内容,往往是一个段落包含多个并列条件,我会额外加规则把它们拆成“条件-动作”成对的子块,这样检索召回时更精准。
分块大小我一般控制在 512 到 1024 个字符之间,重叠区设 80 到 150 个字符。太短会丢上下文,太长会把无关内容混进来。对于定义类内容,比如“什么是严重不良事件”,我会让它独立成块,因为它是高频被复用的事实型知识块。
向量化模型的选择也值得单独说。通用领域的中文 Embedding 模型在医学实体上的语义区分能力往往不够用,特别是“左心室射血分数”和“左房内径”这种看起来结构相似但实际完全不同的医学术语。如果预算和时间允许,建议在一个包含医学词典、药品名、诊断名、检查项目名的语料上对 Embedding 模型做增量训练,即使只训练两三千步,也能明显改善近义混淆。
但向量召回不是万能的。医学检索必须保留字面匹配能力,准确说,BNF。所以我用了混合检索:BM25 关键词召回 + 向量语义召回 + 元数据过滤,再用一个重排序模型对两路结果做融合。比如用户问“入组标准中年龄上限是 65 岁吗”,BM25 能精准命中包含“65岁”的片段,向量召回则能找到语义相关但说法不同的表述,两条路互为兜底,再用重排序模型把最相关的三个块排到最前面。
混合检索的调用逻辑可以抽象成下面这段 Python 骨架。实际项目中我用的是异步调用,但核心思路一致。
def recall_knowledge(query, project_id, user_role, top_k=5): # 1. 元数据过滤:只检索当前项目且有权限的知识库版本 meta_filter = {"project_id": project_id, "roles": user_role, "status": "active"} # 2. BM25 字面召回 bm25_hits = bm25_index.search(query, filter=meta_filter, top_k=top_k * 2) # 3. 向量语义召回 query_vector = embedding_model.encode(query) vector_hits = vector_store.search(query_vector, filter=meta_filter, top_k=top_k * 2) # 4. 合并候选,去重后交给重排序模型 candidates = merge(bm25_hits, vector_hits) reranked = rerank_model.rerank(query, candidates, top_k=top_k) return reranked这个流程跑通了之后,我还加了一步“引用块校验”。重排序出来的 Top K 块里,可能存在互相矛盾的版本。我会在返回给大模型之前,先按知识库的版本优先级过滤掉过期内容。这一步相当于给检索结果前置一道版本关卡,效果非常明显。
2.3 知识权限与版本管理:检索和引用都要带“有效期”
临床研究对权限的敏感度非常高。同一个药物可能在多个试验中使用,不同试验的方案属于不同申办方的知识产权,不能互相串;同一个指南可能有旧版新版,业内要求依据现行有效版本执行。所以知识库的权限必须是多维度的。
我在设计权限体系时用了三个维度:项目维度、角色维度、时间维度。项目维度控制“哪个文档属于哪个试验项目”,角色维度控制“研究者、CRC、数据管理员、监查员分别能看哪些分类”,时间维度控制“某版本从哪天开始生效、哪天废止”。三个维度过滤之后,剩余内容才进入检索候选集。
版本管理上我专门建了一个知识资产表,每条记录包含 doc_id、version、effective_date、retired_date、content_hash。当一个规则有新版本上线时,旧版本并不是删除,而是标记为已废止。这样 Agent 回答时能明确说“该建议基于某指南 2023 年版本,当前已更新至 2025 年版本,请注意核对”。这个细节让临床团队对系统的信任度提升了不少,因为医疗领域最怕的就是引用一个已被替代的旧标准。
权限控制还带来一个工程约束:向量索引要按项目隔离。不要把 A 项目的方案和 B 项目的方案放在同一个索引里靠权限过滤,一旦重排序或者召回逻辑出现漏洞,就有跨项目泄漏风险。我最终是把索引物理拆成项目分片,每个项目一个独立检索端点,权限过滤在更外层统一控制。这属于“宁可多花钱,也不能担风险”的取舍。
3. 数据服务平台:让 Agent 查得准、算得动、可追溯
知识库解决“依据从哪来”,数据服务平台解决“数字怎么拿”。临床研究里任何结论都离不开数字:入组数、筛选失败数、不良事件分级数、检查结果超限数。如果 Agent 把数字算错了,哪怕引用格式再规范,本质上都是不可用的。数据服务平台的核心思路是把数据能力封装成稳定、安全、可审计的 API,让 Agent 只做接口调用,不直接摸原始数据库。
3.1 数据模型与标准化:为什么“字段对齐”比算法更重要
数据服务平台建设的第一个坑不是数据库选型,而是标准不统一。临床研究里的数据源非常多:EDC 里的病例报告表、医院 HIS 里的电子病历、LIS 里的检验数据、随访系统里的量表数据。同一个“患者年龄”,在 HIS 里可能是字符串类型的出生日期,在 EDC 里可能是按入组日期计算的整型,在随访系统里可能根本没有这个字段,只有出生年份。
我建议所有进入数据服务平台的源数据,先做一次标准字段映射,规则如下:统一患者标识(用受试者编号做主键,不做多源 ID 混淆)、统一日期格式、统一单位(比如白细胞计数统一为 10^9/L)、统一术语编码(AE 优先取 MedDRA 编码,诊断优先取 ICD-10,检查项目优先取 LOINC 或院内标准字典)。
如果团队有 CDISC 背景,可以直接把底层表结构向 SDTM 模型靠,把人口学、暴露、不良事件、实验室检查等主题域拆开。即使没做到完整合规,至少建一张标准宽表,把所有常用查询字段拉平。否则 Agent 每次调接口时还要理解十几个源表的口径差异,不现实。
数据服务平台的数据流向,我在架构上分了三层。ODS 层只做增量同步,保持源系统的原始状态;DWD 层做清洗和标准化,统一字段与单位;DWS 层按业务主题预聚合,比如“按中心统计入组进度”“按阶段统计筛选失败原因”。Agent 调用的绝大多数实时查询,尽量落在 DWS 层,少量精确查询落到 DWD 层,避免每次都扫全量增量表。
3.2 数据服务 API 设计:接口稳定,Agent 才稳定
Agent 通过工具调用读取数据,本质上是 Function Calling。因此数据服务的 API 设计必须遵循一个原则:入参和出参都足够确定。如果字段名称今天叫 patient_age、明天改成 age,大模型的函数调用就崩了。接口一旦发布,就要保持向后兼容,所有变更只增不改。
我以“查询受试者人口学信息”为例,给一个完整接口定义。内层数据服务用 FastAPI 实现,对外暴露 POST JSON,Agent 通过 OpenAPI schema 感知这个工具的存在。
{ "name": "get_subject_demographics", "description": "按受试者编号查询人口学信息,用于入组清单核对与筛选分析", "parameters": { "type": "object", "properties": { "subject_id": {"type": "string", "description": "受试者编号,格式如SUBJ-001"}, "project_id": {"type": "string", "description": "项目编号,必填"} }, "required": ["subject_id", "project_id"] } }对应的返回结构保持严格 schema:
{ "subject_id": "SUBJ-001", "birth_year": 1989, "gender": "female", "enrollment_date": "2025-01-15", "center_id": "C002", "data_source": "edc", "updated_at": "2025-06-20T10:30:00Z" }这里有一个小经验:接口返回字段里一定要带 data_source 和 updated_at。Agent 在生成答案时如果用户追问“这个数据是从哪拿的”,它可以追溯到源系统。我在实际项目中还加了一列 data_quality_flag,用来标识该记录是否完整、是否经过人工核查。如果这个字段是 pending,Agent 在回答中会主动提示“该数据尚未完成源数据核查,请谨慎引用”。
数据服务接口还需要做三类辅助接口:列表型接口,比如“查某个中心所有受试者的筛选状态”,返回需要支持分页,Max 限制 200 条;统计型接口,比如“按阶段分组统计入组人数”,结果必须带总计和分组明细;检查型接口,比如“查询某个受试者的逻辑核查问题”,支持按问题编码过滤。
整体来讲,接口设计越“窄”越好,一个小工具解决一个小问题,不要设计一个大而全的“万能查询接口”。大模型在拿到一个接口描述时,如果入参有十几个可选项,它会频繁猜错参数;如果接口描述足够简单,调用成功率会显著上升。
3.3 脱敏、审计与链路追踪:医学数据的“安全边际”不能省
数据服务平台绕不开脱敏和审计。临床上对隐私保护的要求极高,受试者的姓名、身份证号、详细住址、联系方式这类直接标识信息,原则上不应该直接出现在 Agent 的检索链路里。我建议在 ODS 层同步数据时只保留受试者编号和中心编号,不在数据服务 API 中暴露任何人员身份字段。如果某类查询确实需要原始联系方式,比如随访催访,那应该走专门的人工案件系统,而不是走 Agent 工具。
动态脱敏也很重要。同一个受试者的数据,研究者看全部检查结果,CRC 看方案相关的访视结果,数据管理员看数据完整性相关字段。我给每个角色定义了不同的字段可见范围,在服务层统一做字段级过滤。Agent 只是拿到过滤后的视图,它自己并不知道哪些字段被滤掉了,这是最简单的安全边界。
审计追踪分两层。第一层记录“谁调用过什么数据服务工具,传了什么参数,返回了什么结果摘要”;第二层记录“Agent 的推理链路如何选择了某个接口”。这两层日志直接落库,保留至少三年。我在日志里还额外记了 prompt 的 hash,这样如果将来排查“为什么某个回答有偏差”,可以重建当时的上下文。
链路追踪是工程上最容易忽略但最值得做的。我建议用 trace_id 贯穿:用户提问时生成一个 trace_id,Agent 调用知识库接口时带上它,调用数据服务时也带上它,最终回答记录里也放它。临床团队要复盘时,只要把 trace_id 交给工程师,就能把整条链路拉出来看。没有链路追踪,后面所有问题排查都会变成猜谜。
4. Agent 编排:把知识库和数据服务串成可用的工作流
知识库和数据服务都是“底座”,真正让用户感知到价值的,是 Agent 编排层。这一层需要解决四个问题:意图如何识别、工具如何调用、上下文如何压缩、回答如何评估。它本质上是一个“带工具的对话系统”,但要结合临床研究场景做非常多的定制。
4.1 工具调用与路由设计:不要让一个 Agent 干所有事
我在架构上做了一个“总调度 Agent + 专业子 Agent”的分层。总调度 Agent 负责接收用户问题,判断这个问题是要查文档、查数据、还是两者都要,然后分发给对应的专业子 Agent。专业子 Agent 各自持有不同的文档权限、数据工具和 Prompt 前缀。
举例:用户问“某中心的筛选失败率是多少,请结合该中心近三个月的监查报告说明”,总调度会拆成两个子任务——数据服务查筛选失败率(调用统计接口),知识库查监查报告(先检索后摘要)。两个子任务的输出回到总调度,它负责拼接成一段有引用、有数字的完整回答。
路由设计上最忌讳的是把十几个工具一次性全给总调度 Agent。工具越多,模型在选择时越容易混淆,尤其是工具名相近的时候。我的方案是把工具按场景分组:入组与筛选工具组、不良事件工具组、检查结果工具组、文档检索工具组。每个子 Agent 只看到自己场景内的工具,总调度只看到子 Agent 清单。这样每一层的决策空间都变小,准确率就提上来。
工具不用频繁更新。临床研究业务虽然复杂,但查询类型其实很固定,把常见查询固化成十几个接口,比让 Agent 自由生成 SQL 安全得多。我坚决避免让大模型直接写 SQL 访问生产库,因为 SQL 生成的错误可能涉及隐私风险,你压不住。
4.2 Prompt 与上下文压缩:信息太多会稀释答案
临床场景的问题往往需要综合多个片段才能回答,很多人会把检索到的五个块、每个块 800 字全部塞进 Prompt,结果模型被大量重复信息干扰,反而答错。我建议先压缩,再生成。
具体做法是:检索召回 Top 10 个块,先用一个轻量模型做相关性和关键信息提取,输出“该块是否相关、涉及哪个主题、核心结论是什么”,再取压缩后的关键句拼装成模型上下文。这样总 token 数能下降一半以上,模型生成时也更聚焦。
Prompt 里我会固定要求回答遵循以下顺序:先给结论,再给依据,最后给数字和引用。例如“根据 XX 项目方案 2.3 节,入组标准年龄为 18 至 65 岁;根据数据服务返回结果,当前筛选 120 例,合格 89 例,筛选失败率 25.8%,其中因不符合入排标准导致的失败占比 62%”。这种结构化的输出让用户一眼能看到答案,也方便复核。
模型温度设置非常重要。医学场景我统一设为 0.1 到 0.2,偶尔在生成总结性文字时调到 0.3,但事实性回答永远低温度。不要试图让模型“发挥创造性”,临床研究不要创造性,要准确性和可复现性。
上下文压缩还需要一个“未知即未知”的兜底策略。当知识库检索不到任何相关块,或数据服务返回空结果时,Prompt 中明确告诉模型:不要编造,回答“当前知识库中没有找到相关信息,请通过人工途径核实”。这是对抗幻觉的最后一道防线,比任何提示词技巧都有效。
4.3 评估与调优:医学问答必须看“可复核率”
Agent 上线之前,必须先建一个评测集。我一般准备 50 到 80 个真实临床问题,覆盖四类:事实检索题(依据在知识库里能直接找到)、数据计算题(需要调用数据服务计算)、综合分析题(需要同时融合文档与数据)、无答案题(超出知识范围或当前数据不存在)。
每道题的打分维度不用太复杂,我主要看三个:答案正确性、引用可复核性、数字一致性。所谓引用可复核性,就是明确要求用户能把答案点回原始段落或接口返回,能复核的内容永远优先于“听起来合理”的内容。数字一致性则要求大模型回答中的数字必须和数据服务返回值一致,不允许推理变形。
调优第一刀切在检索参数上。如果测出来的答案偏题或引用混乱,先检查知识库 recall 和 rerank 的 Top K 是否合适,再检查 embedding 模型对该类问题的语义距离;第二刀切在工具描述上,如果 Agent 频繁调用错误接口,改写工具 description 比改模型参数效果更好;第三刀才切 Prompt。这个顺序每次都很管用。
线上我还会跑一个轻量反馈通道,用户在每个回答下面点“有帮助/没帮助”,并可选填原因。每周汇总一次低分案例,挑出高频失败场景补进评测集,再迭代一轮模型和知识库。这个闭环比任何一次“大调优”都靠谱,因为所有迭代都有业务数据支撑。
5. 落地实录:从需求到上线的六步走与实际问题速查
写到这里,读者应该已经掌握了这个平台的核心组件。但这套系统真正落地还有组织层面的问题:团队怎么配、时间怎么排、上线前最怕踩什么坑。这一节根据我实际参与项目的经验和现场记录整理,尽量给出一份可以“抄作业”的执行参考。
5.1 从需求到试用,团队应当按六个阶段推进
第一个阶段叫需求确认,4 到 6 周。目标是界定“第一批 Agent 服务哪些用户、处理哪些任务、成功标准是什么”。我习惯让临床运营、数据管理、医学事务各指定一名业务接口人,三个接口人加上两名技术骨干,组一个联合小组。每周开两次短会,把高优先级场景清单和验收口径定下来。
第二个阶段是数据资产盘点,2 到 3 周。知识库方面要盘点有哪些电子版 SOP、指南、方案可以授权进入系统;数据服务方面要理清源系统清单、字段标准和接口可行性。这一步的输出是《数据资产清单》和《知识库授权清单》,后续所有权限配置都在这个基础上做。
第三个阶段是场景 POC,3 到 4 周。选两个场景跑通全链路,比如“方案问答”和“入组统计查询”。POC 的目标不是做得多漂亮,而是验证“知识库检索 + 数据服务调用 + Agent 编排”这条链路在真实数据上是否成立。如果这个阶段底层链路不稳,后面直接停一停,先把底修好再继续。
第四个阶段是正式开发,8 到 12 周。知识库解析管线、数据服务接口、Agent 编排与评测集建设并行推进。这个阶段最容易出现“文档还没洗完、接口还在改、模型调参没有基准”的混乱。我的对策是每两周做一次全链路联调,不管功能完整不完整,至少让每个模块之间能跑通,问题提前暴露。
第五个阶段是用户验收测试,4 到 6 周。找真实业务用户试用,记录试用反馈和失败案例。这个阶段不要着急增加新功能,集中修评测中发现的准确性问题、权限问题和体验问题。
第六个阶段是试运行与运营迭代,持续进行。知识库按月更新,数据服务按需新增接口,评测集随用户反馈不断扩充。项目到这个时候才算真正“活”了。
时间上,从需求确认到试运行,一个中等规模的临床研究项目通常需要 6 到 9 个月。人力我建议最低配置:临床数据管理员 1 名、算法工程师 1 名、后端工程 1 名、产品/项目协调 1 名。人再多也不建议压周期,因为这个项目的瓶颈不在写代码,而在数据准备和跨部门沟通。
5.2 常见问题与排查技巧速查
我把项目推进中真正遇到的高频问题整理成一个速查表,第一列的“问题现象”,第二列是“排查思路”,第三列写的是我实际验证过的处理建议。
| 问题现象 | 排查思路 | 处理建议 |
|---|---|---|
| 文档检索返回不相关内容 | 检查解析管线是否丢失标题层级,向量化模型是否混淆医学实体 | 先看原始文档解析质量,再考虑换 Embedding 或做增量训练 |
| 大模型引用了一个不存在的数字 | 数据服务返回值与答案不一致,或上下文压缩时截断关键条件 | 强制数字由数据服务返回字段直接拼接,不让模型自行推理 |
| Agent 调用数据工具时参数频繁错误 | 工具描述不够清晰,参数命名不符合模型习惯 | 改写 description,给每个参数加示例值,避免多个相似字段名 |
| 同一问题两次回答不一致 | 模型温度过高,或检索结果浮动大 | 将温度降至 0.1 到 0.2,固定检索 Top K,增加确定性输出策略 |
| 权限设置失效,某些角色看到了不该看的内容 | 检查权限过滤是作用于索引还是作用于结果 | 权限必须在检索前过滤,建议按项目分索引,再做角色字段级过滤 |
| 知识库版本更新后,回答仍引用旧版 | 旧版本块未被标记为废止 | 版本管理表补齐 retired_date,检索前按 effective_date 过滤 |
| 数据服务接口响应慢,Agent 超时 | 查询走了全量扫描,或统计接口没做预聚合 | 常用统计尽量命中 DWS 层预聚合表,接口层加查询缓存 |
| 用户反馈回答“看起来对,但没法用” | 生成结果缺少可复核引用 | 增加块级引用和 trace_id,确保每个结论能回溯到源文件和源接口 |
5.3 几条值得长期坚持的实践原则
第一,宁可“笨”一点,也要可追溯。临床试验场景下,一个能指出依据的错误答案比一个说不出依据的“好看答案”更危险。所有 Agent 输出的关键结论必须带引用或数据源标识。如果有些问题无法做到这一点,不要输出,直接转人工。
第二,把知识库当数据库一样管。给文档做版本控制、权限控制、质量抽检,应用一套完整的数据治理机制,而不是当一堆文件丢进去就跑 Embedding。知识库的可信度决定系统的天花板。在这个项目里,知识库质量一旦失控,后面补每一个坑,成本都远高于事前投入。
第三,Agent 的能力边界要公开告诉用户。系统在最显眼的位置标注“本系统回答仅供临床研究过程参考,不构成医学或法规结论”,并建议关键决策由人工复核。这不是甩锅,而是让用户养成“AI 辅助、人工复核”的流程习惯,这个习惯对整个行业都很重要。
第四,业务参与越早越好。评测集建设不能只靠技术人员,一定让医学和数据管理的同事参与命题与打分。用户觉得“好用”的标准,和工程师理解的“准确”之间经常有偏差,只有直接听取他们的反馈,系统才会越来越贴近真实工作流。
项目复盘与一点个人体会
我最初做这个系统时,团队里一位资深的临床数据管理老师说过一句话,到现在我都觉得是这个项目最好的注脚:“在临床研究里,最贵的东西不是模型,是可信度。”工程量可以堆,模型可以换,但一旦数据和知识变得不可信,你就会失去用户的每一次尝试。
根据我这几轮项目的个人体会,最大的风险往往在开头。需求确认阶段如果没有把“知识库边界”和“数据服务口径”谈清楚,后面所有开发都在打补丁。我记得第一次 POC 时,业务方随口问了一个看似简单的问题:“这个项目的入组进度是看随机化人数还是知情同意人数?”就是这种口径问题,让我们改了三次接口逻辑。所以如果你准备复刻这套平台,请把前四周的调研时间真正用好,把“数字口径”“版本依据”“角色权限”问到底。
最后分享一个小技巧,是我们在后期总结出来并且坚持至今的:给知识库里的每个文档和数据源流水号,所有 Agent 的回答在生成时强制带上这两个编号。比如回答“根据 Doc-2025-023 和 DataSvc-003 统计接口,结论如下”。这个习惯在临床团队复盘时帮了很大的忙,你想象一下,几十个 Agent 对话中,你能用流水号把每一个判断的来龙去脉拉出来,这种确定感会给整个系统带来质的变化。临床研究这个行业,从来不缺数据,缺的是把数据变成可信结论的能力。这套平台给我的启发是:AI Agent 可以把知识库和数据服务当作自己最大的靠山,但这座山能不能立得住,取决于背后每一份文档、每一个字段、每一次引用是否经得起推敲。