Tinkering with Marvin AI

Photo by Nik on Unsplash

Tinkering with Marvin AI

A lightweight framework for building reliable AI powered software

Introduction

Recently I was introduced to Marvin AI by my favorite Python community. I just started to tinker with Marvin, and the results were impressive. I'm planning to use it in one of my projects that I open-sourced recently.

Thought of sharing a few notes and ideas I made during my learning process.

Of late, I use FastAPI as my backend framework for most of the solutions that I build. Marvin also suggests using the same when it comes to deployment. So let's just go with it.

In this blog, let's build a set of APIs concerning books. The primary reason being I love to read and listen🎧 to books, and the secondary being I already wrote a blog with BookReview as a functionality. So let's just build this as a continuation, and in a future post link the two 😀

Let's start to explore how we can use Marvin's components and build some useful APIs.

First of all, a brief introduction about Marvin; it is a collection of building blocks that can be used by developers with the highest level of abstraction. What exactly can it do? Per their documentation:

  • AI Models for structuring text into type-safe schemas

  • AI Classifiers for bulletproof classification and routing

  • AI functions for complex business logic and transformations

  • AI applications for interactive use and persistent state

The goal of building Marvin as quoted on their website is

Marvin's goal is to bring the best practices of building dependable, observable software to the frontier of generative AI.

It's been quite abstract so far, so let's just dive in and see what exactly can it do.

As always, let's create a folder, a virtual environment and activate it as the first step.

mkdir marvin-ai
cd marvin-ai

py -m venv venv
venv\Scripts\activate

We then install FastAPI

pip install "fastapi[all]"

Now that we've installed FastAPI, let's go ahead and start writing APIs. It's as easy as importing the package, creating an app and writing a method with a router. Create a file named main.py and write the code below

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return { "message" : "Welcome to BookReview APIs"}

Time to start the uvicorn server and see the response on the browser 💡

uvicorn main:app --reload

Hooray, we see the response like so 👇

Now that the foundation is set to start using Marvin, let's go ahead and install Marvin.

pip install marvin

Marvin uses OpenAI under the hood, which means we need OpenAI's API key. To procure the same, visit OpenAI's website, Sign up and follow the next steps. You may need to provide your phone number for verification. In the past, it used to take a few days for your request to get approved. These days, I think it's pretty fast.

💡
Proceed with the following steps only after you receive your OpenAI API key

Create a .env file at the same level as main.py. This is where we store all our environment variables. Create a variable to store your API key. This is what I created.

MARVIN_OPENAI_API_KEY=<your-api-key-here>

Now we are all set to start exploring. As we saw above, there are four components in Marvin, and let's start with the AI function as I found that to be the simplest of all.

AI Functions

To reiterate, AI functions do not have any source code. It just uses text and description in the form of docstrings to generate outputs. When I came across this method the first time, I was mind-blown 🤩

Let's try a few functions from a book review perspective and check the output.

A simple function that returns a brief review given the name of the book and the author can be written as below.

@ai_fn
def book_review(name_of_book: str, author: str) -> str:
    """
    Given name of a book and author, return a review of the book
    """

@app.get("/book_review")
async def get_book_review(name_of_book: str, author: str):
    review = book_review(name_of_book, author)
    return review

I tried a couple of books and captured the output. Check the results 😎

A Man called Ove by Frederik Backman

The Secret Garden by Frances Hodgson Burnett

I know why the caged bird sings by Maya Angelou

Let's write another function that returns the genre given the name of the book and the author

@ai_fn
def book_genre(name_of_book: str, author: str) -> str:
    """
    Given name of a book and author, return multiple genres of the book
    """

@app.get("/book_genre")
async def get_book_genre(name_of_book: str, author: str):
    genres = book_genre(name_of_book, author)
    return genres

Now let's try a couple of books

Founding Sales - The Startup Sales Handbook by Peter Kazanjy

The Color of Law: A Forgotten History of How Our Government Segregated America by Richard Rothstein

99 Bottles of OOp by Sandi Metz, Katrina Owen

Pretty impressive, isn't it? Most of the trick lies in the correct set of prompts that we give. Prompt engineering is a subject in itself.

AI Classifiers

These let us build multi-label classifiers with no code and no training data. We just define multiple categories for a scenario as Enums in a class.

Per Marvin's documentation,

Given user input, each classifier uses a clever logit bias trick to force an LLM to deductively choose the best option

Let's define a class of different types of sentiments as a Classifier. When we invoke the class by passing a book review, it returns the sentiment.

Here is the code

@ai_classifier
class BookReviewSentiment(Enum):
    """
    Classifies incoming book reviews
    """
    POSITIVE = "Positive"
    NEGATIVE = "Negative"
    NEUTRAL = "Neutral"
    ENTHUSIASTIC = "Enthusiastic"
    CRITICAL = "Critical"
    INDIFFERENT = "Indifferent"
    APPRECITATIVE = "Appreciative"
    DISAPPROVING = "Disapproving"


@app.get("/book_review_classifier")
async def get_book_review_classifier(review: str):
    sentiment = BookReviewSentiment(review)
    return sentiment

Let's test it with a few reviews and see what it returns

A Man Called Ove is a tedious and clichéd portrayal of a grumpy old man, filled with predictable and overused tropes. The story fails to deliver any real depth or originality, leaving readers disappointed by its lackluster plot and one-dimensional characters

The Five-Star Weekend is an enthralling and exhilarating thriller that keeps readers on the edge of their seats from start to finish. With its fast-paced plot, complex characters, and unexpected twists, this book is an absolute must-read for fans of the genre.

What the Neighbors Saw is a mystery novel set in a suburban neighborhood, exploring the secrets of its residents. While the plot held potential for intrigue, the execution lacked the depth needed to fully engage readers, resulting in a somewhat forgettable reading experience.

These are the two components that I explored recently. There is a lot more that Marvin AI offers. I just scratched the surface. Hope I kindled your curiosity to explore further and try using it in your work.

Final Steps

Let's quickly deploy this application so that you can see it working. I chose Render as my cloud provider to deploy these services. It's extremely simple to deploy a FastAPI web service in Render.

I followed their documentation and boom, here is my application deployed 🤩🤩

Two points that need to be noted while deployment are:

  1. By default, Render uses the patch version of Python 3.7. Marvin requires a minimum of 3.9. For this to be reflected, on your render dashboard, go to settings -> Environment -> Add a variable PYTHON_VERSION and give the value as 3.10.7. Only by doing this can Marvin be installed. Of course, you can install any version >= 3.9

  2. In settings, goto Environment menu again, either add a secrets file and add your .env file that has the variable MARVIN_OPENAI_API_KEY and your OpenAI's API key as value. Or, you can add an environment variable directly for Marvin's key.

Quick screenshot from my Render dashboard

Here is my code repo on github

Conclusion

This is my first time with Marvin AI, and the results were good. Concerning speed, I'm yet to test. Feel free to play around with my app that is deployed on Render.

💡
Please be wary to use the APIs though as Open AI has limits on number of requests per minute 😁

References

https://www.askmarvin.ai/src/docs/

https://render.com/docs/deploy-fastapi

https://render.com/docs/python-version