drug-discovery-pipeline について
drug-discovery-pipeline は、GenMol、DiffDock、Boltz2 を順に使って創薬候補をスクリーニングするスキルガイドです。de novo 探索、既知骨格からのリード最適化、バーチャルスクリーニングに対応し、ホステッドとローカル Docker の利用を扱います。
主な機能
- 01GenMol、DiffDock、Boltz2 の連続ワークフロー
- 02de novo 分子生成
- 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詳細
創薬パイプライン
3つの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で実行されていると想定しないでください。各ステップの間にファイルや結果を受け渡しながらコンテナを1つずつ実行するか、各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 対応