Skip to content
Home » Build a Philosophy Quote Generator with Vector Search and Astra DB (Part 3)

Build a Philosophy Quote Generator with Vector Search and Astra DB (Part 3)

Build a Philosophy Quote Generator with Vector Search and Astra DB (Part 3)

In the previous parts of this series, we laid the foundation for creating a Philosophy Quote Generator that leverages vector search to retrieve relevant quotes. Part 1 covered the setup of Astra DB, while Part 2 focused on understanding vector search and how it can enhance the quote retrieval process. In this final part, titled Build a Philosophy Quote Generator with Vector Search and Astra DB (Part 3), we will integrate these concepts into a fully functional application, optimize the system for performance, and implement a simple user interface for interacting with the generator. By the end of this article, you’ll have a scalable solution capable of delivering contextually relevant philosophy quotes.

Overview of the Application

The Philosophy Quote Generator will use Astra DB, a cloud-native NoSQL database built on Apache Cassandra, for storing and retrieving quotes. It will utilize vector search to find the most relevant quotes based on a given prompt or theme. Vector search compares the semantic meaning of the input text to the stored quotes, ensuring that the results are not only keyword matches but contextually accurate.

Key Components of the System

  1. Astra DB: We’ll use Astra DB to store and manage our quotes. Astra DB supports vector search, which allows us to use embeddings for efficient similarity search.
  2. Vector Search: We’ll generate vector embeddings for each quote using a pre-trained model, then store these embeddings in Astra DB to facilitate fast and accurate similarity searches.
  3. User Interface: A simple web interface will allow users to input a prompt, and the backend will return the most relevant philosophy quotes based on vector search.
  4. Backend: The backend will handle requests, interact with Astra DB to retrieve data, and return results to the user interface.

Step 1: Setting Up Astra DB for Vector Search

If you followed along with Part 1, you should already have an Astra DB account and a keyspace set up. In this section, we’ll focus on preparing the database to store vector embeddings for efficient search.

Schema Design for Quotes

The first step is to design a schema for storing the quotes. We’ll create a table called quotes with the following columns:

  • id: A unique identifier for each quote (UUID).
  • text: The text of the quote (String).
  • author: The author of the quote (String).
  • embedding: A vector representation of the quote (List<Double>).
cql
CREATE TABLE quotes (
id UUID PRIMARY KEY,
text TEXT,
author TEXT,
embedding list<double>
);

The embedding column will store the vector representation of the quote, which we’ll generate using a model like BERT or a similar embedding-based model.

Inserting Data into Astra DB

Once the table is created, we can start inserting quotes. For each quote, we’ll need to generate its embedding and insert it into the database.

To generate embeddings, you can use pre-trained models from libraries like Hugging Face’s transformers or OpenAI’s models. Below is a Python script using Hugging Face’s sentence-transformers library to generate embeddings for a set of quotes and insert them into Astra DB.

python
from cassandra.cluster import Cluster
from sentence_transformers import SentenceTransformer
import uuid

# Initialize the model and connect to Astra DB
model = SentenceTransformer('all-MiniLM-L6-v2')
cluster = Cluster(['<your_astra_db_contact_point>'])
session = cluster.connect('<your_keyspace>')

# List of quotes to insert
quotes = [
{"text": "The unexamined life is not worth living.", "author": "Socrates"},
{"text": "I think, therefore I am.", "author": "René Descartes"},
{"text": "Happiness depends upon ourselves.", "author": "Aristotle"}
]

# Insert quotes and their embeddings
for quote in quotes:
embedding = model.encode(quote["text"]).tolist() # Generate embedding
session.execute("""
INSERT INTO quotes (id, text, author, embedding)
VALUES (%s, %s, %s, %s)
"""
, (uuid.uuid4(), quote["text"], quote["author"], embedding))

print("Quotes inserted successfully.")

In this script, we generate embeddings for each quote using a model from the sentence-transformers library, then insert the quote text, author, and embedding into Astra DB.

Step 2: Implementing Vector Search

Now that we have our quotes stored with embeddings in Astra DB, the next step is to implement vector search to retrieve quotes based on user input. Vector search compares the input embedding with the stored embeddings in the database to find the most similar ones.

Astra DB supports vector search through the Vector Search functionality. We’ll use cosine similarity to measure the distance between the input vector and the stored vectors.

Here’s how to implement the vector search in Python:

Searching for Similar Quotes

We’ll need to generate an embedding for the user’s input prompt and compare it with the embeddings stored in the quotes table. We can use the cosine_similarity function from scikit-learn to calculate the similarity between the vectors.

python
from sklearn.metrics.pairwise import cosine_similarity

# Generate embedding for user input
user_input = "What is the meaning of life?"
input_embedding = model.encode(user_input).tolist()

# Fetch all embeddings from Astra DB
rows = session.execute("SELECT id, text, author, embedding FROM quotes")
similarities = []

# Calculate cosine similarity between input and each stored quote
for row in rows:
similarity = cosine_similarity([input_embedding], [row.embedding])[0][0]
similarities.append((similarity, row.text, row.author))

# Sort quotes by similarity (descending)
similarities.sort(reverse=True, key=lambda x: x[0])

# Display the top 3 most similar quotes
for similarity, text, author in similarities[:3]:
print(f"Similarity: {similarity:.4f}\nQuote: '{text}'\nAuthor: {author}\n")

Optimizing the Query

While the above approach works well for smaller datasets, as the database grows, querying all the embeddings for similarity may become slow. To optimize performance, consider the following:

  1. Use Approximate Nearest Neighbors (ANN): Instead of calculating exact cosine similarity, you can use algorithms like FAISS (Facebook AI Similarity Search) to approximate the nearest neighbors. This allows faster searches with minimal trade-offs in accuracy.
  2. Indexing: In larger-scale systems, indexing the embeddings can greatly improve search speed. Astra DB supports secondary indexes, which you can leverage to create an index on the embedding column.

Step 3: Building the User Interface

A simple user interface (UI) will allow users to interact with the Philosophy Quote Generator. We’ll create a basic web interface using Flask, a Python web framework, and display the most similar quotes based on user input.

Flask Setup

First, install Flask and set up a basic application:

bash
pip install flask

Create a app.py file for your Flask application:

python
from flask import Flask, render_template, request
from sentence_transformers import SentenceTransformer
from cassandra.cluster import Cluster
from sklearn.metrics.pairwise import cosine_similarity
import uuid

app = Flask(__name__)

# Initialize model and connect to Astra DB
model = SentenceTransformer('all-MiniLM-L6-v2')
cluster = Cluster(['<your_astra_db_contact_point>'])
session = cluster.connect('<your_keyspace>')

@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
user_input = request.form['quote_prompt']
input_embedding = model.encode(user_input).tolist()

rows = session.execute("SELECT id, text, author, embedding FROM quotes")
similarities = []

for row in rows:
similarity = cosine_similarity([input_embedding], [row.embedding])[0][0]
similarities.append((similarity, row.text, row.author))

similarities.sort(reverse=True, key=lambda x: x[0])
top_quotes = similarities[:3]

return render_template('index.html', top_quotes=top_quotes)

return render_template('index.html', top_quotes=[])

if __name__ == '__main__':
app.run(debug=True)

HTML Template

Create a templates folder and add an index.html file for the UI:

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Philosophy Quote Generator</title>
</head>
<body>
<h1>Philosophy Quote Generator</h1>
<form method="POST">
<label for="quote_prompt">Enter a prompt:</label>
<input type="text" id="quote_prompt" name="quote_prompt" required>
<button type="submit">Generate Quote</button>
</form>

{% if top_quotes %}
<h2>Top Quotes</h2>
<ul>
{% for similarity, text, author in top_quotes %}
<li><strong>{{ text }}</strong> — {{ author }} (Similarity: {{ similarity }})</li>
{% endfor %}
</ul>
{% endif %}
</body>
</html>

Running the Application

To run the application, execute the following command:

bash
python app.py

This will start a local server, and you can access the application in your browser at http://127.0.0.1:5000/.

Step 4: Deploying the Application

Once you’ve tested the application locally, the next step is to deploy it. You can deploy your Flask application using platforms like Heroku, AWS, or any other cloud provider that supports Python web applications.

Here’s a simple guide to deploy on Heroku:

  1. Create a Procfile with the following content:
    text
    web: python app.py
  2. Create a requirements.txt file to list the dependencies:
    text
    flask
    cassandra-driver
    sentence-transformers
    scikit-learn
  3. Push your code to a Git repository and deploy it on Heroku.

Conclusion

In this final part of the series, titled Build a Philosophy Quote Generator with Vector Search and Astra DB (Part 3), we’ve completed our Philosophy Quote Generator. We covered how to:

  • Store and retrieve vector embeddings using Astra DB.
  • Implement vector search to find the most relevant quotes.
  • Build a simple web interface using Flask.
  • Deploy the application for production use.

This project demonstrates how vector search and Astra DB can be leveraged to create an intelligent system capable of delivering contextually relevant philosophy quotes. You can expand upon this foundation by adding more features, such as user ratings, and more complex UI components, and integrating additional data sources for a richer user experience.

Leave a Reply

Your email address will not be published. Required fields are marked *