Overview
Mirascope is a Python toolkit that lets you write LLM calls as regular, typed functions. You decorate a function with @llm.call, return your prompt as the function body, and Mirascope handles sending it to the model and giving you back a response object.
It gives you one unified interface across frontier LLM providers, so the same function shape works whether you target Anthropic, OpenAI, or others. You can also ask for structured output by passing a Pydantic model, and the result is parsed back into that typed object.
It fits the prompt-programming corner of LLM orchestration: instead of stitching together prompt strings and raw API clients by hand, you keep prompts, calls, tools, and parsing inside normal Python functions. It suits developers who want type hints and Pydantic models rather than a heavier framework.
What it does
- Define an LLM call by decorating a Python function with @llm.call and returning the prompt from the function body
- One unified interface to use any frontier LLM, switching providers by changing the model string
- Structured output via Pydantic: pass format=YourModel and call .parse() to get a typed object back
- Tool calling with @llm.tool, including a resume/execute_tools loop for agent-style multi-step runs
- Supports streaming, async, and multi-turn conversations (see the full documentation)
- Lightweight and typed, building on Pydantic models for inputs and outputs
Getting started
Install Mirascope, then write your first call as a decorated Python function. All snippets below are taken directly from the project README.
Install Mirascope
Install the package with all provider extras using uv.
uv add "mirascope[all]"Call an LLM with a decorator
Decorate a function with @llm.call, return the prompt as the function body, and read the response text.
from mirascope import llm
@llm.call("anthropic/claude-sonnet-4-5")
def recommend_book(genre: str):
return f"Recommend a {genre} book."
response = recommend_book("fantasy")
print(response.text())Get structured output
Pass a Pydantic model with format= and call .parse() to receive a typed object.
from pydantic import BaseModel
from mirascope import llm
class Book(BaseModel):
title: str
author: str
@llm.call("anthropic/claude-sonnet-4-5", format=Book)
def recommend_book(genre: str):
return f"Recommend a {genre} book."
book = recommend_book("fantasy").parse()
print(f"{book.title} by {book.author}")Build an agent with tools
Register a tool with @llm.tool, pass it via tools=, and loop on tool_calls with resume/execute_tools.
from pydantic import BaseModel
from mirascope import llm
class Book(BaseModel):
title: str
author: str
@llm.tool
def get_available_books(genre: str) -> list[Book]:
"""Get available books in the library by genre."""
return [Book(title="The Name of the Wind", author="Patrick Rothfuss")]
@llm.call("anthropic/claude-sonnet-4-5", tools=[get_available_books], format=Book)
def librarian(request: str):
return f"You are a librarian. Help the user: {request}"
response = librarian("I want a fantasy book")
while response.tool_calls:
response = response.resume(response.execute_tools())
book = response.parse()
print(f"Recommending: {book.title} by {book.author}")Commands and code are distilled from the project's own documentation — always check the official repo for the latest.
When to use it
- Writing LLM calls as typed Python functions instead of hand-managing prompt strings and raw API clients
- Extracting structured data from text into Pydantic models with validated, typed output
- Switching between LLM providers behind one interface without rewriting call code
- Building tool-using agents that loop through tool calls and resume until they produce a final answer
How Mirascope compares
Mirascope alongside other open-source prompt programming tools AI/TLDR tracks, ranked by GitHub stars.
| Tool | Stars | What it does |
|---|---|---|
| DSPy | ★ 35.8k | A Stanford framework for programming language models with composable modules and automatic prompt optimization instead of hand-written prompts. |
| ell | ★ 5.9k | A Python library that treats prompts as versioned functions, with tooling to track, visualize, and iterate on them as code. |
| GEPA | ★ 5.5k | A reflective, evolutionary optimizer that improves prompts and other text components of a system using language-model feedback. |
| LMQL | ★ 4.2k | A query language for LLMs that mixes Python control flow with prompts and constraints to script multi-step generation. |
| AdalFlow | ★ 4.2k | A PyTorch-like library for building and auto-optimizing LLM pipelines, tuning prompts across the components of a task. |
| TextGrad | ★ 3.6k | A library that optimizes prompts and other text variables using textual gradients, applying a backpropagation-like loop driven by LLM feedback. |
| Mirascope | ★ 1.5k | Write LLM calls as typed Python functions with one interface across providers |