Overview
Marvin is a Python framework for producing structured outputs from LLMs and building agentic AI workflows. It gives you a small set of functions like extract, cast, classify, and generate that turn unstructured text into typed Python objects, so model output flows back into your code as regular values you can validate and use.
It is aimed at Python developers who want type-safe results from language models without writing prompt scaffolding by hand. Marvin uses OpenAI by default but supports all Pydantic AI models, so you can point it at the provider you already use.
As an LLM orchestration tool, Marvin also offers a task-centric layer: you describe objectives as tasks, assign one or more agents to them, and compose tasks into threads to coordinate more complex, multi-step behavior.
What it does
- Structured-output helpers: extract, cast, classify, and generate native Python types from any input
- Type-safe results validated against the result_type you specify (including TypedDict, Enum, and Pydantic types)
- Tasks as discrete, observable units of work that a default or named agent can run
- Named Agent objects with custom instructions for task-specific behavior
- Threads that compose tasks to orchestrate multi-step and multi-agent workflows
- Provider flexibility: defaults to OpenAI and supports all Pydantic AI models
Getting started
Install Marvin, set your LLM provider key, then call one of its structured-output functions or run a task.
Install Marvin
Marvin is available on PyPI. The README installs it with uv.
uv add marvinConfigure your LLM provider
Marvin uses OpenAI by default. Set your API key as an environment variable. To use another model, see Pydantic AI's supported models.
export OPENAI_API_KEY=your-api-keyExtract structured data
Use a structured-output utility like marvin.extract to pull typed values out of unstructured text.
import marvin
result = marvin.extract(
"i found $30 on the ground and bought 5 bagels for $10",
int,
instructions="only USD"
)
print(result) # [30, 10]Run a task
Use marvin.run for the simplest task, optionally asking for structured output via result_type.
import marvin
answer = marvin.run("the answer to the universe", result_type=int)
print(answer) # 42Commands and code are distilled from the project's own documentation — always check the official repo for the latest.
When to use it
- Classify incoming text, such as routing support messages to the right department with a fixed set of labels
- Extract typed fields (numbers, dates, amounts) from messy or unstructured input for downstream code
- Cast free-form descriptions into structured objects like TypedDicts or Pydantic models
- Build multi-step agent workflows by composing tasks and assigning specialized agents
How Marvin compares
Marvin alongside other open-source structured output tools AI/TLDR tracks, ranked by GitHub stars.
| Tool | Stars | What it does |
|---|---|---|
| Guidance | ★ 21.5k | A programming model that interleaves generation, prompting, and control logic to constrain output and enforce formats like JSON or regex patterns. |
| Outlines | ★ 14k | A library for structured generation that constrains an LLM's token output to match a JSON schema, regex, or grammar so the result is always valid. |
| Instructor | ★ 13.2k | A library that wraps an LLM client to return data validated against a schema, retrying automatically on invalid output, with SDKs in several languages. |
| BAML | ★ 8.4k | A domain-specific language for defining LLM functions with typed schemas, parsing flexible model output into reliable structured data across many languages. |
| Marvin | ★ 6.2k | Turn LLM calls into typed Python functions and agentic workflows |
| LM Format Enforcer | ★ 2k | A library that enforces an output format such as JSON schema or regex by filtering the tokens an LLM is allowed to generate at each step. |
| XGrammar | ★ 1.8k | A fast, portable engine for grammar-constrained decoding that guarantees LLM output follows a given structure, used inside many inference servers. |