Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Protein language models (ESM3, ESM C) for sequence generation, structure prediction, inverse folding, and embeddings. Design novel proteins, extract ML features, or fold sequences. Local GPU or EvolutionaryScale Forge API. Use AlphaFold for traditional folding; RDKit for small molecules.
.claude/skills/jaechang-hits-esm-protein-language-model/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 125% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 197% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 114% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 136% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 113% | 0% |
ESM (Evolutionary Scale Modeling) provides pretrained protein language models for generative protein design and representation learning. ESM3 is a multimodal generative model conditioned on sequence, structure, and function simultaneously. ESM C is an efficient embedding model optimized for extracting protein representations for downstream ML tasks.
esm (EvolutionaryScale package)bashpip install esm # For Forge cloud API pip install esm[forge]
pythonfrom esm.models.esmc import ESMC from esm.sdk.api import ESMProtein # Load ESM C model for embeddings model = ESMC.from_pretrained("esmc_600m") # Create protein from sequence protein = ESMProtein(sequence="MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGDGTQDNLSGAEKAVQVKVKALPDAQFEVVHSLAKWKRQQIAATGFHIIPGDKPDNRAGGYDN") # Get per-residue embeddings output = model(protein) embeddings = output.embeddings # shape: (1, seq_len, embedding_dim) print(f"Embedding shape: {embeddings.shape}") # Embedding shape: (1, 101, 1152)
Generate novel protein sequences conditioned on structure, function, or partial sequence.
pythonfrom esm.models.esm3 import ESM3 from esm.sdk.api import ESM3InferenceClient, ESMProtein, GenerationConfig # Load ESM3 locally model = ESM3.from_pretrained("esm3_sm_open_v1") # Generate from partial sequence (fill in masked positions) prompt = ESMProtein(sequence="MKTAYIAK____ISFVK____RQLEERLG") # ____ = positions to generate config = GenerationConfig(track="sequence", num_steps=10, temperature=0.7) generated = model.generate(prompt, config) print(f"Generated sequence: {generated.sequence[:50]}...")
python# Conditional generation: design sequence for a target structure from esm.sdk.api import ESMProtein, GenerationConfig from esm.utils.structure.protein_chain import ProteinChain # Load target structure from PDB chain = ProteinChain.from_pdb("target.pdb") prompt = ESMProtein.from_protein_chain(chain) prompt.sequence = None # Clear sequence, keep structure config = GenerationConfig(track="sequence", num_steps=16, temperature=0.5) designed = model.generate(prompt, config) print(f"Designed sequence ({len(designed.sequence)} residues): {designed.sequence[:50]}...")
Extract fixed-length representations for downstream ML tasks.
pythonfrom esm.models.esmc import ESMC from esm.sdk.api import ESMProtein import torch model = ESMC.from_pretrained("esmc_600m") # or "esmc_300m" for lighter model sequences = [ "MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGDGTQDNLSGAEKAVQVKVKALPDAQFEVVHSLAKWKRQQIAATGFHIIPGDKPDNRAGGYDN", "MKWVTFISLLFLFSSAYSRGVFRRDAHKSEVAHRFKDLGEENFKALVLIAFAQYLQQCPFEDHVKLVNEVTEFAKTCVADESAENCDKS", ] embeddings = [] for seq in sequences: protein = ESMProtein(sequence=seq) output = model(protein) # Mean-pool per-residue embeddings to get fixed-length vector mean_emb = output.embeddings.mean(dim=1) # shape: (1, embedding_dim) embeddings.append(mean_emb) emb_matrix = torch.cat(embeddings, dim=0) print(f"Embedding matrix: {emb_matrix.shape}") # (2, 1152) # Compute pairwise similarity similarity = torch.cosine_similarity(emb_matrix[0:1], emb_matrix[1:2]) print(f"Cosine similarity: {similarity.item():.4f}")
Predict 3D coordinates from amino acid sequence.
pythonfrom esm.models.esm3 import ESM3 from esm.sdk.api import ESMProtein, GenerationConfig model = ESM3.from_pretrained("esm3_sm_open_v1") protein = ESMProtein(sequence="MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGDGTQDNLSGAEKAVQVKVKALPDAQFEVVHSLAKWKRQQIAATGFHIIPGDKPDNRAGGYDN") # Generate structure from sequence config = GenerationConfig(track="structure", num_steps=16) result = model.generate(protein, config) # Save predicted structure result.to_pdb("predicted.pdb") print(f"Saved structure: {len(result.sequence)} residues → predicted.pdb")
Design amino acid sequences that fold into a target 3D structure.
pythonfrom esm.models.esm3 import ESM3 from esm.sdk.api import ESMProtein, GenerationConfig from esm.utils.structure.protein_chain import ProteinChain model = ESM3.from_pretrained("esm3_sm_open_v1") # Load target structure chain = ProteinChain.from_pdb("target_structure.pdb") prompt = ESMProtein.from_protein_chain(chain) # Clear sequence but keep structure coordinates prompt.sequence = None # Generate multiple designs designs = [] for i in range(5): config = GenerationConfig(track="sequence", num_steps=16, temperature=0.7) designed = model.generate(prompt, config) designs.append(designed.sequence) print(f"Design {i+1}: {designed.sequence[:40]}...") print(f"Generated {len(designs)} sequence designs for target structure")
Generate proteins with desired functional annotations (GO terms, enzyme activity).
pythonfrom esm.models.esm3 import ESM3 from esm.sdk.api import ESMProtein, GenerationConfig model = ESM3.from_pretrained("esm3_sm_open_v1") # Condition on functional keywords protein = ESMProtein( sequence=None, # generate de novo function_annotations=["ATP binding", "kinase activity", "protein phosphorylation"], ) config = GenerationConfig(track="sequence", num_steps=32, temperature=0.7) result = model.generate(protein, config) print(f"Function-conditioned sequence: {result.sequence[:50]}...") print(f"Length: {len(result.sequence)} residues")
Use EvolutionaryScale's cloud inference for large models without local GPU.
pythonfrom esm.sdk.forge import ESM3ForgeInferenceClient from esm.sdk.api import ESMProtein, GenerationConfig # Authenticate (requires FORGE_API_TOKEN env var or explicit token) client = ESM3ForgeInferenceClient(model="esm3-open-2024-03", token="your_token_here") protein = ESMProtein(sequence="MKTAYIAKQRQISFVKSHFSRQLEERLG") config = GenerationConfig(track="structure", num_steps=16) result = client.generate(protein, config) result.to_pdb("forge_predicted.pdb") print("Predicted structure via Forge API → forge_predicted.pdb")
| Feature | ESM3 | ESM C | |---------|------|-------| | Primary use | Generative protein design | Embedding extraction | | Capabilities | Sequence generation, structure prediction, inverse folding, function conditioning | Per-residue and mean-pooled embeddings | | Model sizes | esm3_sm_open_v1 (~1.4B params) | esmc_300m, esmc_600m | | GPU requirement | 8GB+ VRAM | 4GB+ VRAM (esmc_300m: 2GB) | | Use case | Design new proteins, predict structures | Downstream ML (classification, clustering, regression) | | Cloud option | Forge API (larger models available) | Local only |
The GenerationConfig controls how ESM3 generates outputs:
track: Which modality to generate ("sequence", "structure", "function")num_steps: Number of iterative refinement steps (higher = better quality, slower)temperature: Sampling temperature (0.0 = greedy, 0.5-0.7 = diverse, 1.0 = maximum diversity)The central data container holding sequence, structure coordinates, and functional annotations:
.sequence — amino acid string (e.g., "MKTAY...").coordinates — 3D atom positions (Nx3 tensor).function_annotations — list of functional keywordsESMProtein.from_protein_chain() to load from PDB structures.to_pdb() to save predicted structuresGoal: Extract embeddings from protein sequences and train a downstream classifier.
pythonfrom esm.models.esmc import ESMC from esm.sdk.api import ESMProtein import torch import numpy as np model = ESMC.from_pretrained("esmc_600m") # Embed a set of sequences sequences = ["MKTAY...", "MKWVT...", "MSGLI..."] # replace with actual sequences labels = [0, 1, 0] # binary labels embeddings = [] for seq in sequences: protein = ESMProtein(sequence=seq) output = model(protein) mean_emb = output.embeddings.mean(dim=1).detach().cpu().numpy() embeddings.append(mean_emb.squeeze()) X = np.array(embeddings) y = np.array(labels) print(f"Feature matrix: {X.shape}") # (n_samples, 1152) # Train a simple classifier from sklearn.linear_model import LogisticRegression clf = LogisticRegression(max_iter=1000).fit(X, y) print(f"Training accuracy: {clf.score(X, y):.2f}")
Goal: Design multiple novel sequences that fold into a target structure, then rank by predicted quality.
ProteinChain.from_pdb() (Core API module 4)temperature=0.7 for diversity (Core API module 1)| Parameter | Module/Function | Default | Range / Options | Effect | |-----------|----------------|---------|-----------------|--------| | num_steps | GenerationConfig | varies | 1–64 | Iterative refinement steps; more = higher quality, slower | | temperature | GenerationConfig | 1.0 | 0.0–1.5 | Sampling diversity; 0.0=greedy, 0.7=balanced, 1.0+=creative | | track | GenerationConfig | — | "sequence", "structure", "function" | Which modality to generate | | model name | from_pretrained | — | "esm3_sm_open_v1", "esmc_300m", "esmc_600m" | Model size/capability tradeoff | | token | ESM3ForgeInferenceClient | env var | API token string | Forge cloud authentication |
embeddings.mean(dim=1).pythonfrom esm.models.esmc import ESMC from esm.sdk.api import ESMProtein import torch import numpy as np model = ESMC.from_pretrained("esmc_300m") sequences = { "Protein_A": "MKTAYIAKQRQISFVK...", "Protein_B": "MKWVTFISLLFLFSSAYS...", "Protein_C": "MSGLILQRAAVIAAGASSAG...", } # Extract embeddings embs = {} for name, seq in sequences.items(): protein = ESMProtein(sequence=seq) output = model(protein) embs[name] = output.embeddings.mean(dim=1).detach().squeeze() # Compute similarity matrix names = list(embs.keys()) sim_matrix = np.zeros((len(names), len(names))) for i, n1 in enumerate(names): for j, n2 in enumerate(names): sim_matrix[i, j] = torch.cosine_similarity(embs[n1].unsqueeze(0), embs[n2].unsqueeze(0)).item() print("Similarity matrix:") for i, name in enumerate(names): print(f" {name}: {sim_matrix[i].round(3)}")
pythonfrom esm.models.esmc import ESMC from esm.sdk.api import ESMProtein import torch import numpy as np model = ESMC.from_pretrained("esmc_600m") # Generate and save protein = ESMProtein(sequence="MKTAYIAKQRQISFVK...") output = model(protein) np.save("embedding.npy", output.embeddings.detach().cpu().numpy()) print("Saved embedding.npy") # Load later (no GPU needed) embedding = np.load("embedding.npy") print(f"Loaded embedding: {embedding.shape}")
| Problem | Cause | Solution | |---------|-------|----------| | CUDA out of memory | Model too large for GPU | Use smaller model (esmc_300m), reduce batch size, or use Forge cloud API | | RuntimeError: no CUDA device | No GPU available | Models work on CPU (slower). Set device="cpu" or use Forge API | | Slow generation | Too many num_steps or CPU inference | Reduce num_steps (8 for drafts), use GPU, or use Forge API for large models | | ImportError: esm | Package not installed | pip install esm (note: this is EvolutionaryScale's esm, not the older Facebook Research esm) | | Low-quality generated sequences | Temperature too high or too few steps | Lower temperature to 0.5, increase num_steps to 32+ | | Forge API authentication error | Invalid or missing API token | Set FORGE_API_TOKEN env var or pass token= explicitly; get token from forge.evolutionaryscale.ai | | KeyError loading model weights | Wrong model name | Use exact names: "esm3_sm_open_v1", "esmc_300m", "esmc_600m" |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 29,258 | 28,331 | -3% | 1 | 1 | 0% | 3,287 | 7,390 | +125% | 0 | 0 | — |
case-02 | fail→pass | 11,593 | 6,482 | -44% | 1 | 1 | 0% | 1,930 | 5,723 | +197% | 0 | 0 | — |
case-03 | fail→pass | 19,174 | 9,082 | -53% | 1 | 1 | 0% | 2,932 | 6,281 | +114% | 0 | 0 | — |
case-04 | pass→pass | 7,948 | 5,334 | -33% | 1 | 1 | 0% | 1,388 | 5,203 | +275% | 0 | 0 | — |
case-05 | pass→pass | 9,583 | 6,155 | -36% | 1 | 1 | 0% | 1,914 | 5,668 | +196% | 0 | 0 | — |
case-06 | pass→pass | 5,465 | 3,079 | -44% | 1 | 1 | 0% | 1,065 | 4,982 | +368% | 0 | 0 | — |
case-07 | fail→pass | 13,621 | 7,257 | -47% | 1 | 1 | 0% | 2,451 | 5,782 | +136% | 0 | 0 | — |
case-08 | fail→pass | 13,844 | 3,581 | -74% | 1 | 1 | 0% | 2,388 | 5,090 | +113% | 0 | 0 | — |
case-09 | fail→pass | 9,597 | 4,380 | -54% | 1 | 1 | 0% | 1,597 | 5,358 | +236% | 0 | 0 | — |
case-10 | pass→pass | 23,163 | 4,885 | -79% | 1 | 1 | 0% | 1,773 | 5,369 | +203% | 0 | 0 | — |
case-11 | fail→pass | 11,008 | 5,592 | -49% | 1 | 1 | 0% | 2,044 | 5,585 | +173% | 0 | 0 | — |
case-12 | fail→pass | 9,234 | 4,142 | -55% | 1 | 1 | 0% | 1,651 | 5,212 | +216% | 0 | 0 | — |
case-13 | fail→pass | 15,920 | 9,955 | -37% | 1 | 1 | 0% | 3,021 | 6,461 | +114% | 0 | 0 | — |
case-14 | fail→pass | 8,769 | 4,969 | -43% | 1 | 1 | 0% | 1,501 | 5,250 | +250% | 0 | 0 | — |
case-15 | fail→pass | 8,843 | 2,968 | -66% | 1 | 1 | 0% | 1,421 | 4,979 | +250% | 0 | 0 | — |
case-16 | pass→pass | 14,837 | 8,236 | -44% | 1 | 1 | 0% | 2,609 | 6,150 | +136% | 0 | 0 | — |
case-17 | pass→pass | 5,446 | 2,935 | -46% | 1 | 1 | 0% | 889 | 4,899 | +451% | 0 | 0 | — |
case-18 | pass→pass | 9,809 | 4,730 | -52% | 1 | 1 | 0% | 1,630 | 5,354 | +228% | 0 | 0 | — |
case-19 | pass→pass | 6,649 | 3,154 | -53% | 1 | 1 | 0% | 1,263 | 5,056 | +300% | 0 | 0 | — |
case-20 | pass→pass | 10,214 | 8,603 | -16% | 1 | 1 | 0% | 1,815 | 6,095 | +236% | 0 | 0 | — |
case-21 | pass→pass | 11,503 | 5,399 | -53% | 1 | 1 | 0% | 2,021 | 5,506 | +172% | 0 | 0 | — |
case-22 | pass→pass | 12,841 | 4,246 | -67% | 1 | 1 | 0% | 2,407 | 5,283 | +119% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +50 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.