Real Ascend Antibody Protenix Pipeline - Broker only

SkillMonitoring & ops

Prepare, submit, monitor, and summarize the real RFdiffusion to ProteinMPNN to Protenix antibody pipeline through the ScienceDiscovery Runner NPU Broker, including custom workspace-local antigen PDBs and chain-labelled epitopes.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Real Ascend Antibody Protenix Pipeline - Broker only skill

What this skill tells your AI

The instructions your AI receives, as published by openjiuwen-ai/sciencediscovery in skills/antibody-protenix-pipeline/SKILL.md and read by ahel’s review.

Use this skill for the Protenix-backed antibody workflow. All model/NPU execution goes through run_npu_job with workload antibody.protenix.v1.

Non-negotiable rules

  • Never use host_bridge, host_launch_request.json, run_shell, a persistent kernel, nohup, or device passthrough to launch model/NPU work.
  • This skill is authoritative for a Protenix Broker run. If legacy antibody/host-setup skills are also selected, do not follow their host-shell launch, polling, or artifact workflow; use only the Broker workflow in this file.
  • run_shell may create or inspect small workspace files/directories, write config.json, probe imports with python -c in a selected environment_id, run the read-only progress probe in step 5, and run the single sleep TICK in step 5. Never use it to launch model/NPU work or reconstruct bundled scripts/PDB examples. Each call uses a fresh process; select the same local Runner and environment ID for these operations. Environment ID selects the latest state, not a historical Revision.
  • Although the complete frozen package is visible under $SCIENCEDISCOVERY_SKILLS_DIR/antibody-protenix-pipeline, do not execute or copy files from its scripts/ / resources/; those package files are for the Broker adapter and operator deployment path, not for Agent-authored execution.
  • There is no default antigen/framework PDB. If the user has not provided target_pdb, framework_pdb, or chain-labelled hotspots, stop and ask for the missing scientific input. Do not run a bundled example.
  • Do not place or guess host paths for MindScience, RFdiffusion, ProteinMPNN, Protenix, checkpoints, HMMER, CANN, Python, or PDB files in config.json. Operator assets are injected by the Broker; scientific PDB inputs must be Session workspace-local relative paths. In particular, never set models_dir, protenix_dir, protenix_ckpt, protenix_ckpt_url, or ckpt; the manager treats these as operator-only and rejects them in Broker mode.
  • Do not edit the operator-provided Protenix checkout for Python 3.12 compatibility. The deployed protenix_py312_compat.py entrypoint handles integral float bounds such as random.randint(0, 1e6) inside the Protenix process.
  • Submit exactly once. If the job reaches failed, cancelled, or interrupted, do not edit paths and do not submit a replacement job in the same run. Return the job ID, exact error, failed stage, and next repair action to the user.
  • Keep monitoring in the main Agent until the Broker job reaches a terminal state. Submitting the job and then ending the turn while it is still queued or running is an incomplete run, not a successful handoff. Do not delegate an NPU job to task or another subagent, because subagents have private workspaces and cannot safely create or declare files in the parent workspace.
  • Immediately after a successful submit, write the returned Broker job ID to antibody_pipeline/broker_job.json with run_shell. This small workspace-local checkpoint is mandatory for long runs because the Agent context may be compacted while the NPU job continues. Before every later run_npu_job(status/logs/result/cancel) call, verify that the job_id argument is the exact UUID returned by submit or read from antibody_pipeline/broker_job.json; if you are uncertain, read that file first. Never call run_npu_job(status/logs/result/cancel) with a placeholder job ID such as JOB_ID_PLACEHOLDER / __JOB_ID_PLACEHOLDER__, and never resubmit just to recover a job ID.
  • Workspace files never establish completion. Only Broker status/logs can say the job is terminal. A progress probe that sees 05_screening files, expected CIF/PDB counts, or quiet logs is a reason to call status next, not a reason to write a report or declare artifacts.
  • After Broker status returns succeeded, the next tool call must be run_npu_job(operation="result", job_id="<job-id>"). This is the only call that automatically declares Broker createdFiles as Project Artifacts (all of them when there are 50 or fewer; the first 50 when there are more). status=succeeded does not declare files. Do not call run_shell, declare_artifact, write any summary/report file, or produce a final answer between successful terminal status and this result call. If more than 50 files were created, the final response MUST tell the user that Project Artifacts only show the first 50 files and that the rest are in the Session workspace.
  • If result returns that the job is not terminal, the completion check was wrong: return to step 5 monitoring. Do not declare artifacts and do not write a summary.
  • Before result succeeds, do not read generated structure/result file contents, do not read screening CSV/Markdown files, do not write any summary/report file under any name, do not call declare_artifact or list_artifacts, and do not reconstruct a final stage-count report. The one allowed write before result is the job-ID checkpoint in step 4.
  • After result, treat result.job.createdFiles, result.job.createdFiles.length, and result.artifacts as the source of truth. Do not create an extra pipeline report. Do not replace result with a handful of manual declare_artifact calls. If result.artifacts is missing or empty after a succeeded job, report that artifact registration did not run; do not try to recover by declaring only screening Markdown/CSV.
  • Report Protenix device placement only from explicit device_target / device_id lines in the Broker log. Never infer CPU or Ascend from duration, token counts, or a post-completion npu-smi snapshot.
  • Do not switch to antibody.pipeline.v1. AlphaFold3 requests use the separate antibody-real-pipeline skill.

Inputs

Confirm only missing scientific/run inputs:

  • custom workspace-local target antigen PDB;
  • custom workspace-local antibody framework PDB;
  • one target-PDB epitope list using the original PDB chain label and residue numbers, for example B45,B46,B49 or [B45,B46,B49];
  • design count;
  • run name, using only letters, digits, dot, underscore, and hyphen;
  • NPU selection and workers per NPU;
  • overwrite permission when reusing a run name.

For a minimal e2e test use one design, NPU 0, one worker, user-provided PDB inputs under antibody_pipeline/inputs/, and no overwrite unless explicitly requested.

Required workflow

  1. Call:
run_npu_job(operation="list_workloads")

Stop if antibody.protenix.v1 is absent. Do not attempt an alternative host execution path.

  1. Resolve the Python environment before creating the job:
  • Use the complete pip package list from requirements.txt when preparing the environment: mindspore==2.7.2, numpy==1.26.4, pandas, biopython==1.83, scipy, scikit-learn, pyyaml, hydra-core, omegaconf, ml-collections, dm-tree==0.1.8, optree, tqdm, attrs, decorator, matplotlib==3.9.2, safetensors, sympy, rdkit==2024.3.5, biotite==1.4.0.
  • Call environment_list(runner_id="local"), skip starter/non-scientific environments, and probe candidate environment IDs through run_shell(runner_id="local", environment_id="<environment-id>", command=...) using the small Python probe below. currentRevisionId is audit information, not a selectable execution parameter.
  • Prefer candidates whose environment name clearly identifies the antibody NPU managed environment, especially antibody-npu-managed-clean; do not choose an older similarly named environment until the clean/current candidate has been probed.
  • If a candidate probe fails, record the missing package/version, then continue probing the next candidate. A single failed run_shell probe is not terminal.
  • Reuse only an environment whose latest state passes the probe and prints MANAGED_ENV_OK.
  • If every candidate fails, call environment_create for a named Python environment on the local Runner, then call environment_install with its environmentId, manager="pip", and the complete package list above. Probe the same environment ID again. Never use pip, pip --user, a host venv, or run_shell for dependency installation.
  • The deployed MindScience Protenix checkout requires biotite==1.4.0 and biotite.structure.io.pdbx.convert.PDBX_BOND_TYPE_ID_TO_TYPE. Always run the inline probe below after installation. If a candidate has an older/incompatible Biotite, use environment_install with the complete package list from requirements.txt, not only the Biotite entry, so the required package versions are validated together. Installation updates the environment in place and records an audit Revision; it does not clone a new execution environment. Do not patch the Protenix checkout or fall back to a host Biotite package.
  • Keep the passing environment ID as <environment-id>. Submit resolves its latest state again; avoid changing dependencies between probe and submit, and re-probe after any managed update. A missing/incompatible package is an environment setup task, not a reason to submit the NPU job early. Do not pass environment_revision_id to submit; it is rejected.

Use this command with run_shell, setting runner_id="local" and environment_id="<environment-id>"; dependency discovery must not depend on host PYTHONPATH:

python - <<'PY'
from importlib import import_module
from importlib.metadata import version
for module in ["mindspore", "numpy", "pandas", "Bio", "scipy", "sklearn", "yaml", "hydra", "omegaconf", "ml_collections", "tree", "optree", "tqdm", "attrs", "decorator", "matplotlib", "safetensors", "sympy", "rdkit", "biotite"]:
    import_module(module)
for distribution, expected in {"mindspore": "2.7.2", "numpy": "1.26.4", "dm-tree": "0.1.8", "rdkit": "2024.3.5", "biotite": "1.4.0"}.items():
    assert version(distribution) == expected, (distribution, version(distribution), expected)
from biotite.structure.io.pdbx import convert as pdbx_convert
assert hasattr(pdbx_convert, "PDBX_BOND_TYPE_ID_TO_TYPE")
print("MANAGED_ENV_OK")
PY
  1. Create only antibody_pipeline/config.json. The minimal form requires explicit workspace-local PDB inputs:
{
  "workspace": "antibody_pipeline",
  "target_pdb": "antibody_pipeline/inputs/target_antigen.pdb",
  "framework_pdb": "antibody_pipeline/inputs/antibody_framework.pdb",
  "hotspots": "[B45,B46,B49]",
  "num_designs": 4,
  "run_name": "custom-antigen-protenix",
  "npus": "0,1,2,3",
  "workers_per_npu": 1,
  "final_step": 160,
  "diffuser_t": 200,
  "force": false
}

Paths authored by the Agent must be relative to the Session workspace. Upload PDB inputs under antibody_pipeline/inputs/ and set target_pdb / framework_pdb to those relative paths. Do not add host asset paths or python.

npus is the comma-separated physical Ascend device list requested by the user, for example "0" for a one-card smoke test or "0,1,2,3" for a four-card run. For normal throughput tests on a four-card Ascend host, prefer "npus": "0,1,2,3" with num_designs at least 4; for a quick smoke test only, reduce to "npus": "0" and "num_designs": 1. workers_per_npu controls RFdiffusion shard concurrency per listed NPU. Protenix inference runs one concurrent JSON job per listed NPU and batches the remaining JSON files round-robin across that list.

Use exactly one hotspots field for both RFdiffusion and screening. Keep the user's original target-PDB chain label and residue numbers; do not create screen_hotspots, rename the chain to T, or convert the residue numbers yourself. The pipeline writes an original-PDB-to-Protenix chain/residue map for each Protenix input and maps the requested residues to Protenix sequence positions internally; if mapping is missing or ambiguous, screening marks the row as a mapping failure instead of reporting zero contacts. If every screened design has a hotspot mapping error, the screening step exits non-zero and the Broker job fails; report the exact hotspot_mapping_error instead of summarizing the run as a completed design. hotspots accepts either B45,B46,B49 or RFdiffusion bracket form [B45,B46,B49]; the manager normalizes it before launch. Keep diffuser_t at least 15 because RFdiffusion rejects smaller schedules.

For example, when the uploaded antigen is antibody_pipeline/inputs/custom_antigen.pdb, the uploaded framework is antibody_pipeline/inputs/custom_framework.pdb, its target chain is B, and the requested epitope is B45,B46,B49, use:

{
  "workspace": "antibody_pipeline",
  "target_pdb": "antibody_pipeline/inputs/custom_antigen.pdb",
  "framework_pdb": "antibody_pipeline/inputs/custom_framework.pdb",
  "hotspots": "[B45,B46,B49]",
  "num_designs": 4,
  "run_name": "custom-antigen-protenix",
  "npus": "0,1,2,3",
  "workers_per_npu": 1,
  "final_step": 160,
  "diffuser_t": 200,
  "force": false
}
  1. Submit once:
run_npu_job(
  operation="submit",
  workload_id="antibody.protenix.v1",
  config_path="antibody_pipeline/config.json",
  environment_id="<environment-id>"
)

Record the returned job ID. Do not submit another job until this job reaches a terminal state; if it fails, this run must stop.

Immediately checkpoint the returned job ID with run_shell on the same local Runner and environment ID (replace the placeholders with the returned values):

python - <<'PY'
import json, os
record = {
    "job_id": "<returned-job-id>",
    "workload_id": "antibody.protenix.v1",
    "config_path": "antibody_pipeline/config.json",
    "run_name": "<run_name>"
}
os.makedirs("antibody_pipeline", exist_ok=True)
with open("antibody_pipeline/broker_job.json", "w", encoding="utf-8") as fh:
    json.dump(record, fh, indent=2)
PY

This is a state checkpoint, not a result summary. It is allowed before the terminal result call. If later monitoring context loses the job ID, read antibody_pipeline/broker_job.json and continue monitoring the recorded job. Before typing any later Broker job_id, check that it is a real UUID from this checkpoint or the submit response. Do not use JOB_ID_PLACEHOLDER / __JOB_ID_PLACEHOLDER__, do not guess the job ID, and do not submit a replacement job.

  1. Monitor continuously until Broker status is terminal.

A monitoring cycle is:

  1. run_npu_job(operation="status", job_id="<job-id>") — required every cycle.
  2. Optionally run_npu_job(operation="logs", job_id="<job-id>").
  3. Optionally one short read-only run_shell progress probe (for example, bounded python -c output in the same environment).
  4. If state is still queued or running, wait with one sleep TICK, then start the next cycle.

Do not skip status for several cycles and decide completion from workspace files. Keep calling status until it returns one of:

  • succeeded
  • failed
  • cancelled
  • interrupted

Sleep TICK (normal wait). Use one dedicated run_shell call for a single sleep and TICK. Do not put this sleep in the progress probe, and do not wrap it in for/while:

run_shell(runner_id="local", environment_id="<environment-id>",
          command="python -c 'import time; time.sleep(100); print(\"TICK\", flush=True)'",
          wait_ms=30000)

If the wait returns running, retain that Shell Execution ID and use execution_status(execution_id=..., wait_ms=30000) until terminal; the wait deadline does not stop the sleep. Do not submit a second TICK while the first is running or unknown. After a completed TICK, start the next Broker status cycle. Shell Execution IDs and Broker job IDs are different; never exchange them.

Forbidden wait patterns: for/while plus sleep inside one tool call; shell sleep … && a progress probe or model launch; tail -f; watch; combining Broker status/probe/sleep into one run_shell. One TICK per cycle is the correct wait.

Progress probe (optional, for stage detail). It may print file existence, paths, counts, log mtimes, per-stage output counts, and short log tails. It may list generated *.pdb / *.cif / *.json names. It must not open or print those files' contents, must not make scientific quality claims, and must not create/edit/delete/declare/launch anything. Reuse the same probe when that is the clearest comparison.

If a probe looks finished (05_screening present, expected design counts, logs stopped growing), the next tool call is still status. Do not write a summary, do not call declare_artifact, and do not give a final answer from the probe.

The Agent must not send a final answer while the job is still queued or running. During a long run, report Broker state, active stage, output counts, and a short log excerpt. One unchanged check is not a failure; TICK and check again.

For long end-to-end validation, external harnesses may also poll the Broker job, but the ScienceDiscovery skill itself remains responsible for monitoring its submitted job to terminal state.

  1. At terminal state:
  • succeeded: the next tool call is run_npu_job(operation="result", job_id="<job-id>"). That call declares Project Artifacts from createdFiles: every file when there are 50 or fewer, otherwise the first 50. Summarize stage counts from result.job.createdFiles / result.job.createdFiles.length, and report how many entries in result.artifacts have ok:true. If createdFiles.length is greater than 50, or result.artifacts contains a truncated entry, the final response MUST include this reminder: only 50 files are registered as Project Artifacts; the remaining files are in the Session workspace under antibody_pipeline/runs/<run_name>/, and antibody_pipeline/artifact_manifest.txt lists them. Tell the user to open the workspace files to find the rest, not only the artifact list. If result says the job is not terminal, return to step 5. Do not read screening CSV/Markdown from the workspace before result. Do not write any extra summary/report file. After result returns, you may read declared screening report/CSV artifacts for top-candidate details.
  • failed, cancelled, or interrupted: stop immediately; do not rewrite config/scripts/PDB files and do not resubmit.

Success criteria

  • Broker state is succeeded.
  • run_npu_job(operation="result") was called after that succeeded status and returned result.artifacts.
  • RFdiffusion, ProteinMPNN, Protenix input/output counts equal num_designs.
  • Screening reports exist below antibody_pipeline/runs/<run_name>/05_screening/.
  • Screening rows contain non-empty target_chain / binder_chain, positive target/binder token counts, and the mapped hotspot_sequence_positions.
  • Project Artifacts include the Broker createdFiles up to the 50-file declaration cap (all of them when there are 50 or fewer).
  • When more than 50 files were created, the final response reminds the user that the remaining files are in the Session workspace, not missing.
  • The final response is based on run_npu_job(operation="result"); it must not be based on an Agent-authored workspace scan or a separately written summary artifact.

Zero candidates passing the scientific screen is a valid result if all pipeline stages and reports completed.

Failure interpretation

SymptomMeaningRequired action
run_npu_job missing or workload absentBroker disabled or wrong stackStop and report deployment mismatch
no managed environment passes the dependency probeScientific environment is absent or incompleteCreate/update it with environment_create / environment_install, then probe the environment ID's latest state before submission
missing target/framework PDBUser has not provided the required scientific PDB input, or the Agent did not write it into the Session workspaceStop and ask the user for the missing PDB; do not run a default example
workspace input path error for a custom PDBAgent-authored custom input is missing or escapes the Session workspaceStop and report the offending relative input
hotspot is absent or insertion-code ambiguousThe requested original PDB residue cannot be mapped safelyStop and ask the user to correct the target chain/residue list; do not guess a replacement residue
target chain or CIF atom mapping is empty/ambiguousScreening cannot identify the Protenix target structure safelyTreat the job as failed and return the exact mapping error; do not report zero contacts
operator asset variable/path errorServer deployment configuration is incompleteStop and report the named variable/path to the operator
Container ID verify failedModel was launched inside bwrap instead of BrokerStop; report incorrect execution path
Protenix jobs failed: ... launched X/Y, completed N, skipped MOne or more parallel Protenix design jobs failed; fail-fast may have intentionally skipped unlaunched designsStop; return the failed design names, completed/skipped counts, job ID, stage, and short logs without resubmitting
workload exit code / model tracebackHost pipeline or model failureStop; return job ID, stage, and short logs without resubmitting
result says the job is not terminalStatus/probe completion check was earlyReturn to step 5; do not declare artifacts
succeeded job but result was never called, or result.artifacts is missing/emptyAutomatic artifact declaration did not runCall result; do not recover by declaring only screening Markdown/CSV

Signals

GitHub stars
55
Forks
12
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
antibody-protenix-pipeline
Source
github.com/openjiuwen-ai/sciencediscovery