A Flask API that takes a free-text request like "I need a wireless mouse that's comfortable for long use, budget around 30$" and returns product recommendations from an Amazon products dataset. Retrieval is done with vector search (pgvector) and the language side with Claude and Titan embeddings on AWS Bedrock.
The whole pipeline runs behind a single endpoint, POST /product/cv:
- The raw user input plus some user metadata (gender, previous brand, ...) is sent to Claude 3.5 Sonnet with a few-shot prompt that rewrites it into one clean descriptive query. This step matters because raw user messages are messy and embed poorly.
- The rewritten query is embedded with Amazon Titan Embeddings v2 (256 dimensions).
- A KNN search over the pre-embedded product catalog runs in PostgreSQL using the
pgvector
<->distance operator, returning the 10 nearest items. - The candidate items and the query go back to Claude, which selects the items that actually satisfy the request and writes a short pitch for each one. The model answers in XML, which gets parsed and returned as JSON. If nothing matches, it returns a plain text explanation instead.
The catalog comes from an Amazon products dataset. Chatbot.ipynb has the cleaning and
exploration work (the result is cleaned_filtered_dataset.csv). Item/embedd_data.py
embeds the cleaned rows in batches with Titan and writes them to embeddings_output.json,
and data/seeding.py loads them into Postgres. Alembic handles the schema migrations.
You need PostgreSQL with the pgvector extension, and AWS credentials with Bedrock access (Claude 3.5 Sonnet and Titan Embeddings enabled, us-east-1).
pip install -r requirements.txt
Set your database URL in config/static.py, run the Alembic migrations, seed the data,
then:
python app.py
There is also a Dockerfile and a buildspec, since this was deployed on AWS at some point.
Example request:
POST /product/cv
{
"user_input": "portable bluetooth speaker with good battery",
"metadata": {"gender": "Male", "previous_brand": "Sony"}
}