☰
制药质量岗转大模型:批记录表格为什么抽不准
2026/10/28 19:12:08 网站建设 项目流程

版权与内容来源声明
本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容,均在附表 A 中标注来源;引用官方原文保持原样,不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准,标注「待验证」的部分请以你本地环境实际输出为判断依据。本文不推荐任何不合规的软件获取方式,也不推荐任何规避地区限制的访问方式,亦不对任何收益结果作承诺。转载请注明出处。

一、QA 桌上那摞纸:六类文件,为什么偏偏批记录抽不准

在制药企业做质量保证,签字是要负责的动作。一批产品从配料到入库,我手上过的纸大致六类:批生产记录、批检验记录、偏差报告、变更控制、放行审核记录,以及托着它们的那套 GMP 文件体系——工艺规程、质量标准、SOP、验证方案。

想把这些活交一部分给大模型,念头很朴素:翻记录、对参数、做大趋势,都是体力活。真动手时撞上的第一个坎,不是模型不够聪明,是我把「一张表」当成「一段文字」扔了进去。

六类文件喂给同一个模型,表现差别很大。

文件类型结构特点抽的时候卡在哪抽错的后果
偏差报告叙述体,一段一段写时间线、根因、CAPA 混在一段里根因归错类,同类偏差反复发生
变更控制表单加影响评估段落评估结论是自然语言,边界模糊影响范围漏项
批检验记录一张主表加多张图谱附件检验项、标准、结果、结论同行结论与数据对不上
批生产记录多表关联、跨页续表、合并单元格见第二到第五章参数归属错、行缺失
放行审核逐项勾选的核对单勾选项要与批记录跨文件对齐该拦的没拦住
GMP 文件体系层级目录加版本版本与生效日期一对多引用了作废版本

偏差报告那种散文,模型反而处理得好:时间、地点、现象、原因,本来就写在句子里。批记录正相反,它是最像「数据」的一份,也是最容易抽错的一份。

原因只有一句:越像表格的东西,越不能直接当文本喂。

二、模型看到的不是表格,是一串 token

2.1 合并单元格不是一个值,是一段区域

在 xlsx 里,合并单元格由 mergeCells 记录:一个区域,加一个左上角的值,其余格子是空的。人眼看过去,是「制粒」管着六行;模型读到的 csv 是——第一行有「制粒」,后面五行是逗号。

  • 行列关系,扁平化之后只剩分隔符;
  • 层级关系(哪个值管着哪几行),扁平化之后完全消失;
  • 跨页关系(这一页接着上一页),连分隔符都没有。

模型拿到一串 token,要还原的是一张有层级的表。这一步它在猜,而猜是不报错的。

2.2 三个必然失真点

失真点纸面或 Excel 里长什么样扁平化后模型看到什么下游后果
合并单元格父级丢失工序列「制粒」跨六行只有第一行有值,其余为空干燥参数被挂到制粒机名下
跨页续表被当新表第三页重复表头,批号只在首页两段互不相干的表行数少一截,一个批次被拆成两个
同名列重名「实际值」「结论」各出现多次一张宽表里三个同名列取到包装数量当投料量

三个点里,最危险的不是抽不到,是抽错还抽得很像。模型不会提示「这里父级缺了」,它会顺着上文补一个最顺的值。这种错,只看输出看不出来。

三、失真点一:合并单元格的父级只在首行出现

3.1 一张真实记录在纸面上长什么样

制粒工序那张记录,人眼看到的是三层:

  • 工序列「制粒」,合并六行;
  • 设备列前三行「制粒机」,后三行「沸腾干燥机」;
  • 项目列六行各不相同:搅拌转速、制粒时间、粘合剂用量、进风温度、干燥时间、水分。

转成 csv 之后:第一行是「制粒,制粒机,搅拌转速,……」,第二、三行工序与设备两列为空,第四行只有设备有值,第五、六行两列全空。

3.2 那三个空格,模型有四种处理方式

  1. 当「同上」——多数时候对,但在工序切换那一行会沿错;
  2. 当「未填」——直接判这份记录不完整,把有效行丢掉;
  3. 按项目名反推——「干燥时间」推成干燥工序,「进风温度」推成总混,推得有理,但没有根据;
  4. 按训练里见过的批记录格式补——最像人,也最不可控。

第三种和第四种最难发现,因为输出读起来很顺。第四种尤其麻烦:它会给你一个格式完全正确、内容凭空捏造的归属。

3.3 归属错一次,后面全歪

一个具体的连锁:如果「进风温度 62℃」被归到「制粒机」,年度产品质量回顾里按设备统计参数分布,沸腾干燥机就少一组、制粒机多一组。下一次同品种出现水分超标偏差,调查会先去看制粒机——方向从一开始就偏了。

这不是模型的问题。喂进去的东西里,本来就没有「这台设备管这几行」这条信息。

3.4 填之前先分清列的角色

向下填充不是「空格都填上」。填错列,等于造数据。我现在的分法是这样:

列的角色判断依据处理方式不这么做的后果
层级父级(工序、设备、房间、班次)值跨多行重复,且是下一级的容器向下填充,并标记继承来源归属串行
叶节点值(项目、标准、实际值、单位)每行独立,重复才是异常不填,空就报缺失造出假数据
汇总行(小计、合计、平均)行首含小计或合计,或整行加粗单独摘出,不进明细汇总被当成一条记录参与统计
签字列(操作人、复核人、日期)通常只在段末出现一次按段落归属,不逐行填把复核人算成操作人
备注列自由文本,常有「同上」「见附页」保留原文,不做语义改写改写后失去原始表述

最后一条要守住:记录里的「同上」是有意义的表述,转成具体值就不再是原文。放行审核看的是原始记录,不是我们整理后的版本。

四、失真点二:跨页续表被当成第二张表

4.1 纸面证据只有三处

批记录按页打印、逐页签字。第三页顶上重复一遍表头,页脚印着「第 3 页 共 5 页」,批号只在首页右上角写一次。除此之外,第三页和一张新表没有任何区别。

按页抽,最常见的两种错:

  • 每页各抽一张表,最后拼起来——表头重复出现,行数看着不少,但每张表都缺上下文;
  • 只抽首页——后面几页整段消失。行数少一截比抽错更麻烦,因为没人会发现。

4.2 续表的第一行,父级在上一页

这是跨页最坑的地方:第三页第一行是「总混」工序的第二条参数,工序与设备两列都是空的。它的父级不在本页。单独看这一页,怎么填都填不出来。

所以顺序只有一个:先并表,再向下填充。反过来做,这一行的父级永久丢失。第六章的脚本按这个顺序写。

4.3 什么时候不能合并

反过来也有坑:同一批里真有两张同结构的表。两台压片机各一张记录,表头一模一样。这时合并,会把两台设备的参数混成一条线。

信号指向续表指向新表说明
表头指纹(列名与顺序)完全一致完全一致只能排除,不能确认
页码连续,如 3/5 接 4/5从 1 重新开始最强信号
上一页末行明细行,无合计合计行加签字次强信号
批号出现位置只在首页每页都印每页都印通常是独立表
表标题含「续表」,或页眉带品名完整标题有则加分,无则不扣
行号跨页连续从 1 重新开始与页码互相印证

我的做法是:页码连续、且上一页末行是明细行,两条同时成立才自动合并,其余一律进人工待核。宁可多一批待核,不要少一批行——待核有人看,丢的行没人看。

五、失真点三:同一张记录里,「结论」出现了三次

5.1 重名不是巧合,是行业习惯

一张批生产记录里,「实际值」至少出现三次:工艺参数的实际值、称量的实际数量、包装的实际数量。「结论」也出现三次:工序结论、中间产品结论、成品结论。批检验记录里还有一个「结论」。

抽成宽表时,同名列表头会被自动改名加后缀,或者被后一个直接覆盖。覆盖的那种最要命:投料 480 kg,包装数量 12000 片,两个值都进了「实际值」,覆盖之后物料平衡按 12000 除以 480 算,出来 25 倍。

数字荒谬,但如果校验只判「是否为空」,它不会报任何问题,一路进到汇总表。

5.2 消歧靠路径,不靠模型猜

做法很土:给每个字段加路径前缀。前缀来自表头层级——哪张表、哪一段、哪一列。

原列名出现位置消歧后的字段名单位校验规则
实际值制粒与干燥参数段process.granulation.actual按项目定落在标准上下限内
实际值称量段dispense.actual_qtykg与投料总量勾稽
实际值包装段pack.actual_qty片与理论产量勾稽
结论工序段process.conclusion无枚举,符合或不符合
结论成品段product.conclusion无与检验结论一致
判定批检验记录qc.judgement无映射到同一枚举

最后一行是另一个坑:中文同义不同名。「结论」「判定」「符合性」,很多厂里混着用,跨表对齐时对不上。这个不能靠模型现场猜,得先建一份字段别名字典,把同义词收敛到一个枚举值上。字典是死的,猜是活的,活的那个每次都不一样。

这份资料是什么:一张把批记录常见列名按「原列名 / 出现位置 / 路径前缀 / 校验规则」对齐的字段对照空白表,和本章的消歧做法配套。放在资料包里,扫码即可获取:

六、把结构写回去:先并表,再向下填充

6.1 三个动作,顺序不能换

  1. 并表:按表头指纹加页码连续性,把续表接回主表;
  2. 填充:对层级列向下填充,并给继承值打标记;
  3. 消歧:列名加路径前缀,也就是第五章那张表。

脚本只做前两步,二十八行,纯标准库。输入是两页导出的 csv,列结构与第三章那张记录一致。

importcsvimportsysdefread_page(path):withopen(path,newline="",encoding="utf-8-sig")asf:return[rforrincsv.reader(f)ifany(c.strip()forcinr)]defstitch(pages):out,seen=[],set()forpageinpages:head=tuple(x.strip()forxinpage[0])ifheadinseen:out.extend(page[1:])continueseen.add(head)out.append(page[0])out.extend(page[1:])returnoutdeffill_down(rows,cols):carry={c:""forcincols}out=[rows[0]]forrinrows[1:]:r=list(r)forcincols:ifr[c].strip():carry[c]=r[c].strip()continuer[c]=carry[c]+"*"out.append(r)returnoutif__name__=="__main__":rows=fill_down(stitch([read_page(p)forpinsys.argv[1:]]),[0,1])print("并表后数据行 %d"%(len(rows)-1))forrinrows:print(" | ".join(xifxelse"_"forxinr))

跑法一行,页数不限,按页序传进去:

python 批记录还原.py p1.csv p3.csv

本机输出,未做任何修饰,星号是我加的继承标记:

并表后数据行 11 工序 | 设备 | 项目 | 标准 | 实际值 | 结论 制粒 | 制粒机 | 搅拌转速 | 300±20 rpm | 312 | 符合 制粒* | 制粒机* | 制粒时间 | 10±1 min | 10 | 符合 制粒* | 制粒机* | 粘合剂用量 | 4.0 kg | 4.0 | 符合 制粒* | 沸腾干燥机 | 进风温度 | 60±5 ℃ | 62 | 符合 制粒* | 沸腾干燥机* | 干燥时间 | 30±5 min | 28 | 符合 制粒* | 沸腾干燥机* | 水分 | ≤3.0 % | 2.4 | 符合 总混 | 三维混合机 | 转速 | 12 rpm | 12 | 符合 总混* | 三维混合机* | 混合时间 | 15±2 min | 15 | 符合 压片 | 压片机 | 片重 | 0.250±0.010 g | 0.253 | 符合 压片* | 压片机* | 硬度 | 60±20 N | 72 | 符合 压片* | 压片机* | 崩解时限 | ≤15 min | 9 | 符合

6.2 输出里有两处值得看

第一处是第八行:「总混* | 三维混合机* | 混合时间」。这一行在原文件里是第三页的第一行,父级两列都是空的,靠上一页末尾的「总混」和「三维混合机」接上。如果没有先并表,这一行填出来就是空的。

第二处是行数:7 加 4 等 11。按页分别抽,两张表加起来也是 11 行,行数对得上,但表头多一份,第三页首行没有父级。行数对得上,不代表结构对,这是我在第一批样本上吃过的亏。

星号的用处正在这里:后面做校验时,「记录里真写了」和「我们补上去的」必须能分开。补上去的值一旦出错,追责要能追到脚本,而不是记到记录上。

6.3 这一段不解决第三个失真点

重名要在表头解析阶段解决,也就是拿到列名的那一刻就加前缀。等数据都成行了再改名,路径信息就丢了。

七、抽完不算完:三道交叉校验兜住安静的错误

7.1 抽取准确不等于记录自洽

模型的活是把字认对,QA 的活是判断这份记录自己跟自己对不对。抽得再准,如果参数归属错了、行少了,记录还是不能用。

三道校验,全是规则,不依赖模型。

校验规则失败时怎么做兜住哪个失真点
批号一致每行批号等于封面批号,继承来的标 inherited该行进待核清单,不静默修正跨页拆分
工序顺序抽出序列是工艺规程序列的子序列,且不逆序报缺失工序与逆序位置行缺失、并表错
数量勾稽投料总量到理论产量到实际产量,相对偏差按工艺规程限度超出即拦,不进汇总同名列取值错
签字完整操作人、复核人、日期三段齐全,日期不倒序标记缺签段落段落归属错

第三条最有效。参数归属错了,数量往往还对;但取值张冠李戴,勾稽一定崩。一个数从 kg 变成片,量级差几十倍,规则一眼就能看出来。

7.2 阈值不要抄别人的

物料平衡的偏差限度写在各家的工艺规程里,品种之间不一样。我一开始照搬了一个通用阈值,结果颗粒剂那几批全被拦下来,白折腾两天。阈值从自己的工艺规程里取,脚本里做成配置项。

7.3 转行的人,优势在这一节

写提示词谁都能学,这三道校验的规则学不来。它要求你知道哪一列必须对、两个数之间为什么必须相等、签字缺一个意味着什么。这些是从偏差调查和放行审核里长出来的,不是从教程里。

同样做批记录抽取,纯算法背景的人容易把字段准确率当终点;质量岗出身的人会追问:剩下的部分错在哪些列,这些列错了,这批产品还能不能放。前一个问题模型能答,后一个问题只有懂放行的人能答。

7.4 落地顺序

  • 先拿二十批做回归样本,人工逐行判一遍,错的按「归属错、缺行、取值错」三类归档;
  • 三类错对应三个修法:归属错改填充规则,缺行改并表判据,取值错改列名路径;
  • 修完再跑同一批样本,看三类错是否各自下降,别只看一个总数;
  • 稳定之后再谈接进放行流程,接之前把待核清单的人工环节留住。

这份资料是什么:一张把「批号一致、工序顺序、数量勾稽、签字完整」四项写成可填规则的三道校验清单,改一改就能贴到自己厂的批记录上。放在资料包里,扫码即可获取:

附表 A:本文引用事实与出处对照表

事实出处核验方式本文位置
批记录由多张表互相关联,同表跨页延续,层级用合并单元格表达制药企业批记录的实际格式,本文归纳本人经手的批生产记录、批检验记录样本一、二
《药品生产质量管理规范(2010年修订)》文件名,以及「第八章 文件管理」章名该规范正文文件公开发布,章名可查;具体条号未逐条核对,故全文不引条号一、七
xlsx 中合并单元格由一个区域加左上角值记录OOXML 表格结构,mergeCells 元素结构定义,与具体软件版本无关二、三
三个失真点的分类与后果本文归纳基于本人经手的记录样本,非统计结论二至五
并表后 11 行、星号标记的继承值本机实测,脚本见 work 目录下的批记录还原脚本,Python 3.13.14,输入两页 csv本机运行,输出原样引用,未改数六
表头指纹、页码、上一页末行三条续表判据本文归纳现场样本试用,非行业标准四
字段路径前缀命名与别名字典本文做法自定规范,可替换五
批号一致、工序顺序、数量勾稽、签字完整四项校验本文归纳,源自放行审核与偏差调查流程规则自定,阈值取自工艺规程七
模型对空白父级的四种处理方式本文观察试用记录,非对照实验三
具体条号、保存年限、物料平衡限度数值未采用未核到可引用的现行原文,故不写全文

附表 B:术语速查表

术语含义出现位置
批生产记录一批产品从配料到包装的全过程操作记录,随批流转全文
批检验记录该批样品的检验项目、数据、图谱与结论的原始记录一、五
偏差报告记录实际执行与规定不符的事件、原因与纠正措施的文档一、七
变更控制对工艺、设备、文件等变更做评估、批准、跟踪的流程一
放行审核出厂前对批记录、检验结果、偏差关闭情况的逐项核查一、七
GMP 文件体系工艺规程、质量标准、SOP、验证文件构成的层级文件集一
合并单元格电子表格中把一块区域并成一个格,只有左上角保存值二、三
续表一张表跨页后在新页重复表头继续书写的部分四
扁平化把带层级和版式的表格压成一行一行的纯文本或 csv二
向下填充把层级列的首行值填到其下属空行,并标记来源三、六
表头指纹列名及其顺序构成的字符串元组,用来判断两页是否同表四、六
物料平衡投入量与产出量之间的数量关系核算五、七
待核清单规则判不准、交人工确认的记录行集合四、七

写在最后:这篇用到的资料

写这篇文章时,把相关的官方文档和源码又翻了一遍,顺手也整理了几份配套的东西:

  • 大模型学习路线图:从零基础到能自己动手做 Agent,按阶段说明每一步该学什么、哪些可以先跳过
  • 《LangChain + LangGraph + MCP 智能体开发实战》视频课:7 个模块,从私有化部署、Embedding+RAG 到 MCP+Agent 全流程
  • AI 大模型知识库(在线可查):Agent Skills 从入门到落地、Claude Skills 完全指南等专题,按目录浏览即可
  • 640 套 AI 大模型行业报告 + 经典 PDF 书籍:看行业落地案例和别人怎么做的时候用得上
  • 大模型零基础到精通教学视频:跟着敲一遍,比只读文档快得多

资料是我自己整理的,放在下面这个码上,扫码即可获取:






如果这篇对你有用,评论区说说你卡在哪一步,我按留言再补后续的拆解。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询