关于 drug-discovery-pipeline
drug-discovery-pipeline 是依次使用 GenMol、DiffDock 和 Boltz2 筛选候选药物的技能指南。它涵盖从头发现、基于骨架的先导优化和虚拟筛选,并说明托管及本地 Docker 模式。
主要功能
- 01GenMol、DiffDock 和 Boltz2 顺序工作流
- 02从头生成分子
- 03基于骨架生成类似物
- 04分子对接与亲和力预测
- 05托管及本地 Docker 模式指南
适用场景
- 01针对目标蛋白寻找初始命中分子
- 02从已知骨架生成类似物
- 03筛选候选分子库
- 04结合对接和亲和力结果排序候选物
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ nvidia-bionemo/ bionemo-agent-toolkit --skill drug-discovery-pipeline安装后在 Claude Code 中输入/drug-discovery-pipeline确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
BENCHMARK.mdskill-card.mdskill.oms.sigevals/config.ymlevals.jsonevals/files/egfr.pdb详细介绍
药物发现流程
依次使用三个 BioNeMo NIM,端到端筛选候选药物:
Step 1: GenMol → Step 2: DiffDock → Step 3: Boltz2
(Generate mols) (Dock to target) (Predict affinity)
概述
此流程适用于:
- 从头发现命中化合物:生成类药分子,并针对目标进行筛选
- 先导优化:从已知骨架出发,生成改良类似物,然后进行对接和评分
- 虚拟筛选:对候选分子库进行对接,并根据对接置信度和亲和力进行筛选
开始之前
请与用户确认:
- 目标蛋白质:结合靶标的 PDB 文件或序列
- 起点:从头生成(无骨架)还是骨架修饰(已知核心)?
- 评分方式:类药性(QED)还是亲脂性(LogP)?
- API 模式:托管模式还是本地 Docker?
对于本地 Docker,不要假设所有 NIM 都同时运行在 localhost:8000 上。可以一次运行一个容器,并在各步骤之间传递文件和结果;也可以在不同的主机端口上启动各个 NIM,并设置每个步骤对应的 URL。
步骤 1:使用 GenMol 生成分子
GenMol 需要 SAFE 表示法输入(不是原始 SMILES)。请使用 safe-mol 软件包。
import requests, json, os
import safe as sf # pip install safe-mol
from pathlib import Path
NGC_API_KEY = os.getenv("NGC_API_KEY")
HOSTED = True
if HOSTED:
genmol_url = "https://health.api.nvidia.com/v1/biology/nvidia/genmol/generate"
headers = {"Content-Type": "application/json",
"Authorization": f"Bearer {NGC_API_KEY}"}
else:
genmol_url = "http://localhost:8000/generate"
headers = {"Content-Type": "application/json"}
# De novo generation (no scaffold):
safe_input = "[*{20-30}]"
# Scaffold decoration (known core):
# scaffold_smiles = "c1ccccc1"
# safe_input = sf.encode(scaffold_smiles) + ".[*{5-10}]"
payload = {
"smiles": safe_input, # field is named 'smiles' but takes SAFE notation
"num_molecules": 30, # request more to compensate for post-generation filtering
"scoring": "QED", # QED or LogP
"unique": True,
"temperature": "1.0", # NOTE: must be string, not float
"noise": "1.0", # NOTE: must be string, not float
}
r = requests.post(genmol_url, headers=headers, json=payload)
r.raise_for_status()
molecules = r.json()["molecules"]
molecules_sorted = sorted(molecules, key=lambda x: x["score"], reverse=True)
top_20 = molecules_sorted[:20]
print(f"Generated {len(molecules)} valid molecules (requested 30)")
print("Top 5 by QED score:")
for m in top_20[:5]:
print(f" {m['smiles'][:50]} score={m['score']:.4f}")
步骤 2:使用 DiffDock 对接分子
准备蛋白质,并对每个候选分子进行对接:
# Load protein (ATOM records only)
receptor_pdb_raw = Path("target.pdb").read_text()
receptor_pdb = "\n".join(line for line in receptor_pdb_raw.splitlines()
if line.startswith("ATOM"))
if HOSTED:
diffdock_url = "https://health.api.nvidia.com/v1/biology/mit/diffdock"
else:
diffdock_url = "http://localhost:8000/molecular-docking/diffdock/generate"
docking_results = []
for i, mol in enumerate(top_20):
payload = {
"protein": receptor_pdb,
"ligand": mol["smiles"],
"ligand_file_type": "txt", # "txt" for SMILES input
"num_poses": 5,
"time_divisions": 20,
"steps": 18,
"save_trajectory": False,
}
r = requests.post(diffdock_url, headers=headers, json=payload)
r.raise_for_status()
result = r.json()
best_conf = result["position_confidence"][0] # rank 1 pose
best_pose = result["ligand_positions"][0]
docking_results.append({
"smiles": mol["smiles"],
"qed_score": mol["score"],
"docking_confidence": best_conf,
"best_pose_sdf": best_pose,
})
print(f" Mol {i+1:2d}: QED={mol['score']:.3f} docking_conf={best_conf:.4f}")
# Rank by docking confidence
docking_results.sort(key=lambda x: x["docking_confidence"], reverse=True)
print(f"\nTop 3 by docking confidence:")
for d in docking_results[:3]:
print(f" {d['smiles'][:50]} conf={d['docking_confidence']:.4f}")
步骤 3:使用 Boltz2 预测结合亲和力
针对对接结果排名靠前的候选分子,预测基于结构的结合亲和力:
if HOSTED:
boltz_url = "https://health.api.nvidia.com/v1/biology/mit/boltz2/predict"
else:
boltz_url = "http://localhost:8000/biology/mit/boltz2/predict"
# Use the target protein sequence (not PDB)
target_sequence = "<YOUR_TARGET_PROTEIN_SEQUENCE>"
affinity_results = []
for d in docking_results[:5]: # score top 5 docking hits
payload = {
"polymers": [
{"id": "A", "molecule_type": "protein", "sequence": target_sequence}
],
"ligands": [
{"id": "L1", "smiles": d["smiles"], "predict_affinity": True}
],
"recycling_steps": 3,
"sampling_steps": 50,
"diffusion_samples": 1,
"output_format": "mmcif",
}
r = requests.post(boltz_url, headers=headers, json=payload)
r.raise_for_status()
result = r.json()
aff = result["affinities"]["L1"]
pic50 = aff["affinity_pic50"][0]
prob_binding = aff["affinity_probability_binary"][0]
affinity_results.append({
**d,
"pic50": pic50,
"probability_binding": prob_binding,
})
print(f" {d['smiles'][:40]} pIC50={pic50:.2f} P(bind)={prob_binding:.3f}")
# Final ranking by pIC50
affinity_results.sort(key=lambda x: x["pic50"], reverse=True)
结果解读
- GenMol QED 分数:0–1;>0.5 表示具有类药性
- DiffDock 置信度:越高,结合姿势预测越可靠
- Boltz2 pIC50:预测的 -log10(IC50);>6 表示亚微摩尔级,>8 表示效力很强
- P(bind):二元结合的概率;>0.7 表示很可能结合
快速参考 — 技能依赖项
| 步骤 | 技能 | 关键端点 |
|---|---|---|
| 分子生成 | genmol-nim | /biology/nvidia/genmol/generate |
| 对接 | diffdock-nim | /molecular-docking/diffdock/generate |
| 亲和力预测 | boltz2-nim | /biology/mit/boltz2/predict |
评论
支持 Markdown