最近有一个项目在 Hacker News 的 Show HN 版块出现名字叫 Sous.bio一句话介绍是“your sous chef in the lab”。这个名字初看有趣细想却切中了一个经常被低估的痛点实验室里的科研工作者日常工作节奏其实非常像后厨——要按菜谱操作、掐时间、控制温度、按顺序添加物料、记录每一步结果。问题是绝大多数实验室的“菜谱”还散落在 PDF、Word、电子表格、聊天记录和纸质实验记录本里从协议整理到实验执行再到结果归档每一步都存在巨大的文本开销和人为误差。我的判断是这类所谓“实验室副主厨”工具的核心价值不在于取代科研人员做实验设计而在于把实验外围的琐碎工作自动化尤其是协议解析、步骤执行、记录归档和数据追溯这一整条链路。这篇文章会从概念、典型工作流、架构设计、最小实现、数据安全边界和工程化建议几个层面展开。如果你正在做生物信息学、实验室自动化、或想用大模型能力改造垂直行业工作流这篇文章值得读完。1. 这篇文章真正要解决的问题先抛出核心问题为什么一个“实验室副主厨”的概念值得讨论从事科研或者支持科研团队的开发者都知道真正的实验流程通常分三层。第一层是实验设计由课题负责人或研究者完成这是高度创造性、不可替代的部分。第二层是实验操作比如配液、孵育、离心、测量这部分由研究人员或自动化设备执行。第三层是实验记录和分析包括每一步发生了什么、用了哪个批次的试剂、温度有没有异常、结果怎么解读。目前大多数数字化工具解决的是第一层和第二层的边缘问题比如用电子实验记录本ELN替代纸质记录本、用实验室信息管理系统LIMS管理样本和结果。但第三层中文本协议到可执行步骤的转化仍然高度依赖人工。研究员拿到一份几十页的英文 protocol需要自己提炼步骤、换算浓度、标注注意事项然后手动敲进记录本里。这个过程既慢又容易出错而且做完之后很难回溯“当时到底为什么这么操作”。Sous.bio 的命名暗示了一种更轻量的替代方式像米其林餐厅里的副主厨一样帮主厨把菜谱拆解成可执行的备菜清单、准备好每一个环节的工具和物料、在关键节点提醒你需要做什么。对于一个做应用软件或 AI 工具的工程师来说这个思路可以直接落到产品架构上解析非结构化实验文本生成结构化步骤清单在实验执行过程中提供辅助提醒最终把整个过程沉淀成可溯源的结构化记录。从工程角度看这篇文章要解决的问题不是“怎么复现某个具体功能”而是“如果要为实验室构建一个副主厨型助手应该从哪些环节切入技术架构怎么搭坑在哪里”。我会尽量用真实场景和最小可运行代码来说明。2. 副主厨逻辑模型与实验室工作流之间的关系要理解这个工具类别先要理解“副主厨”在实验室语境下的准确含义。副主厨并不创造菜谱而是负责把菜谱变成现实确认食材、预处理原料、分配工序、协调时间并在主厨需要时提供所有现场支持。对应到实验室实验方案Protocol就是菜谱。它通常是一段自然语言描述比如“将 10 μL 样本与 90 μL 反应缓冲液混合在 37°C 孵育 30 分钟然后加入 20 μL 终止液立即置于冰上。”这段文字本身不是可直接执行的数据结构。要让系统真正帮助科研人员系统必须能从中提取出几个关键要素操作对象、物料量、时长、温度、顺序、条件和注意事项。这就是“副主厨”的第一层职责把非结构化文本解析为结构化指令。技术上讲这是典型的自然语言理解 信息抽取任务。早期做法是规则模板比如用正则表达式匹配“体积 单位 物料名”这种模式。如果协议文本统一规则方法完全可行。但真实科研文本的写法差异极大同一种操作可能有十几种表达方式所以现在更常见的做法是让大语言模型LLM参与解析再辅以结构化的输出校验。第二层职责是步骤执行与提醒。实验操作不是一次执行完的所有步骤而是在不同的时间节点上触发不同动作。有的步骤需要等待 30 分钟有的操作需要在特定温度和转速条件下进行。一个合格的副主厨系统至少应该能维护一个步骤状态机每个步骤处于“待开始、执行中、已完成、已跳过、异常中断”中的哪一种状态并且能主动提醒下一个动作。第三层职责是数据沉淀与追溯。实验室和厨房有一个本质差别厨房的菜品完成即消费而实验室的结果需要被反复追溯。几个月后研究者可能会问“我在 3 月 5 号跑的这批样本用的到底是不是同一个批次的 buffer”这就要求副主厨不只是生成清单还要记录每个步骤的实际执行结果包括时间戳、操作人、仪器编号、试剂批次和异常备注。所以所谓的“副主厨”本质是三层能力的组合语义解析层、流程执行层和数据归档层。这三层单独拿出来都有现成工具但把它们整合成一个连贯的工作流才是这类 AI 辅助科研工具的难点和价值所在。3. 适合“副主厨”切入的六类实验室工作流把概念落到场景里哪些实验室工作流最适合交给副主厨型工具我认为至少有以下六类每一类的自动化程度和难度都不同。第一类是实验协议解析。这是最基础也最通用的场景。研究员把一篇论文的补充材料、厂商提供的说明书、或者实验室内部沉淀的旧版 protocol 丢给系统系统输出一份结构化的步骤清单。难点在于协议文本经常包含复杂的条件分支比如“若产物纯度低于 90%则重新进行纯化步骤”这就要求系统能够识别条件逻辑而不仅仅是提取步骤。第二类是试剂与耗材检查。实验开始前系统可以根据协议中的物料清单自动比对实验室库存系统标记哪些物料不足、哪些试剂即将过期。这个场景看起来简单但真正实现时涉及到与 LIMS 或库存数据库的对接。如果没有现成系统可以先让研究员在工具里维护一份简单的库存表。第三类是实验批次管理。在分子生物学或药物研发场景中一个实验往往对应多个样本、多个重复。人工管理批次非常容易出错尤其当样本编号相似时。副主厨系统可以自动生成样本编号、批次号和对应的实验记录表确保每个样本的操作记录能关联到最终数据。第四类是过程提醒与异常记录。实验操作中的“等待时间”非常分散有的步骤要求孵育 30 分钟有的要求冷却 2 分钟。系统可以根据步骤清单生成时间线在关键时间点提醒操作者同时允许研究员快速记录异常例如“温度超了 0.5°C”且这些记录会自动附加到对应步骤。第五类是实验报告草稿生成。实验做完之后需要整理成规范化的报告这往往比做实验本身还耗时。如果系统已经把步骤、参数、异常、结果数据都结构化存储了那么报告草稿的生成就是一次模板填充甚至可以用 LLM 生成一段可读的实验描述再由研究员审核修改。第六类是知识检索。实验室里的 protocol 会不断更新不同人可能有不同版本。副主厨工具如果能把所有协议都转成结构化数据就能提供一个比文件夹搜索更可靠的检索入口比如“找一份不需要超速离心机的 RNA 提取方案”系统可以基于步骤特征给出推荐结果。这六类场景并不要求一个产品在初期全部覆盖。更稳妥的切入路径是先做第一类协议解析然后逐步扩展到执行记录和报告生成。这也是很多实验室自动化产品比较常见的演进路线。4. 最小实验室副主厨的架构设计从工程角度出发一个最小可用的实验室副主厨系统应该包括四个模块解析引擎、存储层、执行状态机和交互入口。解析引擎承担协议文本到结构化步骤的转换。在实现上有两种路线一种是纯规则路线依赖正则表达式和词表匹配适合协议文本格式固定的团队另一种是 LLM 辅助路线让大模型把自然语言转换成 JSON 结构然后通过代码做字段校验和修正。实际项目里推荐混合方式先用规则做预处理比如把段落切分成句子、识别编号列表再把无法规则化处理的文本交给 LLM 解析最后把 LLM 输出结果做一次 schema 校验保证步骤、时间、温度、数量等关键字段合法。存储层负责保存协议、步骤、执行记录和异常信息。对于小团队或 MVP 阶段SQLite 就够用了不需要一上来就引入重型数据库。表结构至少要包含协议表、步骤表、执行记录表和异常记录表。协议表存原文和解析后的版本号步骤表存每一步的操作类型、参数描述和执行顺序执行记录表存每次实验的实际执行时间、操作人和结果异常记录表存操作过程中出现的偏离情况。执行状态机是一个容易被忽略但很重要的模块。它不负责教研究员怎么做实验而是维护步骤的执行进度。每一步至少有四个状态pending、in_progress、done、failed。当系统从“等待 30 分钟”这样的步骤中解析出 duration 字段后可以注册一个提醒任务。如果研究员标记某一步失败系统要允许他跳转到重试逻辑或中止整个流程。交互入口决定用户以什么方式使用这个系统。最简单的是命令行工具适合搭建和调试阶段进阶的可以做成 Web 应用方便团队共享数据再往后可以接入 IM 机器人在消息窗口里接收提醒和上报结果。交互入口的选择取决于团队技术水平和实验场景MVP 阶段用 CLI 或 FastAPI 接口就够了。这四个模块中我认为最关键的不是解析引擎而是执行状态机和数据模型。解析结果再漂亮如果执行记录不能稳定落库、状态不能正确流转系统就只是一个文本处理工具无法成为真正意义上的“副主厨”。在研究“实验室副主厨”架构时把状态机的设计放在和数据模型同等重要的位置是很多 AI 辅助科研工具从 Demo 走向实际使用的分水岭。5. 从零实现一个最小可用的实验助手原型下面我们用 Python 写一个最小可运行的实验室副主厨原型。这个原型不依赖外部大模型 API先用规则解析配合简单的文本处理让流程完整跑通。如果后续要接入 LLM只需要替换解析部分的函数即可。5.1 协议解析模块先定义一个结构化的步骤数据类。这里用 dataclass 定义 LabStep包含步骤序号、操作类型、目标和详情描述。# sous_lab/models.py from dataclasses import dataclass from enum import Enum from typing import Optional class ActionType(str, Enum): MIX mix INCUBATE incubate TRANSFER transfer MEASURE measure COMMENT comment dataclass class LabStep: order: int action: ActionType target: str detail: str duration_minutes: Optional[int] None接下来写解析函数。这个版本使用关键词匹配能够识别“混合、孵育、转移、测量、备注”五类常见操作。对于孵育操作会尝试从文本中提取分钟数。# sous_lab/parser.py import re from .models import ActionType, LabStep KEYWORD_MAP [ (ActionType.MIX, [mix, vortex, stir, 混匀, 振荡]), (ActionType.INCUBATE, [incubate, culture, incub, 孵育, 培养]), (ActionType.TRANSFER, [add, pipette, transfer, 加入, 移至, 添加]), (ActionType.MEASURE, [measure, detect, read, 检测, 测量]), ] def _detect_action(line: str) - ActionType: lowered line.lower() for action, keywords in KEYWORD_MAP: for kw in keywords: if kw.lower() in lowered: return action return ActionType.COMMENT def _extract_duration(line: str) - int | None: # 匹配 30 min / 30分钟 / 2 h 等常见写法 m re.search(r(\d)\s*(?:min|分钟|h|小时), line.lower()) if not m: return None value int(m.group(1)) unit m.group(2) if unit in (h, 小时): value * 60 return value def parse_protocol(text: str) - list[LabStep]: steps [] lines [line.strip() for line in text.strip().splitlines() if line.strip()] for idx, line in enumerate(lines, start1): action _detect_action(line) duration _extract_duration(line) if action ActionType.INCUBATE else None step LabStep( orderidx, actionaction, targetline.split(:)[0] if : in line else line[:30], detailline, duration_minutesduration, ) steps.append(step) return steps这段代码的核心逻辑很简单按行切分文本通过关键词判断操作类型并提取孵育时间。实际项目中协议文本往往没有这么规整所以后续应该接入 LLM 做语义解析。但用这个最小版本跑通流程能够让你在不需要大模型的情况下先把数据结构、存储和执行状态机的链路搭建起来。5.2 用 SQLite 存储协议与步骤解析出的结构化步骤需要持久化。这里使用 SQLite建表语句如下-- sous_lab/schema.sql PRAGMA journal_mode WAL; CREATE TABLE IF NOT EXISTS protocol ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, raw_text TEXT NOT NULL, version TEXT DEFAULT 1.0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS protocol_step ( id INTEGER PRIMARY KEY AUTOINCREMENT, protocol_id INTEGER NOT NULL REFERENCES protocol(id), step_order INTEGER NOT NULL, action TEXT NOT NULL, target TEXT, detail TEXT, duration_minutes INTEGER, status TEXT DEFAULT pending, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS run_record ( id INTEGER PRIMARY KEY AUTOINCREMENT, protocol_id INTEGER NOT NULL, started_at DATETIME DEFAULT CURRENT_TIMESTAMP, finished_at DATETIME, operator TEXT, note TEXT ); CREATE TABLE IF NOT EXISTS step_record ( id INTEGER PRIMARY KEY AUTOINCREMENT, run_id INTEGER NOT NULL REFERENCES run_record(id), step_id INTEGER NOT NULL REFERENCES protocol_step(id), actual_start DATETIME, actual_end DATETIME, status TEXT NOT NULL, note TEXT );保存协议时把 raw_text 存入 protocol 表把每一步解析结果批量写入 protocol_step 表。注意 protocol_step 表中的 status 字段它是执行状态机的基础。默认值为 pending表示该步骤尚未开始。5.3 生成今日检查清单的 CLI 子命令为了验证流程是否可用我们写一个简单的命令行入口从指定协议中生成一份可执行的检查清单。# sous_lab/cli.py import sqlite3 import sys from .parser import parse_protocol def load_protocol(db_path: str, title: str) - int: conn sqlite3.connect(db_path) cur conn.cursor() cur.execute( INSERT INTO protocol (title, raw_text) VALUES (?, ?), (title, sys.stdin.read()), ) protocol_id cur.lastrowid conn.commit() conn.close() return protocol_id def add_steps(db_path: str, protocol_id: int, text: str) - None: conn sqlite3.connect(db_path) cur conn.cursor() steps parse_protocol(text) for step in steps: cur.execute( INSERT INTO protocol_step (protocol_id, step_order, action, target, detail, duration_minutes) VALUES (?, ?, ?, ?, ?, ?) , (protocol_id, step.order, step.action.value, step.target, step.detail, step.duration_minutes), ) conn.commit() conn.close() def show_checklist(db_path: str, protocol_id: int) - None: conn sqlite3.connect(db_path) cur conn.cursor() rows cur.execute( SELECT step_order, action, target, duration_minutes, status FROM protocol_step WHERE protocol_id ? ORDER BY step_order , (protocol_id,), ).fetchall() for order, action, target, duration, status in rows: marker [ ] if status done: marker [x] print(f{marker} {order:02d} {action:10s} {target} ({duration or -})) conn.close() if __name__ __main__: db_path sys.argv[1] proto_id int(sys.argv[2]) show_checklist(db_path, proto_id)这个 CLI 入口做的事情非常朴素读取协议标题和文本调用解析器生成步骤落库再输出一份带勾选框的检查清单。虽然功能很初级但它已经构成了一个最小闭环——从自然语言协议到可执行的步骤清单。后续添加提醒、异常记录和结果上传都是在闭环上做增量。6. 运行结果与效果验证我们先准备一段简单的中文实验文本将 10 μL 样本与 90 μL 反应缓冲液混合。 在 37°C 孵育 30 分钟。 加入 20 μL 终止液。 检测荧光信号。运行流程如下# 初始化数据库 sqlite3 lab.db sous_lab/schema.sql # 保存协议从标准输入读取文本 echo 将 10 μL 样本与 90 μL 反应缓冲液混合。\n在 37°C 孵育 30 分钟。\n加入 20 μL 终止液。\n检测荧光信号。 | python -m sous_lab.cli lab.db 1 # 展示检查清单 python -m sous_lab.cli lab.db 1预期输出为[ ] 01 mix 将 10 μL 样本与 90 μL 反应缓冲液混合。 ( - ) [ ] 02 incubate 在 37°C 孵育 30 分钟。 (30) [ ] 03 transfer 加入 20 μL 终止液。 ( - ) [ ] 04 measure 检测荧光信号。 ( - )验证成功与否看四点第一步骤顺序是否与原文一致第二孵育步骤的 duration 是否被识别为 30第三操作类型分类是否符合直觉第四数据库中的 protocol_step 表是否有四条记录。如果某一步没有正确分类优先检查关键词是否覆盖了文本表达方式。真实场景中用户可能会写“置于 37 度培养箱中 30 分钟”而不是“在 37°C 孵育 30 分钟”。这时候关键词匹配就会失效需要考虑扩展词表或引入 LLM。这也是最小原型与生产系统之间最明显的差异点。7. 常见问题与排查思路问题现象可能原因排查方式解决方案步骤数量变少解析时按空行切分空行过多导致步骤合并打印切分后的 lines 数组调整文本预处理逻辑去除空行但不丢失编号列表孵育时间识别为 None文本写法是“30min”或“半小时”正则未覆盖检查原文本并单元测试 _extract_duration补充正则表达式比如半小时映射为 30操作类型全部变成 comment关键词列表没有覆盖该语言表达抽查识别结果并人工标注错误类型扩充关键词表或接入 LLM 解析数据库表重复创建报错schema.sql 重复执行但缺少 IF NOT EXISTS查看 SQLite 错误信息建表语句加 IF NOT EXISTS或使用 migration 工具CLI 读取协议时内容为空echo 命令把换行符处理掉了检查命令行输入使用 heredoc 或从文件中读取协议文本状态无法流转没有实现状态机更新逻辑查看 step_record 表和代码在 CLI 中增加 step done 命令更新对应记录这些排查思路不仅适用于这个原型也适用于自定义协议时遇到的大部分问题。核心原则是先确认数据转换正确再检查数据库读写最后才去看上层逻辑。8. 工程化建议与安全边界当实验室副主厨系统从原型走向实际使用有几个工程问题需要提前考虑。第一解析结果的校验与人工确认。无论用规则还是 LLM 解析协议解析结果都不能直接作为执行依据。推荐做法是生成解析后的步骤清单后由研究员在界面或 CLI 中确认确认无误后再进入执行阶段。解析结果必须有版本管理协议更新后旧版本的执行记录仍然要保留用于追溯。第二权限与数据隔离。实验室数据高度敏感不同课题组之间通常不允许相互查看实验记录。系统在设计时要考虑多租户隔离至少保证协作者之间的数据不可见。最小实现可以在协议表和执行记录表上增加 owner 字段并通过所有查询强制带 owner 条件。生产环境建议引入正规的权限模型比如 RBAC。第三执行记录不可删除只可追加更正。实验记录属于科研原始数据一旦删除很难追责。设计上应该禁止物理删除采用软删除或状态标记。如果某一次实验步骤标注错误应该新增一条更正记录而不是直接修改原记录。第四LLM 的安全使用边界。如果解析引擎依赖 LLM不要把协议文本直接发送到不可控的外部服务。实验室内部网络环境允许时优先部署本地模型或私有化 API。所有发送给模型的文本都要在系统日志以外做访问控制和审计。如果实验内容涉及未公开研究更应该遵循这一原则。第五提醒机制要可配置且可取消。实验过程中研究员可能因为临时讨论或仪器排队而偏离时间线。系统的提醒不能是“一刀切”的固定时间点而应该允许用户推迟、暂停或取消提醒否则会变成一种新的打扰。第六与现有工具的集成。实验室通常已经有 ELN、LIMS、共享网盘等系统。副主厨系统早期可以选择不依赖这些系统用 SQLite 和本地文件独立运行但如果要长期使用应该预留与 LIMS 或 ELN 的导入导出接口至少支持将结构化步骤导出为 Excel 或 Markdown方便研究员人工粘贴到旧系统中。9. 总结与下一步回到开头的判断Sous.bio 这类“实验室副主厨”工具的想象力不在于替代科学家思考而在于把实验流程中大量碎片化的文本处理和记录工作吸收掉。本文从概念出发分析了协议解析、执行状态、数据沉淀三层能力并给出了一个最小可运行的原型。这个原型虽然简单但已经覆盖了从自然语言文本到结构化步骤清单的完整闭环后续无论是接 LLM 解析、加提醒服务还是做 Web 界面都能在这个骨架上生长出来。如果你正在考虑做类似方向我建议先不要急着上大模型和复杂架构而是用本文的 SQLite CLI 方案跑通两条真实协议样本。你会很快发现真正的坑不在技术而在协议文本的多样性上——有的协议包含条件分支有的引用其他文档有的干脆只有一句话“按之前流程走”。解决这些坑的过程才是这个产品方向真正有价值的部分。下一步值得深入的方向有三个第一解析结果的人工确认与版本管理这是进入实际使用的底线第二执行状态机与提醒机制的完善这决定了它是否配得上“副主厨”的名字第三与现有实验室系统的集成方案这是能否被团队长期采用的关键。实验室自动化的赛道不缺数据缺的是能把数据流动起来的中间层而“副主厨”正好站在这个位置上。