hari-huynh commited on
Commit
dfc4889
1 Parent(s): fe81246

Update ReAct Agent with Web-search Tool

Browse files
prompts/react_prompt_v2.txt CHANGED
@@ -1,6 +1,6 @@
1
- Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand in Markdown format.
2
- Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.
3
- Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.
4
 
5
  TOOLS:
6
 
@@ -19,7 +19,9 @@ Action Input: the input to the action
19
  Observation: the result of the action
20
  ```
21
 
22
- If knowledge graph provide enough information, you MUST NOT use any tool.
 
 
23
  When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:
24
 
25
  ```
 
1
+ You are an assistant who helps users find suitable jobs by answering questions related to recruitment information from companies' job postings.
2
+ You MUST answer briefly but with complete information in Markdown format.
3
+ You MUST bold phrases related to jobs, skills, companies, etc.
4
 
5
  TOOLS:
6
 
 
19
  Observation: the result of the action
20
  ```
21
 
22
+ You must prioritize searching on the Knowledge Graph. If the knowledge graph does not have enough information, you MUST search on the web.
23
+ You MUST not duplicate queries.
24
+ If both of you do not provide enough information, you must answer "I cannot answer this question."
25
  When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:
26
 
27
  ```
react_agent_v2.py CHANGED
@@ -1,13 +1,17 @@
1
  from langchain.agents import Tool, AgentType, initialize_agent
2
  from langchain.memory import ConversationBufferMemory
 
3
  from langchain_google_genai import ChatGoogleGenerativeAI
4
  from langchain.agents import AgentExecutor
5
-
6
  from langchain.agents.format_scratchpad import format_log_to_str
7
  from langchain.agents.output_parsers import ReActSingleInputOutputParser
8
  from langchain.tools.render import render_text_description
9
  import os
10
  from tools.kg_search import lookup_kg
 
 
 
11
  from dotenv import load_dotenv
12
  from langchain.agents import Tool
13
  from langchain_core.prompts import PromptTemplate
@@ -19,6 +23,12 @@ llm = ChatGoogleGenerativeAI(
19
  temperature = 0
20
  )
21
 
 
 
 
 
 
 
22
 
23
  kg_query = Tool(
24
  name = 'Query Knowledge Graph',
@@ -27,16 +37,14 @@ kg_query = Tool(
27
  )
28
 
29
 
30
- tools = [kg_query]
31
- # memory = ConversationBufferMemory(memory_key="chat_history")
32
- #
33
- # agent_chain = initialize_agent(tools,
34
- # llm,
35
- # agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
36
- # memory=memory,
37
- # verbose=True)
38
 
39
- # agent_prompt = hub.pull("hwchase17/react-chat")
40
 
41
  with open("prompts/react_prompt_v2.txt", "r") as file:
42
  react_template = file.read()
@@ -68,6 +76,17 @@ memory = ConversationBufferMemory(memory_key="chat_history")
68
 
69
  agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, memory=memory)
70
 
 
 
 
 
 
 
 
 
 
 
 
71
  # result = agent_executor.invoke({"input": "Have any company recruit Machine Learning jobs?"})
72
  # print(result)
73
 
@@ -81,17 +100,6 @@ agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, memory=me
81
  # result = agent_executor.invoke(question)
82
  # print(result)
83
 
84
- def get_react_agent(memory):
85
- agent_executor = AgentExecutor(
86
- agent = agent,
87
- tools = tools,
88
- verbose = True,
89
- memory = memory
90
- )
91
-
92
- return agent_executor
93
-
94
-
95
  if __name__ == "__main__":
96
  while True:
97
  try:
 
1
  from langchain.agents import Tool, AgentType, initialize_agent
2
  from langchain.memory import ConversationBufferMemory
3
+ # from langchain.utilities import DuckDuckGoSearchAPIWrapper
4
  from langchain_google_genai import ChatGoogleGenerativeAI
5
  from langchain.agents import AgentExecutor
6
+ from langchain import hub
7
  from langchain.agents.format_scratchpad import format_log_to_str
8
  from langchain.agents.output_parsers import ReActSingleInputOutputParser
9
  from langchain.tools.render import render_text_description
10
  import os
11
  from tools.kg_search import lookup_kg
12
+ from tools.tavily_search import tavily_search
13
+ from tools.tavily_search_v2 import tavily_search, tavily_qna_search
14
+
15
  from dotenv import load_dotenv
16
  from langchain.agents import Tool
17
  from langchain_core.prompts import PromptTemplate
 
23
  temperature = 0
24
  )
25
 
26
+ # search = DuckDuckGoSearchAPIWrapper()
27
+ #
28
+ # search_tool = Tool(name="Current Search",
29
+ # func=search.run,
30
+ # description="Useful when you need to answer questions about detail jobs information or search a job."
31
+ # )
32
 
33
  kg_query = Tool(
34
  name = 'Query Knowledge Graph',
 
37
  )
38
 
39
 
40
+ web_search = Tool(
41
+ name = 'Web Search',
42
+ func = tavily_qna_search,
43
+ description = "Useful for when you need to search for external information."
44
+ )
45
+
46
+ tools = [kg_query, web_search]
 
47
 
 
48
 
49
  with open("prompts/react_prompt_v2.txt", "r") as file:
50
  react_template = file.read()
 
76
 
77
  agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, memory=memory)
78
 
79
+
80
+ def get_react_agent(memory):
81
+ agent_executor = AgentExecutor(
82
+ agent=agent,
83
+ tools=tools,
84
+ verbose=True,
85
+ memory=memory
86
+ )
87
+
88
+ return agent_executor
89
+
90
  # result = agent_executor.invoke({"input": "Have any company recruit Machine Learning jobs?"})
91
  # print(result)
92
 
 
100
  # result = agent_executor.invoke(question)
101
  # print(result)
102
 
 
 
 
 
 
 
 
 
 
 
 
103
  if __name__ == "__main__":
104
  while True:
105
  try:
requirements.txt CHANGED
@@ -6,4 +6,4 @@ langchain-core
6
  faiss-cpu
7
  neo4j
8
  langchainhub
9
- chainlit
 
6
  faiss-cpu
7
  neo4j
8
  langchainhub
9
+ tavily-python
tools/tavily_search.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from langchain_google_genai import ChatGoogleGenerativeAI
4
+ from langchain_community.tools.tavily_search import TavilySearchResults
5
+ from langchain.tools import BaseTool, StructuredTool, tool
6
+
7
+ load_dotenv()
8
+
9
+ os.environ["TAVILY_API_KEY"] = os.getenv("TAVILY_API_KEY")
10
+ os.environ["GOOGLE_API_KEY"] = os.getenv("GEMINI_API_KEY")
11
+
12
+
13
+ def tavily_search(question: str) -> str:
14
+ """
15
+ useful for when you need to search relevant informations such as: jobs, companies from Web sites.
16
+ """
17
+
18
+ # setup prompt
19
+ # prompt = [{
20
+ # "role": "system",
21
+ # "content": f'You are an AI critical thinker research assistant. ' \
22
+ # f'Your sole purpose is to write well written, critically acclaimed,' \
23
+ # f'objective and structured reports on given text.'
24
+ # }, {
25
+ # "role": "user",
26
+ # "content": f'Information: """{content}"""\n\n' \
27
+ # f'Using the above information, answer the following' \
28
+ # f'query: "{query}" in a detailed report --' \
29
+ # f'Please use MLA format and markdown syntax.'
30
+ # }]
31
+
32
+ tool_search = TavilySearchResults(
33
+ max_results = 3,
34
+ include_raw_content = True
35
+ )
36
+
37
+ # prompt_search = f"""You are an expert at finding information about the job,
38
+ # the company, and the skills required for that job.
39
+ # Try to find out what is relevant to the company, the job, and the skills required for that job.
40
+ # If the questions are not relevant, answer them in your own words.
41
+ #
42
+ # Query: {question}
43
+ # """
44
+
45
+ # Search
46
+ # for information on Web sites: Indeed, LinkedIn, TopCV
47
+ # by
48
+ # using
49
+ # entity in user
50
+ # question(Job
51
+ # Titles, Company, Location, etc).
52
+ # Using
53
+ # search
54
+ # pattern: site:indeed
55
+
56
+ search_prompt = f"""
57
+ Response to user question by search job descriptions include: job titles, company, required skill, education, etc related to job recruitment posts in Vietnam.
58
+
59
+ Query: {question}
60
+ """
61
+
62
+ result = tool_search.invoke({"query": search_prompt})
63
+
64
+ # llm_chat = ChatGoogleGenerativeAI(
65
+ # model = "gemini-1.5-flash-latest",
66
+ # temperature = 0
67
+ # )
68
+
69
+ # content = []
70
+ # for i in result:
71
+ # content.append(i['content'])
72
+
73
+ # prompt = f"""
74
+ #
75
+ # You are a career consultant, based on the information you have contents: {content},
76
+ # consider yourself an expert to summarize summary details not too short the content and
77
+ # highlight the content related to the company's job and the necessary skills and return must 1 URL
78
+ #
79
+ # You can add information you know about the question {question}
80
+ # """
81
+
82
+ # response_prompt = f"""
83
+ # Generate a concise and informative summary of the results in a polite and easy-to-understand manner based on question and Tavily search results.
84
+ # Returns URLs at the end of the summary for proof.
85
+ #
86
+ # Question: {question}
87
+ # Search Results: {str(result)}
88
+ #
89
+ # Answer:
90
+ # """
91
+
92
+ # response = llm_chat.invoke(response_prompt)
93
+
94
+ return result
95
+
96
+
97
+ if __name__ == "__main__":
98
+ question = "Recruitment information for the position of Software Engineer?"
99
+ result = tavily_search(question)
100
+ print(result)
tools/tavily_search_v2.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from langchain_google_genai import ChatGoogleGenerativeAI
4
+ from tavily import TavilyClient
5
+ from langchain.tools import BaseTool, StructuredTool, tool
6
+
7
+ load_dotenv()
8
+
9
+ os.environ["TAVILY_API_KEY"] = os.getenv("TAVILY_API_KEY")
10
+ os.environ["GOOGLE_API_KEY"] = os.getenv("GEMINI_API_KEY")
11
+
12
+ def tavily_search(question: str) -> str:
13
+ """
14
+ useful for when you need to search relevant informations such as: jobs, companies from Web sites.
15
+ """
16
+
17
+ search_prompt = f"""
18
+ Response to user question by search job descriptions include: job titles, company, required skill, education, etc related to job recruitment posts in Vietnam.
19
+
20
+ Query: {question}
21
+ """
22
+
23
+ tavily = TavilyClient(
24
+ api_key = os.environ["TAVILY_API_KEY"],
25
+ )
26
+
27
+ response = tavily.search(
28
+ query = question,
29
+ include_raw_content = True,
30
+ max_results = 5
31
+ )
32
+
33
+ search_results = ""
34
+ for obj in response["results"]:
35
+ search_results += f"""
36
+ - Page content: {obj["raw_content"]}
37
+ Source: {obj["url"]}
38
+
39
+ """
40
+
41
+ print(search_results)
42
+
43
+ response_prompt = f"""
44
+ Generate a concise and informative summary of the results in a polite and easy-to-understand manner based on question and Tavily search results.
45
+ Returns URLs at the end of the summary for proof.
46
+
47
+ Question: {question}
48
+ Search Results:
49
+ {search_results}
50
+
51
+ Answer:
52
+ """
53
+
54
+ # return context
55
+
56
+ def tavily_qna_search(question: str) -> str:
57
+ tavily = TavilyClient(
58
+ api_key=os.environ["TAVILY_API_KEY"],
59
+ )
60
+
61
+ response = tavily.qna_search(query=question)
62
+ return response
63
+
64
+ if __name__ == "__main__":
65
+ question = "Software Engineer job postings in Vietnam"
66
+
67
+ result = tavily_search(question)
68
+ print(result)