AWEsumCare-Demo / app.py
ray
update to v5
10de6c4
raw
history blame
10.2 kB
import glob
import gradio as gr
import openai
import os
from dotenv import load_dotenv
import phoenix as px
import llama_index
from llama_index import Prompt, ServiceContext, VectorStoreIndex, SimpleDirectoryReader
from llama_index.chat_engine.types import ChatMode
from llama_index.llms import ChatMessage, MessageRole
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.text_splitter import SentenceSplitter
from llama_index.extractors import TitleExtractor
from llama_index.ingestion import IngestionPipeline
from chat_template import CHAT_TEXT_QA_PROMPT, TEXT_QA_SYSTEM_PROMPT
from schemas import ChatbotVersion, ServiceProvider
from chatbot import Chatbot, IndexBuilder
from custom_io import MarkdownReader, UnstructuredReader, default_file_metadata_func
from qdrant import client as qdrantClient
from llama_index import set_global_service_context
from service_provider_config import get_service_provider_config
load_dotenv()
# initial service setup
px.launch_app()
llama_index.set_global_handler("arize_phoenix")
# llama_index.set_global_handler("wandb", run_args={"project": "llamaindex"})
openai.api_key = os.getenv("OPENAI_API_KEY")
IS_LOAD_FROM_VECTOR_STORE = True
VDB_COLLECTION_NAME = "demo-v5"
MODEL_NAME = ChatbotVersion.CHATGPT_4.value
CHUNK_SIZE = 8191
LLM, EMBED_MODEL = get_service_provider_config(
service_provider=ServiceProvider.OPENAI, model_name=MODEL_NAME)
service_context = ServiceContext.from_defaults(
chunk_size=CHUNK_SIZE,
llm=LLM,
embed_model=EMBED_MODEL,
)
set_global_service_context(service_context)
class AwesumIndexBuilder(IndexBuilder):
def _load_doucments(self):
directory = "./awesumcare_data/awesumcare_manual_data"
# all_files = glob.glob(os.path.join(directory, '*.md'))
# faq_files = [f for f in all_files if 'FAQ' in os.path.basename(f)]
# print(faq_files)
dir_reader = SimpleDirectoryReader(directory, file_extractor={
".pdf": UnstructuredReader(),
".docx": UnstructuredReader(),
".pptx": UnstructuredReader(),
".md": MarkdownReader()
},
recursive=True,
# input_files=faq_files,
exclude=["*.png", "*.pptx", "*.docx", "*.pdf"],
file_metadata=default_file_metadata_func)
self.documents = dir_reader.load_data()
print(f"Loaded {len(self.documents)} docs")
def _setup_service_context(self):
super()._setup_service_context()
def _setup_vector_store(self):
self.vector_store = QdrantVectorStore(
client=qdrantClient, collection_name=self.vdb_collection_name)
super()._setup_vector_store()
def _setup_index(self):
super()._setup_index()
if self.is_load_from_vector_store:
self.index = VectorStoreIndex.from_vector_store(self.vector_store)
print("set up index from vector store")
return
pipeline = IngestionPipeline(
transformations=[
# SentenceSplitter(),
self.embed_model,
],
vector_store=self.vector_store,
)
pipeline.run(documents=self.documents, show_progress=True)
self.index = VectorStoreIndex.from_vector_store(self.vector_store)
class AwesumCareToolChatbot(Chatbot):
DENIED_ANSWER_PROMPT = ""
SYSTEM_PROMPT = ""
CHAT_EXAMPLES = [
"什麼是安心三寶?",
"點樣立平安紙?",
"甚麼是⾒證?",
"訂立每份⽂件需要多少錢以及付款⽅法?",
"通過安⼼三寶製作的⽂件有法律效⼒嗎?",
]
def _setup_observer(self):
pass
def _setup_index(self):
super()._setup_index()
# def _setup_index(self):
# self.index = VectorStoreIndex.from_documents(
# self.documents,
# service_context=self.service_context
# )
# super()._setup_index()
def _setup_query_engine(self):
super()._setup_query_engine()
self.query_engine = self.index.as_query_engine(
text_qa_template=CHAT_TEXT_QA_PROMPT)
def _setup_tools(self):
from llama_index.tools.query_engine import QueryEngineTool
self.tools = QueryEngineTool.from_defaults(
query_engine=self.query_engine)
return super()._setup_tools()
def _setup_chat_engine(self):
# testing #
from llama_index.agent import OpenAIAgent
self.chat_engine = OpenAIAgent.from_tools(
tools=[self.tools],
llm=LLM,
similarity_top_k=1,
verbose=True
)
print("set up agent as chat engine")
# testing #
# self.chat_engine = self.index.as_chat_engine(
# chat_mode=ChatMode.BEST,
# similarity_top_k=5,
# text_qa_template=CHAT_TEXT_QA_PROMPT)
super()._setup_chat_engine()
class AweSumCareContextChatbot(AwesumCareToolChatbot):
def _setup_query_engine(self):
pass
def _setup_tools(self):
pass
def _setup_chat_engine(self):
self.chat_engine = self.index.as_chat_engine(
chat_mode=ChatMode.CONTEXT,
similarity_top_k=5,
system_prompt=TEXT_QA_SYSTEM_PROMPT.content,
text_qa_template=CHAT_TEXT_QA_PROMPT)
class AweSumCareSimpleChatbot(AwesumCareToolChatbot):
def _setup_query_engine(self):
pass
def _setup_tools(self):
pass
def _setup_chat_engine(self):
self.chat_engine = self.index.as_chat_engine(
chat_mode=ChatMode.SIMPLE)
model_name = MODEL_NAME
index_builder = AwesumIndexBuilder(vdb_collection_name=VDB_COLLECTION_NAME,
embed_model=EMBED_MODEL,
is_load_from_vector_store=IS_LOAD_FROM_VECTOR_STORE)
# gpt-3.5-turbo-1106, gpt-4-1106-preview
awesum_chatbot = AwesumCareToolChatbot(model_name=model_name, index_builder=index_builder)
awesum_chatbot_context = AweSumCareContextChatbot(model_name=model_name, index_builder=index_builder)
awesum_chatbot_simple = AweSumCareSimpleChatbot(model_name=model_name, index_builder=index_builder)
def service_setup(model_name):
CHUNK_SIZE = 1024
LLM, EMBED_MODEL = get_service_provider_config(
service_provider=ServiceProvider.OPENAI, model_name=model_name)
service_context = ServiceContext.from_defaults(
chunk_size=CHUNK_SIZE,
llm=LLM,
embed_model=EMBED_MODEL,
)
set_global_service_context(service_context)
return LLM, EMBED_MODEL
def vote(data: gr.LikeData):
if data.liked:
gr.Info("You up-voted this response: " + data.value)
else:
gr.Info("You down-voted this response: " + data.value)
chatbot = gr.Chatbot()
with gr.Blocks() as demo:
gr.Markdown("# Awesum Care demo")
# with gr.Row():
# model_selector = gr.Radio(
# value=ChatbotVersion.CHATGPT_35.value,
# choices=[ChatbotVersion.CHATGPT_35.value, ChatbotVersion.CHATGPT_4.value],
# label="Select Chatbot Model (To be implemented)"
# )
with gr.Tab("With relevant context sent to system prompt"):
context_interface = gr.ChatInterface(
awesum_chatbot_context.stream_chat,
examples=awesum_chatbot.CHAT_EXAMPLES,
)
chatbot.like(vote, None, None)
# with gr.Tab("With function calling as tool to retrieve"):
# function_call_interface = gr.ChatInterface(
# awesum_chatbot.stream_chat,
# examples=awesum_chatbot.CHAT_EXAMPLES,
# )
# chatbot.like(vote, None, None)
# with gr.Tab("Vanilla ChatGPT without modification"):
# vanilla_interface = gr.ChatInterface(
# awesum_chatbot_simple.stream_chat,
# examples=awesum_chatbot.CHAT_EXAMPLES)
gr.Markdown("instructions:\n"
"\nUsing model gpt-4-preview-1106, the most advanced model now in the market.\n"
"\n(Note that it can be much slower than gpt-3.5, openai's api can be unstable sometimes.)\n"
# "\nThree Tabs:\n"
# "1. Relevant context: retreiving relevant documents and send to ChatGPT.\n"
# "2. Give tools to chatgpt to retrieve context: the most advanced, slowest (>30s to use the tools, before answering).\n"
# "3. Vanilla ChatGPT: self-explanatory.\n"
)
# @model_selector.change(inputs=[model_selector, chatbot], outputs=[context_interface, function_call_interface, vanilla_interface])
# def switch_model(model_name, my_chatbot):
# print(model_name)
# print(my_chatbot.config())
# LLM, EMBED_MODEL = service_setup(model_name)
# # global awesum_chatbot, awesum_chatbot_context, awesum_chatbot_simple
# # Logic to switch models - create new instances of the chatbots with the selected model
# index_builder = AwesumIndexBuilder(vdb_collection_name=VDB_COLLECTION_NAME,
# embed_model=EMBED_MODEL,
# is_load_from_vector_store=IS_LOAD_FROM_VECTOR_STORE)
# awesum_chatbot = AwesumCareToolChatbot(model_name=model_name, index_builder=index_builder, llm=LLM)
# awesum_chatbot_context = AweSumCareContextChatbot(model_name=model_name, index_builder=index_builder)
# awesum_chatbot_simple = AweSumCareSimpleChatbot(model_name=model_name, index_builder=index_builder)
# # return awesum_chatbot.stream_chat, awesum_chatbot_context.stream_chat, awesum_chatbot_simple.stream_chat
# new_context_interface = gr.ChatInterface(
# awesum_chatbot_context.stream_chat,
# )
# new_function_call_interface = gr.ChatInterface(
# awesum_chatbot.stream_chat,
# )
# new_vanilla_interface = gr.ChatInterface(
# awesum_chatbot_simple.stream_chat,
# )
# return new_context_interface, new_function_call_interface, new_vanilla_interface
demo.queue()
demo.launch(share=False, auth=("demo", os.getenv("PASSWORD")))