Semantic-Embedding-for-Mood-Based-Yoga-Session-Recommendation-and-Report-Generation-Proof-of-Concept
This repo shows the codes for Semantic Embedding for Mood-Based Yoga Session Recommendation and Report Generation
curl -fsSL https://ollama.com/install.sh | sh
Then use required LLMs and Embeddings from Ollama
- Python3 venv -m yoga
- source yoga/bin/activate
- pip install -r requirements
Python3 mood_9.py
From same project directory run
python3 curl_caller_mood.py
- A directory called reports is generated with PDF reports based on mood which was given in the prompts as mentioned in curl_caller_mood.py
- A CSV file for metrics analysis is generated yoga_asana_metrics.csv
- Instantiate a
FastAPI
object to manage routing and endpoint handling. - Define endpoints for processing user prompts and serving PDF reports.
- Set logging to the
DEBUG
level to capture detailed logs. - Use
StreamHandler
to ensure logs are visible in the console during runtime. - Log all key operations and errors for debugging and tracking.
- Embedding Model: Choose a pre-trained embedding model (
mxbai-embed-large
) to compute vector representations of text. - Similarity Threshold: Set a similarity threshold (
0.62
) to determine if an asana matches the user prompt. - API Endpoints:
- Ollama API for embedding generation.
- Ollama API for generating comments via a large language model (LLM).
- Report Directory: Create a folder named
reports
to store generated PDF reports. - CSV Metrics File: Define a CSV file (
yoga_asana_metrics.csv
) to log request metrics.
- Define a list of yoga asanas, each containing:
- Name: Name of the asana.
- Utterances: Sample phrases representing moods the asana addresses.
- Details:
- Step-by-step instructions.
- Recommended frequency and timing.
- Dietary and lifestyle recommendations.
- Benefits.
- Create a dictionary (
cached_embeddings
) to store embeddings of predefined asana utterances. - Use the cache to avoid redundant API calls for embeddings.
- On application startup:
- Test the embedding API by generating an embedding for a sample text.
- Log success or failure of the embedding model.
- Precompute embeddings for all utterances in the predefined asanas using the embedding API.
- Store these embeddings in the
cached_embeddings
dictionary for efficient retrieval during requests.
Step 1: Receive User Input
- Accept a JSON payload containing a prompt (e.g., "I feel overwhelmed and stressed with my work").
- Parse and validate the input using
Pydantic
.
Step 2: Generate Prompt Embedding
- Send the user prompt to the embedding API to retrieve its semantic vector representation.
- If the embedding generation fails, return a
500 Internal Server Error
response.
Step 3: Find the Best Asana
- Iterate through the predefined asanas and compute the cosine similarity between the prompt embedding and the cached embeddings of asana utterances.
- Select the asana with the highest similarity score above the threshold (
0.62
). - Measure and log the time taken for this matching process.
- No Match Handling:
- If no asana meets the similarity threshold:
- Log the event with
no_route
. - Save metrics to the CSV file.
- Return a "no match" response to the user.
- Log the event with
- If no asana meets the similarity threshold:
Step 4: Generate Final Comment
- Use the LLM API to generate a personalized comment about the selected asana.
- Pass a few-shot example (predefined input-output pairs) and the selected asana's details to the API for context.
- If the LLM API fails, use a fallback message and log the error.
Step 5: Generate PDF Report
- Use the
ReportLab
library to create a PDF report containing:- User prompt and similarity score.
- Detailed instructions for the recommended asana.
- Dietary and lifestyle recommendations.
- LLM-generated final comment.
- Save the PDF in the
reports
directory. - If PDF generation fails, return a
500 Internal Server Error
response.
Step 6: Log Metrics
- Record the following details in the CSV file:
- Date and time of the request.
- Selected asana and similarity score.
- LLM metrics (response time, tokens processed, etc.).
- PDF generation time and embedding match duration.
Step 7: Return Response
- Respond to the user with:
- Selected asana details.
- LLM-generated final comment.
- Download link for the PDF report.
- Total processing time.
- Accept a filename as input.
- Locate the corresponding PDF file in the
reports
directory. - Return the file as a downloadable response.
- Error Handling:
- Return a
404 Not Found
response if the file doesn’t exist.
- Return a
- Send a POST request to the embedding API with the prompt or utterance.
- Parse and return the embedding vector from the API response.
- Compute the similarity between two embeddings using: [ \text{Cosine Similarity} = \frac{\text{dot product of vectors}}{\text{product of vector magnitudes}} ]
- Compare the prompt embedding against cached embeddings for all asana utterances.
- Return the asana with the highest similarity score above the threshold.
- Send the selected asana's details and user prompt to the LLM API.
- Use few-shot learning to guide the LLM in generating concise, context-aware comments.
- Use the
ReportLab
library to create a visually structured PDF with:- Header: Mood-Based Yoga Recommendation Report.
- User prompt and similarity score.
- Detailed instructions and recommendations for the asana.
- Final comment.
- Save the report in the
reports
directory.
- Record key metrics for each request:
- Request Details: User prompt, selected asana.
- Performance Metrics:
- Embedding match duration (logged as
embed_match_duration
in nanoseconds). - LLM response time and tokens processed.
- PDF generation time.
- Embedding match duration (logged as
- Save these metrics to the
yoga_asana_metrics.csv
file.
- Handle exceptions at every step:
- Log errors with detailed messages.
- Return user-friendly HTTP error responses:
500
for internal server issues.404
for missing files.
- Start the FastAPI server using
uvicorn
on port5000
. - Test endpoints using tools like
curl
or Postman to ensure end-to-end functionality.
Look into the web_integration directory and run the codes accordingly. The web integration uses gradio and sqlalchemiy to use a local database “yoga_interactions.db” having columns such as: id, timestamp, prompt, final_response, pdf_file_path
When ready
When got response
Sometimes, if output is not suitable, just re-SUBMIT
Example
Example query to be given as input into the gradio:
Modify as per Detailed_Mood_Issue column of mood_asana_details.csv file
• I'm feeling guilty and remorseful.
• Irritability is affecting my mood.
• Dealing with restlessness and impatience.
• Agitation is making me restless.
• I'm feeling lonely and isolated.
etc…