Skip to main content
Oracles provide predictions (structure, embeddings, etc.) that energy terms use to compute scores. This guide shows you how to add your own.

The Oracle base class

All oracles inherit from Oracle and must implement a predict() method that takes a list of chains and returns an OracleResult:
Key points:
  • result_class must be set to your custom result class (a subclass of OracleResult). This enables type checking when energy terms access results.
  • Oracles are not copied during system copies — they are shared references. This avoids duplicating heavy model weights in memory.

Defining a result class

Result classes use Pydantic BaseModel and must implement save_attributes():
The input_chains field is inherited from OracleResult and is always required — it records which chains were passed to the oracle.

Implementing predict()

The predict() method receives a list of Chain objects and must return an instance of your result class:

Folding vs embedding oracles

For common prediction types, BAGEL provides specialized base classes with more structure:

FoldingOracle

For models that predict 3D structures. Implement fold() instead of predict():
FoldingOracle automatically routes predict() to fold(). Energy terms access the structure via oracles_result.get_structure(oracle).

EmbeddingOracle

For language models that produce per-residue embeddings. Implement embed(), _pre_process(), and _post_process():
Energy terms access embeddings via oracles_result.get_embeddings(oracle).

Example: a custom oracle

Here is a simple property oracle that computes a solubility score based on sequence composition:
You can then write a custom energy term that uses this oracle: