资讯详情 护士转大模型:给药频次缩写被读成普通文本
📅 2026/10/28 10:18:18
版权与内容来源声明本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容均在附表 A 中标注来源引用官方原文保持原样不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准标注「待验证」的部分请以你本地环境实际输出为判断依据。本文不推荐任何不合规的软件获取方式也不对任何收益结果作承诺。转载请注明出处。一、一份脱敏的给药清单模型排出了八次1.1 原文长什么样一位在内科病房做了六年的护士下称小周想把交接班用的给药清单整理成一张按时间排的表。她把清单脱敏后粘进对话框只说了一句「按时间帮我排一下」。清单是这样的药名与剂量都已去掉只留频次和给药途径⚠️代码待验证[01] 某注射用抗菌药 q8h 静滴 [02] 某口服片剂 tid 口服 [03] 某缓释片 qd 口服 [04] 某止痛药 prn 口服 [05] 某抗过敏药 st 静推 [06] 某胃黏膜保护剂 ac 口服 tid1.2 模型给出的时间表回复很整齐整齐到小周第一眼觉得「挺好用」q8h被排成 00:00、03:00、06:00……21:00一共 8 行。tid被并进同一类理由写得像那么回事「每日三次与上一条同频」。prn被排成 08:00、16:00、22:00 三个固定钟点。st被标成「status状态待确认」。「ac 口服 tid」里的 ac 直接消失了只剩 tid。五处偏差错在同一个地方模型把这六个缩写当成普通英文 token而不是一套有固定折算规则的行业符号。它没有查表这一步只有语言模型的语感而语感在这类符号上没有用武之地。这份表读起来完全通顺时间点也对齐了。人判断「好不好」时下意识看的就是顺不顺而字段级的错恰恰不破坏通顺。所以判据不能是「像不像护士写的」只能换成能机检的东西——下面把它落到两个数字上。二、为什么这套缩写天然容易被读成普通文本2.1 q8h 里的 8是间隔不是次数给药频次开头的 q 来自拉丁语 quaque每。q8h读作「每 8 小时一次」8 是间隔小时数24 除以 8 得 3一天三次。模型见到「q 数字」最省力的解释是把数字当数量一天 8 次。这个错法在纸笔时代就有。ISMP美国安全用药实践研究所的易错缩写清单里记过一条同类案例q6PM每晚 6 点被读成「每 6 小时」——同一个「q 加数字」的形状被套进了「间隔」的模板。区别只在人知道后面跟的是钟点还是小时数。2.2 bid / tid / qid 的字母没有语义锚点bid是 bis in dietid是 ter in dieqid是 quater in die后半截都是 in die每日区别只在 bis / ter / quater。这三层词源模型手里没有它看到的是三个只差一两个字母的 token很容易并成一类。更麻烦的是tid与q8h一日都是 3 次看上去完全等价。差别在间隔的性质——tid 跟着三餐走早中晚之间隔四五个小时晚餐到次日早餐隔十几个小时q8h 是等间隔每 8 小时一次铺满 24 小时。次数相同、约束不同这是整套符号里最容易被合并的一条。qid与q6h是同一类陷阱都是 4 次一个随三餐加睡前、间隔不均一个严格每 6 小时。2.3 prn 是条件不是时间prn是 pro re nata必要时。它描述的是「什么情况下可以用」不是「几点必须给」。一旦被当成时间型模型就会凭空生成一份固定计划。对一条本不该有固定计划的医嘱这比漏抽更麻烦漏抽会在核对时被发现凭空生成的东西看起来像原始数据。acante cibum饭前和pcpost cibum饭后属于同一类它们是相对时点必须挂在某个主频次上才成立。单独一个 ac不构成一条可排期的记录。2.4 st 是一次性事件不是「持续」st是 statim立即指立刻执行一次。模型常把它展开成每日一次甚至每日三次多出来的那几次原文里根本不存在。这条错得隐蔽因为它输出的是「更完整」的计划而不是明显矛盾的计划。把这四类错法收在一起就得到一张可以对着查的表读错类型模型常见表现校验办法数字当次数q8h 被排成一天 8 次等间隔型必须满足「次数 24 ÷ 间隔小时数」相邻缩写合并tid 与 q8h 被视为同一件事间隔性质不同则禁止合并字段里必须分开记条件当时间prn 被排进三个固定钟点prn 的一日次数必须为 0且计划字段必须为空一次性当持续st 被展开成每日一次或三次st 的次数必须为 1且不得带重复计划相对时点被吞「ac 口服 tid」只剩 tidac / pc 缺失要进缺失清单不能静默丢弃写法不归一QD、q.d.、qd 被当成三种不同频次去点、转小写、查表三步归一后再比对词源丢失bid 被当成无意义字符串或英文单词只认白名单枚举查不到直接转人工这张表的用处不在于「知道模型会错」而在于每一条都能写成断言。写成断言之后错的样本会自己跳出来。三、判据把每条医嘱折成两个数字3.1 折算表判据的全部内容就是这张表。左边是原文右边是两个数字加一个性质。表里没有「大概」「通常」因为一旦允许模糊校验就没法写。缩写原文含义24 小时内次数最小间隔小时间隔性质qd每日一次124等间隔固定钟点bid每日两次212等间隔tid每日三次3无必须留空随三餐间隔不均qid每日四次4无必须留空常按三餐加睡前间隔不均q6h每 6 小时一次46等间隔q8h每 8 小时一次38等间隔q12h每 12 小时一次212等间隔st立即一次1无一次性事件不重复prn必要时用0无条件触发不排固定计划ac饭前依附主频次无相对时点pc饭后依附主频次无相对时点看这张表要盯住两处。第一处是 tid 与 q8h 同一行数字不同、最小间隔一栏一个为空一个有值——这就是判据的落点不是次数是间隔性质。第二处是 prn 的次数写 00 不是「没有」是「不排进固定计划」这两个意思在工程上完全不同前者会被当成字段缺失后者才是正确语义。qid 与 q6h 同理数字都是 4性质一个是「不均」一个是「等间隔」。中文病历里 qid 常按三餐加睡前排布各地各科习惯不完全一致本文只把它记为「间隔不均」具体钟点归院内制度。3.2 两个数字怎么互相约束有了次数和最小间隔自洽校验就变成了四条算术第一条等间隔型的次数必须等于 24 除以间隔小时数。q8h 只能是 3q6h 只能是 4q12h 只能是 2。这一条直接拦住「一天 8 次」。第二条次数乘最小间隔不得超过 24。这条是保险丝次数填对了、间隔填成 3 小时时3 乘 3 得 9 看着没超所以还要靠第一条兜住。第三条不均型的最小间隔必须为空。tid 一旦填了 6 或 8说明模型在把它往等间隔上靠这就是合并的前兆直接判不通过。第四条条件型不得带计划。prn 的次数字段必须是 0时间点数组必须是空数组。四条都不涉及「临床上该不该这么给」只涉及「这条记录自己跟自己对不对得上」。这是本文全部讨论的边界这里做的是把医嘱缩写结构化的工程问题不产出任何给药决策临床执行一律以医嘱原件与院内制度为准由有资质的人员核对。3.3 为什么不能拿「解释得顺」当判据小周最初的判断依据是「它说得挺清楚」。问题在于解释是自然语言没法机检也没法复现同一段原文跑两次可能给出两种解释你没法说哪次对跑一百条只能靠人逐条读。两个数字不一样。它们能被写进断言、能进单元测试、能在批量跑的时候自己冒出来。这就是本文要换判据的全部理由——不是为了更严谨好听是为了让错误可复现。四、从字符串到可校验对象4.1 先定字段再谈抽取字段设计的目标只有一个让上面四条约束写得出来。最小可用的一组是三个键⚠️代码待验证{freq_raw:q8h,times_per_day:3,min_interval_h:8}但三个键不够因为 tid 和 q8h 会撞在一起——它们的 times_per_day 都是 3。必须再加一个性质字段才能把两者分开。完整的单条记录长这样⚠️代码待验证[{span:[01],freq_raw:q8h,freq_norm:q8h,times_per_day:3,min_interval_h:8,interval_kind:fixed,anchor:null,count:null},{span:[02],freq_raw:tid,freq_norm:tid,times_per_day:3,min_interval_h:null,interval_kind:uneven,anchor:meal,count:null},{span:[04],freq_raw:prn,freq_norm:prn,times_per_day:0,min_interval_h:null,interval_kind:conditional,anchor:null,count:null}]interval_kind这个字段是整套设计的枢纽取值只有五个fixed等间隔、uneven不均、once一次性、conditional条件、relative相对时点。它不承载任何临床含义只回答一个问题这条记录的「间隔」是不是一个确定的数。标准里的做法可以拿来对照。FHIR一套医疗数据交换标准的 Dosage 结构里给药时间放在Timing.repeat下用 frequency 加 period 加 periodUnit 表达频次。官方定义里给的例子原文是「to express “3 times per day”, 3 would be the frequency and “1 day” would be the period」也就是 3 次配 1 天。这个结构能表达次数表达不了「等间隔」——3 次 1 天既可能是 tid 也可能是 q8h。要落到具体钟点得用timeOfDay而 timeOfDay 与 frequency / period 是互斥的选了钟点就不能再用频次描述。所以「次数 最小间隔」这两个数字是在标准之上自己必须补的一层指望数据格式替你区分 tid 和 q8h 是不现实的。至于 prnFHIR 用Dosage.asNeeded这个布尔字段承载原文自由文本留在Dosage.text两条路各管一段这个设计思路值得照抄。4.2 抽取提示词只查表不解释提示词的作用不是让模型「理解护理」是让它别自由发挥。核心是三条只输出字段、查不到就填 null、每条都要回填片段编号。⚠️代码待验证你只做字段抽取不做解释不补全缺失信息。 输入一段给药计划每行前有片段编号形如 [01] [02]。 输出JSON 数组每条记录字段固定为 span / freq_raw / freq_norm / times_per_day / min_interval_h / interval_kind / anchor / count不得增删字段。 规则 1. freq_raw 原样抄写不改大小写、不删点freq_norm 做归一去空格、去点、转小写。 2. freq_norm 只允许出现在这张白名单里 qd bid tid qid q6h q8h q12h st prn ac pc 不在白名单内一律填 null并写进 missing不许猜。 3. times_per_day 与 min_interval_h 必须按白名单折算不许自行推算。 4. interval_kind 只能是 fixed / uneven / once / conditional / relative。 5. tid 与 qid 的 min_interval_h 必须为 null不许填 6 或 8。 6. prn 的 times_per_day 必须为 0不许给出任何具体钟点。 7. st 的 count 必须为 1。 8. ac / pc 单独出现时anchor 填 null 并写进 missing与主频次同段出现时 anchor 填该主频次的 freq_norm。 9. 一行里出现两个频次且互相冲突时两个都抽interval_kind 填 conflict。第 9 条是给小周那张清单里的 [06] 准备的一行里既有 ac 又有 tid正确做法不是二选一而是把两层都留下来。删掉任何一层都是在替原文做决定。4.3 校验函数有了字段校验就是纯算术。下面这段不调用模型全是字典和正则⚠️代码待验证importre CHART{qd:(1,24,fixed),bid:(2,12,fixed),tid:(3,None,uneven),qid:(4,None,uneven),q6h:(4,6,fixed),q8h:(3,8,fixed),q12h:(2,12,fixed),st:(1,None,once),prn:(0,None,conditional),ac:(None,None,relative),pc:(None,None,relative),}QNHre.compile(r^q(\d{1,2})h$)defnormalize(raw):returnre.sub(r[\s.],,(rawor)).lower()defexpand(key):ifkeyinCHART:returnCHART[key]mQNH.fullmatch(key)ifnotm:returnNonehint(m.group(1))ifh0or24%h:returnNone# 不能整除 24折算结果不唯一交人return(24//h,h,fixed)defcheck(rec):errs[]keynormalize(rec.get(freq_raw))baseexpand(key)ifbaseisNone:return{pass:False,errors:[缩写不在白名单内或间隔无法整除 24转人工]}times,interval,kindbaseifrec.get(times_per_day)!times:errs.append(一日次数与缩写不符应为 %s%times)ifrec.get(interval_kind)!kind:errs.append(间隔性质填错应为 %s%kind)ifkindfixed:ifrec.get(min_interval_h)!interval:errs.append(等间隔型的最小间隔应为 %s 小时%interval)iftimesandintervalandtimes*interval24:errs.append(次数乘间隔超过 24 小时)ifkindunevenandrec.get(min_interval_h)isnotNone:errs.append(tid / qid 不得填最小间隔间隔并不相等)ifkindconditional:ifrec.get(times_per_day)!0orrec.get(schedule):errs.append(prn 不得生成固定计划)ifkindonceandrec.get(count)!1:errs.append(st 是一次性事件count 必须为 1)ifkindrelativeandnotrec.get(anchor):errs.append(ac / pc 必须挂在主频次上)ifrec.get(times_per_day)andrec[times_per_day]4andnotQNH.fullmatch(key):errs.append(一日次数超过 4 且没有 qNh 支撑转人工)return{pass:noterrs,errors:errs}最后那条守卫值得单独说。它拦的不是「次数多」是「次数多到不可能由一个非 qNh 缩写推出来」。模型把 q8h 读成 8 次时这条会同时触发两条错误次数与缩写不符、次数超过 4 且无 qNh 支撑。两道闸门比一道可靠。4.4 批量跑一遍⚠️代码待验证python check_freq.py--indata/orders_sample.jsonl--outreports/freq_conflicts.tsv产出的是一份冲突清单哪一行次数对不上、哪一行间隔性质填错、哪一行 prn 生成了计划。这份清单本身就是评测集的种子。五、你真正能带走的不是背缩写5.1 两样别人拿不到的东西第一样是符号系统的严谨性。护理岗每天都在跟一套不口语的符号打交道缩写有版本、有科室差异、有手写歧义写错一个字意思就变了。你知道qd和qid在潦草字迹下会混所以你会本能地要求「不要把这两个放在同一列里靠猜」。这个直觉落到工程上就是白名单枚举加别名归一表——不做自由文本匹配只认表里的值。第二样是对流程约束的敏感度。三查七对不是口号它是一组可执行的双人核对动作。你做过上千次所以你知道「同一件事由两个独立来源确认」比「一个人看两遍」可靠。落到工程上这就是交叉校验次数由缩写推一遍间隔由缩写推一遍两个结果互相对对不上就拦。5.2 落到工程上是 schema 加校验器你原来的动作对应的工程物具体产出抄写医嘱时逐字核对字段级断言白名单枚举 归一函数给药前的双人核对交叉校验次数与间隔互推对不上即拦交接班时口头复述一遍状态快照与差异比对两次抽取结果做 diff只核变化项发现笔迹可疑就回问低置信分流missing 列表 转人工队列上报不良事件失败样本回流冲突清单直接进评测集这张表想说的是你不需要先变成算法工程师才能做这件事。上面五行的右列全部是普通 Python 能写完的东西难点在左列——知道哪些地方必须拦。左列是你的存量右列是三个月的增量。5.3 要补的三块按这个顺序顺序补什么到什么程度够用1Python 基础能读写 JSON、能写正则、能写函数与列表推导2schema 设计能判断一个字段该不该拆、该用什么类型、缺失怎么表达3评测思维能造覆盖不同错法的样本、能写判定函数、能解释每条为什么不过顺序不能反。跳过第一步直接学提示词遇到输出格式错乱你改不动跳过第三步直接做项目你会做出一个自己觉得挺好、别人一测全是错的东西。反过来有一件事不用补不用去推注意力怎么算也不用懂训练。这个方向九成的工作是把业务规则说清楚、把输出约束住、把错的样本捞出来——前两件你做了很多年。给药频次折算表与校验器骨架这一章讲的能力映射落到手上就是一张折算表加一个校验函数。资料包里放了可以直接改的骨架白名单和断言都留了扩展位。放在资料包里扫码即可获取六、一个能拿出去讲的小项目6.1 边界先划清楚项目可以叫「给药频次核对器」。输入一段脱敏的给药计划输出两样东西每行的结构化记录、以及冲突清单。它不做三件事不排具体执行时间、不判断医嘱是否合理、不生成任何给药建议。这三件事都要有资质的人做。守住这条边界验收标准就能写成「该拦的有没有拦住」一旦越界验收标准会变成「排得对不对」那是临床判断你既证明不了也不该由模型来证明。6.2 评测集怎么造二十条就够起步关键是覆盖不同错法不是堆数量。样本类型造法期望判定单一等间隔只有 q8h 一行格式规整通过同数不同性质tid 与 q8h 各一行并列出现通过但两条的 interval_kind 必须不同条件型只有 prn无指征描述通过且计划字段为空一次性只有 st通过count 必须为 1相对时点缺主频次只写「ac 口服」没有 tid不通过转人工一行两个频次「ac 口服 tid」通过但必须抽出两层anchor 有值写法变体QD、q.d.、qd 三种写法混排通过归一后必须是同一个值无法整除出现 q5h 这类间隔不通过折算不唯一转人工一个反直觉的经验难样本要自己按经验写不要等模型出错再收集——等它出错你收集到的永远是它犯过的错。6.3 验收三条不写「准确」这种词写三条能执行的第一标注为「不通过」的那几类必须全部给出不通过判定漏一条就是判据失效。第二标注为「通过」的样本必须判通过。全部判不通过也能满足第一条但那样的东西没有价值。第三每条判定都要能点回原文的哪一行片段编号。点不回去的结论对了也算失败——你没法向别人解释这个结论从哪来。第三条最容易被跳过但它决定这东西能不能交给别人用。七、什么时候必须停手7.1 四种交给人的情况第一种缩写不在白名单里。中文病历里还有 qod隔日一次、qam / qpm早晚、qw每周这类写法白名单没收全的时候正确动作是把表补全再跑不是让模型猜一个最接近的。第二种一行里出现两个互相冲突的频次。这时候不是模型读错是原文本身有歧义归开嘱方与核对的人处理程序只负责标出来。第三种prn 缺指征。必要条件没写清「什么时候用」就没有依据这时候即使频次抽对了也没有意义照样转人工。第四种跨科室写法差异。同一个缩写在不同科室的习惯不完全一样程序只认本院的白名单版本跨院数据不直接复用。这四种有一个共同点错的代价不由程序承担。凡是代价落在别人身上的判断都要留一个人在环里。7.2 一个十秒钟就能做的动作不管输出多整齐验收时只做一个动作让它指出这条结论对应原文的哪一行。指得出来再谈对错指不出来直接弃用。小周那份表如果做了这一步st被标成「status」时会立刻露馅——原文里没有 status 这个词是模型自己补的。这个动作拦住的问题比任何一次重新提问都多。7.3 这道题的分界线最后把边界再说清一次因为这是医疗场景里最容易被写歪的地方。本文从头到尾讨论的是一件事把给药频次缩写折算成「24 小时内次数」和「最小间隔小时数」两个字段再用算术检查这两个字段跟原始缩写自不自洽。这是数据结构与语义的题跟「这个医嘱该不该开」「应该几点执行」没有关系。真要落地临床执行一律以医嘱原件与院内制度为准由有资质的人员核对。模型不能替代护士做判断也不该被放在需要判断的位置上。核对器能做的事只有一件在有人复核之前把对不上的地方摆到桌面上。脱敏给药计划的标注模板与错法样本造法第七章讲的「点得回去」怎么落成字段靠的就是这份模板——它把片段编号、频次原文、折算结果串在同一条记录上冲突项单独一列。放在资料包里扫码即可获取附表 A本文引用事实与出处对照表事实出处核验方式本文位置每日一次的缩写 q.d. / QD 容易被误读为 q.i.d.每日四次ISMP《List of Error-Prone Abbreviations, Symbols, and Dose Designations》美国安全用药实践研究所ISMP2015 版与 2024 版 PDF 均收录该条下载官方 PDF 原文逐行比对表格中 Intended Meaning 与 Misinterpretation 两列第二章 2.2每晚 6 点的写法 q6PM 容易被误读为「每 6 小时」同上2015 版 PDF 原文条目同上PDF 原文比对第二章 2.1每日一次的 q1d 容易被误读为 qid每日四次同上2015 版 PDF 原文条目同上PDF 原文比对第二章 2.2QD 可能被误读为「每日四次」也可能被看成数字 00QOD 可能被误读为每日一次或每日四次ISMP Canada《Dangerous Abbreviations, Symbols and Dose Designations》加拿大安全用药实践研究所下载官方 PDF比对 DO NOT USE 表第二章 2.2FHIR 当前发布版本为 v5.0.0R5截至 2026-10-25 为该规范页面标注的 current published versionHL7 FHIR 官方规范站点 Dosage 页页头声明hl7.org/fhir/dosage.html打开官方页面读取版本声明文字第四章 4.1Timing.repeat 用 frequency 与 period 表达频次官方定义原句为「to express “3 times per day”, 3 would be the frequency and “1 day” would be the period」periodUnit 取 UCUM 时间单位HL7 FHIR Timing 数据类型定义经 HL7 官方发布的多个 IG 定义页交叉比对条文一致比对三份 HL7 官方 IG 的定义页副本字段描述逐字相同第四章 4.1Timing.repeat.timeOfDay 与 when、frequency、period 不能同时使用同上Timing.repeat.timeOfDay 的注释原文同上多份官方副本交叉比对第四章 4.1Dosage.asNeeded 为布尔字段表示「按需」Dosage.text 保存自由文本用法说明HL7 FHIR 官方规范站点 Dosage 页结构表hl7.org/fhir/dosage.html打开官方页面读取元素表原文第四章 4.1bid / tid / qid 分别来自拉丁语 bis in die、ter in die、quater in dieprn 为 pro re natast 为 statim药学拉丁缩写通行用法属行业惯例未检索到统一强制文本待验证未见可引用的强制性规范原文本文按通行词源转述不写具体条号第二章 2.1、2.2、2.3中文病历中 qid 常按三餐加睡前排布各地各科习惯不完全一致无统一强制标准文本行业惯例待验证未检索到统一标准原文本文只把它记为「间隔不均」具体钟点归院内制度第三章 3.1附表 B术语速查表术语一句话解释在本文哪里用到给药频次缩写用几个字母表示一天给几次、间隔多久的一套行业符号如 tid、q8h全文qNhq 加数字加 h 的写法数字是间隔小时数不是次数第二章 2.1、第四章 4.324 小时内次数把一条医嘱折成「一天执行几次」用于和缩写互相验算第三章 3.1最小间隔两次执行之间至少要隔多少小时等间隔型才有这个值第三章 3.1、3.2间隔性质区分等间隔、间隔不均、一次性、条件触发、相对时点五类第四章 4.1自洽校验只检查一条记录内部字段是否互相矛盾不涉及临床判断第三章 3.2tid每日三次随三餐走间隔并不相等第二章 2.2、第三章 3.1q8h每 8 小时一次一天三次间隔相等第二章 2.1、第三章 3.1prn必要时用是条件不是时间不排固定计划第二章 2.3、第三章 3.1st立即执行一次一次性事件不重复第二章 2.4ac / pc饭前 / 饭后是相对时点必须挂在主频次上第二章 2.3、第三章 3.1白名单枚举只接受预先列出的值表外的输入一律不猜第二章 2.4、第四章 4.2片段编号给原文每一行打的标号用来把字段指回原文第四章 4.1、第七章 7.2FHIR Dosage医疗数据交换标准里描述用法用量的结构含 timing 与 asNeeded第四章 4.1转人工无法自动判定时把记录退回给人处理不让程序猜第二章 2.4、第七章 7.1写在最后这篇用到的资料写这篇文章时把相关的官方文档和源码又翻了一遍顺手也整理了几份配套的东西大模型学习路线图从零基础到能自己动手做 Agent按阶段说明每一步该学什么、哪些可以先跳过《LangChain LangGraph MCP 智能体开发实战》视频课7 个模块从私有化部署、EmbeddingRAG 到 MCPAgent 全流程AI 大模型知识库在线可查Agent Skills 从入门到落地、Claude Skills 完全指南等专题按目录浏览即可640 套 AI 大模型行业报告 经典 PDF 书籍看行业落地案例和别人怎么做的时候用得上大模型零基础到精通教学视频跟着敲一遍比只读文档快得多资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「AI」优先通过。资料按「先路线、再动手、最后查漏」的顺序整理好了建议先看学习路线那一份照着它挑一条适合自己当前基础的路径再往下看。