← 全部笔记

Note 03 药理

一千倍的错误:
药理引擎里的单位换算

6 MIN READ 阮家忆 药理 / 量纲

药理引擎要装 410 种药。每种药自带剂量范围、半衰期、分布容积、生物利用度、蛋白结合率、效应靶点,以及一对 Emax 与 EC50。它们来自不同的资料:有的按微克每公斤给,有的按毫克每小时滴注;浓度有的写作纳克每毫升,有的写作毫单位每毫升。

粗数一下,11 种浓度单位,加上毫克、微克每公斤、微克每公斤每分、毫克每小时、单位每分钟这些剂量与速率单位。而引擎内部只认三个量:质量用毫克,时间用秒,浓度用毫克每升。所有换算必须发生在边界,而且只发生一次。

三个边界,三次事故

第一个边界是剂量到质量。这里要处理两件事:按体重给药的每公斤系数,和质量前缀。早期版本做了前者,漏了后者。于是「微克每公斤」被当成「毫克每公斤」读,剂量偏高一千倍。

第二个边界是速率到每秒质量。比第一个多一个时间维度:默认按每分钟解释,按小时给的除以三千六百。早期版本把「微克每分钟」直接当成「毫克每秒」——质量前缀和时间维度一起错,偏高六万倍。

第三个边界是浓度到药物自己声明的单位。引擎内部算出来的浓度是毫克每升,而每种药的 EC50 写在它自己的单位体系里。两边不统一时,差的又是一千倍。这次的表现最像「药不行」:肾上腺素 1 毫克静推,血压几乎不动。

为什么它看起来是对的

因为 Hill 方程会替错误打掩护:

E = Emax · Cn / (EC50n + Cn)

剂量偏大时,浓度早就越过 EC50,曲线饱和在接近满效应的位置,看起来「这药很强」;剂量偏小时,效应趴在底部,看起来「这个病人不敏感」。两种错误都不会让曲线变形,只会让整条曲线平移——而平移在没有对照的时候,和个体差异长得一模一样。

这是单位错误最坏的地方:它不是让结果变丑,是让结果变得可信。一条难看的曲线你会去查,一条合理的曲线你会拿去解释病情。

单位不是格式。它是模型的一部分,而且是最容易被当成格式的那一部分。 药理笔记 / 2026

怎么让它现形

判据不是「数值对不对」,而是「剂量-效应是不是单调、有没有区分度」。固定一种药,从低到高给五个滴注速率,看稳态浓度是否随之线性上升、效应是否铺满整条曲线,而不是一开始就贴顶或者一直贴底。

滴注速率 微克/公斤/分稳态浓度 纳克/毫升效应平均动脉压 毫米汞柱
0.020.02918%94
0.050.07239%99
0.100.14459%103
0.200.28777%106
0.500.71891%108

这是肾上腺素。浓度与速率严格线性,效应是标准的 S 形,0.5 微克每公斤每分的稳态 0.72 纳克每毫升与临床实测吻合。这条曲线一旦有任何一段是平的,就说明某个边界漏了——不是模型不真,是翻译错了。

写进约定里的四条

现在固定在文档里:分布容积一律用升每公斤;半衰期一律用小时;起效速率常数一律用每小时;滴注速率的单位,取自该药该给药途径自己声明的那一项。最后一条是为了让「速率」永远知道自己该怎么被解释——它不是一个数,它是一个带单位的数。

还有一个习惯:任何「看起来差不多」的曲线,都要拿数量级去对一次。不是对小数点后两位,是对「这个数应该是一点几还是几百」。数量级对不上,后面所有推理都是精致的废话。

Lesson 一千倍的错误不会报错。它只会让一个能救命的剂量变成一条平线,或者让一条平线看起来像「这个病人不敏感」。两种情况都不会有人怀疑代码。

最后

单位换算不是脏活。它是模型与现实之间唯一的一层翻译。翻译错了,后面的方程再漂亮,也只是在精确地描述一个不存在的人。

顺带一提,这也是为什么我后来把「剂量-效应的单调性」写成断言,而不是靠看一眼曲线。眼睛能分辨形状,分辨不了量级。

回到 / Archive 全部笔记 ↗

Contact 交流

如果你也在做类似的东西,
欢迎写信。

806117943@qq.com ↗

物理、界面、数值方法,或者任何一个还没做完的模拟。