File size: 4,230 Bytes
64a9585
 
 
 
 
 
 
 
 
 
 
 
a3ace0e
 
 
64a9585
36ca3a6
64a9585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29bf3fe
 
64a9585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36ca3a6
64a9585
36ca3a6
64a9585
 
 
 
 
 
 
 
 
 
 
 
 
739daa1
64a9585
 
 
 
77ac978
64a9585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0f4b730
 
 
 
64a9585
 
 
 
29bf3fe
64a9585
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from typing import Dict

import streamlit as st
import pickle
from langchain import OpenAI
from langchain.prompts import PromptTemplate
import os

from langchain import OpenAI
from langchain.chains.qa_with_sources import load_qa_with_sources_chain


# with open("data/key.txt") as f:
#     openai_key = f.read().strip()
# os.environ["OPENAI_API_KEY"] = openai_key


def get_docstore():
    with open("data/acn_homepage_faiss_store_1000_tokens.pickle", "rb") as f:
        store = pickle.load(f)
    return store


def init_chain():
    question_prompt_template = """長い文書の次の部分を使って、質問に答えるために関連するテキストがあるかどうかを確認します。
    関連するテキストがあれば、そのテキストを返す。なかったら、「関連情報なし」と返さないてください。

    {context}

    質問: {question}
    関連するテキスト:"""
    QUESTION_PROMPT = PromptTemplate(
        template=question_prompt_template, input_variables=["context", "question"]
    )

    combine_prompt_template = """
    あなたは、アクセンチュアのAIアシスタントです。
    あなたには、以下のような長いドキュメントの抜粋部分と質問が与えられています。
    提供されたテキストを参考して答えてください。
    提供されたテキストに根拠がない場合は、わからないと答えなさい。答えを作り上げないでください。
    =========
    テキスト:{summaries}
    =========
    質問: {question}
    =========
    答案:"""
    COMBINE_PROMPT = PromptTemplate(
        template=combine_prompt_template, input_variables=["summaries", "question"]
    )

    chain = load_qa_with_sources_chain(OpenAI(temperature=0), 
                                    chain_type="map_reduce", 
                                    return_intermediate_steps=True, 
                                    question_prompt=QUESTION_PROMPT, 
                                    combine_prompt=COMBINE_PROMPT,
                                    verbose=True
                                    )
    return chain

# format the result to markdown format
def format_result_to_markdown(result: dict):
    result_markdown = ""
    result_markdown += f"""
**Answer**
{result["output_text"].strip()}
    """
    for i, intermediate_step in enumerate(result["intermediate_steps"]):
        link = result["input_documents"][i].metadata["source"]
        result_markdown += f"""
**Link**: {link}  
**Extracted Information**: {intermediate_step}
        """

    return result_markdown

if __name__ == "__main__":
    st.title("ACN AIアシスタント(超爆速版※)")
    st.subheader("ACN HPをベースとしているため、HPにある内容のみ回答します。")
    st.text("※超爆速とは、開発スピードを指しています。Botの反応速度ではありません。")
    st.markdown(
        """
## 質問の例:
- アクセンチュアのAI領域のリーダーは誰ですか?
- アクセンチュアのCEOは誰ですか?
- アクセンチュアの社長は誰ですか?
- アクセンチュアの事業内容は?
- アクセンチュアの事業所在地は?
- アクセンチュア社員の有給は何日ありますか?
        """
    )
    docsearch = get_docstore()
    chain = init_chain()
    question = st.text_input("質問を入力してください", "")

    answer_slot = st.empty()
    with st.spinner("答案を検索中..."):
        if st.button("Submit"):
            try:
                query = question.strip()
                # st.write("len(docsearch):", len(docsearch))
                # st.write("help(docsearch.index):", help(docsearch.index))
                # st.write("help(docsearch.index.search):", help(docsearch.index.search))
                st.write(len(docsearch.index_to_docstore_id))
                docs = docsearch.similarity_search(query, k=3)
                result = chain(
                    {"input_documents": docs, "question": query},
                )

                answer_slot.markdown(format_result_to_markdown(result))
            except Exception as e:
                st.write(e)