389

反应条件与产率预测:让路线更可行

反应条件与产率预测让合成路线更可执行。这篇讲清建模难点、数据问题与实际可期待的能力。

逆合成给出「用什么反应」,但「具体怎么做」——催化剂、配体、碱、溶剂、温度、时间——才决定反应成败。条件预测试图填补这一环,但它是合成 AI 中最困难的部分之一。

为什么条件预测这么难

困难 说明
条件空间巨大 催化剂 × 配体 × 碱 × 溶剂 × 温度 × 浓度 = 组合爆炸
数据记录不完整 专利与文献常省略细节(加料顺序、浓度、后处理)
只有成功案例 失败的条件不会被记录,模型学不到「什么不行」
条件相互耦合 换溶剂可能要求换碱,不能独立预测
底物特异性强 同一反应类型,不同底物的最优条件可能完全不同
「标准条件」偏倚 文献中大量使用作者习惯的条件,不代表最优

「只有成功案例」是最根本的问题:一篇论文报告「用 Pd(OAc)₂/XPhos/K₂CO₃/甲苯/100℃ 得到 85% 产率」,但不会告诉你作者先试了五种其它条件都失败了。模型因此学到的是「什么条件常被使用」,而非「什么条件最优」。

建模方式

# 通常分解成多个子任务
#
# 1) 催化剂/试剂选择 → 多分类
# 2) 溶剂选择         → 多分类
# 3) 温度             → 回归
# 4) 时间             → 回归
#
# 输入特征:
#   - 反应物与产物的分子表示(指纹/图)
#   - 反应类型(模板或反应指纹)
#   - 官能团存在情况
#
# 挑战:这些子任务相互依赖,独立预测会给出不自洽的组合
#      (如推荐了一个在该溶剂中不溶的碱)

用 ASKCOS 做条件推荐

import requests

r = requests.post("http://localhost/api/v2/context/", json={
    "reactants": "c1ccc(Br)cc1.OB(O)c1ccccc1",
    "products": "c1ccc(-c2ccccc2)cc1",
    "num_results": 10,
})

for i, ctx in enumerate(r.json()["output"], 1):
    print(f"{i}. 温度 {ctx['temperature']:.0f}°C")
    print(f"   溶剂:   {ctx['solvent']}")
    print(f"   试剂:   {ctx['reagent']}")
    print(f"   催化剂: {ctx['catalyst']}")
    print(f"   评分:   {ctx['score']:.3f}")

# 输出的是「统计上常见的条件组合」
# 对熟悉的反应类型(如 Suzuki)通常合理,
# 但不是针对该具体底物优化的条件

产率预测:期望要放低

  • 公开数据的产率预测精度普遍不高:在 USPTO 等数据集上,模型的 R² 常常很低,实用价值有限。
  • 原因:产率受太多未记录因素影响——原料纯度、搅拌效率、后处理方式、操作者技能、规模;且文献产率本身有报告偏倚(倾向报告最好的一次)。
  • 例外情况在单一反应类型 + 高通量实验(HTE)数据上,产率预测可以做得不错。因为条件被系统性地变化、数据标准化、且包含低产率的失败案例。
  • 启示:产率预测要有用,必须基于自己产生的、标准化的、包含失败案例的数据。

更有效的路径:高通量实验 + 主动学习

# 与其依赖公开数据训练通用模型,
# 不如针对具体反应做 HTE + 主动学习优化

import numpy as np
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import Matern, WhiteKernel

# 1) 定义条件空间
conditions = {
    "catalyst": ["Pd(OAc)2", "Pd2(dba)3", "PdCl2(dppf)", "XPhos-Pd-G3"],
    "ligand":   ["XPhos", "SPhos", "RuPhos", "BrettPhos", "none"],
    "base":     ["K2CO3", "Cs2CO3", "K3PO4", "KOtBu", "NaOtBu"],
    "solvent":  ["toluene", "dioxane", "THF", "DMF", "tAmOH"],
    "temp":     [60, 80, 100, 120],
}
# 组合数 = 4 × 5 × 5 × 5 × 4 = 2000

# 2) 初始实验:设计一个覆盖性好的小集合(如 24~96 个)
#    用拉丁超立方或 D-最优设计

# 3) 用高斯过程建模,贝叶斯优化选下一批
def select_next_batch(X_tested, y_tested, X_candidates, batch_size=24):
    kernel = Matern(nu=2.5) + WhiteKernel()
    gp = GaussianProcessRegressor(kernel=kernel, normalize_y=True)
    gp.fit(X_tested, y_tested)

    mu, sigma = gp.predict(X_candidates, return_std=True)
    # 期望改进(EI)或上置信界(UCB)
    ucb = mu + 2.0 * sigma
    return np.argsort(ucb)[-batch_size:]

# 4) 迭代 2~4 轮,通常能找到接近最优的条件
#    比全因子筛选(2000 个实验)省几十倍工作量

# 关键:这个方法有效,因为:
#   - 数据是自己产生的,条件标准化
#   - 包含失败案例(低产率也是信息)
#   - 针对具体底物,不需要跨底物泛化

这是条件优化最实际的路径:不指望通用模型给出最优条件,而是用少量标准化实验 + 贝叶斯优化针对具体反应寻优。

合理的期望

任务 可行性
给出「典型条件」作为起点 可行且有用
缩小条件筛选范围 可行
预测具体底物的最优条件 目前不现实
公开数据上的精确产率预测 不现实
HTE 数据上的单反应类型产率预测 可行
贝叶斯优化找最优条件 可行且高效

关键要点

  • 条件预测的根本困难是文献只记录成功案例、细节不完整
  • 模型给的是「统计上常见的条件」,不是针对该底物的最优条件;
  • 公开数据上的产率预测精度普遍不高,HTE 数据上则可行
  • 贝叶斯优化 + 少量标准化实验,是条件优化最实际的路径

延伸资源