import gradio as gr import os from typing import List from langchain.llms import OpenAIChat from langchain.prompts import PromptTemplate from langchain.chains.question_answering import load_qa_chain from langchain.chains import LLMChain, ChatVectorDBChain from langchain.callbacks.base import CallbackManager from langchain.chains.chat_vector_db.prompts import CONDENSE_QUESTION_PROMPT as SYNTHESIS_PROMPT from langchain.document_loaders import DirectoryLoader from langchain.embeddings import OpenAIEmbeddings from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.vectorstores.faiss import FAISS response_prompt_template = """You are an AI assistant for the machine learning monitoring startup Arthur. You are given the following extracted parts of a long document and a question. If the question includes a request for code, provide a code block directly from the documentation. Don't try to make up an answer. If the question is not about Arthur, politely inform them that you are tuned to only answer questions about Arthur. ========= Example 1: Question: What data do I need to send to Arthur? ========= **3. What if my data is proprietary? Can I still use Arthur?** Yes! Arthur offers on-premises installation for customers with data security requirements. By integrating Arthur into your business's on-premises stack, you can be confident that all security requirements are met while still getting the benefits of the computation and analytics Arthur provides. *** **4. What if I don’t have ground truth labels for my data? Or what if I will have the ground truth labels in the future, but they are not available yet?** You don't need ground truth labels to log your model's inferences with Arthur. If your ground truth labels become available after your model's inferences, whether seconds later or years later, Arthur can link these new ground truth values to your model's past predictions, linking the new values by ID to their corresponding inferences already in the Arthur system. In the meantime, Arthur’s data drift metrics can offer leading indicators of model underperformance to keep you covered if your ground truth labels are delayed or never become available. *** ========= Answer in Markdown: The data you need to get into Arthur is only the inference data - no ground truth is needed, since it can be uploaded at a later time. Also, if you have proprietary data, you can install Arthur on-premises to keep your own data security protocols. ========= Now the real question: Question: {question} ========= {context} ========= Answer in Markdown:""" RESPONSE_PROMPT = PromptTemplate( template=response_prompt_template, input_variables=["context", "question"] ) def get_docs_vectorstore(dir_name): loader = DirectoryLoader(dir_name) raw_documents = loader.load() text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200, ) documents = text_splitter.split_documents(raw_documents) embeddings = OpenAIEmbeddings() return FAISS.from_documents(documents, embeddings) def get_langchain_agent(api_key): os.environ["OPENAI_API_KEY"] = api_key vectorstore = get_docs_vectorstore("files/arthur-docs-markdown") manager = CallbackManager([]) question_manager = CallbackManager([]) stream_manager = CallbackManager([]) question_gen_llm = OpenAIChat( temperature=0, verbose=True, callback_manager=question_manager, ) streaming_llm = OpenAIChat( streaming=True, callback_manager=stream_manager, verbose=True, temperature=0, ) question_generator = LLMChain( llm=question_gen_llm, prompt=SYNTHESIS_PROMPT, callback_manager=manager ) chat_response_generator = load_qa_chain( streaming_llm, chain_type="stuff", prompt=RESPONSE_PROMPT, callback_manager=manager ) agent = ChatVectorDBChain( vectorstore=vectorstore, combine_docs_chain=chat_response_generator, question_generator=question_generator, callback_manager=manager, return_source_documents=True) os.environ["OPENAI_API_KEY"] = "" return agent def get_source_doc(output): sources = output["source_documents"] assert len(sources) > 0 source_document = sources[0] html_filename = source_document.metadata['source'] source_doc_link = html_filename.replace('files/', '') source_doc_file = html_filename.replace('files/docs.arthur.ai/', '').replace('.html', '') with open(source_doc_file, 'r') as f: source_text = f.read() return source_text, source_doc_link def chat(inp, history, agent): history = history or [] result = agent({"question": inp, "chat_history": history}) chat_result = result["answer"] source_doc, source_link = get_source_doc(result) response = "" for word in chat_result.split(" "): response += word + " " yield history + [(inp, response)], history + [(inp, response)], source_doc, source_link def launch_ask_arthur(share=False): with gr.Blocks() as demo: with gr.Row(): gr.Markdown("