Skip to main content
Looking to use this in code? See Tutorial 05: MIFYing Legacy Code for a practical walkthrough.
Object-oriented programming organizes related data and the methods that operate on it into classes. Mellea applies the same principle to LLM interactions: an MObject is a Python class whose fields and methods can be exposed to a model in a controlled, structured way. The @mify decorator turns any class into an MObject. You specify exactly which fields and methods are visible to the LLM — nothing else is exposed.

The @mify decorator

fields_include controls which fields appear in the prompt. template is a Jinja2 template that controls how those fields are rendered. The m.query() call sends the rendered object plus the question to the model. @mify is useful whenever you need to expose structured data to a model without leaking internal state.

Methods as tools

When you mify a class, every method that has a docstring is automatically registered as a tool the LLM can call. Use funcs_include or funcs_exclude to control which methods are exposed:
Only from_markdown is registered as a tool. The model can call it during a m.transform() or m.query() operation; internal_helper is invisible. When a class method and an LLM operation would produce the same result, Mellea will note that the direct method call is available:

Working with documents

Mellea provides mified wrappers around Docling documents for working with PDFs and other rich documents.
This loads the PDF and parses it into Mellea’s intermediate representation. From there you can extract structured elements:
Table is already an MObject, so you can pass it directly to m.transform() or m.query():
The seed loop is a simple retry strategy: LLM output is non-deterministic, so iterating over seeds gives multiple independent samples until one produces a valid table structure.
Note: LLM output is non-deterministic. Your exact results will vary.

When to use MObjects

MObjects are well-suited for:
  • Document querying — wrap a document, expose only the relevant sections, query or transform them with the model
  • Tool registration — expose a controlled set of methods as tools the LLM can invoke during generation
  • Evolving existing codebases — add @mify to an existing class to make it LLM-accessible without rewriting it
For simple one-off generation, m.instruct() is usually sufficient. MObjects add value when you have structured data or methods that the model needs to reason about or call. See also: Context and Sessions | Generative Functions