Before we get started, you will need to download and install ollama. Mellea can work with many different types of backends, but everything in this tutorial will “just work” on a Macbook running IBM’s Granite 3.3 8B model. We also recommend that you download and install uv. You can run any of the examples in the tutorial with:
uv run example_name.py --with mellea
If running on an Intel mac, you may get errors related to torch/torchvision versions. Conda maintains updated versions of these packages. You will need to create a conda environment and run conda install 'torchvision>=0.22.0' (this should also install pytorch and torchvision-extra). Then, you should be able to run uv pip install mellea. To run the examples, you will need to use python <filename> inside the conda environment instead of uv run --with mellea <filename>.
If you are using python >= 3.13, you may encounter an issue where outlines cannot be installed due to rust compiler issues (error: can't find Rust compiler). You can either downgrade to python 3.12 or install the rust compiler to build the wheel for outlines locally.
Once you have ollama installed and running, we can get started with our first generative piece of code:
# file: https://github.com/generative-computing/mellea/blob/main/docs/examples/tutorial/simple_email.py#L1-L8
import mellea

# INFO: this line will download IBM's Granite 3.3 8B model.
m = mellea.start_session()

email = m.instruct("Write an email inviting interns to an office party at 3:30pm.")
print(str(email))
Here, we initialized a backend running Ollama on a local machine using the granite3.3-chat model. We then ask the model to generate an email and print it to the console.
Mellea supports many other models and backends. By default, a new Mellea session will run IBM’s capable Granite 8B model on your own laptop. This is a good (and free!) way to get started. If you would like to try out other models or backends, you can explicitly specify the backend and model in the start_session method. For example, mellea.start_session(backend_name="ollama", model_id=mellea.model_ids.IBM_GRANITE_3_3_8B).
Before continuing, let’s wrap this call into a function with some arguments:
# file: https://github.com/generative-computing/mellea/blob/main/docs/examples/tutorial/simple_email.py#L13-L27
import mellea

def write_email(m: mellea.MelleaSession, name: str, notes: str) -> str:
  email = m.instruct(
    "Write an email to {{name}} using the notes following: {{notes}}.",
    user_variables={"name": name, "notes": notes},
  )
  return email.value  # str(email) also works.

m = mellea.start_session()
print(write_email(m, "Olivia",
                  "Olivia helped the lab over the last few weeks by organizing intern events, advertising the speaker series, and handling issues with snack delivery."))
Voila, we now have an email-writing function! Notice how the instruct method can take a dictionary of variables as user_variables. These are filled by treating the instruction description as a jinja template. The m.instruct() function returns a ModelOutputThunk per default, which has the model output string bound to the field .value.