> ## Documentation Index
> Fetch the complete documentation index at: https://proto.evodesign.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools

> Bioinformatics tools that Proto orchestrates for sequence analysis, structure prediction, and more

# Tools

<Note>
  For full tool documentation, API references, and standalone usage guides, see the **[Proto Tools docs](/docs/tools/introduction)**.
</Note>

Tools are standardized Python implementations of 120+ bioinformatics tools: structure predictors, sequence scorers, gene annotators, and alignment engines. When a [constraint](/docs/language/concepts/constraints) needs to predict a protein's 3D structure or search for sequence motifs, it calls a tool.

Tools are rarely called directly; constraints call them behind the scenes, and the [optimizer](/docs/language/concepts/optimizers) manages caching and execution. Understanding tools nonetheless helps in configuring constraints effectively.

## The Input / Config / Output Pattern

Every tool follows the same three-part pattern using Pydantic models:

<div className="block dark:hidden">
  <svg viewBox="0 0 880 300" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Tool input and config flowing into the tool function and out as tool output" style={{width:"100%",height:"auto",display:"block"}}><defs><pattern id="gridtools1L" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="1.2" fill="#344649" fillOpacity="0.10" /></pattern><marker id="arrtools1L" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 L3,5 z" fill="#768b8e" /></marker></defs><rect x="12" y="12" width="856" height="276" rx="16" fill="#f9fcfc" stroke="#dee9e8" strokeWidth="1.2" /><rect x="12" y="12" width="856" height="276" rx="16" fill="url(#gridtools1L)" /><path d="M234,88 C 286,88 286,141 336,141" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools1L)" /><path d="M234,218 C 286,218 286,165 336,165" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools1L)" /><path d="M526,153 L628,153" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools1L)" /><rect x="44" y="52" width="190" height="72" rx="10" fill="#eef2f4" stroke="#dbe3e6" strokeWidth="1.2" /><rect x="54" y="64" width="4" height="48" rx="2" fill="#768b8e" /><text x="66" y="80" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="14" fontWeight="600" fill="#344649" textAnchor="start">ToolInput</text><text x="66" y="99" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#768b8e" textAnchor="start">(primary data)</text><rect x="44" y="182" width="190" height="72" rx="10" fill="#eef2f4" stroke="#dbe3e6" strokeWidth="1.2" /><rect x="54" y="194" width="4" height="48" rx="2" fill="#768b8e" /><text x="66" y="210" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="14" fontWeight="600" fill="#344649" textAnchor="start">ToolConfig</text><text x="66" y="229" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#768b8e" textAnchor="start">(parameters)</text><rect x="336" y="117" width="190" height="72" rx="10" fill="#046e7a" /><rect x="346" y="129" width="4" height="48" rx="2" fill="#bfe2e7" /><text x="358" y="146" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#ffffff" textAnchor="start">Tool Function</text><text x="358" y="164" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#bfe2e7" textAnchor="start">run\_tool()</text><rect x="628" y="117" width="190" height="72" rx="10" fill="#2f8f6b" /><rect x="638" y="129" width="4" height="48" rx="2" fill="#d4ebe0" /><text x="650" y="145" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="14" fontWeight="600" fill="#ffffff" textAnchor="start">ToolOutput</text><text x="650" y="164" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#d4ebe0" textAnchor="start">(results + metadata)</text><g fill="#ffffff" stroke="#9eb4b2" strokeWidth="1.4"><circle cx="234" cy="88" r="3.2" /><circle cx="336" cy="141" r="3.2" /><circle cx="234" cy="218" r="3.2" /><circle cx="336" cy="165" r="3.2" /><circle cx="526" cy="153" r="3.2" /><circle cx="628" cy="153" r="3.2" /></g></svg>
</div>

<div className="hidden dark:block">
  <svg viewBox="0 0 880 300" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Tool input and config flowing into the tool function and out as tool output" style={{width:"100%",height:"auto",display:"block"}}><defs><pattern id="gridtools1D" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="1.2" fill="#9eb4b2" fillOpacity="0.10" /></pattern><marker id="arrtools1D" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 L3,5 z" fill="#7e9498" /></marker></defs><rect x="12" y="12" width="856" height="276" rx="16" fill="#0e1718" stroke="#2b3c3e" strokeWidth="1.2" /><rect x="12" y="12" width="856" height="276" rx="16" fill="url(#gridtools1D)" /><path d="M234,88 C 286,88 286,141 336,141" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools1D)" /><path d="M234,218 C 286,218 286,165 336,165" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools1D)" /><path d="M526,153 L628,153" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools1D)" /><rect x="44" y="52" width="190" height="72" rx="10" fill="#1b2829" stroke="#33474a" strokeWidth="1.2" /><rect x="54" y="64" width="4" height="48" rx="2" fill="#7e9498" /><text x="66" y="80" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="14" fontWeight="600" fill="#d6e1df" textAnchor="start">ToolInput</text><text x="66" y="99" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#8aa0a2" textAnchor="start">(primary data)</text><rect x="44" y="182" width="190" height="72" rx="10" fill="#1b2829" stroke="#33474a" strokeWidth="1.2" /><rect x="54" y="194" width="4" height="48" rx="2" fill="#7e9498" /><text x="66" y="210" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="14" fontWeight="600" fill="#d6e1df" textAnchor="start">ToolConfig</text><text x="66" y="229" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#8aa0a2" textAnchor="start">(parameters)</text><rect x="336" y="117" width="190" height="72" rx="10" fill="#0a7e8c" /><rect x="346" y="129" width="4" height="48" rx="2" fill="#c0e6ea" /><text x="358" y="146" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#ffffff" textAnchor="start">Tool Function</text><text x="358" y="164" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#c0e6ea" textAnchor="start">run\_tool()</text><rect x="628" y="117" width="190" height="72" rx="10" fill="#2f8f6b" /><rect x="638" y="129" width="4" height="48" rx="2" fill="#cfeadd" /><text x="650" y="145" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="14" fontWeight="600" fill="#ffffff" textAnchor="start">ToolOutput</text><text x="650" y="164" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#cfeadd" textAnchor="start">(results + metadata)</text><g fill="#13201f" stroke="#566b6e" strokeWidth="1.4"><circle cx="234" cy="88" r="3.2" /><circle cx="336" cy="141" r="3.2" /><circle cx="234" cy="218" r="3.2" /><circle cx="336" cy="165" r="3.2" /><circle cx="526" cy="153" r="3.2" /><circle cx="628" cy="153" r="3.2" /></g></svg>
</div>

* **Input**: *What* to analyze. The primary data: sequences, structures, files.
* **Config**: *How* to analyze it. Parameters and settings. Always optional; sensible defaults are built in.
* **Output**: Results plus standardized metadata (execution time, success status, tool ID, warnings).

## Tool Categories

<CardGroup cols={3}>
  <Card title="Structure Prediction" icon="box" href="/docs/tools/structure-prediction/overview">
    Predict 3D structures from sequences.

    **AlphaFold2**, **AlphaFold3**, **Boltz2**, **Chai1**, **ESMFold**, **Protenix**, **ViennaRNA**
  </Card>

  <Card title="Structure Design" icon="pencil-ruler" href="/docs/tools/structure-design/overview">
    Generate novel protein backbone structures.

    **RFDiffusion3**
  </Card>

  <Card title="Structure Dynamics" icon="orbit" href="/docs/tools/structure-dynamics/overview">
    Sample conformational ensembles.

    **BioEmu**
  </Card>

  <Card title="Inverse Folding" icon="undo-2" href="/docs/tools/inverse-folding/overview">
    Design sequences for target structures.

    **ProteinMPNN**, **LigandMPNN**, **FAMPNN**
  </Card>

  <Card title="Masked Models" icon="arrow-left-right" href="/docs/tools/masked-models/overview">
    Protein language models for scoring and sampling.

    **ESM2**, **ESM3**
  </Card>

  <Card title="Causal Models" icon="arrow-right" href="/docs/tools/causal-models/overview">
    Autoregressive models for generation and scoring.

    **Evo1**, **Evo2**, **ProGen2**
  </Card>

  <Card title="Sequence Scoring" icon="gauge" href="/docs/tools/sequence-scoring/overview">
    Predict functional effects from genomic sequences.

    **Enformer**, **Borzoi**, **AlphaGenome**, **Segmasker**
  </Card>

  <Card title="Gene Annotation" icon="tag" href="/docs/tools/gene-annotation/overview">
    Annotate sequences with genes, domains, and motifs.

    **PyHMMER**, **CRISPR-tracr**, **MinCED**
  </Card>

  <Card title="Sequence Alignment" icon="columns-3" href="/docs/tools/sequence-alignment/overview">
    Search databases and align sequences.

    **BLAST**, **MMseqs2**, **MAFFT**, **ColabFold Search**
  </Card>

  <Card title="ORF Prediction" icon="microscope" href="/docs/tools/orf-prediction/overview">
    Find open reading frames in DNA.

    **Orfipy**, **Prodigal**
  </Card>

  <Card title="RNA Splicing" icon="scissors" href="/docs/tools/rna-splicing/overview">
    Predict splice sites and specificity.

    **SpliceTransformer**
  </Card>

  <Card title="Database Retrieval" icon="database" href="/docs/tools/database-retrieval/overview">
    Fetch sequences and structures from public databases.

    **UniProt**, **PDB**, **NCBI**, **SequenceFetch**
  </Card>

  <Card title="Structure Alignment" icon="move-3d" href="/docs/tools/structure-alignment/overview">
    Align and compare 3D protein structures.

    **TMAlign**, **USAlign**
  </Card>
</CardGroup>

## How Tools Connect to Constraints

When a [constraint](/docs/language/concepts/constraints) such as `structure_plddt_constraint` is created, the constraint function internally calls the appropriate tool. Here is the flow:

<div className="block dark:hidden">
  <svg viewBox="0 0 1090 310" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="How a constraint calls a tool and returns a normalized score" style={{width:"100%",height:"auto",display:"block"}}><defs><pattern id="gridtools2L" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="1.2" fill="#344649" fillOpacity="0.10" /></pattern><marker id="arrtools2L" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 L3,5 z" fill="#768b8e" /></marker></defs><rect x="12" y="12" width="1066" height="286" rx="16" fill="#f9fcfc" stroke="#dee9e8" strokeWidth="1.2" /><rect x="12" y="12" width="1066" height="286" rx="16" fill="url(#gridtools2L)" /><path d="M258,77 L308,77" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><path d="M522,77 L572,77" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><path d="M786,77 L836,77" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><path d="M892,110 C 872,150 860,172 840,204" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><path d="M780,204 C 760,172 748,150 728,110" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><path d="M632,110 C 612,150 600,172 580,204" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><path d="M520,204 C 500,172 488,150 448,110" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><path d="M384,110 C 384,160 210,160 210,110" fill="none" stroke="#9eb4b2" strokeWidth="1.6" markerEnd="url(#arrtools2L)" /><rect x="44" y="44" width="214" height="66" rx="10" fill="#eef2f4" stroke="#dbe3e6" strokeWidth="1.2" /><rect x="54" y="56" width="4" height="42" rx="2" fill="#768b8e" /><text x="66" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#344649" textAnchor="start">Optimizer</text><text x="66" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#768b8e" textAnchor="start">score\_energy()</text><rect x="308" y="44" width="214" height="66" rx="10" fill="#eef2f4" stroke="#dbe3e6" strokeWidth="1.2" /><rect x="318" y="56" width="4" height="42" rx="2" fill="#768b8e" /><text x="330" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#344649" textAnchor="start">Constraint</text><text x="330" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#768b8e" textAnchor="start">evaluate()</text><rect x="572" y="44" width="214" height="66" rx="10" fill="#eef2f4" stroke="#dbe3e6" strokeWidth="1.2" /><rect x="582" y="56" width="4" height="42" rx="2" fill="#768b8e" /><text x="594" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#344649" textAnchor="start">Constraint Function</text><text x="594" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#768b8e" textAnchor="start">structure\_plddt\_constraint()</text><rect x="836" y="44" width="214" height="66" rx="10" fill="#046e7a" /><rect x="846" y="56" width="4" height="42" rx="2" fill="#bfe2e7" /><text x="858" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#ffffff" textAnchor="start">Tool</text><text x="858" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#bfe2e7" textAnchor="start">run\_esmfold()</text><rect x="704" y="204" width="214" height="66" rx="10" fill="#eef2f4" stroke="#dbe3e6" strokeWidth="1.2" /><rect x="714" y="216" width="4" height="42" rx="2" fill="#768b8e" /><text x="726" y="229" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#344649" textAnchor="start">Raw Results</text><text x="726" y="248" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#768b8e" textAnchor="start">(structures, scores)</text><rect x="440" y="204" width="214" height="66" rx="10" fill="#2f8f6b" /><rect x="450" y="216" width="4" height="42" rx="2" fill="#d4ebe0" /><text x="462" y="229" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#ffffff" textAnchor="start">Normalized Score</text><text x="462" y="248" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#d4ebe0" textAnchor="start">0.0 to 1.0</text><g fill="#ffffff" stroke="#9eb4b2" strokeWidth="1.4"><circle cx="258" cy="77" r="3.2" /><circle cx="308" cy="77" r="3.2" /><circle cx="522" cy="77" r="3.2" /><circle cx="572" cy="77" r="3.2" /><circle cx="786" cy="77" r="3.2" /><circle cx="836" cy="77" r="3.2" /><circle cx="892" cy="110" r="3.2" /><circle cx="840" cy="204" r="3.2" /><circle cx="780" cy="204" r="3.2" /><circle cx="728" cy="110" r="3.2" /><circle cx="632" cy="110" r="3.2" /><circle cx="580" cy="204" r="3.2" /><circle cx="520" cy="204" r="3.2" /><circle cx="448" cy="110" r="3.2" /><circle cx="384" cy="110" r="3.2" /><circle cx="210" cy="110" r="3.2" /></g></svg>
</div>

<div className="hidden dark:block">
  <svg viewBox="0 0 1090 310" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="How a constraint calls a tool and returns a normalized score" style={{width:"100%",height:"auto",display:"block"}}><defs><pattern id="gridtools2D" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="1.2" fill="#9eb4b2" fillOpacity="0.10" /></pattern><marker id="arrtools2D" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 L3,5 z" fill="#7e9498" /></marker></defs><rect x="12" y="12" width="1066" height="286" rx="16" fill="#0e1718" stroke="#2b3c3e" strokeWidth="1.2" /><rect x="12" y="12" width="1066" height="286" rx="16" fill="url(#gridtools2D)" /><path d="M258,77 L308,77" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><path d="M522,77 L572,77" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><path d="M786,77 L836,77" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><path d="M892,110 C 872,150 860,172 840,204" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><path d="M780,204 C 760,172 748,150 728,110" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><path d="M632,110 C 612,150 600,172 580,204" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><path d="M520,204 C 500,172 488,150 448,110" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><path d="M384,110 C 384,160 210,160 210,110" fill="none" stroke="#566b6e" strokeWidth="1.6" markerEnd="url(#arrtools2D)" /><rect x="44" y="44" width="214" height="66" rx="10" fill="#1b2829" stroke="#33474a" strokeWidth="1.2" /><rect x="54" y="56" width="4" height="42" rx="2" fill="#7e9498" /><text x="66" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#d6e1df" textAnchor="start">Optimizer</text><text x="66" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#8aa0a2" textAnchor="start">score\_energy()</text><rect x="308" y="44" width="214" height="66" rx="10" fill="#1b2829" stroke="#33474a" strokeWidth="1.2" /><rect x="318" y="56" width="4" height="42" rx="2" fill="#7e9498" /><text x="330" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#d6e1df" textAnchor="start">Constraint</text><text x="330" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#8aa0a2" textAnchor="start">evaluate()</text><rect x="572" y="44" width="214" height="66" rx="10" fill="#1b2829" stroke="#33474a" strokeWidth="1.2" /><rect x="582" y="56" width="4" height="42" rx="2" fill="#7e9498" /><text x="594" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#d6e1df" textAnchor="start">Constraint Function</text><text x="594" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#8aa0a2" textAnchor="start">structure\_plddt\_constraint()</text><rect x="836" y="44" width="214" height="66" rx="10" fill="#0a7e8c" /><rect x="846" y="56" width="4" height="42" rx="2" fill="#c0e6ea" /><text x="858" y="70" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#ffffff" textAnchor="start">Tool</text><text x="858" y="88" fontFamily="'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace" fontSize="10.5" fontWeight="400" fill="#c0e6ea" textAnchor="start">run\_esmfold()</text><rect x="704" y="204" width="214" height="66" rx="10" fill="#1b2829" stroke="#33474a" strokeWidth="1.2" /><rect x="714" y="216" width="4" height="42" rx="2" fill="#7e9498" /><text x="726" y="229" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#d6e1df" textAnchor="start">Raw Results</text><text x="726" y="248" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#8aa0a2" textAnchor="start">(structures, scores)</text><rect x="440" y="204" width="214" height="66" rx="10" fill="#2f8f6b" /><rect x="450" y="216" width="4" height="42" rx="2" fill="#cfeadd" /><text x="462" y="229" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="14.5" fontWeight="600" fill="#ffffff" textAnchor="start">Normalized Score</text><text x="462" y="248" fontFamily="Geist, ui-sans-serif, system-ui, -apple-system, sans-serif" fontSize="12" fontWeight="400" fill="#cfeadd" textAnchor="start">0.0 to 1.0</text><g fill="#13201f" stroke="#566b6e" strokeWidth="1.4"><circle cx="258" cy="77" r="3.2" /><circle cx="308" cy="77" r="3.2" /><circle cx="522" cy="77" r="3.2" /><circle cx="572" cy="77" r="3.2" /><circle cx="786" cy="77" r="3.2" /><circle cx="836" cy="77" r="3.2" /><circle cx="892" cy="110" r="3.2" /><circle cx="840" cy="204" r="3.2" /><circle cx="780" cy="204" r="3.2" /><circle cx="728" cy="110" r="3.2" /><circle cx="632" cy="110" r="3.2" /><circle cx="580" cy="204" r="3.2" /><circle cx="520" cy="204" r="3.2" /><circle cx="448" cy="110" r="3.2" /><circle cx="384" cy="110" r="3.2" /><circle cx="210" cy="110" r="3.2" /></g></svg>
</div>

**The tool is configured through the constraint's `function_config`.** For example, the `structure_plddt_constraint` config selects which structure predictor to use:

```python python icon="python" theme={null}
from proto_language.constraint import structure_plddt_constraint

# The constraint internally calls the specified tool
Constraint(
    inputs=[protein_segment],
    function=structure_plddt_constraint,
    function_config={
        "structure_tool": "esmfold",  # Which tool to use: "esmfold", "boltz2", "alphafold3", ...
    },
    weight=2.0,
)
```

### Tool Caching

When the same sequence is evaluated by multiple constraints that use the same tool, the tool cache prevents redundant computation:

```python python icon="python" theme={null}
# Both constraints use ESMFold internally.
# The second call hits the cache -- no redundant GPU work.
plddt_constraint = Constraint(
    inputs=[segment],
    function=structure_plddt_constraint,
    function_config={"structure_tool": "esmfold"},
)
ptm_constraint = Constraint(
    inputs=[segment],
    function=structure_ptm_constraint,
    function_config={"structure_tool": "esmfold"},
)
```

The optimizer manages cache lifecycle. See [Optimizers: Tool Cache Management](/docs/language/concepts/optimizers#tool-cache-management) for configuration options.

## GPU vs CPU Tools

<Columns>
  <Column>
    ### GPU Tools

    Deep learning models that require NVIDIA GPUs.

    * **Structure Prediction:** AlphaFold3, Boltz2, Chai1, ESMFold, Protenix
    * **Inverse Folding:** ProteinMPNN, LigandMPNN
    * **Language Models:** ESM2, ESM3, Evo2, ProGen2
    * **Sequence Scoring:** Enformer, Borzoi, AlphaGenome
    * **Structure Design:** RFDiffusion3
    * **Structure Dynamics:** BioEmu
    * **RNA Splicing:** SpliceTransformer
  </Column>

  <Column>
    ### CPU Tools

    Classical bioinformatics algorithms. Run anywhere.

    * **Gene Annotation:** PyHMMER, MinCED
    * **Sequence Alignment:** BLAST, MMseqs2, MAFFT, ColabFold Search
    * **ORF Prediction:** Orfipy, Prodigal
    * **Structure Prediction:** ViennaRNA (RNA only)
  </Column>
</Columns>

<Tip>
  When designing optimization pipelines, put CPU-based filter constraints early to screen out bad proposals before GPU-based scoring constraints run. This minimizes expensive GPU time.
</Tip>

## Next Steps

<CardGroup cols={2}>
  <Card title="Tools Documentation" icon="wrench" href="/docs/tools/introduction">
    Full tool API references, standalone usage guides, and detailed documentation
  </Card>

  <Card title="Constraints" icon="square-function" href="/docs/language/concepts/constraints">
    See how tools power constraint evaluation
  </Card>

  <Card title="Generators" icon="cpu" href="/docs/language/concepts/generators">
    Generators that implement language model tools
  </Card>

  <Card title="Optimizers" icon="chart-line" href="/docs/language/concepts/optimizers">
    How optimizers manage tool caching
  </Card>
</CardGroup>
