JKilpatrick/youtube_ai_makerspace
4
1 2import os3from langchain.embeddings.openai import OpenAIEmbeddings4from langchain.embeddings import CacheBackedEmbeddings5from langchain.storage import LocalFileStore6 7import chainlit as cl 8from chainlit.playground.providers import ChatOpenAI 9from dotenv import load_dotenv10load_dotenv()11 12from langchain.chat_models import ChatOpenAI13from langchain.prompts import ChatPromptTemplate14from langchain.schema.runnable import RunnablePassthrough15from langchain.embeddings.openai import OpenAIEmbeddings16from langchain.embeddings import CacheBackedEmbeddings17from langchain.storage import LocalFileStore18from langchain.vectorstores import Pinecone19 20from operator import itemgetter21import pinecone22 23# =============================================================================24# Retrieval Chain25# =============================================================================26def load_llm():27 llm = ChatOpenAI(28 model='gpt-3.5-turbo',29 temperature=0.0,30 )31 return llm32 33 34def load_vectorstore():35 36 pinecone.init(37 api_key=os.getenv('PINECONE_API_KEY'),38 environment=os.getenv('PINECONE_ENV')39 )40 41 #index = pinecone.GRPCIndex("youtube-index")42 index = pinecone.Index("youtube-index")43 store = LocalFileStore("./cache/")44 core_embeddings_model = OpenAIEmbeddings()45 46 embedder = CacheBackedEmbeddings.from_bytes_store(47 core_embeddings_model,48 store,49 namespace=core_embeddings_model.model50 )51 52 text_field = "text"53 54 vectorstore = Pinecone(55 index,56 embedder, 57 text_field58 )59 60 return vectorstore61 62 63def qa_chain():64 65 vectorstore = load_vectorstore()66 67 llm = load_llm()68 retriever = vectorstore.as_retriever()69 70 template = """You are a helpful assistant that answers questions on the provided context, if its not answered within the context respond with "This query is not directly mentioned by AI Makerspace" then respond the best to your ability. 71 Additionally, the context includes a specific integer formatted as <int>, representing a timestamp. 72 In your response, include this integer as a citation, formatted as a YouTube video link: "https://www.youtube.com/watch?v=[video_id]&t=<int>s" and text of link be the title of video.73 74 75 ### CONTEXT76 {context}77 78 ### QUESTION79 {question}80 """81 82 prompt = ChatPromptTemplate.from_template(template)83 84 retrieval_augmented_qa_chain = (85 {"context": itemgetter("question") | retriever,86 "question": itemgetter("question")87 }88 | RunnablePassthrough.assign(89 context=itemgetter("context")90 )91 | {92 "response": prompt | llm,93 "context": itemgetter("context"),94 }95 )96 97 return retrieval_augmented_qa_chain98 99# =============================================================================100# Chainlit101# =============================================================================102@cl.on_chat_start103async def on_chat_start():104 chain = qa_chain()105 cl.user_session.set("chain", chain)106 msg=cl.Message(content="What is your question about AI Makerspace?")107 await msg.send()108 109@cl.on_message110async def on_message(message: cl.Message):111 chain=cl.user_session.get("chain")112 res = chain.invoke({"question" : message.content})113 114 answer = res['response'].content115 await cl.Message(content=answer).send()116 117 '''118 source_documents = set()119 120 for document in res['context']:121 source_url = document.metadata['source_document']122 source_documents.add(source_url)123 124 combined_message = answer + "\n\nSource Documents:\n" + "\n".join(source_documents)125 126 await cl.Message(content=combined_message).send()127 '''