dgl1797 commited on
Commit
6065fb1
·
1 Parent(s): 6111a60

agent dev checkpoint

Browse files
__pycache__/connectors.cpython-312.pyc DELETED
Binary file (671 Bytes)
 
local.ipynb CHANGED
@@ -10,7 +10,7 @@
10
  },
11
  {
12
  "cell_type": "code",
13
- "execution_count": 1,
14
  "id": "660cfadd",
15
  "metadata": {},
16
  "outputs": [
@@ -39,6 +39,10 @@
39
  " <th>question</th>\n",
40
  " <th>Level</th>\n",
41
  " <th>file_name</th>\n",
 
 
 
 
42
  " </tr>\n",
43
  " </thead>\n",
44
  " <tbody>\n",
@@ -48,6 +52,10 @@
48
  " <td>20</td>\n",
49
  " <td>20</td>\n",
50
  " <td>20</td>\n",
 
 
 
 
51
  " </tr>\n",
52
  " <tr>\n",
53
  " <th>unique</th>\n",
@@ -55,6 +63,10 @@
55
  " <td>20</td>\n",
56
  " <td>1</td>\n",
57
  " <td>6</td>\n",
 
 
 
 
58
  " </tr>\n",
59
  " <tr>\n",
60
  " <th>top</th>\n",
@@ -62,6 +74,10 @@
62
  " <td>How many studio albums were published by Merce...</td>\n",
63
  " <td>1</td>\n",
64
  " <td></td>\n",
 
 
 
 
65
  " </tr>\n",
66
  " <tr>\n",
67
  " <th>freq</th>\n",
@@ -69,6 +85,10 @@
69
  " <td>1</td>\n",
70
  " <td>20</td>\n",
71
  " <td>15</td>\n",
 
 
 
 
72
  " </tr>\n",
73
  " </tbody>\n",
74
  "</table>\n",
@@ -81,230 +101,55 @@
81
  "top 8e867cd7-cff9-4e6c-867a-ff5ddc2550be \n",
82
  "freq 1 \n",
83
  "\n",
84
- " question Level file_name \n",
85
- "count 20 20 20 \n",
86
- "unique 20 1 6 \n",
87
- "top How many studio albums were published by Merce... 1 \n",
88
- "freq 1 20 15 "
 
 
 
 
 
 
 
 
 
 
 
 
89
  ]
90
  },
91
- "execution_count": 1,
92
  "metadata": {},
93
  "output_type": "execute_result"
94
  }
95
  ],
96
  "source": [
97
- "import os\n",
98
  "from connectors import fetch_questions\n",
 
99
  "\n",
100
  "DEFAULT_API_URL = \"https://agents-course-unit4-scoring.hf.space\"\n",
101
  "QUESTIONS_URL = f\"{DEFAULT_API_URL}/questions\"\n",
102
  "SUBMIT_URL = f\"{DEFAULT_API_URL}/submit\"\n",
103
- "HFTOKEN=os.getenv(\"HF_TOKEN\")\n",
104
  "\n",
105
- "questions = fetch_questions(QUESTIONS_URL)\n",
106
- "questions.describe()"
107
- ]
108
- },
109
- {
110
- "cell_type": "markdown",
111
- "id": "41b1c193",
112
- "metadata": {},
113
- "source": [
114
- "# Agent"
115
- ]
116
- },
117
- {
118
- "cell_type": "code",
119
- "execution_count": 2,
120
- "id": "02fe107c",
121
- "metadata": {},
122
- "outputs": [
123
- {
124
- "name": "stderr",
125
- "output_type": "stream",
126
- "text": [
127
- "c:\\Users\\dgl17\\Desktop\\Lavoro\\Personal\\Final_Assignment_Template\\hfagent\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
128
- " from .autonotebook import tqdm as notebook_tqdm\n"
129
- ]
130
- }
131
- ],
132
- "source": [
133
- "from langgraph.graph import StateGraph, START, END\n",
134
- "from langchain_huggingface import ChatHuggingFace, HuggingFacePipeline\n",
135
- "from typing import TypedDict, Any\n",
136
- "from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer\n",
137
- "import torch\n",
138
- "import random as rng"
139
- ]
140
- },
141
- {
142
- "cell_type": "markdown",
143
- "id": "4cb1b488",
144
- "metadata": {},
145
- "source": [
146
- "## Schemas"
147
- ]
148
- },
149
- {
150
- "cell_type": "code",
151
- "execution_count": 3,
152
- "id": "01b8a368",
153
- "metadata": {},
154
- "outputs": [],
155
- "source": [
156
- "class ActionsSchema(TypedDict):\n",
157
- " name: str\n",
158
- " arguments: dict[str, Any] # name - value\n",
159
- " observation: Any | None\n",
160
  "\n",
161
- "class AgentSchema(TypedDict):\n",
162
- " query: str\n",
163
- " answer: str\n",
164
- " actions: list[ActionsSchema]"
165
- ]
166
- },
167
- {
168
- "cell_type": "code",
169
- "execution_count": null,
170
- "id": "c8687b82",
171
- "metadata": {},
172
- "outputs": [
173
- {
174
- "name": "stderr",
175
- "output_type": "stream",
176
- "text": [
177
- "Fetching 3 files: 0%| | 0/3 [00:00<?, ?it/s]"
178
- ]
179
- }
180
- ],
181
- "source": [
182
- "class RootAgent():\n",
183
- " __MODELID = \"mistralai/Mistral-7B-Instruct-v0.2\"\n",
184
- " \n",
185
- " def __init__(self):\n",
186
- " sg = StateGraph(AgentSchema)\n",
187
- " tokenizer = AutoTokenizer.from_pretrained(self.__MODELID)\n",
188
- " model = AutoModelForCausalLM.from_pretrained(self.__MODELID, dtype=torch.bfloat16, device_map=\"auto\")\n",
189
- " pipe = pipeline(\"text-classification\", model=model, tokenizer=tokenizer, temperature=0.3, do_sample=True, max_new_tokens=512)\n",
190
- " self.brain = ChatHuggingFace(llm=HuggingFacePipeline(pipeline=pipe))\n",
191
- " sg.add_node(\"plan\", self.__plan)\n",
192
- " sg.add_edge(START, \"plan\")\n",
193
- " sg.add_edge(\"plan\", END)\n",
194
- " self.agentflow = sg.compile()\n",
195
- " return\n",
196
- " \n",
197
- " def __call__(self, query: str):\n",
198
- " return self.agentflow.invoke({\"actions\": [], \"query\": query, \"answer\": \"\"})\n",
199
- " \n",
200
- " ## nodes ##\n",
201
- " def __plan(self, state: AgentSchema) -> AgentSchema:\n",
202
- " stageprompt = f\"\"\"\n",
203
- " The user asked the following question: {state.get(\"query\", \"\")}.\n",
204
- " In past iterations you observed the following results: {state.get(\"actions\", [])}\n",
205
- "\n",
206
- " You are the planning manager entitled to develop an efficient plan to obtain the answer, for this reason you must follow these rules:\n",
207
- " 1. IF you can answer directly without using any tools, given the information you have, generate the [Answer Structured JSON](#Answer-Structured-JSON) format\n",
208
- " 2. OTHERWISE generate a plan consisting of tool calls for which you have all the data to pass as arguments following the [Plan Structured JSON](#Plan-Structured-JSON) format\n",
209
- "\n",
210
- " !IMPORTANT: ALWAYS use one of the two JSON format for your answer!\n",
211
- " \n",
212
- " #Answer Structured JSON\n",
213
- " ```json\n",
214
- " {\"{'Answer': '<answer1>,<answer2>,...'}\"}\n",
215
- " ```\n",
216
- " !IMPORTANT: Only provide the comma separated answers that are directly asked by the user, without any formatting or measurement unit!\n",
217
- " ## Examples\n",
218
- " 1. user: 'what is the capital of Italy?' --> {\"{'Answer': 'Rome'}\"}\n",
219
- " 2. user: 'What is the nearest city to Firenze? How many kilometers? --> past iterations: [{\"{'name': 'web_search', 'arguments': {'query': 'Distance between Firenze and Pisa in Kilometers'}, 'observation': '150 KM'}\"}] --> {\"{'Answer': 'Pisa,150'}\"}\n",
220
- "\n",
221
- " #Plan Structured JSON\n",
222
- " ```json\n",
223
- " {\"\"\"{'Plan': [\n",
224
- " {'name': '<tool_name>', 'arguments': {'<argument_name_1>': argument_value_1, '<argument_name_2>': argument_value_2, ...}},\n",
225
- " {'name': '<tool_name>', 'arguments': {'<argument_name_1>': argument_value_1}},\n",
226
- " ...\n",
227
- " ]}\"\"\"}\n",
228
- " ```\n",
229
- " !IMPORTANT: Those will be used as function calls so be extremely precise on argument<-->value mappings, moreover to better understand\n",
230
- " the task, always place a Reasoning string before the plan JSON\n",
231
- " ## Examples\n",
232
- " 1. user: 'What is the distance between Rome and Paris?' --> Reasoning: To get the distance I need to search the web, since it is a very\n",
233
- " specific question and I can choose between web_search and wiki_search, I think it is better to search in the web with query='distance Rome to Paris in Kilometers' --> {\"\"\"{\n",
234
- " 'Plan': [\n",
235
- " {'name': '<web_search>', 'arguments': {'query': 'distance Rome to Paris'}},\n",
236
- " ...\n",
237
- " ]\n",
238
- " }\"\"\"}\n",
239
- " \"\"\"\n",
240
- " response = self.brain.invoke(stageprompt)\n",
241
- " return {\"query\": state.get(\"query\"), \"answer\": response, \"actions\": []}\n",
242
  "\n",
243
- "agent = RootAgent()"
 
 
 
244
  ]
245
  },
246
  {
247
- "cell_type": "code",
248
- "execution_count": null,
249
- "id": "64fb34d8",
250
  "metadata": {},
251
- "outputs": [
252
- {
253
- "name": "stdout",
254
- "output_type": "stream",
255
- "text": [
256
- "The user asked the following question: Who are the pitchers with the number before and after Taishō Tamai's number as of July 2023? Give them to me in the form Pitcher Before, Pitcher After, use their last names only, in Roman characters..\n",
257
- " In past iterations you observed the following results: []\n",
258
- "\n",
259
- " You are the planning manager entitled to develop an efficient plan to obtain the answer, for this reason you must follow these rules:\n",
260
- " 1. IF you can answer directly without using any tools, given the information you have, generate the [Answer Structured JSON](#Answer-Structured-JSON) format\n",
261
- " 2. OTHERWISE generate a plan consisting of tool calls for which you have all the data to pass as arguments following the [Plan Structured JSON](#Plan-Structured-JSON) format\n",
262
- "\n",
263
- " !IMPORTANT: ALWAYS use one of the two JSON format for your answer!\n",
264
- "\n",
265
- " #Answer Structured JSON\n",
266
- " ```json\n",
267
- " {'Answer': '<answer1>,<answer2>,...'}\n",
268
- " ```\n",
269
- " !IMPORTANT: Only provide the comma separated answers that are directly asked by the user, without any formatting or measurement unit!\n",
270
- " ## Examples\n",
271
- " 1. user: 'what is the capital of Italy?' --> {'Answer': 'Rome'}\n",
272
- " 2. user: 'What is the nearest city to Firenze? How many kilometers? --> past iterations: [{'name': 'web_search', 'arguments': {'query': 'Distance between Firenze and Pisa in Kilometers'}, 'observation': '150 KM'}] --> {'Answer': 'Pisa,150'}\n",
273
- "\n",
274
- " #Plan Structured JSON\n",
275
- " ```json\n",
276
- " {'Plan': [\n",
277
- " {'name': '<tool_name>', 'arguments': {'<argument_name_1>': argument_value_1, '<argument_name_2>': argument_value_2, ...}},\n",
278
- " {'name': '<tool_name>', 'arguments': {'<argument_name_1>': argument_value_1}},\n",
279
- " ...\n",
280
- " ]}\n",
281
- " ```\n",
282
- " !IMPORTANT: Those will be used as function calls so be extremely precise on argument<-->value mappings, moreover to better understand\n",
283
- " the task, always place a Reasoning string before the plan JSON\n",
284
- " ## Examples\n",
285
- " 1. user: 'What is the distance between Rome and Paris?' --> Reasoning: To get the distance I need to search the web, since it is a very\n",
286
- " specific question and I can choose between web_search and wiki_search, I think it is better to search in the web with query='distance Rome to Paris in Kilometers' --> {\n",
287
- " 'Plan': [\n",
288
- " {'name': '<web_search>', 'arguments': {'query': 'distance Rome to Paris'}},\n",
289
- " ...\n",
290
- " ]\n",
291
- " }\n",
292
- "{'query': \"Who are the pitchers with the number before and after Taishō Tamai's number as of July 2023? Give them to me in the form Pitcher Before, Pitcher After, use their last names only, in Roman characters.\", 'answer': \"The user asked the following question: Who are the pitchers with the number before and after Taishō Tamai's number as of July 2023? Give them to me in the form Pitcher Before, Pitcher After, use their last names only, in Roman characters..\\n In past iterations you observed the following results: []\\n\\n You are the planning manager entitled to develop an efficient plan to obtain the answer, for this reason you must follow these rules:\\n 1. IF you can answer directly without using any tools, given the information you have, generate the [Answer Structured JSON](#Answer-Structured-JSON) format\\n 2. OTHERWISE generate a plan consisting of tool calls for which you have all the data to pass as arguments following the [Plan Structured JSON](#Plan-Structured-JSON) format\\n\\n !IMPORTANT: ALWAYS use one of the two JSON format for your answer!\\n\\n #Answer Structured JSON\\n ```json\\n {'Answer': '<answer1>,<answer2>,...'}\\n ```\\n !IMPORTANT: Only provide the comma separated answers that are directly asked by the user, without any formatting or measurement unit!\\n ## Examples\\n 1. user: 'what is the capital of Italy?' --> {'Answer': 'Rome'}\\n 2. user: 'What is the nearest city to Firenze? How many kilometers? --> past iterations: [{'name': 'web_search', 'arguments': {'query': 'Distance between Firenze and Pisa in Kilometers'}, 'observation': '150 KM'}] --> {'Answer': 'Pisa,150'}\\n\\n #Plan Structured JSON\\n ```json\\n {'Plan': [\\n {'name': '<tool_name>', 'arguments': {'<argument_name_1>': argument_value_1, '<argument_name_2>': argument_value_2, ...}},\\n {'name': '<tool_name>', 'arguments': {'<argument_name_1>': argument_value_1}},\\n ...\\n ]}\\n ```\\n !IMPORTANT: Those will be used as function calls so be extremely precise on argument<-->value mappings, moreover to better understand\\n the task, always place a Reasoning string before the plan JSON\\n ## Examples\\n 1. user: 'What is the distance between Rome and Paris?' --> Reasoning: To get the distance I need to search the web, since it is a very\\n specific question and I can choose between web_search and wiki_search, I think it is better to search in the web with query='distance Rome to Paris in Kilometers' --> {\\n 'Plan': [\\n {'name': '<web_search>', 'arguments': {'query': 'distance Rome to Paris'}},\\n ...\\n ]\\n }\", 'actions': []}\n"
293
- ]
294
- },
295
- {
296
- "ename": "",
297
- "evalue": "",
298
- "output_type": "error",
299
- "traceback": [
300
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
301
- "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
302
- ]
303
- }
304
- ],
305
  "source": [
306
- "query = questions[\"question\"].iloc[rng.randint(0, len(questions[\"question\"]))]\n",
307
- "print(agent(query))"
308
  ]
309
  }
310
  ],
 
10
  },
11
  {
12
  "cell_type": "code",
13
+ "execution_count": null,
14
  "id": "660cfadd",
15
  "metadata": {},
16
  "outputs": [
 
39
  " <th>question</th>\n",
40
  " <th>Level</th>\n",
41
  " <th>file_name</th>\n",
42
+ " <th>Question</th>\n",
43
+ " <th>Final answer</th>\n",
44
+ " <th>file_path</th>\n",
45
+ " <th>Annotator Metadata</th>\n",
46
  " </tr>\n",
47
  " </thead>\n",
48
  " <tbody>\n",
 
52
  " <td>20</td>\n",
53
  " <td>20</td>\n",
54
  " <td>20</td>\n",
55
+ " <td>20</td>\n",
56
+ " <td>20</td>\n",
57
+ " <td>20</td>\n",
58
+ " <td>20</td>\n",
59
  " </tr>\n",
60
  " <tr>\n",
61
  " <th>unique</th>\n",
 
63
  " <td>20</td>\n",
64
  " <td>1</td>\n",
65
  " <td>6</td>\n",
66
+ " <td>20</td>\n",
67
+ " <td>19</td>\n",
68
+ " <td>6</td>\n",
69
+ " <td>20</td>\n",
70
  " </tr>\n",
71
  " <tr>\n",
72
  " <th>top</th>\n",
 
74
  " <td>How many studio albums were published by Merce...</td>\n",
75
  " <td>1</td>\n",
76
  " <td></td>\n",
77
+ " <td>How many studio albums were published by Merce...</td>\n",
78
+ " <td>3</td>\n",
79
+ " <td></td>\n",
80
+ " <td>{'Steps': '1. I did a search for Mercedes Sosa...</td>\n",
81
  " </tr>\n",
82
  " <tr>\n",
83
  " <th>freq</th>\n",
 
85
  " <td>1</td>\n",
86
  " <td>20</td>\n",
87
  " <td>15</td>\n",
88
+ " <td>1</td>\n",
89
+ " <td>2</td>\n",
90
+ " <td>15</td>\n",
91
+ " <td>1</td>\n",
92
  " </tr>\n",
93
  " </tbody>\n",
94
  "</table>\n",
 
101
  "top 8e867cd7-cff9-4e6c-867a-ff5ddc2550be \n",
102
  "freq 1 \n",
103
  "\n",
104
+ " question Level file_name \\\n",
105
+ "count 20 20 20 \n",
106
+ "unique 20 1 6 \n",
107
+ "top How many studio albums were published by Merce... 1 \n",
108
+ "freq 1 20 15 \n",
109
+ "\n",
110
+ " Question Final answer \\\n",
111
+ "count 20 20 \n",
112
+ "unique 20 19 \n",
113
+ "top How many studio albums were published by Merce... 3 \n",
114
+ "freq 1 2 \n",
115
+ "\n",
116
+ " file_path Annotator Metadata \n",
117
+ "count 20 20 \n",
118
+ "unique 6 20 \n",
119
+ "top {'Steps': '1. I did a search for Mercedes Sosa... \n",
120
+ "freq 15 1 "
121
  ]
122
  },
123
+ "execution_count": 8,
124
  "metadata": {},
125
  "output_type": "execute_result"
126
  }
127
  ],
128
  "source": [
 
129
  "from connectors import fetch_questions\n",
130
+ "from datasets import load_dataset\n",
131
  "\n",
132
  "DEFAULT_API_URL = \"https://agents-course-unit4-scoring.hf.space\"\n",
133
  "QUESTIONS_URL = f\"{DEFAULT_API_URL}/questions\"\n",
134
  "SUBMIT_URL = f\"{DEFAULT_API_URL}/submit\"\n",
 
135
  "\n",
136
+ "MODELID = \"nemotron-3-nano:4b\"\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  "\n",
138
+ "questions = fetch_questions(QUESTIONS_URL)\n",
139
+ "dataset = load_dataset(\"gaia-benchmark/GAIA\", \"2023_level1\")[\"validation\"].to_pandas()\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  "\n",
141
+ "questiondf = questions.merge(right=dataset, how=\"left\", on=\"task_id\").drop(columns=[\"Level_y\", \"file_name_y\"]).rename(columns={\n",
142
+ " \"Level_x\": \"Level\", \"file_name_x\": \"file_name\"\n",
143
+ "})\n",
144
+ "questiondf.describe()\n"
145
  ]
146
  },
147
  {
148
+ "cell_type": "markdown",
149
+ "id": "99632633",
 
150
  "metadata": {},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  "source": [
152
+ "# Execution"
 
153
  ]
154
  }
155
  ],
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
 
src/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from . import agent
2
+
3
+ __all__ = ["agent"]
src/agent.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_ollama import ChatOllama
2
+ from langgraph.graph import StateGraph, START, END
3
+ from typing import TypedDict, Literal, Any
4
+ from tools import TOOL_LIST
5
+ from prompts import PLANNER, ANSWER
6
+
7
+ class ObservationSchema(TypedDict):
8
+ tool_name: str
9
+ arguments: dict[str, Any]
10
+ observation: Any
11
+
12
+ class AgentSchema(TypedDict):
13
+ query: str
14
+ pastit: list[ObservationSchema]
15
+ answer: str
16
+
17
+ class ReActAgent():
18
+ def __init__(self, modelid: str, verbose: bool = False):
19
+ self.brain = ChatOllama(model=modelid, validate_model_on_init=True)
20
+ workflow = StateGraph(AgentSchema)
21
+ self.verbose = verbose
22
+
23
+ # nodes #
24
+
25
+ # edges #
26
+ workflow.add_conditional_edges(START, self.plan)
27
+
28
+ # compile
29
+ self.workflow = workflow.compile(); return
30
+
31
+ def __call__(self, query: str):
32
+ return self.workflow.invoke({"query": query, "pastit": [], "answer": ""})
33
+
34
+ # nodes #
35
+ def answer(self, state: AgentSchema) -> AgentSchema:
36
+ self.brain.reasoning = False; self.brain.temperature = 0
37
+ messages = [
38
+ {'role': 'system', 'content': ANSWER.format(past_iterations=state.get("pastit", []))},
39
+ {'role': 'user', 'content': state.get("query", "")}
40
+ ]
41
+ response = self.brain.invoke(messages)
42
+ if self.verbose: print(response.content)
43
+ return {"query": state.get("query", ""), "pastit": state.get("pastit", []), "answer": response.content}
44
+
45
+ def reason(self, state: AgentSchema) -> AgentSchema:
46
+ self.brain.reasoning = True; self.brain.temperature = 0.3
47
+
48
+ # edges #
49
+ def plan(self, state: AgentSchema) -> Literal["answer", "reason", "tool_call"]:
50
+ self.brain.reasoning = True; self.brain.temperature = 0
51
+ messages = [
52
+ {'role': 'system', 'content': PLANNER.format(past_iterations=state.get("pastit", []))},
53
+ {'role': 'user', 'content': state.get("query", "")}
54
+ ]
55
+ response = self.brain.invoke(messages)
56
+ if self.verbose: print(f"#------ Reasoning ------#\n{response.additional_kwargs.get("reasoning_content", "")}\n#---------------------#\n\n#------ Response -------#\n{response.content}\n#-------------------------#\n")
57
+ return ["answer", "reason", "tool_call"][int(response.content)-1]
src/prompts.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ PLANNER = (
2
+ """
3
+ You are planning the best way to answer the user questions, you have the following info from past iterations:
4
+ {past_iterations}
5
+
6
+ Now you need to carefully plan the next step, you can decide one of the following options:
7
+ 1. You have all the necessary information to provide the answers to the user questions
8
+ 2. You have all the necessary information but you need to reason on the questions before providing correct answers
9
+ 3. You don't have all the necessary information to proceed with an answer, it will be necessary to call some tools before proceeding
10
+
11
+ After reasoning on what to do, provide the number corresponding to your choice for the next step.
12
+ **IMPORTANT:** Only provide a single digit number corresponding to the option you want to follow
13
+ """
14
+ )[0].strip()
15
+
16
+ ANSWER = (
17
+ """
18
+ You got the following information from past iterations: {past_iterations}
19
+
20
+ Answer the user's questions by providing a single unformatted word/digit answer for each question he asked.
21
+
22
+ **Format Examples:**
23
+ 1. User: "What is the first name of the singer of Thriller and at what age did he die?" -> Answer: "Michael, 51"
24
+ """
25
+ )[0].strip()
src/tools.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_core.tools import tool
2
+
3
+ @tool
4
+ def web_search(query: str) -> str:
5
+ """
6
+ This tool can be used to search the web for information
7
+
8
+ Arguments:
9
+ * query -> search string
10
+
11
+ Returns:
12
+ * string containing the research results
13
+ """
14
+ return "Hello World!"
15
+
16
+ TOOL_LIST = [web_search]