anpigon commited on
Commit
9b6516b
1 Parent(s): 6c93025

refactor(app.py): remove unused imports and variables

Browse files

feat(app.py): add support for persisting vector store to disk and increase number of retrieved documents to 3
feat(app.py): add functionality to reduce number of retrieved documents to 1 if the maximum number of tokens is exceeded
feat(app.py): add verbose mode to retrieval chain to aid debugging
feat(app.py): update chatbot to use the new RetrievalQA chain and add support for displaying source documents in the response

Files changed (1) hide show
  1. app.py +49 -71
app.py CHANGED
@@ -1,52 +1,23 @@
1
- from langchain.chat_models import ChatOpenAI
2
- from langchain.document_loaders import PyPDFLoader
3
- from langchain.embeddings.openai import OpenAIEmbeddings
4
- from langchain.embeddings.cohere import CohereEmbeddings
5
- from langchain.text_splitter import CharacterTextSplitter
6
- from langchain.vectorstores.elastic_vector_search import ElasticVectorSearch
7
- from langchain.vectorstores import Chroma
8
- from PyPDF2 import PdfWriter
9
  import gradio as gr
10
- import os
11
- from dotenv import load_dotenv
12
- import openai
13
-
14
- load_dotenv()
15
- #비밀키 가져오기 시도중
16
- # api_key = os.getenv('OPENAI_API_KEY') ## .env 파일 업로드하면 숨겨지지 않음 안됨
17
- # api_key = os.environ['my_secret'] ## 안불러와짐
18
- # api_key = os.getenv('my_secret') ## 3트 .env 대신 secret키를 불러오는 형태로 도전
19
- os.environ["OPENAI_API_KEY"] = os.environ['my_secret']
20
-
21
- loader = PyPDFLoader("/home/user/app/docs.pdf")
22
- documents = loader.load()
23
-
24
- text_splitter = CharacterTextSplitter(chunk_size=800, chunk_overlap=0)
25
- texts = text_splitter.split_documents(documents)
26
-
27
- #vector embedding
28
- embeddings = OpenAIEmbeddings()
29
- vector_store = Chroma.from_documents(texts, embeddings)
30
- retriever = vector_store.as_retriever(search_kwargs={"k": 2})
31
-
32
  from langchain.chat_models import ChatOpenAI
33
- from langchain.chains import RetrievalQAWithSourcesChain
34
-
35
- llm = ChatOpenAI(model_name="gpt-4", temperature=0) # Modify model_name if you have access to GPT-4
36
-
37
- chain = RetrievalQAWithSourcesChain.from_chain_type(
38
- llm=llm,
39
- chain_type="stuff",
40
- retriever = retriever,
41
- return_source_documents=True)
42
-
43
  from langchain.prompts.chat import (
44
  ChatPromptTemplate,
45
- SystemMessagePromptTemplate,
46
  HumanMessagePromptTemplate,
 
47
  )
 
 
 
 
 
 
 
48
 
49
- system_template="""Use the following pieces of context to answer the users question shortly.
 
 
50
  Given the following summaries of a long document and a question, create a final answer with references ("SOURCES"), use "SOURCES" in capital letters regardless of the number of sources.
51
  If you don't know the answer, just say that "I don't know", don't try to make up an answer.
52
  ----------------
@@ -56,55 +27,62 @@ You MUST answer in Korean and in Markdown format:"""
56
 
57
  messages = [
58
  SystemMessagePromptTemplate.from_template(system_template),
59
- HumanMessagePromptTemplate.from_template("{question}")
60
  ]
61
 
62
  prompt = ChatPromptTemplate.from_messages(messages)
63
 
64
- from langchain.chat_models import ChatOpenAI
65
- from langchain.chains import RetrievalQAWithSourcesChain
66
-
67
  chain_type_kwargs = {"prompt": prompt}
68
 
69
- llm = ChatOpenAI(model_name="gpt-4", temperature=0) # Modify model_name if you have access to GPT-4
70
-
71
- chain = RetrievalQAWithSourcesChain.from_chain_type(
72
  llm=llm,
73
  chain_type="stuff",
74
- retriever = retriever,
75
  return_source_documents=True,
76
- chain_type_kwargs=chain_type_kwargs
 
 
77
  )
78
 
79
- query = "행복한 인생이란?"
80
- result = chain(query)
81
-
82
-
83
- for doc in result['source_documents']:
84
- print('내용 : ' + doc.page_content[0:100].replace('\n', ' '))
85
- print('파일 : ' + doc.metadata['source'])
86
- print('페이지 : ' + str(doc.metadata['page']))
87
-
88
-
89
- def respond(message, chat_history): # 채팅봇의 응답을 처리하는 함수를 정의합니다.
90
 
 
 
91
  result = chain(message)
92
 
93
- bot_message = result['answer']
 
 
 
 
 
 
 
 
 
 
 
94
 
95
- for i, doc in enumerate(result['source_documents']):
96
- bot_message += '[' + str(i+1) + '] ' + doc.metadata['source'] + '(' + str(doc.metadata['page']) + ') '
97
 
98
- chat_history.append((message, bot_message)) # 채팅 기록에 사용자의 메시지와 봇의 응답을 추가합니다.
 
99
 
100
- return "", chat_history # 수정된 채팅 기록을 ��환합니다.
101
 
102
- with gr.Blocks(theme='gstaff/sketch') as demo: # gr.Blocks()를 사용하여 인터페이스를 생성합니다.
 
103
  gr.Markdown("# 안녕하세요. 세이노와 대화해보세요.")
104
  chatbot = gr.Chatbot(label="채팅창") # '채팅창'이라는 레이블을 가진 채팅봇 컴포넌트를 생성합니다.
105
  msg = gr.Textbox(label="입력") # '입력'이라는 레이블을 가진 텍스트박스를 생성합니다.
106
  clear = gr.Button("초기화") # '초기화'라는 레이블을 가진 버튼을 생성합니다.
107
 
108
- msg.submit(respond, [msg, chatbot], [msg, chatbot]) # 텍스트박스에 메시지를 입력하고 제출하면 respond 함수가 호출되도록 합니다.
109
- clear.click(lambda: None, None, chatbot, queue=False) # '초기화' 버튼을 클릭하면 채팅 기록을 초기화합니다.
110
- demo.launch(debug=True) # 인터페이스를 실행합니다. 실행하면 사용자는 '입력' 텍스트박스에 메시지를 작성하고 제출할 있으며, '초기화' 버튼을 통해 채팅 기록을 초기화 할 수 있습니다.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ from langchain.chains import RetrievalQA
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  from langchain.chat_models import ChatOpenAI
4
+ from langchain.embeddings.openai import OpenAIEmbeddings
 
 
 
 
 
 
 
 
 
5
  from langchain.prompts.chat import (
6
  ChatPromptTemplate,
 
7
  HumanMessagePromptTemplate,
8
+ SystemMessagePromptTemplate,
9
  )
10
+ from langchain.vectorstores import Chroma
11
+
12
+ from constants import persist_directory
13
+
14
+ embedding = OpenAIEmbeddings()
15
+ vector_store = Chroma(persist_directory=persist_directory, embedding_function=embedding)
16
+ retriever = vector_store.as_retriever(search_kwargs={"k": 3})
17
 
18
+ llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
19
+
20
+ system_template = """Use the following pieces of context to answer the users question shortly.
21
  Given the following summaries of a long document and a question, create a final answer with references ("SOURCES"), use "SOURCES" in capital letters regardless of the number of sources.
22
  If you don't know the answer, just say that "I don't know", don't try to make up an answer.
23
  ----------------
 
27
 
28
  messages = [
29
  SystemMessagePromptTemplate.from_template(system_template),
30
+ HumanMessagePromptTemplate.from_template("{question}"),
31
  ]
32
 
33
  prompt = ChatPromptTemplate.from_messages(messages)
34
 
 
 
 
35
  chain_type_kwargs = {"prompt": prompt}
36
 
37
+ chain = RetrievalQA.from_chain_type(
 
 
38
  llm=llm,
39
  chain_type="stuff",
40
+ retriever=retriever,
41
  return_source_documents=True,
42
+ chain_type_kwargs=chain_type_kwargs,
43
+ reduce_k_below_max_tokens=True,
44
+ verbose=True,
45
  )
46
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
+ # 채팅봇의 응답을 처리하는 함수를 정의합니다.
49
+ def respond(message, chat_history):
50
  result = chain(message)
51
 
52
+ bot_message = result["answer"]
53
+
54
+ for i, doc in enumerate(result["source_documents"]):
55
+ bot_message += (
56
+ "["
57
+ + str(i + 1)
58
+ + "] "
59
+ + doc.metadata["source"]
60
+ + "("
61
+ + str(doc.metadata["page"])
62
+ + ") "
63
+ )
64
 
65
+ # 채팅 기록에 사용자의 메시지와 봇의 응답을 추가합니다.
66
+ chat_history.append((message, bot_message))
67
 
68
+ # 수정된 채팅 기록을 반환합니다.
69
+ return "", chat_history
70
 
 
71
 
72
+ # gr.Blocks()를 사용하여 인터페이스를 생성합니다.
73
+ with gr.Blocks(theme="gstaff/sketch") as demo:
74
  gr.Markdown("# 안녕하세요. 세이노와 대화해보세요.")
75
  chatbot = gr.Chatbot(label="채팅창") # '채팅창'이라는 레이블을 가진 채팅봇 컴포넌트를 생성합니다.
76
  msg = gr.Textbox(label="입력") # '입력'이라는 레이블을 가진 텍스트박스를 생성합니다.
77
  clear = gr.Button("초기화") # '초기화'라는 레이블을 가진 버튼을 생성합니다.
78
 
79
+ msg.submit(
80
+ respond, [msg, chatbot], [msg, chatbot]
81
+ ) # 텍스트박스에 메시지를 입력하고 제출하면 respond 함수가 호출되도록 합니다.
82
+ clear.click(
83
+ lambda: None, None, chatbot, queue=False
84
+ ) # '초기화' 버튼을 클릭하면 채팅 기록을 초기화합니다.
85
+
86
+ demo.launch(
87
+ debug=True
88
+ ) # 인터페이스를 실행합니다. 실행하면 사용자는 '입력' 텍스트박스에 메시지를 작성하고 제출할 수 있으며, '초기화' 버튼을 통해 채팅 기록을 초기화 할 수 있습니다.