Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from langchain.agents import create_tool_calling_agent, AgentExecutor
|
3 |
+
from langchain.memory import ConversationBufferWindowMemory
|
4 |
+
from langchain_core.prompts import MessagesPlaceholder, ChatPromptTemplate
|
5 |
+
from langchain_core.runnables import RunnableConfig
|
6 |
+
from langchain_community.callbacks import StreamlitCallbackHandler
|
7 |
+
|
8 |
+
# models
|
9 |
+
from langchain_openai import ChatOpenAI
|
10 |
+
from langchain_anthropic import ChatAnthropic
|
11 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
12 |
+
|
13 |
+
# custom tools
|
14 |
+
from tools.search_ddg import search_ddg
|
15 |
+
from tools.fetch_page import fetch_page
|
16 |
+
|
17 |
+
###### dotenv を利用しない場合は消してください ######
|
18 |
+
try:
|
19 |
+
from dotenv import load_dotenv
|
20 |
+
load_dotenv()
|
21 |
+
except ImportError:
|
22 |
+
import warnings
|
23 |
+
warnings.warn("dotenv not found. Please make sure to set your environment variables manually.", ImportWarning)
|
24 |
+
################################################
|
25 |
+
|
26 |
+
CUSTOM_SYSTEM_PROMPT = """
|
27 |
+
あなたは、ユーザーのリクエストに基づいてインターネットで調べ物を行うアシスタントです。
|
28 |
+
利用可能なツールを使用して、調査した情報を説明してください。
|
29 |
+
既に知っていることだけに基づいて答えないでください。回答する前にできる限り検索を行ってください。
|
30 |
+
(ユーザーが読むページを指定するなど、特別な場合は、検索する必要はありません。)
|
31 |
+
|
32 |
+
検索結果ページを見ただけでは情報があまりないと思われる場合は、次の2つのオプションを検討して試してみてください。
|
33 |
+
|
34 |
+
- 検索結果のリンクをクリックして、各ページのコンテンツにアクセスし、読んでみてください。
|
35 |
+
- 1ページが長すぎる場合は、3回以上ページ送りしないでください(メモリの負荷がかかるため)。
|
36 |
+
- 検索クエリを変更して、新しい検索を実行してください。
|
37 |
+
- ユーザーは日本に住んでいます。情報は日本の地域に限定してください。
|
38 |
+
- 時期の指定がない場合は、2024年の最新情報を検索ください。
|
39 |
+
|
40 |
+
ユーザーは非常に忙しく、あなたほど自由ではありません。
|
41 |
+
そのため、ユーザーの労力を節約するために、直接的な回答を提供してください。
|
42 |
+
|
43 |
+
=== 悪い回答の例 ===
|
44 |
+
- これらのページを参照してください。
|
45 |
+
- これらのページを参照してコードを書くことができます。
|
46 |
+
- 次のページが役立つでしょう。
|
47 |
+
|
48 |
+
=== 良い回答の例 ===
|
49 |
+
- これはサンプルコードです。 -- サンプルコードをここに --
|
50 |
+
- あなたの質問の答えは -- 回答をここに --
|
51 |
+
|
52 |
+
回答の最後には、参照したページのURLを**必ず**記載してください。(これにより、ユーザーは回答を検証することができます)
|
53 |
+
|
54 |
+
ユーザーが使用している言語で回答するようにしてください。
|
55 |
+
ユーザーが日本語で質問した場合は、日本語で回答してください。ユーザーがスペイン語で質問した場合は、スペイン語で回答してください。
|
56 |
+
"""
|
57 |
+
|
58 |
+
|
59 |
+
def init_page():
|
60 |
+
st.set_page_config(
|
61 |
+
page_title="Web Browsing Agent",
|
62 |
+
page_icon="🤗"
|
63 |
+
)
|
64 |
+
st.header("Web Browsing Agent 🤗")
|
65 |
+
# st.sidebar.title("Options")
|
66 |
+
|
67 |
+
|
68 |
+
def init_messages():
|
69 |
+
# clear_button = st.button("Clear Conversation", key="clear")
|
70 |
+
if "messages" not in st.session_state:
|
71 |
+
st.session_state.messages = [
|
72 |
+
{"role": "assistant", "content": "こんにちは!なんでも質問をどうぞ!"}
|
73 |
+
]
|
74 |
+
st.session_state['memory'] = ConversationBufferWindowMemory(
|
75 |
+
return_messages=True,
|
76 |
+
memory_key="chat_history",
|
77 |
+
k=10
|
78 |
+
)
|
79 |
+
|
80 |
+
# このようにも書ける
|
81 |
+
# from langchain_community.chat_message_histories import StreamlitChatMessageHistory
|
82 |
+
# msgs = StreamlitChatMessageHistory(key="special_app_key")
|
83 |
+
# st.session_state['memory'] = ConversationBufferMemory(memory_key="history", chat_memory=msgs)
|
84 |
+
|
85 |
+
|
86 |
+
def select_model(temperature=0):
|
87 |
+
models = ("GPT-4o","GPT-4o-mini", "Claude 3.5 Sonnet", "Gemini 1.5 Pro")
|
88 |
+
model_choice = st.radio("Choose a model:", models)
|
89 |
+
if model_choice == "GPT-4o":
|
90 |
+
return ChatOpenAI(temperature=temperature, model_name="gpt-4o")
|
91 |
+
elif model_choice == "GPT-4o-mini":
|
92 |
+
return ChatOpenAI(temperature=temperature, model_name="gpt-4o-mini")
|
93 |
+
elif model_choice == "Claude 3.5 Sonnet":
|
94 |
+
return ChatAnthropic(temperature=temperature, model_name="claude-3-5-sonnet-20240620")
|
95 |
+
elif model_choice == "Gemini 1.5 Pro":
|
96 |
+
return ChatGoogleGenerativeAI(temperature=temperature, model="gemini-1.5-pro-latest")
|
97 |
+
|
98 |
+
|
99 |
+
def create_agent():
|
100 |
+
tools = [search_ddg, fetch_page]
|
101 |
+
prompt = ChatPromptTemplate.from_messages([
|
102 |
+
("system", CUSTOM_SYSTEM_PROMPT),
|
103 |
+
MessagesPlaceholder(variable_name="chat_history"),
|
104 |
+
("user", "{input}"),
|
105 |
+
MessagesPlaceholder(variable_name="agent_scratchpad")
|
106 |
+
])
|
107 |
+
llm = select_model()
|
108 |
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
109 |
+
return AgentExecutor(
|
110 |
+
agent=agent,
|
111 |
+
tools=tools,
|
112 |
+
verbose=True,
|
113 |
+
memory=st.session_state['memory']
|
114 |
+
)
|
115 |
+
|
116 |
+
|
117 |
+
def main():
|
118 |
+
init_page()
|
119 |
+
init_messages()
|
120 |
+
web_browsing_agent = create_agent()
|
121 |
+
|
122 |
+
for msg in st.session_state['memory'].chat_memory.messages:
|
123 |
+
st.chat_message(msg.type).write(msg.content)
|
124 |
+
|
125 |
+
if prompt := st.chat_input(placeholder="2024年9月の東京のイベント情報を教えて"):
|
126 |
+
st.chat_message("user").write(prompt)
|
127 |
+
|
128 |
+
with st.chat_message("assistant"):
|
129 |
+
# コールバック関数の設定 (エージェントの動作の可視化用)
|
130 |
+
st_cb = StreamlitCallbackHandler(
|
131 |
+
st.container(), expand_new_thoughts=True)
|
132 |
+
|
133 |
+
# エージェントを実行
|
134 |
+
response = web_browsing_agent.invoke(
|
135 |
+
{'input': prompt},
|
136 |
+
config=RunnableConfig({'callbacks': [st_cb]})
|
137 |
+
)
|
138 |
+
st.write(response["output"])
|
139 |
+
|
140 |
+
|
141 |
+
if __name__ == '__main__':
|
142 |
+
main()
|