← Về thư mục
📄 / / profiles / r-and-d / raw_evidence / scientific-agent-skills / skills / opentrons-integration / references / protocol_authoring.md

Protocol Authoring Guide

Use this guide to turn a wet-lab method into a reviewable Opentrons Python protocol. It targets Protocol API v2 and assumes the protocol will be imported into the Opentrons App.

1. Convert the Method into Explicit Inputs

Create a protocol specification before writing code.

Hardware

Labware and consumables

Liquids and assay constraints

Operations

Record every assumption that has not been confirmed by the operator.

2. Choose the API Level Deliberately

The API level controls both available methods and behavior. It is not merely a documentation label.

  1. Check the robot's maximum supported level in the App.
  2. Identify the minimum level for each required feature.
  3. Use the highest of those minimums.
  4. Raise the level further only for a specific fix or behavior that the method needs.

At the 2026-07-23 baseline:

Do not declare an unsupported API level just because a newer local Python package can simulate it.

3. Keep Top-Level Code Declarative

A protocol file normally contains imports, metadata, requirements, optional parameter definitions, helper functions, and run().

from opentrons import protocol_api

metadata = {
    "protocolName": "Assay setup",
    "author": "Automation Team",
    "description": "Prepare an eight-sample assay plate.",
}
requirements = {"robotType": "Flex", "apiLevel": "2.29"}


def add_parameters(parameters: protocol_api.ParameterContext) -> None:
    parameters.add_int(
        variable_name="sample_count",
        display_name="Sample count",
        default=8,
        minimum=1,
        maximum=24,
    )


def run(protocol: protocol_api.ProtocolContext) -> None:
    sample_count = protocol.params.sample_count
    protocol.comment(f"Preparing {sample_count} samples")

Avoid top-level network calls, package installation, local machine paths, or other side effects. Protocol analysis evaluates the protocol in a controlled environment, and the robot may not have workstation packages or network access.

Do not use apiLevel in both metadata and requirements.

4. Build a Deck Manifest

Create a simple manifest before calling load methods:

Slot Item Adapter/module Notes
A3 Flex trash bin — Required for dropped tips
C1 50 µL tip rack Flex tip-rack adapter if required Left pipette
C2 Sample rack — Tubes 1–8
D1 Temperature Module GEN2 Aluminum block Master mix
Thermocycler PCR plate Thermocycler Module GEN2 Destination

Then check:

Use named variables and labels:

sample_rack = protocol.load_labware(
    "opentrons_24_tuberack_nest_1.5ml_snapcap",
    "C2",
    label="Samples 1-8",
)

Labels appear in setup and run views and are more useful than generic names such as plate1.

5. Use Exact Labware Definitions

The API load name identifies geometry, not merely a product category.

Loading on an adapter should reflect the physical stack:

adapter = protocol.load_adapter(
    "opentrons_96_well_aluminum_block",
    "D1",
)
plate = adapter.load_labware(
    "opentrons_96_wellplate_200ul_pcr_full_skirt"
)

For modules, call the module or module adapter's load_labware() method. Do not repeat a deck slot already supplied to load_module().

6. Represent Initial Liquids

Liquid definitions improve setup visualization but do not move or measure liquid.

master_mix = protocol.define_liquid(
    name="Master mix",
    description="2x PCR master mix",
    display_color="#E377C2",
)

reagent_rack.load_liquid(
    wells=["A1"],
    volume=500,
    liquid=master_mix,
)

For varying volumes:

sample_rack.load_liquid_by_well(
    volumes={"A1": 30, "A2": 40, "A3": 50},
    liquid=sample,
)

In API 2.22+ protocols, prefer labware-level methods over deprecated Well.load_liquid().

Declared volumes support visualization and meniscus calculations. They do not replace physical setup checks or a source-volume budget.

7. Define Runtime Parameters

Use runtime parameters for values an operator should set without editing code:

Keep hardware geometry and safety-critical invariants in code unless every allowed choice is separately validated.

def add_parameters(parameters: protocol_api.ParameterContext) -> None:
    parameters.add_float(
        variable_name="transfer_volume",
        display_name="Transfer volume",
        description="Volume delivered to each destination.",
        default=25.0,
        minimum=10.0,
        maximum=40.0,
        unit="µL",
    )
    parameters.add_bool(
        variable_name="dry_run",
        display_name="Dry run",
        description="Shorten delays and use test-safe behavior.",
        default=False,
    )

Constraints:

Use defaults that simulate successfully. Do not make a hazardous setting the default.

8. Structure the Protocol

Separate configuration from repetitive actions:

def transfer_samples(
    pipette: protocol_api.InstrumentContext,
    sources: list[protocol_api.Well],
    destinations: list[protocol_api.Well],
    volume: float,
) -> None:
    for source, destination in zip(sources, destinations, strict=True):
        pipette.transfer(
            volume,
            source,
            destination,
            new_tip="always",
            mix_after=(3, min(volume, 20)),
        )

Guidelines:

protocol.comment() text is computed during analysis. Do not rely on it to report a live sensor value that only exists during physical execution.

9. Plan Tips and Contamination

Define a policy before choosing new_tip:

Examples of unsafe optimization:

Count multi-channel tips as tip sets. A full 8-channel pickup consumes eight tips, and a full 96-channel pickup consumes an entire rack.

10. Budget Volumes

For each source:

required source volume =
    delivered volume
  + disposal volume
  + mixing and pre-wet loss
  + geometry-dependent dead volume
  + validated reserve

For each destination, calculate the maximum intermediate volume, not just the final expected volume. Include mix strokes, carryover splits, and any material left before a subsequent transfer.

Do not use a pipette below its supported range. For example, 100 nL is below the range of every current Opentrons pipette and requires a different dispensing technology or a redesigned dilution scheme.

11. Data and Dependencies

12. Review Checklist