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.
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:
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
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.
References
https://www.askmarvin.ai/src/docs/