I am trying to build a Rage Pipeline for a dataset containing 100 coffee shops in LA. The goal is to use the column Combined Review Text to recommend different coffee shops to the users. The goal is to create the rag pip-line, build a flask app in order to containerize it and deploy on google cloud run. Here is my code and a snipped on my dataset. Really appreciate any help. The output of the LLM should be 1 coffee shops with its name, address, and website. import os import pandas as pd from langchain.prompts import PromptTemplate # from langchain.document_loaders import DataFrameLoader from langchain_community.document_loaders import DataFrameLoader from langchain_community.vectorstores import Chroma from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI from dotenv import load_dotenv load_dotenv() # Env & paths print( os.getenv("GOOGLE_API_KEY")) GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") DATA_PATH = "updated_coffee_shops.csv" DB_DIR = "./chroma_db" # Models embedding_model = GoogleGenerativeAIEmbeddings(model="models/embedding-001") llm_model = ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0.75, top_p=0.8) # Build or load Chroma vectorstore if not os.path.isdir(DB_DIR) or not os.listdir(DB_DIR): df = pd.read_csv(DATA_PATH) loader = DataFrameLoader(df, page_content_column="Combined Review Text") docs = loader.load() vectorstore = Chroma.from_documents( documents=docs, embedding_function=embedding_model, persist_directory=DB_DIR ) vectorstore.persist() else: vectorstore = Chroma( persist_directory=DB_DIR, embedding_function=embedding_model ) retriever = vectorstore.as_retriever() # Instructional prompt template rag_prompt = PromptTemplate.from_template(""" You're a friendly and knowledgeable coffee shop expert in Los Angeles. Use the following context to answer the student's question. Context: {context} Question: {question} Provide your recommendation in a conversational way, explaining why this coffee shop would be perfect for them. Include specific details about the coffee shop's features, atmosphere, and what makes it unique. Make sure to prominently include the name and address in your response. Instructions: - Keep your response clear and concise. Give you best guess based on the reviews of other customers. - In your output include: • Name of the coffee shop • Address of the place • a brief explanation of why it fits according to context and the user's interests • the each club’s **detail URL from the `Website` field** in the context (do not make up URLs) and • the detail URL exactly once, in plain text at the end, like `Link: https://…` """) # Main answering function def answer_question(question: str) -> str: docs = retriever.get_relevant_documents(question) # Format context with metadata context = "\n\n".join([ f"Coffee Shop: {doc.metadata.get('Name', 'Unknown')}\n" f"Address: {doc.metadata.get('Address', 'N/A')}\n" f"Detail URL: {doc.metadata.get('Website', 'N/A')}\n" f"Description: {doc.page_content}" for doc in docs[:3] ]) # Format prompt prompt = rag_prompt.format(context=context, question=question) # Call Gemini model response = llm_model.invoke(prompt) return response.content The flask App from flask import Flask, request, jsonify from model import answer_question # your function that answers questions app = Flask(__name__) @app.route("/") def index(): return "RAG Gemini API is up!" @app.route("/ask", methods=["POST"]) def ask(): data = request.get_json() question = data.get("question", "") if not question: return jsonify({"error": "Missing question"}), 400 try: answer = answer_question(question) return jsonify({"answer": answer}) except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == "__main__": # Cloud Run will set PORT; default to 5002 locally import os port = int(os.getenv("PORT", 5002)) app.run(host="0.0.0.0", port=port) Out put when curl command is run curl -X POST http://127.0.0.1:5002/ask \ -H "Content-Type: application/json" \ -d '{"question":"Where can I find good matcha?"}' Image of output Terminal output Continue reading...