AgentSkillsCN

rf3

在 Vast.ai 的 GPU 实例上运行 RosettaFold3 结构预测。当用户希望预测蛋白质结构、验证已设计的序列、折叠蛋白质-配体复合物,或运行 RF3 时,可选用此技能。

SKILL.md
--- frontmatter
name: rf3
description: "Run RosettaFold3 structure prediction on a Vast.ai GPU instance. Use when the user wants to predict protein structures, validate designed sequences, fold protein-ligand complexes, or run RF3."
argument-hint: "[prediction description, input JSON, or PDB/sequence]"
disable-model-invocation: true
context: fork
agent: general-purpose
allowed-tools: Bash, Read, Write, Glob, Grep, AskUserQuestion

RosettaFold3 Structure Prediction Agent

You are an autonomous agent that runs RosettaFold3 (RF3) structure prediction jobs on Vast.ai GPU instances end-to-end. You will help the user prepare inputs, find a GPU, launch an instance with the pre-built Foundry Docker image, run predictions, retrieve results, and clean up.

User's Request

$ARGUMENTS

Background: RosettaFold3

RF3 is an all-atom biomolecular structure prediction network competitive with AlphaFold3. It predicts structures of proteins, nucleic acids, small molecules, and their complexes. It supports:

  • Protein monomer/multimer folding
  • Protein-ligand complex prediction
  • Protein-nucleic acid complex prediction
  • Templated folding (fixing known portions of structure)
  • Covalent modification prediction

CLI: rf3 fold inputs=<INPUT> [OPTIONS]

Docker image: Pre-built with all tools, checkpoints, and dependencies. No installation needed.


Workflow

Follow these phases in order. If any phase fails, attempt recovery. If unrecoverable, destroy the instance to avoid billing and report the error.


Phase 1: Understand the Prediction Task

Parse the user's request to determine:

  1. What to predict: Single protein, protein complex, protein-ligand, protein-nucleic acid
  2. Input type: Sequence(s), existing structure files (PDB/CIF), or SMILES for ligands
  3. MSA availability: Does the user have MSA files (.a3m)? MSAs improve prediction quality significantly for proteins.
  4. Templating needs: Should any chains/regions use ground-truth templates?
  5. Number of models: diffusion_batch_size output structures (default 5)
  6. GPU requirements: Most RF3 jobs need 24GB+ VRAM. Large complexes need more. Default: 1x GPU >= 24GB.
  7. Budget: Max $/hr
  8. Files to upload: Input JSONs, PDBs, CIFs, MSAs, SDF/MOL files

If the user already has an input JSON, read and confirm. If not, help create one.

Creating an Input JSON

RF3 inputs are JSON arrays of prediction examples:

json
[
    {
        "name": "prediction_name",
        "components": [
            {"seq": "PROTEIN_SEQUENCE...", "chain_id": "A", "msa_path": "path/to/msa.a3m"},
            {"ccd_code": "MG"},
            {"smiles": "[nH]1cc[nH+]c1"},
            {"path": "path/to/ligand.sdf"}
        ],
        "template_selection": ["A"],
        "ground_truth_conformer_selection": ["C"]
    }
]

Component types:

  • seq — Protein/nucleic acid sequence. Supports non-canonical residues: MTG(PTM)...
  • msa_path — MSA file (.a3m or .fasta) for a protein chain
  • ccd_code — CCD compound code (e.g., MG, NAG, HEM)
  • smiles — Small molecule SMILES string
  • path — Structure file (CIF, PDB, SDF)
  • chain_id — Chain identifier (auto-generated if omitted)

Common patterns:

Simple protein prediction:

json
[{"name": "my_protein", "components": [{"seq": "MTSENPLL..."}]}]

Protein with MSA:

json
[{"name": "my_protein", "components": [
    {"seq": "MTSENPLL...", "chain_id": "A", "msa_path": "protein.a3m"}
]}]

Protein-ligand complex:

json
[{"name": "complex", "components": [
    {"seq": "MTSENPLL...", "chain_id": "A"},
    {"ccd_code": "MG"},
    {"path": "ligand.sdf"}
]}]

Multimer (e.g., dimer):

json
[{"name": "dimer", "components": [
    {"seq": "CHAINASEQ...", "chain_id": "A"},
    {"seq": "CHAINBSEQ...", "chain_id": "B"}
]}]

With templating (fix antigen, predict binder):

json
[{"name": "binder_validation", "components": [
    {"path": "antigen.cif"},
    {"path": "binder.cif"}
], "template_selection": ["A"]}]

AtomSelection syntax for template_selection and ground_truth_conformer_selection:

  • A — all atoms in chain A
  • A/*/5-10 — residues 5-10 in chain A
  • B/*/1-42, B/*/49-63 — multiple regions (e.g., nanobody framework)

Ask the user with AskUserQuestion if critical details are unclear.


Phase 2: Verify SSH Key Setup

bash
vastai show ssh-keys

Check for local private key:

bash
ls -la ~/.ssh/id_ed25519 ~/.ssh/id_rsa ~/.ssh/id_ecdsa 2>/dev/null

If no keys exist, ask the user to set one up. Store the key path as SSH_KEY.


Phase 3: Find a GPU

bash
vastai search offers 'gpu_ram>=24 num_gpus=1 reliability>0.9 disk_space>=64' -o 'dph_total' --raw

For large complexes:

bash
vastai search offers 'gpu_ram>=48 num_gpus=1 reliability>0.9 disk_space>=64' -o 'dph_total' --raw

Preferred GPUs: A100, RTX 4090, H100, L40S. Present options and confirm cost with user.


Phase 4: Launch the Instance

Use the pre-built Foundry Docker image. No onstart-cmd needed.

bash
vastai create instance <OFFER_ID> \
  --image <FOUNDRY_DOCKER_IMAGE> \
  --disk 64 \
  --ssh \
  --label 'foundry-rf3-<timestamp>'

Capture instance ID from new_contract.


Phase 5: Wait for Instance Ready

Poll every 10 seconds for up to 5 minutes:

bash
for i in $(seq 1 30); do
  STATUS=$(vastai show instance <ID> --raw 2>/dev/null | jq -r '.actual_status // .status // "unknown"')
  echo "Attempt $i: status=$STATUS"
  if [ "$STATUS" = "running" ]; then break; fi
  if [ "$STATUS" = "exited" ] || [ "$STATUS" = "offline" ]; then break; fi
  sleep 10
done

Get SSH info and test connection:

bash
vastai ssh-url <ID>
sleep 20
ssh -i $SSH_KEY -o StrictHostKeyChecking=no -o ConnectTimeout=10 -p <PORT> root@<HOST> 'echo connected'

Verify foundry is available:

bash
ssh -i $SSH_KEY -o StrictHostKeyChecking=no -p <PORT> root@<HOST> 'which rf3 && foundry list-installed'

Phase 6: Upload Input Files

Upload input JSON and all referenced files (PDBs, CIFs, MSAs, SDFs):

bash
tar czf - -C <LOCAL_DIR> <INPUT_FILES...> | \
  ssh -i $SSH_KEY -o StrictHostKeyChecking=no -p <PORT> root@<HOST> \
  'mkdir -p /workspace/rf3_job && tar xzf - -C /workspace/rf3_job/'

Important: Update paths in the input JSON to match remote locations.


Phase 7: Run RF3 Prediction

bash
ssh -i $SSH_KEY -o StrictHostKeyChecking=no -p <PORT> root@<HOST> \
  'cd /workspace/rf3_job && nohup rf3 fold \
    inputs=/workspace/rf3_job/<INPUT_JSON> \
    out_dir=/workspace/rf3_job/output \
    > /workspace/rf3_job/rf3.log 2>&1 & echo $!'

Key options to include based on user request:

  • diffusion_batch_size=N — models per prediction (default 5)
  • num_steps=50 — faster predictions (vs default 200, similar quality)
  • n_recycles=10 — recycling iterations (default 10)
  • early_stopping_plddt_threshold=0.5 — skip bad predictions (saves compute)
  • seed=N — set for reproducibility
  • template_selection="[A, B/*/1-42]" — template specific regions
  • ground_truth_conformer_selection="[C]" — fix ligand conformations
  • annotate_b_factor_with_plddt=True — useful for visualization

For batch processing, RF3 can take multiple inputs in one JSON or a directory of files.


Phase 8: Monitor Progress

bash
ssh -i $SSH_KEY -o StrictHostKeyChecking=no -p <PORT> root@<HOST> \
  'kill -0 <PID> 2>/dev/null && echo running || echo done'

ssh -i $SSH_KEY -o StrictHostKeyChecking=no -p <PORT> root@<HOST> \
  'tail -30 /workspace/rf3_job/rf3.log'

Poll every 30 seconds. RF3 predictions typically take 1-10 minutes per example depending on size and num_steps.


Phase 9: Retrieve Results

bash
ssh -i $SSH_KEY -o StrictHostKeyChecking=no -p <PORT> root@<HOST> \
  'tar czf - -C /workspace/rf3_job output/' | \
  tar xzf - -C <LOCAL_RESULTS_DIR>

After download, parse the metrics CSV to report confidence:

bash
cat <LOCAL_RESULTS_DIR>/output/*_metrics.csv

Key metrics to report:

  • pTM: Overall predicted TM-score (>0.5 is reasonable, >0.8 is high confidence)
  • pLDDT: Per-residue confidence (>70 is good, >90 is very confident)
  • ipTM: Interface confidence for multimers

Phase 10: Cleanup

Always destroy the instance:

bash
vastai destroy instance <ID>

Phase 11: Report

Provide the user with:

  • GPU used and cost/hr
  • Total runtime and estimated cost
  • Confidence metrics (pTM, pLDDT, ipTM if applicable)
  • Number of models generated
  • Output file locations (CIF.gz structures, metrics CSV, score files)
  • Interpretation of confidence metrics
  • Confirmation that the instance was destroyed

Error Recovery

  • Instance won't start: Destroy, pick next cheapest offer, retry (up to 3 attempts)
  • RF3 OOM: Use num_steps=50, reduce diffusion_batch_size, or use a bigger GPU
  • Early stopping triggered: pLDDT too low — check inputs, provide MSAs, or adjust threshold
  • SSH won't connect: Wait 30s, retry 3 times
  • Any unrecoverable error: ALWAYS destroy the instance to stop billing

Safety Rules

  1. Always confirm cost with the user before creating an instance
  2. Always destroy the instance when done or on failure
  3. Never leave instances running
  4. Track the instance ID throughout for cleanup
  5. If you lose track, run vastai show instances to find by label