AiZynthFinder 是阿斯利康开源的逆合成规划工具,用蒙特卡洛树搜索配合神经网络策略进行路线搜索。它是目前最容易上手、最适合集成进自有流程的开源逆合成工具。
安装与配置
pip install aizynthfinder
# 下载公开数据(模型 + 模板 + 库存)
download_public_data .
# 会生成 config.yml 与相关文件
# config.yml 结构
expansion:
uspto:
- uspto_model.onnx # 单步逆合成模型
- uspto_templates.csv.gz # 反应模板库
filter:
uspto:
- uspto_filter_model.onnx # 正向反应可行性过滤
stock:
zinc:
- zinc_stock.hdf5 # 可购买化合物库
properties:
time_limit: 120 # 秒
iteration_limit: 100
max_transforms: 6 # 最大步数
cutoff_number: 50 # 每步保留的候选数
cutoff_cumprob: 0.995
命令行使用
# 单个分子
aizynthcli --config config.yml \
--smiles "Cc1ccc(cc1)S(=O)(=O)Nc1ccc(cc1)C(=O)O" \
--output result.json.gz
# 批量(SMILES 文件,每行一个)
aizynthcli --config config.yml \
--smiles targets.txt \
--output results.json.gz \
--nproc 8
Python API
from aizynthfinder.aizynthfinder import AiZynthFinder
finder = AiZynthFinder(configfile="config.yml")
finder.stock.select("zinc")
finder.expansion_policy.select("uspto")
finder.filter_policy.select("uspto")
finder.target_smiles = "Cc1ccc(cc1)S(=O)(=O)Nc1ccc(cc1)C(=O)O"
finder.tree_search()
finder.build_routes()
stats = finder.extract_statistics()
print(f"是否找到完整路线: {stats['is_solved']}")
print(f"最短路线步数: {stats['number_of_steps']}")
print(f"前体数量: {stats['number_of_precursors']}")
print(f"搜索用时: {stats['search_time']:.1f} s")
# 查看路线
for i, route in enumerate(finder.routes[:3]):
print(f"\n=== 路线 {i} (得分 {route['score']:.3f}) ===")
# route['reaction_tree'] 是路线的树结构
# route['image'] 可直接显示路线图(Jupyter 中)
批量筛选可合成性
from aizynthfinder.aizynthfinder import AiZynthFinder
import pandas as pd
def batch_synthesizability(smiles_list, config="config.yml",
time_limit=30):
finder = AiZynthFinder(configfile=config)
finder.stock.select("zinc")
finder.expansion_policy.select("uspto")
finder.filter_policy.select("uspto")
finder.config.search.time_limit = time_limit
results = []
for smi in smiles_list:
try:
finder.target_smiles = smi
finder.tree_search()
finder.build_routes()
s = finder.extract_statistics()
results.append({
"smiles": smi,
"solved": s["is_solved"],
"n_steps": s.get("number_of_steps"),
"top_score": finder.routes[0]["score"] if finder.routes else None,
})
except Exception as e:
results.append({"smiles": smi, "solved": False,
"error": str(e)})
return pd.DataFrame(results)
# 用于生成模型产出的过滤
df = batch_synthesizability(generated_smiles, time_limit=30)
print(f"可解比例: {df['solved'].mean():.1%}")
print(f"可解分子的平均步数: {df[df['solved']]['n_steps'].mean():.1f}")
# 关键:把 solved 与 n_steps 作为分子设计的筛选维度
# 比单纯的 SA Score(见 348)更贴近真实合成可行性
自定义库存:让结果贴合实际
这是最值得做的定制:默认的 ZINC 库存与你实际能采购或库存的化合物不同。用自家的砌块清单,得到的路线才真正可执行。
from aizynthfinder.context.stock import InMemoryInchiKeyQuery
from rdkit import Chem
# 方法一:从 SMILES 文件建库存
def build_custom_stock(smiles_file, output_hdf5):
import pandas as pd
smiles = [line.strip() for line in open(smiles_file) if line.strip()]
inchi_keys = []
for smi in smiles:
m = Chem.MolFromSmiles(smi)
if m:
inchi_keys.append(Chem.MolToInchiKey(m))
df = pd.DataFrame({"inchi_key": inchi_keys})
df.to_hdf(output_hdf5, key="table", mode="w")
build_custom_stock("our_building_blocks.smi", "custom_stock.hdf5")
# 方法二:在 config.yml 中注册
# stock:
# inhouse:
# - custom_stock.hdf5
# zinc:
# - zinc_stock.hdf5
# 使用时可同时选多个库存
finder.stock.select(["inhouse", "zinc"])
# 也可以设置库存的优先级或价格信息,
# 让搜索优先使用便宜/现货的原料
结果解析与可视化
import json, gzip
# 从输出文件读取
with gzip.open("results.json.gz") as f:
data = json.load(f)
for entry in data["data"]:
print(entry["target"], entry["is_solved"], entry["number_of_steps"])
# Jupyter 中可视化路线
from aizynthfinder.interfaces import AiZynthApp
app = AiZynthApp("config.yml") # 交互式界面
# 或直接显示路线图
from IPython.display import display
display(finder.routes[0]["image"])
调参建议
| 参数 | 影响 | 建议 |
|---|---|---|
time_limit |
搜索时长 | 批量筛选 15~30 s;重点分子 120 s+ |
max_transforms |
最大步数 | 默认 6;复杂分子可加大但会变慢 |
cutoff_number |
每步保留候选数 | 50 常用;加大提高覆盖但更慢 |
| filter policy | 正向可行性过滤 | 建议开启,能剔除不合理的切断 |
| stock | 可购买库 | 用自家库存最有价值 |
局限与注意
- 「找不到路线」不等于「不能合成」:可能只是模板库覆盖不到,或搜索时间不够。这是最容易被误读的输出。
- 「找到路线」也不等于「路线可行」:模型没见过失败反应,可能给出行不通的方案。必须由合成化学家评审。
- USPTO 模板库有偏:来自专利反应,某些反应类型过度代表。
- 不处理立体化学的选择性:手性构建的可行性需要人工判断。
- 不给出反应条件:需要配合条件预测(见 389《反应条件与产率预测》)或人的经验。
常见坑与提示
- 用自家砌块库存替换默认 ZINC,是最值得做的定制;
- 建议开启 filter policy,能剔除化学上不合理的切断;
- 「找不到路线」可能只是模板覆盖不足,不等于不能合成;
- 批量筛选用短 time_limit,重点分子单独跑长时间。
延伸资源
- 概念:384《逆合成分析入门》;对照工具:386《ASKCOS》、387《IBM RXN for Chemistry》;
- 合成可及性:390《合成可及性再讨论》、348《在分子生成中加入 SA Score 约束》;反应数据:399《反应数据库》。