ftn03 commited on
Commit
b3ff8d8
Β·
0 Parent(s):

Initial commit - Search Engine Tool Agent

Browse files

Standalone Streamlit app with LangChain agent using DuckDuckGo, Wikipedia, and Arxiv tools.

Files changed (4) hide show
  1. .env.example +4 -0
  2. .gitignore +4 -0
  3. app.py +103 -0
  4. requirements.txt +11 -0
.env.example ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ OPENAI_API_KEY=your_openai_api_key
2
+ GROQ_API_KEY=your_groq_api_key
3
+ LANGCHAIN_API_KEY=your_langchain_api_key
4
+ LANGCHAIN_PROJECT=SearchEngineToolAgent
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .env
2
+ __pycache__/
3
+ *.pyc
4
+ .venv/
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ # Load environment variables
5
+ load_dotenv()
6
+
7
+ # LangSmith tracking
8
+ os.environ['LANGCHAIN_TRACING_V2'] = 'true'
9
+ os.environ['LANGCHAIN_PROJECT'] = os.getenv('LANGCHAIN_PROJECT', 'SearchEngineToolAgent')
10
+
11
+ import streamlit as st
12
+ from langchain_community.tools import ArxivQueryRun, WikipediaQueryRun, DuckDuckGoSearchRun
13
+ from langchain_community.utilities import WikipediaAPIWrapper, ArxivAPIWrapper
14
+ from langchain_groq import ChatGroq
15
+ from langchain_openai import ChatOpenAI
16
+ from langchain.agents import create_agent
17
+ from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
18
+
19
+ # Arxiv and Wikipedia tools
20
+ api_wrapper_wiki = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=250)
21
+ wiki_tool = WikipediaQueryRun(api_wrapper=api_wrapper_wiki)
22
+
23
+ api_wrapper_arxiv = ArxivAPIWrapper(top_k_results=1, doc_content_chars_max=250)
24
+ arxiv_tool = ArxivQueryRun(api_wrapper=api_wrapper_arxiv)
25
+
26
+ search_tool = DuckDuckGoSearchRun(name="ddgsSearch")
27
+
28
+ tools = [wiki_tool, arxiv_tool, search_tool]
29
+
30
+ # LLM
31
+ llm = ChatOpenAI(model="gpt-5-nano-2025-08-07", streaming=True)
32
+
33
+ system_prompt = """
34
+ You are a helpful assistant. You have access to tools to search the web, wikipedia and arxiv. Use them only when needed.
35
+ When facing an issue with one tool, try another tool. Your answer should be anchored to the tools.
36
+ Always respond in the same language as the user. Don't stop when facing an issue with one tool.
37
+ If none of the tools work, summarize the situation and say you can't find the answer.
38
+ """
39
+ search_agent = create_agent(model=llm, tools=tools, system_prompt=system_prompt)
40
+
41
+ # Streamlit UI
42
+ st.title("πŸ” Langchain - Chat with Search")
43
+ st.markdown("""
44
+ In this example, we're using `StreamlitCallbackHandler` to display the thoughts and actions of an agent in an interactive Streamlit app.
45
+ Try more LangChain 🀝 Streamlit Agent examples at [https://blog.langchain.com/langchain-streamlit/]
46
+ """)
47
+
48
+ # Sidebar for settings
49
+ st.sidebar.title("Settings")
50
+
51
+ if "messages" not in st.session_state:
52
+ st.session_state.messages = [
53
+ {"role": "assistant", "content": "πŸ‘‹ Hi, I am a chatbot πŸ€– that can search the web 🌐. How can I help you?"}
54
+ ]
55
+
56
+ for msg in st.session_state.messages:
57
+ st.chat_message(msg["role"]).markdown(msg["content"])
58
+
59
+ if prompt := st.chat_input(placeholder="Ask me anything"):
60
+
61
+ st.session_state.messages.append({"role": "user", "content": prompt})
62
+
63
+ with st.chat_message("user"):
64
+ st.markdown(prompt)
65
+
66
+ with st.chat_message("assistant"):
67
+ # Convert session messages to proper format
68
+ input_messages = [{"role": msg["role"], "content": msg["content"]} for msg in st.session_state.messages]
69
+
70
+ config = {"configurable": {"thread_id": "chat_session"}}
71
+
72
+ final_response = ""
73
+
74
+ with st.spinner("Thinking..."):
75
+ step = 0
76
+ for chunk in search_agent.stream(
77
+ {"messages": input_messages},
78
+ config=config,
79
+ stream_mode="values"
80
+ ):
81
+ latest_message = chunk["messages"][-1]
82
+ step += 1
83
+
84
+ if isinstance(latest_message, AIMessage):
85
+ if latest_message.content and latest_message.tool_calls:
86
+ with st.expander(f"πŸ’­ Step {step} : Reasoning", expanded=False):
87
+ st.markdown(latest_message.content)
88
+ if latest_message.tool_calls:
89
+ for tool_call in latest_message.tool_calls:
90
+ st.info(f"πŸ”§ Step {step} - Calling **{tool_call['name']}** with: `{tool_call['args']}`")
91
+ if latest_message.content and not latest_message.tool_calls:
92
+ final_response = latest_message.content
93
+
94
+ elif isinstance(latest_message, ToolMessage):
95
+ with st.expander(f"πŸ“„ Step {step} : Result from **{latest_message.name}**", expanded=False):
96
+ st.markdown(latest_message.content[:100])
97
+
98
+ if final_response:
99
+ st.session_state.messages.append({"role": "assistant", "content": final_response})
100
+ st.markdown(final_response)
101
+ else:
102
+ st.session_state.messages.append({"role": "assistant", "content": "I'm sorry, I couldn't find any information about that."})
103
+ st.markdown("I'm sorry, I couldn't find any information about that.")
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ python-dotenv
3
+ langchain
4
+ langchain-core
5
+ langchain-community
6
+ langchain-openai
7
+ langchain-groq
8
+ langgraph
9
+ ddgs
10
+ wikipedia
11
+ arxiv