LLM abstractions that aren't obstructions

Mirascope is a Python toolkit that provides the right level of abstraction for building LLM agents your way. Modular. Extensible. Reliable. Open Source.

pip install mirascope
1from mirascope.core import openai, prompt_template
2from openai.types.chat import ChatCompletionMessageParam
3from pydantic import BaseModel
4
5
6class Chatbot(BaseModel):
7    history: list[ChatCompletionMessageParam] = []
8
9    @openai.call(model="gpt-4o-mini", stream=True)
10    @prompt_template(
11        """
12        SYSTEM: You are a helpful assistant.
13        MESSAGES: {self.history}
14        USER: {question}
15        """
16    )
17    def _call(self, question: str): ...
18
19    def run(self):
20        while True:
21            question = input("(User): ")
22            if question in ["quit", "exit"]:
23                print("(Assistant): Have a great day!")
24                break
25            stream = self._call(question)
26            print("(Assistant): ", end="", flush=True)
27            for chunk, _ in stream:
28                print(chunk.content, end="", flush=True)
29            print("")
30            if stream.user_message_param:
31                self.history.append(stream.user_message_param)
32            self.history.append(stream.message_param)
33
34
35Chatbot().run()

Core Components

1from mirascope.core import openai, prompt_template
2
3@openai.call("gpt-4o-mini")
4@prompt_template("Recommend a {genre} book")
5def recommend_book(genre: str): ...
6    
7response = recommend_book("fantasy")
8print(response)
9# > Sure! I would recommend The Name of the Wind by...
1@openai.call("gpt-4o-mini", stream=True)
2def recommend_book(genre: str):
3    """Recommend a {genre} book."""
4
5stream = recommend_book("fantasy")
6for chunk, _ in stream:
7    print(chunk, end="", flush=True)
8# > Sure! I would recommend...
1from mirascope.core import openai, prompt_template
2
3def format_book(title: str, author: str):
4    return f"{title} by {author}"
5    
6@openai.call(
7    "gpt-4o-mini",
8    tools=[format_book],
9    tool_choice="required",
10)
11@prompt_template("Recommend a {genre} book")
12def recommend_book(genre: str): ...
13    
14response = recommend_book("fantasy")
15if tool := response.tool
16    print(tool.call())
17# > The Name of the Wind by Patrick Rothfuss
1from mirascope.core import openai, prompt_template
2
3@openai.call(
4    "gpt-4o-mini",
5    stream=True,
6    tools=[format_book],
7    tool_choice="required"
8)
9@prompt_template("Recommend two (2) {genre} books")
10def recommend_book(genre: str): ...
11    
12stream = recommend_book("fantasy")
13for chunk, tool in stream:
14    if tool:
15        print(tool.call())
16    else:
17        print(chunk, end="", flush=True)
18# > The Name of the Wind by Patrick Rothfuss
19# > Mistborn: The Final Empire by Brandon Sanderson
1from mirascope.core import openai, prompt_template
2from pydantic import BaseModel
3
4class Book(BaseModel):
5    title: str
6    author: str
7    
8@openai.call("gpt-4o-mini", response_model=Book)
9@prompt_template("Recommend a {genre} book")
10def recommend_book(genre: str):
11    
12book = recommend_book("fantasy")
13assert isinstance(book, Book)
14print(book)
15# > title='The Name of the Wind' author='Patrick Rothfuss'
1from mirascope.core import openai, prompt_template
2from pydantic import BaseModel
3
4class Book(BaseModel):
5    title: str
6    author: str
7
8@openai.call("gpt-4o-mini", stream=True, response_model=Book)
9@prompt_template("Recommend a {genre} book")
10def recommend_book(genre: str): ...
11    
12book_stream = recommend_book("fantasy")
13for partial_book in book_stream:
14    print(partial_book)
15# > title=None author=None
16# > title='The Name' author=None
17# > title='The Name of the Wind' author=None
18# > title='The Name of the Wind' author='Patrick'
19# > title='The Name of the Wind' author='Patrick Rothfuss'

You're in control

Simple and transparent abstractions ensure you're in the driver's seat. Abstractions must be useful without getting in your way and blinding your view.

Type hints you'll love

We’ve taken care of all of the annoying Python typing so that you can have proper type hints in as simple an interface as possible.

Build your way

Simple, clean building blocks enable fast and reliable development without forcing you to do things our way. While we have recommendations and best practices, you're still always able to do things your way to best suit your needs.

Trusted by engineers building the next generation of AI-native applications

The Pydantic inspired LLM framework the space has been missing. Simple, modular, extensible...helps where you need it, stays out of your way when you don't.

Vince Trost

Co-Founder / Plastic Labs

Mirascope's simplicity made it the natural next step from a provider's API (OpenAI) — all without fighting unnecessary complexity of other tools like LangChain. We have all the bells and whistles necessary for production while maintaining ease of use and easy onboarding of new team members.

Jake Duth

Co-Founder & CTO / Reddy

As the author of Mirascope, I'm certainly biased, but there's a reason I've worked day and night on this package — it solves the problems I have with existing developer tools. Mirascope is simple and easy to use, and honestly building with Mirascope is the most fun I've had coding in my life.

William Bakst

Founder / Mirascope

Start Building With Mirascope

Mirascope can help improve your application development experience no matter how simple or complex.

It will feel like writing the Python you already know.

Read the Docs
Join the Community