🎯核心问题:发酵DoE为什么需要一个agent技能

发酵工艺优化(fermentation DoE)是生物制造中最昂贵、最不可逆的环节之一。一次2L生物反应器批次可能耗时5-7天,耗材成本数千元,而一次错误的实验设计——比如漏掉了关键交互项、在错误的scale上做优化、或者用了一个无法检测的assay——意味着整周产能被浪费。

传统的DoE工具(JMP、Minitab、Design-Expert)解决了统计设计问题,但它们有三个根本性的盲区:

📋 传统DoE工具的三个盲区
盲区 后果
不检查readiness 生成了一个漂亮的CCD设计,但assay还没建立、scale bridge没做、historical ledger是空的——设计在数学上正确,在实验上不可执行
不管理长期状态 第一轮batch的结果散落在Excel和ELN里,第二轮设计时agent无法自动读取prior results、无法做sequential augmentation、无法保留negative-result memory
不与agent harness集成 无法被Claude Code、Codex CLI这类编码代理直接驱动;无法在CI里跑preflight;无法fan-out到并行sub-agent做文献综述和evidence ingestion

BioSymphony Ferm DoE的回答是:把整个发酵DoE生命周期建模成一个agent可读写的durable artifact。这个artifact就是 campaign_manifest.json——一个JSON文件,记录了目标、响应、因子、约束、scale context、决策规则、证据、可行性,以及每一轮batch的状态。任何能读文件、跑shell命令的agent harness都能拾起这个技能,驱动战役从intake走到follow-up。

设计哲学:状态活在一个文件里,不在agent的对话上下文里。这意味着会话可以暂停、恢复、在agent之间交接、在agent和人之间交接。同一个 ferm-doe validate 命令在笔记本上、在CI里、在AWS Lambda后面跑出来的结果完全一致。

🏗️架构全景:一个manifest,九个门控

整个系统的核心循环可以用README里的那张mermaid图概括:

# BioSymphony Ferm DoE 核心循环 Question → Read SKILL.md → campaign_manifest.json → validate --summary ├── RED · blocking → fix failed checks → 回到 manifest ├── YELLOW · proceed → generate-design → analyze → plan-wave2 → finalize └── GREEN · worth running → 同上,但readiness全绿

关键在于:agent不是直接跳到"生成设计"这一步。它必须先通过 validate --summary 这个readiness门控。门控会检查9个独立的gate,每个gate返回一个score和一组issues(blocker或warning):

📋 九个Readiness Gate
Gate 检查内容 失败后果
contract manifest schema完整性、profile声明的required_blocks是否齐全 blocker
data_trust historical_run_ledger的 provenance、QC标记、异常值 blocker/warning
factor 因子定义完整性、范围合理性、mixture因子是否sum-to-1 blocker/warning
response 响应定义、assay method是否声明、检测限/线性范围 blocker/warning
assay assay readiness——响应是否真的可测、方法是否验证 blocker
assay_power 统计功效——给定n和噪声,能否检测到声明效应 warning
feasibility 设备产能、试剂库存、时间窗口是否支持设计规模 blocker/warning
cost_time 预算与周期是否在decision_rules声明的边界内 warning
mode_transfer scale-transfer模式——bridge criteria是否声明、是否qualified blocker/warning

这9个gate的score取平均,结合blocker/warning计数,输出三态:

🚦Readiness门控:RED/YELLOW/GREEN三态决策

readiness评分的核心逻辑在 readiness.pyscore_campaign_readiness 函数里。它不只是一个分数——它是一个决策路由器

if blockers: status = "RED" # 有blocker,禁止继续 elif score >= 0.82 and not warnings: status = "GREEN" # 全绿,值得跑 else: status = "YELLOW" # 有warning,可继续但带限制

三态的语义是严格的:

这个三态系统的价值在于:它把"这个实验设计能不能跑"这个判断从agent的LLM推理里拿出来了,变成了确定性的代码判断。Agent不需要"觉得"一个设计ready了——代码会告诉它。这和ScholarLoop的"LLM只做开放式推理,一切可验证的都由代码执行"是同一个哲学。

📋Profile注册表:9种发酵战役模板

发酵工艺优化不是一个 homogeneous 的问题。screening一个新菌株的active factors、用RSM找一个optimum、优化media blend、做fed-batch的split-plot、从shake flask scale-up到2L、build一个scale-down model、做confirmation runs、sequential augmentation——每一种都是不同的战役,需要不同的required blocks、advised blocks、DoE家族。

BioSymphony用9个profile把这些战役模板化。每个profile在 profiles.pyPROFILE_REGISTRY 里声明:

📋 9个Profile及其约束
Profile required_blocks advised_doe_families
screening 无(permissive) DSD, PB, fractional factorial
optimization_rsm responses, factors CCD, Box-Behnken, optimal I
mixture factors(至少一个mixture类型) Scheffé, extreme-vertices
split_plot_fed_batch responses, factors(需hard-to-change因子) split-plot
scale_up_bridge scale_context(direction=scale_up) DSD, CCD, Box-Behnken
scale_down_qualification scale_context + recapitulation_criterion full factorial, DSD
confirmation custom constrained, full factorial
sequential_augmentation doe(需previous_wave_ref) sequential augmentation, optimal D/I
custom 用户自定义 用户自定义

关键设计:required_blocks 缺失会触发blocker(RED),advised_blocks 缺失只触发warning(YELLOW)。这意味着profile是composable的——一个scale_up_bridge战役可以同时advised arms(多臂结构)和risk_register,但即使你没有arms,它也不会RED,只会YELLOW提醒你"建议加arms做reference+target对照"。

一个特别值得注意的profile是 split_plot_fed_batch。Fed-batch发酵有hard-to-change setpoints(whole-plot,比如温度设定值,改一次要等整个batch)和easy-to-change media(sub-plot,每次run可以换)。传统DoE工具经常错误地用fully randomized design处理fed-batch,导致伪自由度和错误的F检验。BioSymphony在profile层面就要求 factor_hard_to_change_required: True,从源头防止这个统计错误。

🧬DoE家族选择器:14种设计家族与最小运行数

选对DoE家族是发酵DoE的核心决策。BioSymphony在 doe_families.pyFAMILY_REGISTRY 里维护了14种家族,每种都带minimum-runs guidance、是否支持quadratic curvature、是否支持two-factor interactions、typical use case:

📋 14个DoE家族的关键属性
家族 min_runs quadratic 2FI 典型用途
definitive_screening2k+1partial≤10因子筛选,怀疑曲率
plackett_burmannext_mult_4(k+1)极低资源主效应筛选
fractional_factorial2^(k-p)depends(res)4-8因子筛选到优化过渡
full_factorial∏levelsdepends≤4因子或categorical-heavy
central_composite2^k+2k+n_c筛选后RSM优化
box_behnken2k(k-1)+n_c角点不可行时的RSM
optimal_d / optimal_imodel_terms+n_cmodel-depmodel-dep非标准约束下的计算机生成设计
scheffe_mixturemedia/feed blend优化
extreme_vertices_mixture带约束的mixture
split_plotfed-batch hard/easy-to-change
sequential_augmentation基于prior wave结果增补
custom_constrained用户自定义约束

这个taxonomy的价值不只是参考——它会驱动warning。如果一个campaign声明了 optimization_rsm profile但选了 plackett_burman(不支持quadratic),validator会发出warning:"RSM优化建议CCD或Box-Behnken,PB无法拟合曲率"。同样,如果设计的run数低于家族的 min_runs_formula,会触发minimum-runs shortfall warning。

这里有一个重要的诚实声明:doe_families.py 的docstring写的是 "Conservative; deeper analysis is a statistician's job." BioSymphony不替代统计学家——它提供一个保守的、不会犯低级错误的起点,把需要专业判断的留给人类。

🔌适配器路由:47工具注册表与优雅降级

BioSymphony最工程化的部分是它的适配器层。发酵DoE的backend landscape极其碎片化:BoFire(BASF的Bayesian optimization框架)、BoTorch(Meta的Gaussian process + acquisition)、ENTMOOT(树模型优化)、OMLT(可微分ML优化)、TabPFN(表格foundation model)、pyDOE3(经典设计)、SALib(敏感性分析)、scipy(统计检验)……没有一个工具能cover所有场景。

BioSymphony的解决方案是 docs/TOOL_REGISTRY.mddocs/tool-registry.json——一个curated的47工具注册表,每个工具标注claim level和route reason。运行时,adaptive_backend_surface 让BoFire、BayBE、Ax/BoTorch、ENTMOOT、OMLT、TabPFN在同一套design preflight checks后面竞争。

关键设计模式是优雅降级。以BoFire适配器为例:

def is_available() -> bool: return importlib.util.find_spec("bofire") is not None

每个适配器都用 importlib.util.find_spec 检查可选依赖是否存在。如果BoFire没装,is_available() 返回False,系统回退到deterministic local planning(stdlib DoE),并在routing decision里标注"bofire not installed, fell back to stdlib"。这意味着:

路由决策本身是有逻辑的。BoFire适配器的 routing_decision 检查四个route reason:

BOFIRE_ROUTE_REASONS = ( "non_box_constraints", # 非箱型约束 "multi_objective_responses", # 多目标响应 "scale_fidelity_structure", # scale fidelity结构 "operator_requested_bofire", # 操作员显式请求 )

只有当campaign确实有non-box constraints、多目标响应、或scale fidelity结构时,系统才会建议路由到BoFire。否则stdlib DoE就够了——不需要为了一个简单的screening design拖入整个Bayesian optimization栈。

一个特别值得注意的已知陷阱记录在AGENTS.md里:当BoFire的 SoboStrategy 配合 NChooseK 约束时,上游issue #450会无限stall。BioSymphony的应对是路由到ENTMOOT v2或enforce cardinality post-hoc——这是一个被代码固化下来的运维知识,而不是留给agent去"发现"的坑。

⚖️Scale-bridge:kLa、P/V、tip-speed的资格认证

发酵工艺最危险的错误之一是在错误的scale上做优化。shake flask里的最优条件到了2L可能完全失效——因为kLa(体积氧传质系数)、P/V(单位体积功率)、tip speed(叶尖速度)、mixing time、OUR(氧摄取速率)、RQ(呼吸商)、VVM(每分钟通气体积比)这些工程参数随scale非线性变化。

BioSymphony的 scale_context block和 bridge.py 模块解决这个问题。一个scale-bridge战役需要声明:

compute_bridge_qualification 函数会在 to_arm(目标scale)生成qualification design:把criterion target固定在engineering recipe值,emit center-point replicates(和可选的factor perturbations),让操作员对比recapitulation是否达成。

关键在于claim level的诚实bridge.pyCLAIM_LEVEL = "bridge_qualification_planning"NON_CLAIM 明确声明:

"Bridge qualification is a planned design at the target scale. It does not establish that the small or large scale recapitulates the other until executed runs satisfy the manifest's recapitulation_criterion with provenance."

也就是说:BioSymphony可以规划一个scale-bridge的qualification design,但它不会声称bridge已经qualified——除非你真的跑了那些runs,结果满足manifest里声明的recapitulation criterion,并且带着provenance被ingest回来。这是一个planning→qualification→evidence的三阶段诚实链。

工程数学本身委托给 scale_recipe.compute_scale_recipe,保证 ferm-doe scale-recipe 子命令和bridge qualification用的是同一套criterion-matched setpoint推导。这避免了"CLI算一遍、bridge算一遍、结果不一致"的bug。

💰成本诚实栈:五个数字,不许只报一个

生物制造的cost modeling是一个充满自我欺骗的领域。一个常见的失败模式是:有人报一个"simulator number"(理论最优条件下的yield × 理论单价),然后假装这就是COGS。BioSymphony用 docs/COST_MODEL_REALISM_CHECK.mdtemplates/cost_stack.template.md 强制一个五层数字栈

📋 成本诚实栈的五个数字
层级 含义 为什么单独不够
Simulator number 理论最优条件下的yield × 理论单价 假设100%收率、无批次变异、无下游损失
Bulk reagent number 大宗试剂成本(培养基、补料、前体) 不含人工、设备折旧、耗材
Fully-loaded shake-flask COGS 含人工、耗材、设备分摊的完整shake-flask成本 shake-flask ≠ 生产scale,不能外推
CMO benchmark 合同制造组织报价基准 反映市场价但可能含/不含不同scope
Stated range 显式声明的不确定区间 承认成本本身有分布,不是点估计

这个设计的核心信念是:一个数字说不了真话,五个数字才能三角验证。如果simulator number和CMO benchmark差10倍,那中间一定有一个假设是错的——而BioSymphony要求你把五个数字都摆出来,让矛盾可见。

🐝Scientific Swarm与cumulative dossier

对于复杂的campaign,BioSymphony支持 Scientific Swarm 模式——一个per-corpus的swarm plus integrator plus harvester的cumulative dossier pattern。这不是ad-hoc的并行dispatch,而是一个有结构的证据累积工作流。

Swarm模式的核心是 swarm.py 维护的一组dossier文件:

SWARM_DOSSIER_FILES = [ "evidence_swarm_plan.json", # swarm计划 "evidence_table_template.csv", # 证据表模板 "evidence_rows.normalized.csv", # 归一化证据行 "evidence_ingestion_report.json",# ingestion报告 "factor_universe.json", # 因子宇宙 "assumption_attack_report.json", # 假设攻击报告 "observability_plan.json", # 可观测性计划 "control_run_strategy.json", # 对照策略 "symphony_agent_graph.json", # agent图 "swarm_adjudication_brief.md", # 裁决简报 ]

Evidence table的schema是结构化的——每一行证据带 lane_idsource_typesource_refsource_trustlicenseextraction_methodagent_idreview_statusclaim_typeentity_typeclaimfactor_or_responsesuggested_actionsuggested_rolephaseeffect_directionseverity……这意味着每一条证据都是可溯源的——你知道它从哪来、谁提取的、review状态如何、建议什么action。

关键设计原则在AGENTS.md里写得很清楚:One coherent dossier per campaignCITATIONS.jsonNOTES.mdSOURCES.bib、per-corpus EVIDENCE.csv),不是N个isolated reports。Bounded workers(并行sub-agent、swarm corpora、integrator和harvester角色)通过 task_request contract协调,不是ad-hoc dispatch。

这个pattern的价值在于negative-result memory。传统DoE工具的第一轮结果和第二轮设计之间是断裂的——第二轮的agent不知道第一轮哪些因子被证明无效。BioSymphony的cumulative dossier让每一轮的evidence、assumption attack、observability plan都持久化,下一轮的agent可以直接读取,避免重复验证已知无效的因子。

🏆设计锦标赛:多候选方案的裁决

当readiness通过后,BioSymphony不是直接生成一个设计——它运行一个 design tournamenttournament.py)。run_design_tournament 会:

  1. 调用 propose_candidate_designs 生成多个候选设计(不同DoE家族、不同run budget)
  2. 对每个候选调用 score_candidate 评分
  3. 如果Scientific Swarm启用,先 ensure_swarm_review 把swarm的evidence-backed factor roles、assumption safety、observability、control strategy纳入评分
  4. 如果campaign arms启用,走per-arm tournament(每个arm独立裁决)
  5. 在accepted候选里选 total_score 最高的作为selected design

裁决策略(adjudication_policy)是显式声明的,有四条规则:

📋 设计锦标赛裁决策略
  1. 不把skeptical audit lane选为executable design——audit lane是用来挑刺的,不是用来跑的
  2. readiness为RED时拒绝所有executable designs——硬约束,不可覆盖
  3. 优先feasible、assay-ready、mode-aware的设计,而非纯统计score——一个统计score最高但assay没ready的设计不该被选
  4. Scientific Swarm启用时,优先align with evidence-backed factor roles、assumption safety、observability、control strategy的设计

这个设计的深层逻辑是:统计最优 ≠ 实验最优。一个D-optimal设计可能在数学上最优,但如果它要求的run数超出了试剂库存,或者它的某个因子组合在prior evidence里已被证明无效,那它就不该被选。Tournament把这个多维度tradeoff显式化,而不是留给agent去"感觉"。

🛡️声明边界:它不声称什么

BioSymphony最值得尊敬的设计是它的 NON_CLAIMS.md 和贯穿全代码库的claim level标注。在一个充斥着"AI优化发酵工艺""智能实验设计"这类营销话术的领域,BioSymphony明确声明它不做什么

Claim Boundaries:本仓库在lab work之前验证measurement readiness、manifest结构、profile fit。它不验证实际lab测量,除非result rows带着provenance和QC evidence被ingest进来。

不声称optimized、validated、production-ready、或GxP-ready行为。

每一个适配器都带 CLAIM_LEVELNON_CLAIM 常量。BoFire适配器声明 CLAIM_LEVEL = "bofire_adapter_planning",并明确:"BoFire-backed candidates are planned model-based suggestions. They do not validate assay readiness, scale transfer, or physical execution." Bridge模块声明 CLAIM_LEVEL = "bridge_qualification_planning"。这些claim level会写进run packet——操作员和reviewer看到的不是"优化设计",而是"planning support, claim level: X"。

这不仅是法律意义上的cover-your-ass。这是一个认识论设计:系统在每一个输出上都标注自己的认知边界,防止下游(agent或人)把planning support误读为validated result。在一个"AI说它优化了"就可能被当成真优化的时代,这种自我标注是稀缺的工程美德。

另一个关键边界是public safety。AGENTS.md列出了一系列"Do not add":private strain details、unpublished sequences、customer batch records、confidential media formulations、API keys、private workstation paths、private issue-tracker IDs、raw private campaign artifacts。所有public demo都是synthetic或public-source的,并显式标注"synthetic"。这意味着这个仓库可以被审计、被fork、被CI测试,而不会泄露任何真实campaign的敏感信息。

💡对生物制造AI化的启示

BioSymphony Ferm DoE代表了一种我认为被低估的AI-for-science范式:不是用LLM替代领域专家,而是用LLM驱动一个领域专家设计的确定性harness。它的价值不在"AI更聪明",而在:

对比那些"用一个LLM agent跑整个发酵优化"的demo项目,BioSymphony的路径更慢、更重、更不性感——但它更接近真实生物制造R&D的工作方式。真实的发酵DoE不是一个prompt-to-design的魔法,而是一个intake→readiness→design→execute→analyze→follow-up的长期循环,中间有无数的门控、交接、negative result、scale transfer陷阱。BioSymphony把这些都建模了,而不是假装它们不存在。

对于想用AI做生物制造工艺开发的团队,BioSymphony提供了一个可借鉴的架构蓝图:把领域知识固化成profile registry和DoE family taxonomy,把工程约束固化成readiness gate,把工具碎片化解决成adapter registry with graceful degradation,把长期状态固化成durable manifest,把认知边界固化成claim level标注。这套架构不依赖任何特定LLM——任何能读写文件、跑shell的agent harness都能驱动它。

一句话总结:BioSymphony Ferm DoE不是"用AI做发酵DoE"——它是"给发酵DoE的领域知识套上一个agent可驱动的确定性harness"。状态活在一个文件里,readiness由代码判定,claim level自我标注,工具栈优雅降级。这是2026年生物制造AI化应该有的样子:不是更聪明的LLM,而是更诚实的工程边界。

📄项目信息

📋 BioSymphony Ferm DoE

仓库:BioSymphony/ferm-doe(MIT License,pre-alpha)

语言:Python 3.10+,运行时stdlib-only,可选extra路由到BoFire/BoTorch/ENTMOOT等

测试:455 tests pass,38 expected skips(可选依赖未装时的优雅降级)

部署:AWS Lambda和Modal scaffold,同一命令跑在笔记本/CI/云endpoint

Agent harness兼容:Symphony with Linear、Claude Code with Linear、Codex CLI、OpenAI Agents SDK、自定义orchestrator

核心artifact:campaign_manifest.json(durable state,pause/resume/handoff)

Profile数:9(screening、optimization_rsm、mixture、split_plot_fed_batch、scale_up_bridge、scale_down_qualification、confirmation、sequential_augmentation、custom)

DoE家族数:14

工具注册表:47个BO/DoE和sidecar工具

Public demo数:12个campaign-shaped demo + adaptive-backend-eval + starter-studies

注:本文基于BioSymphony Ferm DoE仓库的公开代码、README、AGENTS.md、SKILL.md和源码分析撰写。所有引用的代码片段和设计声明均锚定于仓库实际文件。仓库状态为pre-alpha,public demo均为synthetic planning fixture,不构成lab-validation或production-readiness声明。