Spaces:
Sleeping
Sleeping
Commit
·
4a9c4cd
1
Parent(s):
0078b66
1st launch attempt at rag openai chatbot
Browse files- app.py +136 -0
- chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/data_level0.bin +3 -0
- chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/header.bin +3 -0
- chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/index_metadata.pickle +3 -0
- chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/length.bin +3 -0
- chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/link_lists.bin +3 -0
- chromadb_storage_openai_upgrade/chroma.sqlite3 +3 -0
- requirements.txt +13 -0
app.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import openai
|
| 3 |
+
import chromadb
|
| 4 |
+
import numpy as np
|
| 5 |
+
from dotenv import load_dotenv
|
| 6 |
+
import gradio as gr
|
| 7 |
+
import logging
|
| 8 |
+
|
| 9 |
+
# Load environment variables (optional if you want to keep the dotenv usage)
|
| 10 |
+
load_dotenv()
|
| 11 |
+
|
| 12 |
+
# Define OpenAI-based model
|
| 13 |
+
class OpenAIChatbot:
|
| 14 |
+
def __init__(self, api_key):
|
| 15 |
+
self.embedding_model = "text-embedding-3-large" # OpenAI model with 3072 dimensions
|
| 16 |
+
self.chat_model = "gpt-4o"
|
| 17 |
+
self.api_key = api_key
|
| 18 |
+
|
| 19 |
+
def get_response(self, prompt):
|
| 20 |
+
"""Get a response from OpenAI GPT-4 model."""
|
| 21 |
+
try:
|
| 22 |
+
openai.api_key = self.api_key
|
| 23 |
+
response = openai.chat.completions.create(
|
| 24 |
+
model=self.chat_model,
|
| 25 |
+
messages=[
|
| 26 |
+
{"role": "system", "content": "You are a helpful AI assistant."},
|
| 27 |
+
{"role": "user", "content": prompt}
|
| 28 |
+
]
|
| 29 |
+
)
|
| 30 |
+
# Correctly access the message content in the response
|
| 31 |
+
return response.choices[0].message.content
|
| 32 |
+
except Exception as e:
|
| 33 |
+
print(f"Error generating response: {e}")
|
| 34 |
+
return "Error: Unable to generate a response."
|
| 35 |
+
|
| 36 |
+
def text_to_embedding(self, text):
|
| 37 |
+
"""Convert text to embedding using OpenAI embedding model."""
|
| 38 |
+
try:
|
| 39 |
+
openai.api_key = self.api_key
|
| 40 |
+
response = openai.embeddings.create(
|
| 41 |
+
model=self.embedding_model,
|
| 42 |
+
input=text
|
| 43 |
+
)
|
| 44 |
+
# Access the embedding using the 'data' attribute
|
| 45 |
+
embedding = np.array(response.data[0].embedding)
|
| 46 |
+
print(f"Generated embedding for text: {text}")
|
| 47 |
+
return embedding
|
| 48 |
+
except Exception as e:
|
| 49 |
+
print(f"Error generating embedding: {e}")
|
| 50 |
+
return None
|
| 51 |
+
|
| 52 |
+
# Modify LocalEmbeddingStore to ensure correct dimensionality (3072) in ChromaDB
|
| 53 |
+
class LocalEmbeddingStore:
|
| 54 |
+
def __init__(self, storage_dir="./chromadb_storage_openai_upgrade"):
|
| 55 |
+
# Use ChromaDB client with persistent storage
|
| 56 |
+
self.client = chromadb.PersistentClient(path=storage_dir)
|
| 57 |
+
self.collection_name = "chatbot_docs"
|
| 58 |
+
|
| 59 |
+
# Get the collection without adding new embeddings
|
| 60 |
+
self.collection = self.client.get_or_create_collection(name=self.collection_name)
|
| 61 |
+
|
| 62 |
+
def search_embedding(self, query_embedding, num_results=3):
|
| 63 |
+
"""Search for the most relevant document based on embedding similarity."""
|
| 64 |
+
if query_embedding.shape[0] != 3072:
|
| 65 |
+
raise ValueError("Query embedding dimensionality must be 3072.")
|
| 66 |
+
|
| 67 |
+
print(f"Query embedding: {query_embedding}") # Debugging: Log the query embedding
|
| 68 |
+
results = self.collection.query(
|
| 69 |
+
query_embeddings=[query_embedding.tolist()], # Ensure embeddings are converted to list format
|
| 70 |
+
n_results=num_results
|
| 71 |
+
)
|
| 72 |
+
print(f"Search results: {results}") # Debugging: Print results to check for any issues
|
| 73 |
+
return results['documents'], results['distances']
|
| 74 |
+
|
| 75 |
+
# Modify RAGSystem to integrate ChromaDB search
|
| 76 |
+
class RAGSystem:
|
| 77 |
+
def __init__(self, openai_client, embedding_store):
|
| 78 |
+
self.openai_client = openai_client
|
| 79 |
+
self.embedding_store = embedding_store
|
| 80 |
+
|
| 81 |
+
def get_most_relevant_document(self, query_embedding, similarity_threshold=0.7):
|
| 82 |
+
"""Retrieve the most relevant document based on cosine similarity."""
|
| 83 |
+
docs, distances = self.embedding_store.search_embedding(query_embedding)
|
| 84 |
+
# Check if the results are empty or have low relevance
|
| 85 |
+
if not docs or not distances or distances[0][0] < similarity_threshold:
|
| 86 |
+
print("No relevant documents found or similarity is too low.")
|
| 87 |
+
return None, None # Return None if no relevant documents found
|
| 88 |
+
return docs[0], distances[0][0] # Return the most relevant document and the first distance value
|
| 89 |
+
|
| 90 |
+
def chat_with_rag(self, user_input):
|
| 91 |
+
"""Handle the RAG process."""
|
| 92 |
+
query_embedding = self.openai_client.text_to_embedding(user_input)
|
| 93 |
+
if query_embedding is None or query_embedding.size == 0:
|
| 94 |
+
return "Failed to generate embeddings."
|
| 95 |
+
|
| 96 |
+
context_document_id, similarity_score = self.get_most_relevant_document(query_embedding)
|
| 97 |
+
if not context_document_id:
|
| 98 |
+
return "No relevant documents found."
|
| 99 |
+
|
| 100 |
+
# Assuming metadata retrieval works
|
| 101 |
+
context_metadata = f"Metadata for {context_document_id}" # Placeholder, implement as needed
|
| 102 |
+
|
| 103 |
+
prompt = f"""Context (similarity score {similarity_score:.2f}):
|
| 104 |
+
{context_metadata}
|
| 105 |
+
|
| 106 |
+
User: {user_input}
|
| 107 |
+
AI:"""
|
| 108 |
+
return self.openai_client.get_response(prompt)
|
| 109 |
+
|
| 110 |
+
# Gradio UI
|
| 111 |
+
def chat_ui(user_input, api_key, chat_history):
|
| 112 |
+
"""Handle chat interactions and update history."""
|
| 113 |
+
if not api_key.strip():
|
| 114 |
+
return "Please provide your OpenAI API key before proceeding."
|
| 115 |
+
|
| 116 |
+
# Initialize OpenAIChatbot with the user's API key
|
| 117 |
+
chatbot = OpenAIChatbot(api_key)
|
| 118 |
+
embedding_store = LocalEmbeddingStore(storage_dir="./chromadb_storage_openai_upgrade")
|
| 119 |
+
rag_system = RAGSystem(openai_client=chatbot, embedding_store=embedding_store)
|
| 120 |
+
|
| 121 |
+
if not user_input.strip():
|
| 122 |
+
return chat_history
|
| 123 |
+
ai_response = rag_system.chat_with_rag(user_input)
|
| 124 |
+
chat_history.append((user_input, ai_response))
|
| 125 |
+
return chat_history
|
| 126 |
+
|
| 127 |
+
# Gradio interface
|
| 128 |
+
with gr.Blocks() as demo:
|
| 129 |
+
api_key_input = gr.Textbox(label="Enter your OpenAI API Key", placeholder="API Key here...", type="password")
|
| 130 |
+
chat_history = gr.Chatbot(label="OpenAI Chatbot with RAG", elem_id="chatbox")
|
| 131 |
+
user_input = gr.Textbox(placeholder="Enter your prompt here...")
|
| 132 |
+
submit_button = gr.Button("Submit")
|
| 133 |
+
submit_button.click(chat_ui, inputs=[user_input, api_key_input, chat_history], outputs=chat_history)
|
| 134 |
+
|
| 135 |
+
if __name__ == "__main__":
|
| 136 |
+
demo.launch()
|
chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/data_level0.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7fdb1852b1f33ec1f06620483cd9e9d769c843b4adf1363f384efb44adee359d
|
| 3 |
+
size 12428000
|
chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/header.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0d262a9eef1210b3dc49c38d785567356b10abbbd2fb6d37eca142c5b84b5c26
|
| 3 |
+
size 100
|
chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/index_metadata.pickle
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:25f02c7038ec98303a0cb01efa8c999074d64d11ce28277128cf076afb8005f5
|
| 3 |
+
size 46767
|
chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/length.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:077b99a97702a239d38650d7bc68f98136901063b4cf7df1e8601ffe6fbac674
|
| 3 |
+
size 4000
|
chromadb_storage_openai_upgrade/b567b3ad-af02-467e-8f86-862c4b7a61d1/link_lists.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5be490c12afb0e518d3f633b8ebe724a648b6309a86c1654727144bbb7f5c7fa
|
| 3 |
+
size 8420
|
chromadb_storage_openai_upgrade/chroma.sqlite3
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:43cc6200827205a8da0155b1bd590a4916a7e9124eb0d555a06f2ac40c3d4e27
|
| 3 |
+
size 47734784
|
requirements.txt
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
python-dotenv
|
| 2 |
+
gradio
|
| 3 |
+
groq
|
| 4 |
+
chromadb
|
| 5 |
+
langchain
|
| 6 |
+
pymupdf
|
| 7 |
+
numpy
|
| 8 |
+
fpdf
|
| 9 |
+
pygments
|
| 10 |
+
weasyprint
|
| 11 |
+
langchain-community
|
| 12 |
+
transformers
|
| 13 |
+
sentence-transformers
|