Opentrons 液体处理实战指南:Protocol API v2 命令分层、吸头策略与液体分类编程
2026/9/11 14:29:55 网站建设 项目流程

Opentrons 液体处理实战指南:Protocol API v2 命令分层、吸头策略与液体分类编程

【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills

本篇技术指南以 scientific-agent-skills 仓库中 skills/opentrons-integration/references/liquid_handling.md 为骨架,完整讲解 Opentrons Flex 与 OT-2 机器人上 Python Protocol API v2 协议中液体处理的命令选型、源目标映射、吸头污染策略、流速与位置控制、液体分类(liquid class)、液体存在检测、部分吸头拾取与序列稀释等核心实操;并结合仓库内的模板脚本与仿真测试,给出可模拟、可验证、可直接落地的完整方案。读完本文,你将能够根据实验的物理需求(而非命令长短)正确选型液体处理命令,写出可审计、可仿真、可安全部署到真机上的 Protocol API v2 协议。

选命令的原则:从实验物理行为出发

在 Opentrons Protocol API v2 中,液体处理存在多个调用层级。一个最常见的错误是"哪个调用写起来最短就选哪个"。液体处理指南明确要求:从实验所需的物理行为选择命令,而不是从编码便利性出发。

无论选择哪一层命令,以下物理量始终是每一条命令的隐含前提:

  • 正确的液体体积(源体积、目标体积、死体积、抛洒体积);
  • 正确的耗材几何(板/孔/储液槽尺寸与高度偏移);
  • 正确的移液器量程与吸头容量;
  • 吸头状态(已拾取、已污染、可复用)与污染控制边界。

这三类要素共同决定了命令展开后的物理动作是否安全、准确。

命令分层:三种编程模型

构建块命令(Building-block commands):显式控制每一拍

当吸液与分液需要独立控制(例如粘稠、易挥发、易起泡、低体积或含磁珠工作流)时,使用底层原语:

pipette.pick_up_tip() pipette.aspirate(50, source.bottom(z=1), flow_rate=25) protocol.delay(seconds=1) pipette.dispense(50, destination.bottom(z=2), flow_rate=20, push_out=5) pipette.blow_out(destination.top(z=-1)) pipette.drop_tip()

优势

  • 位置与顺序完全显式,命令间不存在隐式行为;
  • 每步可独立设置流速与延时;
  • 对粘稠、易挥发、易起泡、低体积或磁珠类工作流提供精细控制。

代价

  • 作者必须自行管理吸头状态与体积状态;
  • 更容易出现"无吸头时吸液""超出移液器容量""残留体积未处理"等错误。

从仓库的 api_reference.md 可以看到,构建块命令还包括air_gap()touch_tip()move_to()等,且 API 2.27 之后aspirate()/dispense()增加了end_locationmovement_delay参数、新增了dynamic_mix()

标准复杂命令:常规源-目标映射

对常规的一对一、一对多、多对一映射,使用高层命令:

pipette.transfer( volume=50, source=source_plate.wells()[:8], dest=destination_plate.wells()[:8], new_tip="always", mix_after=(3, 30), )

三个命令的分工:

  • transfer():一个或多个源到目标的转移;
  • distribute():一个源到多个目标,通常带一个额外的抛洒(disposal)体积;
  • consolidate():多个源汇集到一个目标。

务必检查仿真运行日志。复杂命令会被展开为大量构建块,而展开方式随参数与 API 级别变化。仓库的 test_scripts.py 正是据此断言序列稀释模板的展开结果:11 步稀释对应 11 次 Mixing、1 + 11 + 1次拾取/丢弃吸头、11×2+1次 100 µL 吸液。

液体分类复杂命令(Flex API 2.24+):借用 Opentrons 验证过的液体行为

当吸头/移液器组合受支持、且实验液体与验证模型接近时,使用 Opentrons 验证的液体分类(liquid class):

viscous = protocol.get_liquid_class("glycerol_50") pipette.transfer_with_liquid_class( liquid_class=viscous, volume=50, source=reservoir["A1"], dest=plate["A1"], new_tip="always", trash_location=trash, )

相关方法:distribute_with_liquid_class()consolidate_with_liquid_class()

已验证的液体分类包括 water(水)、80% 乙醇、50% 甘油。一个液体分类会同时控制多个耦合属性:流速、浸入与回缩行为、延时、空气间隙、位置与 push-out。指南明确警告:不要随意覆盖其中单个属性而不做完整测试——这些属性相互耦合,单独改动可能破坏整体行为。

需要特别注意的适用范围:Opentrons 验证的液体分类仅适用于受支持的 Flex 移液器与吸头组合,不适用于 OT-2 移液器。API 2.24 才引入液体分类(见 api_reference.md 的版本门控表)。

源与目标映射:把映射关系显式化

复杂命令接受单个孔或一个序列。把预期的映射关系写清楚:

映射实现方式
单源 → 单目标一次transfer()
单源 → 多目标重复 transfer 或一次distribute()
多源 → 单目标重复 transfer 或一次consolidate()
等长源/目标列表成对transfer()

不要假设行优先顺序。耗材迭代通常是按列优先(column-major)进行的(api_reference.md),在安全关键场景中应使用命名孔或显式列表:

# 显式样本顺序更易于审计 sample_wells = [plate[name] for name in ("A1", "B1", "C1", "D1")]

多通道移液器的锚定规则:所引用的孔锚定的是移液器的主通道(primary channel)。

  • 满 8 通道移液器通常通过引用 A 行孔来寻址整列;
  • 满 96 通道移液器寻址整个 96 孔板架或整块板;
  • 部分列(partial-column)布局的主通道不同,必须查阅对应布局文档,不能沿用满列的假设。

吸头策略:new_tip是一次污染决策

new_tip本质上是污染边界的编码,而不只是吸头用量优化:

策略典型用途主要风险
"always"独立样本、对照、独立的源-目标对吸头消耗更高
"once"同一污染域内的试剂分发被污染的吸头回到共享源
"never"显式外包pick_up_tip()drop_tip()隐藏或无效的吸头状态

共享试剂的吸头复用判断要点:

  • 同一吸头反复从同一源吸液,仅在吸头永不接触不兼容的目标液体时才可能可接受;
  • 浸入式分液(submerged dispense)可能润湿吸头外壁或内壁;
  • touch_tip、混匀或底部接触式分液都会增加污染风险;
  • 对照与样本通常必须分开吸头。

为每一条条件分支计算吸头用量。多通道操作消耗的是整组吸头(tip sets),不是单个命令调用数。仓库 serial_dilution_template.py 的序列稀释步骤使用new_tip="always"(每步新吸头),而加稀释液步骤使用new_tip="once",测试断言总吸头数为1 + 11 + 1(稀释液 1 支 + 11 步各 1 支 + 末列移走 1 支),正是"按污染边界逐分支计算吸头"的落地示例。

流速、位置与延时

相对流速与绝对流速

rate=是对已配置流速的乘法因子

pipette.aspirate(50, source, rate=0.5)

受支持的现代 API 也接受绝对流速参数(单位 µL/s):

pipette.aspirate(50, source, flow_rate=25)

规则:每个动作只用一种形式。绝对值的单位是 µL/s;数值应通过针对具体液体的测试建立,而不是照抄其他移液器的设置。api_reference 同样强调"不要同时提供两种形式"(api_reference.md)。

位置(Position)

source.bottom(z=1) source.top(z=-2) destination.center()
  • 底部吸液可减少残留体积,但增加碰撞与扰动沉淀(pellet)的风险;
  • 顶部或近顶部分液可减少接触污染,但可能飞溅;
  • 侧向偏移可减少起泡,但要求已知的孔几何;
  • touch_tip()在大孔与储液槽中可能不安全;API 2.28+ 会拒绝某些大空间用法

空气间隙与 push-out

空气间隙可减少滴落,但占用移液器容量:

pipette.aspirate(80, source) pipette.air_gap(10) pipette.dispense(90, destination)

液体加空气的总量必须能装进移液器。分液后用push_out让柱塞再多推进一小段距离:

pipette.dispense(80, destination, push_out=5)

更大幅度的排空使用 blowout。当气溶胶、气泡或交叉污染重要时,避免对着液体吹气

混匀:标准 mix 与动态混匀

标准混匀:

pipette.mix( repetitions=5, volume=40, location=plate["A1"].bottom(z=1), aspirate_flow_rate=20, dispense_flow_rate=30, final_push_out=5, )

混匀体积必须低于可用液体体积与移液器上限;同时要考虑沉淀、磁珠、细胞、起泡与封板膜(plate seals)。

API 2.27 增加动态混匀(移动过程中同时吸/排):

well = plate["A1"] pipette.dynamic_mix( aspirate_start_location=well.bottom(z=1), aspirate_end_location=well.bottom(z=4), dispense_start_location=well.bottom(z=4), dispense_end_location=well.bottom(z=1), repetitions=3, volume=50, )

动态运动对几何非常敏感:先用仿真检查路径,再用真实耗材做干跑(dry-run),之后才允许用于样本

动态吸液与分液(API 2.27)

API 2.27 可以在一次柱塞动作中在两个位置之间移动

pipette.aspirate( volume=100, location=well.bottom(z=1), end_location=well.bottom(z=5), movement_delay=1, )

这可用于跟随变化的液面(meniscus)或扫过一段液柱。注意:它并不能自动证明声明的液体体积或几何是正确的——声明值与实际物理状态必须单独验证。

液体定义与弯月面:define_liquidload_liquidmeniscus()

声明液体与装载体积

用耗材级方法声明设置体积:

buffer = protocol.define_liquid( name="Buffer", description="Assay buffer", display_color="#1F77B4", ) reservoir.load_liquid( wells=["A1"], volume=12_000, liquid=buffer, )

API 2.22+ 提供load_liquid_by_well()(按孔传入体积字典)与load_empty()(标记空孔),旧的Well.load_liquid()已在 API 2.22+ 协议中弃用(api_reference.md)。仓库的 runtime_parameters_template.py 与 serial_dilution_template.py 都是先define_liquid、再load_liquid的标准用法;测试会断言声明体积足以覆盖整个运行的消耗(如序列稀释模板声明 12 mL ≥ 8×11×100 µL = 8800 µL,见 test_scripts.py)。

弯月面位置(API 2.23+)

start_surface = reservoir["A1"].meniscus(z=-1, target="start") end_surface = reservoir["A1"].meniscus(z=-1, target="end")

计算出的液面位置取决于液体体积与耗材几何。配合动态吸液/分液时,target="start"target="end"表示操作两端预期的液面位置。

安全底线:在机器人上确认声明的体积、孔几何与液面行为之前,不要依赖弯月面定位

液体存在检测:Flex 压力传感器

Flex 压力传感移液器支持三种显式操作:

present = pipette.detect_liquid_presence(reservoir["A1"]) pipette.require_liquid_presence(reservoir["A1"]) height = pipette.measure_liquid_height(reservoir["A1"])

或者在每次吸液前全局启用检查:

pipette = protocol.load_instrument( "flex_1channel_1000", "left", tip_racks=[tips], liquid_presence_detection=True, )

运行约束(务必遵守):

  • 必须使用全新、干燥、空的吸头;
  • 每次检查可能增加5–50 秒运行时间,取决于孔深与体积;
  • 8 通道移液器仅在通道 1 与通道 8 有压力传感器
  • 96 通道移液器仅在通道 1 与通道 96 有压力传感器
  • 湿吸头会导致"缺液"检测失效;
  • 检测不能替代源体积规划

当全局检测耗时过高时,在关键源上使用显式检查(require_liquid_presence/detect_liquid_presence)更划算。相关能力门控:液体存在检测自 API 2.20 起可用(api_reference.md)。

部分吸头拾取:喷嘴布局配置

支持的布局与最低 API 版本:

移液器布局最低 API
Flex 96 通道column(整列)2.16
Flex 96 通道row、single2.20
Flex 8 通道single、partial column2.20
OT-2 多通道single、partial column2.20
from opentrons.protocol_api import ALL, COLUMN pipette.configure_nozzle_layout( style=COLUMN, start="A12", tip_racks=[partial_rack], ) # 部分列操作... pipette.configure_nozzle_layout( style=ALL, tip_racks=[full_rack], )

关键规则:

  • configure_nozzle_layout()重置pipette.tip_racks
  • 全量拾取与部分拾取必须使用分开的吸头架变量
  • Flex 96 通道全架拾取需要适配器(adapter)
  • Flex 96 通道部分拾取不得使用适配器
  • 绝不要把拾取或目标孔位置传给会让活动喷嘴悬在架/耗材之外的布局;
  • 台面边缘可达范围取决于布局与起始喷嘴;
  • 台面可达允许时,优先用 96 通道移液器的12 列喷嘴做整列拾取;
  • 首次物理使用前必须仿真并做纯吸头干跑

可用常量包括ALLCOLUMNROWSINGLEPARTIAL_COLUMN,支持范围取决于移液器与 API(api_reference.md)。关于各布局的目标孔选取规则,可参见仓库整理的官方资料索引 references/sources.md。

序列稀释模式:8 通道 × 96 孔板的完整实现

对满 96 孔板 + 8 通道移液器,推荐流程:

  1. 第 1 列预装母液(stock);
  2. 第 2–12 列加入稀释液;
  3. 从第 1 列转移到第 2 列并混匀,再 2→3,依此类推;
  4. 每一步稀释使用新吸头组,除非已验证的方法另有规定;
  5. 若需要等量终体积,从第 12 列移走一个转移体积

引用 A 行孔即可寻址整列:

pipette.transfer( 100, source=plate.rows()[0][0:11], dest=plate.rows()[0][1:12], mix_after=(3, 50), new_tip="always", )

吸头预算必须覆盖 11 步序列转移 + 稀释液添加 + 末列终体积移除

仓库提供了这一模式的完整可运行模板 serial_dilution_template.py:它加载两架opentrons_flex_96_tiprack_200ul、一个 15 mL 储液槽与一块 96 孔板,用group_steps()(API 2.29 步骤分组)把"加稀释液→序列稀释→终体积均一化"三个阶段组织成三个逻辑组,稀释液阶段用new_tip="once"一次吸头连做 11 列,序列阶段new_tip="always",最后pick_up_tip()/aspirate(100)/dispense(100, trash)/drop_tip()把第 12 列抽至 100 µL。仿真测试逐项验证了这些物理行为(test_scripts.py):11 次混匀、13 次吸头拾取/丢弃、23 次 100 µL 吸液、恰好 1 次丢弃到 Trash、且稀释液绝不进入第 1 列(母液列)。

液体处理最终审查清单

在把协议交给仿真与真机之前,逐项核对:

  • 每个体积都在移液器与吸头量程内;
  • 空气 + 液体总量不超容量;
  • 源包含死体积与抛洒体积;
  • 目标在每个中间步骤都不超容量;
  • 混匀体积物理可得;
  • 位置不接触孔底或沉淀;
  • 吸头策略与污染边界一致;
  • 多通道孔引用与当前喷嘴布局一致;
  • 液体检测使用全新干燥吸头;
  • 仿真展开结果与预期命令顺序一致;
  • 液体特异性行为已通过干跑验证。

落地验证:本地仿真与测试资产

液体处理代码必须在钉版(pinned)opentrons 包下仿真。仓库钉版环境(requirements-flex.txt、requirements-ot2.txt):

  • Flex:opentrons==9.1.1,API 2.29(uv run --with "opentrons==9.1.1" opentrons_simulate protocol.py);
  • OT-2:opentrons==9.0.0,API 2.28 兼容仿真;9.1.1 包在 Flex/OT-2 产品线分叉后会直接拒绝 OT-2 协议,OT-2 分析必须在 OT-2 App 中完成。

仓库 tests/opentrons-integration/test_scripts.py 展示了如何把"液体处理正确性"变成可断言的事实:对每个 Flex 模板调用opentrons.simulate.simulate(),再对运行日志统计吸液/分液次数、吸头拾取/丢弃次数、混匀次数与最终注释,从而锁定体积预算与步骤数——例如"8 孔 × 50 µL + 3 次 20 µL 抛洒 = 460 µL 缓冲液,且单次吸液不超过 200 µL 吸头容量"(test_scripts.py)。这套"仿真→日志断言"的方法可以直接复用到你自己的液体处理协议上。

完整的分层验证流程(语法编译 → 本地仿真 → 资源审计 → App 分析 → 操作者复核 → 干跑 → 受控放行)见 references/validation_and_operations.md;液体处理在整个 Opentrons skill 中的定位与其余参考文档的索引见 SKILL.md。

最后重申安全边界:成功的 Python 语法与本地仿真绝不等于可以上真机。物理执行前必须完成 App 分析、操作者复核与无害液体干跑,并随时可触达急停按钮。

【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询