逆合成给出「用什么反应」,但「具体怎么做」——催化剂、配体、碱、溶剂、温度、时间——才决定反应成败。条件预测试图填补这一环,但它是合成 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 数据上则可行;
- 贝叶斯优化 + 少量标准化实验,是条件优化最实际的路径。
延伸资源
- 平台:386《ASKCOS》;反应预测:388《反应产物预测》;
- 自动化实验:391《自驱动实验室 Self-Driving Lab》;工艺优化:397《工艺路线优化》。