蛋白质模型平台 · API 调用说明

Base URL:https://ai4s.cypherpharma.cloud/api · 网页版入口:返回平台

鉴权

所有 /api/* 请求都必须带 API Token,放在 Authorization 头里:

Authorization: Bearer <API_TOKEN>

Token 由平台管理员分配,请勿写入前端代码或公开仓库。缺失或错误会返回 401。

本页面本身是公开文档,不含任何凭据;网页版的登录密码与 API Token 是两套独立的认证方式。

快速开始

四步完成一次预测:提交 → 轮询 → 列产物 → 下载。

BASE=https://ai4s.cypherpharma.cloud/api
TOKEN=<API_TOKEN>

# 1) 健康检查
curl -s $BASE/health -H "Authorization: Bearer $TOKEN"

# 2) 提交作业
curl -s -X POST $BASE/jobs \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "boltz",
    "input_text": "name: demo\nchains:\n  - id: A\n    type: protein\n    sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n    copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n",
    "params": {"samples": 1}
  }'
# → {"job_id":"f534c9a1...","status":"queued",...}

# 3) 轮询状态(queued → running → done)
curl -s $BASE/jobs/<JOB_ID> -H "Authorization: Bearer $TOKEN"

# 4) 列产物并下载
curl -s $BASE/jobs/<JOB_ID>/files -H "Authorization: Bearer $TOKEN"
curl -s -G $BASE/jobs/<JOB_ID>/file \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode 'path=results.json' -o results.json

接口一览

方法路径用途
GET/health健康检查,返回队列与运行数
GET/models模型清单、显存曲线与默认参数
POST/jobs提交作业
GET/jobs作业列表,支持 ?status=queued&limit=50
GET/jobs/{id}作业详情(含 result_dir、error)
POST/jobs/{id}/cancel取消排队或运行中的作业
GET/jobs/{id}/files递归列出产物(相对路径 + 字节数)
GET/jobs/{id}/file?path=下载单个产物
GET/stats队列、GPU、各模型峰值显存统计

输入格式

预测类 5 个模型(boltz / protenix / chai1 / colabfold / openfold3)统一使用 YAML spec,通过 input_text 内联提交:

name: demo                 # 作业名,影响产物文件名
chains:
  - id: A
    type: protein          # protein | dna | rna
    sequence: MQIFVKTLT... # 单字母序列
    copies: 1
  - id: B
    type: protein
    sequence: GSHMK...
ligands:
  - id: L
    type: ligand
    smiles: "CC(=O)O"      # 或者 ccd: ATP
    copies: 1
msa: none                  # none | server | cached | /path/to/x.a3m
seeds: [42]
samples: 1
recycles: 3
字段说明
msanone 单序列模式(最快,无需联网);server 自动取 MSA(依赖外网);cached 使用缓存;也可写 .a3m 路径
copies同一条序列的拷贝数
ligands配体用 smiles 或 CCD 代码
seeds / samples / recycles随机种子 / 采样数 / recycle 次数
Protenix 限制:只支持 msa: none,且 recycles 建议 ≥ 10,否则 pLDDT 会明显偏低。
设计类(rfantibody / bindcraft2)不使用上面的 YAML,输入是各自的 JSON 配置,见下文。

7 个模型

model类型输入规模上限说明
boltz预测YAML1500 tokensBoltz-2,通用复合物
protenix预测YAML1500 tokensProtenix 2.0,AF3 风格
chai1预测YAML500 tokensChai-1,抗体/复合物
colabfold预测YAML2000 tokens最省显存,适合长序列
openfold3预测YAML1500 tokensOpenFold-3
rfantibody设计JSON—三阶段抗体设计
bindcraft2设计JSON—Campaign 式 binder 设计

boltz

{"model":"boltz","input_text":"name: ubq\nchains:\n  - id: A\n    type: protein\n    sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n    copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}

protenix

{"model":"protenix","input_text":"name: ubq\nchains:\n  - id: A\n    type: protein\n    sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n    copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 10\n"}

chai1

{"model":"chai1","input_text":"name: ubq\nchains:\n  - id: A\n    type: protein\n    sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n    copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}

colabfold

{"model":"colabfold","input_text":"name: ubq\nchains:\n  - id: A\n    type: protein\n    sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n    copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}

openfold3

{"model":"openfold3","input_text":"name: ubq\nchains:\n  - id: A\n    type: protein\n    sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n    copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}

rfantibody

三阶段抗体设计。耗时数十分钟起,target_pdb 必须是服务器上已存在的路径(无上传接口)。

{"model":"rfantibody","input_text":"{\"target_pdb\":\"/home/xiaodong/models/targets/flu_HA.pdb\",\"num_designs\":2,\"design_loops\":\"H1:7,H2:6,H3:5-13\",\"hotspots\":\"B146,B170,B177\",\"diffuser_t\":15,\"num_seqs\":1,\"num_recycles\":3}"}

bindcraft2

内置靶点:dynorphin_a、hIL2R、hIL7RA、hPD1、hPDL1、mPDL1。

{"model":"bindcraft2","input_text":"{\"modality\":\"binder\",\"target\":\"hPDL1\",\"campaign_name\":\"pdl1_round1\",\"number_of_final_designs\":1,\"max_trajectories\":2,\"binder_lengths\":[60,80],\"validation_recycles\":3}"}

params 参数

提交时 params 是可选的,会覆盖 spec 里的同名字段:

键作用适用范围
samples采样数全部预测类
recycles / recyclingrecycle 次数全部预测类
seeds[42] 或 "42 43"全部预测类
steps扩散步数boltz / protenix
timeout单作业超时秒数,默认 3600全部
forcetrue 时绕过 tokens 上限全部
extra透传给后端全部

提交后返回的 tokens 是折算残基数,est_vram_mb 是预估峰值显存;超过单卡 22000 MB 会直接 422。

结果产物

预测类作业的 result_dir 结构固定:

<job_id>/
├── _spec.yaml       实际执行的 spec
├── results.json     结构化分数与结构文件路径
├── report.html      人工查看用的汇总页
└── work/<cache_key>/  后端原生输出(.cif / .pdb / .npz)

results.json 里每个采样一项:

{"results":[
  {"id":"boltz_s42_m0","seed":42,"sample":0,
   "path":".../predictions/demo/demo_model_0.cif",
   "plddt":92.08,"ptm":0.910,"iptm":0.0,"ranking":0.919}
]}
path 是服务器绝对路径。下载时用 /jobs/{id}/files 返回的相对路径,或去掉 result_dir 前缀。

设计类产物不同:RFantibody 输出 1_rfdiffusion.qv / 2_proteinmpnn.qv / 3_rf2.qv;BindCraft2 输出 3_Ranked/、summary.csv、campaign_metadata.json。

错误码

状态码含义处理
401Token 缺失或错误检查 Authorization: Bearer
404作业或文件不存在确认 job_id 与 path
422输入不合法 / 超过 tokens 上限 / 预估显存超限缩小规模或修 spec
429网页版登录尝试过多等待 5 分钟
500服务端异常查看作业详情里的 error

Python 示例

import time, requests

BASE = "https://ai4s.cypherpharma.cloud/api"
HEAD = {"Authorization": "Bearer <API_TOKEN>"}

spec = """name: demo
chains:
  - id: A
    type: protein
    sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG
msa: none
seeds: [42]
samples: 1
recycles: 3
"""

job = requests.post(BASE + "/jobs", headers=HEAD,
                    json={"model": "boltz", "input_text": spec}).json()
jid = job["job_id"]

while True:
    info = requests.get(f"{BASE}/jobs/{jid}", headers=HEAD).json()
    if info["status"] in ("done", "failed", "cancelled"):
        break
    time.sleep(5)

if info["status"] == "done":
    files = requests.get(f"{BASE}/jobs/{jid}/files", headers=HEAD).json()["files"]
    for f in files:
        if f["path"].endswith(".cif"):
            data = requests.get(f"{BASE}/jobs/{jid}/file", headers=HEAD,
                                params={"path": f["path"]}).content
            open("model.cif", "wb").write(data)

并发与约束