mcpField
A
adaptyv-bio

adaptyv-bio

github.com/jaechang-hits其他38468 次安装6 天前更新
代码仓库

关于 adaptyv-bio

adaptyv-bio 是面向蛋白质工程人员的技能,可通过 REST API 和 Python SDK 提交序列进行无细胞表达与结合表征。它支持实验提交、状态跟踪及亲和力结果获取,适用于迭代筛选流程。

主要功能

  1. 01提交蛋白质序列进行实验
  2. 02批量提交序列
  3. 03跟踪实验状态
  4. 04获取结合亲和力结果
  5. 05列出并筛选实验历史

适用场景

  1. 01通过结合测定验证设计变体
  2. 02开展机器学习引导的定向进化
  3. 03筛选纳米抗体或抗体
  4. 04将实验亲和力数据用于序列优化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill adaptyv-bio

安装后在 Claude Code 中输入/adaptyv-bio确认已加载。

详细介绍

Adaptyv Bio

概述

Adaptyv Bio 是一个蛋白质表达与表征平台,可通过 REST API 和 Python SDK 访问。用户提交蛋白质序列(抗体、纳米抗体、酶、结合蛋白),数天内即可收到表达的蛋白质及结合亲和力测量结果(通过生物层干涉测定法测得 KD)。该平台专为高通量定向进化循环而设计:生成候选序列(通过计算或文库设计)→ 通过 API 订购表达和检测 → 获取亲和力数据 → 重新训练模型或筛选优选候选序列 → 重复。SDK 可通过 Python 处理实验提交、状态轮询和结果检索。

适用场景

  • 筛选计算设计的蛋白质变体,以实验验证其结合亲和力
  • 运行 ML 指导的定向进化循环,在计算机模拟候选序列生成与湿实验表征之间交替进行
  • 订购纳米抗体、抗体或结合结构域的无细胞表达,无需维护湿实验基础设施
  • 使用 REST API 自动化高通量蛋白质表征流程
  • 将实验亲和力数据(KD 值)与计算模型相结合,对蛋白质序列进行贝叶斯优化
  • 使用实验结合数据验证 ESM、AlphaFold 或对接预测
  • 对于 LIMS 风格的序列和质粒管理,请使用 benchling-integration;如果需要自动化无细胞表达和亲和力表征,且无需搭建湿实验环境,请改用 Adaptyv Bio

先决条件

  • Python 软件包:adaptyvbio、requests、pandas
  • 账户:需要 Adaptyv Bio 账户;从控制面板获取 API 密钥
  • 数据要求:FASTA 格式或纯字符串格式的蛋白质序列;靶蛋白规格
pip install adaptyvbio requests pandas
# Set API key as environment variable
export ADAPTYV_API_KEY="your_api_key_here"

快速入门

import adaptyvbio as ab
import os

# Initialize client
client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])

# List available experiment types
experiment_types = client.get_experiment_types()
for et in experiment_types:
    print(f"  {et['name']}: {et['description']}")

核心 API

模块 1:序列提交

提交蛋白质序列,以进行无细胞表达和表征。

import adaptyvbio as ab
import os

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])

# Submit a single protein sequence for expression
sequence = "MAQRITLPSGMKELRLSYNMGEIVYKIEPVGSIVHIEYYDPENKDTLVNKPSDIVELTMPGKLVVENAKTFAEK"

submission = client.submit_experiment(
    experiment_type="expression",   # "expression" or "binding"
    sequences=[sequence],
    metadata={
        "project": "nanobody_optimization_round1",
        "designer": "ESM2_1000_candidates",
    }
)

experiment_id = submission["experiment_id"]
print(f"Submitted experiment: {experiment_id}")
print(f"Status: {submission['status']}")
print(f"Estimated completion: {submission.get('estimated_completion', 'N/A')}")
# Submit batch of sequences (up to 96 per experiment)
import pandas as pd

# Load candidate sequences from CSV
candidates = pd.read_csv("esm_candidates.csv")  # columns: name, sequence, score
top_candidates = candidates.nlargest(48, "score")

sequences = top_candidates["sequence"].tolist()
names = top_candidates["name"].tolist()

batch_submission = client.submit_experiment(
    experiment_type="binding",
    sequences=sequences,
    sequence_names=names,
    target="target_protein_name",  # registered target in your Adaptyv account
    metadata={"round": 2, "parent_experiment": experiment_id}
)
print(f"Batch experiment: {batch_submission['experiment_id']}")
print(f"Sequences submitted: {len(sequences)}")
模块 2:实验状态跟踪

轮询实验状态,并在实验完成后检索结果。

import adaptyvbio as ab
import os
import time

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])
experiment_id = "exp_abc123"  # from submission step

# Check current status
status = client.get_experiment_status(experiment_id)
print(f"Status: {status['status']}")  # "pending", "running", "complete", "failed"
print(f"Progress: {status.get('progress', 0):.0%}")

# Poll until complete (with timeout)
max_wait_hours = 72
poll_interval_minutes = 30
timeout = max_wait_hours * 3600

start = time.time()
while time.time() - start < timeout:
    status = client.get_experiment_status(experiment_id)
    print(f"[{time.strftime('%H:%M')}] Status: {status['status']}")
    if status["status"] in ("complete", "failed"):
        break
    time.sleep(poll_interval_minutes * 60)

print(f"Final status: {status['status']}")
模块 3:结果检索

下载并解析实验结果。

import adaptyvbio as ab
import pandas as pd
import os

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])
experiment_id = "exp_abc123"

# Get results (only available when status is "complete")
results = client.get_experiment_results(experiment_id)

# Convert to DataFrame
records = []
for result in results["results"]:
    records.append({
        "name": result.get("sequence_name", "unnamed"),
        "sequence": result["sequence"],
        "kd_nM": result.get("kd_nM"),          # binding dissociation constant
        "yield_ug": result.get("yield_ug"),      # expression yield
        "expression_pass": result.get("expression_pass"),
        "binding_pass": result.get("binding_pass"),
    })

df = pd.DataFrame(records)
df = df.sort_values("kd_nM", ascending=True)  # rank by affinity (lower KD = tighter binding)

print(f"Results: {len(df)} sequences")
print(f"Successfully expressed: {df['expression_pass'].sum()}")
print(f"KD range: {df['kd_nM'].min():.2f} – {df['kd_nM'].max():.2f} nM")
print(df[["name", "kd_nM", "yield_ug", "expression_pass"]].head(10).to_string())

df.to_csv(f"{experiment_id}_results.csv", index=False)
模块 4:实验历史和项目管理
import adaptyvbio as ab
import pandas as pd
import os

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])

# List all experiments
experiments = client.list_experiments(project="nanobody_optimization")
print(f"Total experiments: {len(experiments)}")

for exp in experiments:
    print(f"  {exp['experiment_id']}: {exp['status']} | "
          f"{exp['n_sequences']} seqs | {exp['created_at'][:10]}")

# Retrieve all results across experiments for a project
all_results = []
for exp in experiments:
    if exp["status"] == "complete":
        results = client.get_experiment_results(exp["experiment_id"])
        for r in results["results"]:
            r["experiment_id"] = exp["experiment_id"]
            r["round"] = exp.get("metadata", {}).get("round", "unknown")
            all_results.append(r)

project_df = pd.DataFrame(all_results)
print(f"\nAll results: {len(project_df)} sequences across {len(experiments)} experiments")
print(f"Best KD: {project_df['kd_nM'].min():.3f} nM")
模块 5:与序列设计集成

将 Adaptyv Bio 的结果与计算蛋白质设计工具集成。

import adaptyvbio as ab
import pandas as pd
import numpy as np
import os

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])

def run_design_iteration(previous_results_df, n_new_candidates=48):
    """
    Closed-loop protein engineering iteration.
    Input: DataFrame with sequence, kd_nM from previous round
    Output: submitted experiment_id for new round
    """
    # Select top performers as parents for next round
    parents = previous_results_df.nsmallest(5, "kd_nM")["sequence"].tolist()
    print(f"Top parent KDs: {previous_results_df.nsmallest(5, 'kd_nM')['kd_nM'].values}")

    # --- Placeholder for computational design step ---
    # In practice: call ESM, ProteinMPNN, or mutation scanning here
    # new_sequences = design_model.generate(parents, n=n_new_candidates)
    # For demonstration, create random variants:
    new_sequences = [p[:20] + "X" * 10 + p[30:] for p in parents[:3]]  # placeholder

    # Submit new candidates
    submission = client.submit_experiment(
        experiment_type="binding",
        sequences=new_sequences,
        metadata={"round": "auto", "parent_kd_min": parents[0] if parents else None}
    )
    print(f"Round submitted: {submission['experiment_id']}")
    return submission["experiment_id"]

# Example: load round 1 results and start round 2
round1 = pd.read_csv("exp_round1_results.csv")
if not round1.empty:
    next_id = run_design_iteration(round1)
    print(f"Round 2 experiment ID: {next_id}")

核心概念

KD(解离常数)

KD 用于衡量蛋白质与靶标之间的结合亲和力。KD 越低,结合越紧密:

  • µM 范围(>1000 nM):结合较弱,通常不适用于治疗
  • 100–1000 nM:中等结合
  • 1–100 nM:结合良好,属于典型抗体范围
  • <1 nM:结合极佳(皮摩尔级抗体、纳米抗体)

Adaptyv Bio 使用生物层干涉测定法(BLI)的稳态或动力学测量结果,以 nM 为单位报告 KD。

无细胞表达

Adaptyv Bio 使用无细胞蛋白质合成(CFPS)系统(小麦胚芽或大肠杆菌提取物)表达蛋白质,无需克隆。这支持高通量筛选(96 孔板格式,以天而非周计),但也存在一些限制:真核生物修饰(如糖基化以及复杂蛋白质中的二硫键)可能与基于细胞的表达有所不同。

常见工作流

工作流 1:闭环定向进化
import adaptyvbio as ab
import pandas as pd
import os
import time

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])

ROUNDS = 3
CANDIDATES_PER_ROUND = 48
TARGET = "your_target_protein"

all_data = pd.DataFrame()

for round_num in range(1, ROUNDS + 1):
    print(f"\n=== Round {round_num} ===")

    # Step 1: Generate candidates (replace with actual design model)
    if round_num == 1:
        sequences = ["MAQRITLPSGMKELRL" + "A" * 20 for _ in range(CANDIDATES_PER_ROUND)]
    else:
        parents = all_data.nsmallest(5, "kd_nM")["sequence"].tolist()
        # In practice: sequences = design_model.generate_variants(parents, n=CANDIDATES_PER_ROUND)
        sequences = parents[:CANDIDATES_PER_ROUND]  # placeholder

    # Step 2: Submit
    submission = client.submit_experiment(
        experiment_type="binding",
        sequences=sequences,
        target=TARGET,
        metadata={"round": round_num}
    )
    exp_id = submission["experiment_id"]
    print(f"Submitted {len(sequences)} sequences: {exp_id}")

    # Step 3: Wait for results (skip in demo; poll in production)
    # time.sleep(72 * 3600)

    # Step 4: Retrieve results
    results = client.get_experiment_results(exp_id)
    round_df = pd.DataFrame(results["results"])
    round_df["round"] = round_num
    all_data = pd.concat([all_data, round_df], ignore_index=True)

    best = round_df.nsmallest(1, "kd_nM").iloc[0]
    print(f"Best KD this round: {best['kd_nM']:.2f} nM")

all_data.to_csv("directed_evolution_all_rounds.csv", index=False)
print(f"\nFinal best KD: {all_data['kd_nM'].min():.3f} nM")
工作流 2:批量筛选与排序
import adaptyvbio as ab
import pandas as pd
import matplotlib.pyplot as plt
import os

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])

# Retrieve completed experiment results and rank
exp_id = "exp_completed_123"
results = client.get_experiment_results(exp_id)
df = pd.DataFrame(results["results"])
df = df.dropna(subset=["kd_nM"]).sort_values("kd_nM")

# Summary statistics
print(f"Sequences tested: {len(df)}")
print(f"Expression success rate: {df['expression_pass'].mean():.0%}")
print(f"Binding positives (KD < 100 nM): {(df['kd_nM'] < 100).sum()}")

# Rank plot
fig, ax = plt.subplots(figsize=(10, 4))
ax.semilogy(range(len(df)), df["kd_nM"].values, 'o', markersize=4)
ax.axhline(100, color='red', linestyle='--', label='100 nM threshold')
ax.set_xlabel("Sequence rank")
ax.set_ylabel("KD (nM)")
ax.set_title(f"Binding Affinity Rank — {exp_id}")
ax.legend()
plt.tight_layout()
plt.savefig(f"{exp_id}_rank_plot.pdf", bbox_inches="tight")

# Export top hits
top_hits = df.head(10)[["sequence_name", "sequence", "kd_nM", "yield_ug"]]
top_hits.to_csv(f"{exp_id}_top_hits.csv", index=False)
print(f"\nTop 10 hits:\n{top_hits.to_string(index=False)}")

关键参数

参数模块/函数默认值范围 / 选项作用
experiment_typesubmit_experiment—"expression"、"binding"检测类型:仅表达检测,或表达检测 + 结合检测
sequencessubmit_experiment—字符串列表,最多 96 个每次实验要筛选的蛋白质序列
targetsubmit_experiment—已注册的靶标名称用于测量结合情况的靶蛋白
metadatasubmit_experiment{}字典与实验一同存储的自定义键值对
projectlist_experimentsNone字符串按项目名称筛选实验
KD 阈值下游分析—1–1000 nM用户自定义的命中筛选阈值

最佳实践

  1. 加入阳性和阴性对照序列:每批实验都应加入已知的结合剂(阳性对照)和一条乱序/空序列(阴性对照)。这样可以验证检测性能,并在对未经测试的变体得出结论前发现批次级故障。

  2. 按照板型(48 或 96 孔)分批设计候选序列:Adaptyv Bio 以 48 孔或 96 孔格式运行实验。设计候选序列批次时应尽量填满整板——半板的成本与满板相同,但每次实验产生的数据点更少。

  3. 提交时记录所有元数据:在 metadata 字段中加入轮次编号、亲本序列、计算模型版本和生成参数。这样可以为论文发表和结果复现还原设计与实验历史。

  4. 先按表达产量筛选,再按 KD 排序:表达失败或表达量低于检测阈值的蛋白质,其 KD 值不可靠。按 KD 排序前,务必先筛选 expression_pass == True。

  5. 使用 API 自动化轮询—获取—设计循环:实现自动化流程,每 6–12 小时轮询一次,在实验完成后获取结果、运行设计模型并提交下一轮,从而消除迭代式蛋白质工程中的手动瓶颈。

常见操作示例

示例:将命中结果导出为 FASTA
import adaptyvbio as ab
import os

client = ab.Client(api_key=os.environ["ADAPTYV_API_KEY"])

def results_to_fasta(exp_id, top_n=10, kd_cutoff_nM=100, output_file="top_hits.fasta"):
    results = client.get_experiment_results(exp_id)
    hits = [r for r in results["results"]
            if r.get("expression_pass") and r.get("kd_nM", float("inf")) < kd_cutoff_nM]
    hits.sort(key=lambda x: x["kd_nM"])

    with open(output_file, "w") as f:
        for r in hits[:top_n]:
            name = r.get("sequence_name", r["sequence"][:8])
            f.write(f">{name}_KD{r['kd_nM']:.1f}nM\n{r['sequence']}\n")

    print(f"Exported {min(top_n, len(hits))} sequences to {output_file}")

results_to_fasta("exp_abc123", top_n=10, kd_cutoff_nM=50)
示例:按 KD 分布比较不同轮次
import pandas as pd
import matplotlib.pyplot as plt

# Load all rounds
rounds = {
    1: pd.read_csv("exp_round1_results.csv"),
    2: pd.read_csv("exp_round2_results.csv"),
    3: pd.read_csv("exp_round3_results.csv"),
}

fig, ax = plt.subplots(figsize=(8, 5))
for round_num, df in rounds.items():
    kd_vals = df.dropna(subset=["kd_nM"])["kd_nM"]
    ax.hist(kd_vals, bins=20, alpha=0.6, label=f"Round {round_num} (n={len(kd_vals)})")

ax.set_xlabel("KD (nM)")
ax.set_ylabel("Count")
ax.set_title("KD Distribution Across Directed Evolution Rounds")
ax.legend()
plt.tight_layout()
plt.savefig("kd_distribution_by_round.pdf", bbox_inches="tight")

故障排查

问题原因解决方案
AuthenticationErrorAPI 密钥无效或缺失设置 ADAPTYV_API_KEY 环境变量;在 Adaptyv 控制面板中重新生成密钥
实验状态卡在 "pending"队列积压或缺少靶标配置联系 Adaptyv 支持;确认靶蛋白已在账户中注册
所有序列都显示 expression_pass=False序列可能过长、含有无效字符或存在折叠问题检查序列长度(典型上限:<300 aa);确认不含非标准氨基酸;在结合检测前先进行表达筛选
KD 值波动较大(>3×)表达产量低导致 BLI 信号噪声较大筛选 yield_ug > 5;重新设计序列以改善表达
状态为 "complete" 后 results 字段仍为空API 时序问题;结果尚未持久化等待 10 分钟后重试;查看 Adaptyv 状态页面
每批限制为少于 96 条序列账户套餐限制升级账户;将任务拆分为多个、每个包含 48 条序列的实验
CSV 中部分序列缺少 KD 值BLI 拟合失败(结合动力学较差或不结合)kd_nM=None 的序列是不结合剂;将其视为阴性结果

相关技能

  • esm-protein-language-model — 生成候选序列以提交给 Adaptyv Bio
  • benchling-integration — 使用 LIMS 管理蛋白质工程序列,并与 Adaptyv Bio 实验配套
  • pymoo — 使用 Adaptyv Bio 的 KD + 产量数据作为适应度函数进行多目标优化

参考资料

评论

支持 Markdown