Spaces:
Runtime error
Runtime error
File size: 37,542 Bytes
07d2942 |
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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
{
"cells": [
{
"cell_type": "code",
"execution_count": 5,
"id": "f9e39a86-a9db-4571-bdc1-bf2a14675345",
"metadata": {},
"outputs": [],
"source": [
"\n",
"import os\n",
"import json\n",
"\n",
"from dotenv import load_dotenv\n",
"load_dotenv()\n",
"\n",
"TAVILY_API_KEY = os.environ.get(\"TAVILY_API_KEY\")\n",
"OPENAI_API_KEY = os.environ.get(\"OPENAI_API_KEY\")"
]
},
{
"cell_type": "markdown",
"id": "5348dd2b-a2ae-4fa6-8268-be6da402898c",
"metadata": {},
"source": [
"### Use tools ###"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "e47f6678-69ff-4ead-96c7-d4b7cd59e561",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'url': 'https://maps.google.com.tw/',\n",
" 'content': 'Find local businesses, view maps and get driving directions in Google Maps.'},\n",
" {'url': 'https://www.google.com.tw/maps?hl=zh-TW&tab=wl&output=classic&dg=brw',\n",
" 'content': '利用「Google 地圖」尋找本地商家、檢視地圖或規劃行車路線。'},\n",
" {'url': 'https://twfile.com/五角味食堂/92277974',\n",
" 'content': '五角味食堂,商業統一編號:92277974,地址:彰化縣北斗鎮文昌里復興路臨100-1號,負責人姓名:李雅筑,OpenData(4) 五角味食堂(24項情報)-台灣公司情報網 台灣公司情報網'},\n",
" {'url': 'https://www.findcompany.com.tw/五角味食堂',\n",
" 'content': '五角味食堂. 資本總額 (元) 30,000. 負責人. 李雅筑. 登記地址. 彰化縣北斗鎮文昌里復興路臨100-1號 郵遞區號查詢. 設立日期. 2023-03-31.'},\n",
" {'url': 'https://twypage.com/sd-1654806-B-彰化-五角味食堂.html',\n",
" 'content': '五角味食堂,統編:92277974,地址:彰化縣北斗鎮文昌里復興路臨100-1號,負責人:李雅筑,設立日期:2023-03-31,變更日期:2023-03-31,公司狀態:核准設立 「查詢最新營業狀況請至財政部稅務入口網 」,營業項目:食品什貨、飲料零售業,餐館業'}]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
"\n",
"\n",
"tool = TavilySearchResults()\n",
"tool.invoke({\"query\": \"五角味食堂\t彰化縣北斗鎮文昌里復興路臨100-1號\"})\n"
]
},
{
"cell_type": "markdown",
"id": "2c1f236e-88bf-46e7-8e39-cbc9d7330f56",
"metadata": {},
"source": [
"### Define agent - AgentExecutor ###"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "22837788-d2f0-48a0-ad71-ff6226d5bd39",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import AgentExecutor, create_openai_functions_agent\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"\n",
"instructions = \"\"\"As a helpful and rigorous retail analyst, given the provided query and a list of search results for the query, your task is to first use store name and address to identify relevant information. After that, from the relevant information, extract `store_name`, `address`, `description`, `category`, `provide_alcohol` and `phone_number` from the found relevant information. Note that `category` can only be `小吃店`, `日式料理(含居酒屋,串燒)`, `火(鍋/爐)`, `東南亞料理(不含日韓)`, `海鮮熱炒`, `特色餐廳(含雞、鵝、牛、羊肉)`, `傳統餐廳`, `燒烤`, `韓式料理(含火鍋,烤肉)`, `西餐廳(含美式,義式,墨式)`, `西餐廳(餐酒館、酒吧、飛鏢吧、pub、lounge bar)`, `西餐廳(土耳其、漢堡、薯條、法式、歐式、印度)` or `早餐`. According to our experience,`provide_alcohol` can be inferred based on whether a store is suitable for scenarios such as Gathering, Chill, Enjoying Together, Drinking Freely, Winery, Wine Cellar, Wine Storage, Relaxing, Unwinding, Lyrical, Romantic, Pleasant, Stress Relief, Wine and Dine, Light Drinking Gatherings, Birthday Celebrations, Socializing, Parties, Networking, After Work Relaxation with a Drink, Relaxing Places Suitable for Drinking, Every Dish Goes Well with Beer, Shared Dishes, Dining Together, Atmosphere Suitable for Celebratory Drinking, Places Suitable for Light Drinking Gatherings with Friends, Small Shops Suitable for Relaxing and Light Drinking. `description` is a summary of key piece of evidence and reasons that lead you decide `category` and `provide_alcohol` .\n",
"\n",
" It's very important to omit unrelated results. Do not make up any assumption.\n",
" Please think step by step, and output a single json that starts with `{` and ends with `}`. An example output json is like {\"store_name\": \"...\", \"address\": \"...\", \"description\": \"... products, service or highlights ...\", \"category\": \"...\", \"phone_number\": \"...\", \"provide_alcohol\": true or false}\n",
" If no relevant information has been found, simply output json with empty values.\"\"\"\n",
"base_prompt = hub.pull(\"langchain-ai/openai-functions-template\")\n",
"prompt = base_prompt.partial(instructions=instructions)\n",
"llm = ChatOpenAI(temperature=0, )\n",
"tavily_tool = TavilySearchResults()\n",
"tools = [tavily_tool]\n",
"agent = create_openai_functions_agent(llm, tools, prompt)\n",
"agent_executor = AgentExecutor(\n",
" agent=agent,\n",
" tools=tools,\n",
" verbose=True,\n",
")\n",
"agent_executor.invoke({\"input\": \"五角味食堂\t彰化縣北斗鎮文昌里復興路臨100-1號\"})\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "38770f28-9950-49dc-a305-0ea180ae417c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3m\n",
"Invoking: `tavily_search_results_json` with `{'query': '五角味食堂 彰化縣北斗鎮文昌里復興路臨100-1號'}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.facebook.com/people/五角味食堂/100088207986612/', 'content': '五角味食堂, 彰化縣. 209 likes · 1 talking about this. 五角味食堂~ 一個結合.台灣.日本.中國.韓國.泰國.口味料理的複合式美食餐廳。 裡面以餃子類為主打!'}, {'url': 'https://twfile.com/五角味食堂/92277974', 'content': '五角味食堂,商業統一編號:92277974,地址:彰化縣北斗鎮文昌里復興路臨100-1號,負責人姓名:李雅筑,OpenData(4) 五角味食堂(24項情報)-台灣公司情報網 台灣公司情報網'}, {'url': 'https://opengovtw.com/ban/92277974', 'content': '所在地為彰化縣北斗鎮文昌里復興路臨100-1號。 ... 五角味食堂: 彰化縣北斗鎮文昌里復興路臨100-1號: 李雅筑: 30000: 獨資: 1120816972: 財政部營業稅籍資料. 營業人名稱: 五角味食堂 : 營業地址: 彰化縣北斗鎮文昌里復興路臨100-1號 :'}, {'url': 'https://www.google.com.tw/maps?hl=zh-TW&tab=wl&output=classic&dg=brw', 'content': '利用「Google 地圖」尋找本地商家、檢視地圖或規劃行車路線。'}, {'url': 'https://maps.google.com.tw/', 'content': 'Find local businesses, view maps and get driving directions in Google Maps.'}]\u001b[0m\u001b[32;1m\u001b[1;3m{\n",
"\"store_name\": \"五角味食堂\",\n",
"\"address\": \"彰化縣北斗鎮文昌里復興路臨100-1號\",\n",
"\"description\": \"五角味食堂是一個結合台灣、日本、中國、韓國、泰國口味料理的複合式美食餐廳,主打餃子類食物。\",\n",
"\"category\": \"小吃店\",\n",
"\"phone_number\": \"\",\n",
"\"provide_alcohol\": false\n",
"}\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"{'input': '五角味食堂\\t彰化縣北斗鎮文昌里復興路臨100-1號',\n",
" 'output': '{\\n\"store_name\": \"五角味食堂\",\\n\"address\": \"彰化縣北斗鎮文昌里復興路臨100-1號\",\\n\"description\": \"五角味食堂是一個結合台灣、日本、中國、韓國、泰國口味料理的複合式美食餐廳,主打餃子類食物。\",\\n\"category\": \"小吃店\",\\n\"phone_number\": \"\",\\n\"provide_alcohol\": false\\n}'}"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": []
},
{
"cell_type": "markdown",
"id": "479c0691-72b1-4f43-9120-43007ea4c041",
"metadata": {},
"source": [
"### Utilities - external API wrapper (NOT TOOL!) ###"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "3d5884e2-c6b4-4454-bf21-f7b6bbfe2193",
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.utilities import SerpAPIWrapper\n",
"SERPAPI_API_KEY=\"9d4e074bca8f9f7fa9ca5e05b874ea7da4f07cb505292ab29a0e1b91ffa0340a\"\n",
"os.environ[\"SERPAPI_API_KEY\"] = SERPAPI_API_KEY\n",
"SERPER_API_KEY=\"37128e339289d0e855c54f9afa9aa489bd7c23da\"\n",
"os.environ['SERPER_API_KEY']=SERPER_API_KEY\n",
"\n",
"from langchain_community.utilities import GoogleSerperAPIWrapper\n",
"\n",
"### SERPER ###\n",
"serper = GoogleSerperAPIWrapper(gl = 'tw', lr = 'lang_zh-TW', hl='zh-tw', k = 30) \n",
"# search.run(\"Obama's first name?\")\n",
"# serper_results = serper.results(\"宜窩餐飲有限公司 台北市 -inurl:twincn.com -inurl:findcompany.com.tw -inurl:iyp.com.tw -inurl:twypage.com -inurl:alltwcompany.com -inurl:zhupiter.com -inurl:twinc.com.tw\")\n",
"serper_results = serper.results(\"致仙飲食店 澎湖縣 -inurl:twincn.com -inurl:findcompany.com.tw -inurl:iyp.com.tw -inurl:twypage.com -inurl:alltwcompany.com -inurl:zhupiter.com -inurl:twinc.com.tw\")\n",
"print( serper_results.keys() )\n",
"print( serper_results['knowledgeGraph'])\n",
"print( serper_results['organic'] )\n",
"\n",
"\n",
"### SERP API ###\n",
"serp = SerpAPIWrapper(params = {\n",
" \"gl\": 'tw', \n",
" \"lr\": 'lang_zh-TW', \n",
" \"hl\": 'zh-tw',\n",
" \"google_domain\": \"google.com.tw\"\n",
"}) # utilities\n",
"# serp_results = serp.results(\"宜窩餐飲有限公司 台北市 -inurl:twincn.com -inurl:findcompany.com.tw -inurl:iyp.com.tw -inurl:twypage.com -inurl:alltwcompany.com -inurl:zhupiter.com -inurl:twinc.com.tw\")\n",
"# serp_results = serp.results(\"吉祥餛飩麵食館 台北市 -inurl:twincn.com -inurl:findcompany.com.tw -inurl:iyp.com.tw -inurl:twypage.com -inurl:alltwcompany.com -inurl:zhupiter.com -inurl:twinc.com.tw\")\n",
"serp_results = serp.results(\"致仙飲食店 澎湖縣 -inurl:twincn.com -inurl:findcompany.com.tw -inurl:iyp.com.tw -inurl:twypage.com -inurl:alltwcompany.com -inurl:zhupiter.com -inurl:twinc.com.tw\")\n",
"\n",
"\n",
"print( serp_results.keys() )\n",
"print( serp_results['knowledge_graph'] \n",
" "
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "4c7290fb-931a-4f93-8469-ab4821b6c033",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n"
]
},
{
"ename": "ValueError",
"evalue": "An output parsing error occurred. In order to pass this error back to the agent and have it try again, pass `handle_parsing_errors=True` to the AgentExecutor. This is the error: Could not parse output: No.",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mOutputParserException\u001b[0m Traceback (most recent call last)",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/agents/agent.py:1167\u001b[0m, in \u001b[0;36mAgentExecutor._iter_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m 1166\u001b[0m \u001b[38;5;66;03m# Call the LLM to see what to do.\u001b[39;00m\n\u001b[0;32m-> 1167\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43magent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mplan\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1168\u001b[0m \u001b[43m \u001b[49m\u001b[43mintermediate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1169\u001b[0m \u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 1170\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1171\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1172\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m OutputParserException \u001b[38;5;28;01mas\u001b[39;00m e:\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/agents/agent.py:732\u001b[0m, in \u001b[0;36mAgent.plan\u001b[0;34m(self, intermediate_steps, callbacks, **kwargs)\u001b[0m\n\u001b[1;32m 731\u001b[0m full_output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mllm_chain\u001b[38;5;241m.\u001b[39mpredict(callbacks\u001b[38;5;241m=\u001b[39mcallbacks, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mfull_inputs)\n\u001b[0;32m--> 732\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moutput_parser\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfull_output\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/agents/output_parsers/self_ask.py:41\u001b[0m, in \u001b[0;36mSelfAskOutputParser.parse\u001b[0;34m(self, text)\u001b[0m\n\u001b[1;32m 40\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfinish_string \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m last_line:\n\u001b[0;32m---> 41\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m OutputParserException(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCould not parse output: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtext\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 42\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m AgentFinish({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124moutput\u001b[39m\u001b[38;5;124m\"\u001b[39m: last_line[\u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfinish_string) :]}, text)\n",
"\u001b[0;31mOutputParserException\u001b[0m: Could not parse output: No.",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[22], line 22\u001b[0m\n\u001b[1;32m 12\u001b[0m tools \u001b[38;5;241m=\u001b[39m [\n\u001b[1;32m 13\u001b[0m Tool(\n\u001b[1;32m 14\u001b[0m name\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIntermediate Answer\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 17\u001b[0m )\n\u001b[1;32m 18\u001b[0m ]\n\u001b[1;32m 19\u001b[0m self_ask_with_search \u001b[38;5;241m=\u001b[39m initialize_agent(\n\u001b[1;32m 20\u001b[0m tools, llm, agent\u001b[38;5;241m=\u001b[39mAgentType\u001b[38;5;241m.\u001b[39mSELF_ASK_WITH_SEARCH, verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 21\u001b[0m )\n\u001b[0;32m---> 22\u001b[0m \u001b[43mself_ask_with_search\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m五角味食堂\t彰化縣北斗鎮文昌里復興路臨100-1號\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain_core/_api/deprecation.py:168\u001b[0m, in \u001b[0;36mdeprecated.<locals>.deprecate.<locals>.warning_emitting_wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 166\u001b[0m warned \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 167\u001b[0m emit_warning()\n\u001b[0;32m--> 168\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mwrapped\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/chains/base.py:600\u001b[0m, in \u001b[0;36mChain.run\u001b[0;34m(self, callbacks, tags, metadata, *args, **kwargs)\u001b[0m\n\u001b[1;32m 598\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(args) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 599\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`run` supports only one positional argument.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 600\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m[\n\u001b[1;32m 601\u001b[0m _output_key\n\u001b[1;32m 602\u001b[0m ]\n\u001b[1;32m 604\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[1;32m 605\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m(kwargs, callbacks\u001b[38;5;241m=\u001b[39mcallbacks, tags\u001b[38;5;241m=\u001b[39mtags, metadata\u001b[38;5;241m=\u001b[39mmetadata)[\n\u001b[1;32m 606\u001b[0m _output_key\n\u001b[1;32m 607\u001b[0m ]\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain_core/_api/deprecation.py:168\u001b[0m, in \u001b[0;36mdeprecated.<locals>.deprecate.<locals>.warning_emitting_wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 166\u001b[0m warned \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 167\u001b[0m emit_warning()\n\u001b[0;32m--> 168\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mwrapped\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/chains/base.py:383\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, run_name, include_run_info)\u001b[0m\n\u001b[1;32m 351\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Execute the chain.\u001b[39;00m\n\u001b[1;32m 352\u001b[0m \n\u001b[1;32m 353\u001b[0m \u001b[38;5;124;03mArgs:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 374\u001b[0m \u001b[38;5;124;03m `Chain.output_keys`.\u001b[39;00m\n\u001b[1;32m 375\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 376\u001b[0m config \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m 377\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcallbacks\u001b[39m\u001b[38;5;124m\"\u001b[39m: callbacks,\n\u001b[1;32m 378\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtags\u001b[39m\u001b[38;5;124m\"\u001b[39m: tags,\n\u001b[1;32m 379\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmetadata\u001b[39m\u001b[38;5;124m\"\u001b[39m: metadata,\n\u001b[1;32m 380\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_name\u001b[39m\u001b[38;5;124m\"\u001b[39m: run_name,\n\u001b[1;32m 381\u001b[0m }\n\u001b[0;32m--> 383\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 384\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 385\u001b[0m \u001b[43m \u001b[49m\u001b[43mcast\u001b[49m\u001b[43m(\u001b[49m\u001b[43mRunnableConfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43mk\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mis\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 386\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_only_outputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_only_outputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 387\u001b[0m \u001b[43m \u001b[49m\u001b[43minclude_run_info\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minclude_run_info\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 388\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/chains/base.py:166\u001b[0m, in \u001b[0;36mChain.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 164\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 165\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n\u001b[0;32m--> 166\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 167\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_end(outputs)\n\u001b[1;32m 169\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m include_run_info:\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/chains/base.py:156\u001b[0m, in \u001b[0;36mChain.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 153\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 154\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_validate_inputs(inputs)\n\u001b[1;32m 155\u001b[0m outputs \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 156\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 157\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[1;32m 158\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(inputs)\n\u001b[1;32m 159\u001b[0m )\n\u001b[1;32m 161\u001b[0m final_outputs: Dict[\u001b[38;5;28mstr\u001b[39m, Any] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_outputs(\n\u001b[1;32m 162\u001b[0m inputs, outputs, return_only_outputs\n\u001b[1;32m 163\u001b[0m )\n\u001b[1;32m 164\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/agents/agent.py:1433\u001b[0m, in \u001b[0;36mAgentExecutor._call\u001b[0;34m(self, inputs, run_manager)\u001b[0m\n\u001b[1;32m 1431\u001b[0m \u001b[38;5;66;03m# We now enter the agent loop (until it returns something).\u001b[39;00m\n\u001b[1;32m 1432\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_continue(iterations, time_elapsed):\n\u001b[0;32m-> 1433\u001b[0m next_step_output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_take_next_step\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1434\u001b[0m \u001b[43m \u001b[49m\u001b[43mname_to_tool_map\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1435\u001b[0m \u001b[43m \u001b[49m\u001b[43mcolor_mapping\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1436\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1437\u001b[0m \u001b[43m \u001b[49m\u001b[43mintermediate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1438\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1439\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1440\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(next_step_output, AgentFinish):\n\u001b[1;32m 1441\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_return(\n\u001b[1;32m 1442\u001b[0m next_step_output, intermediate_steps, run_manager\u001b[38;5;241m=\u001b[39mrun_manager\n\u001b[1;32m 1443\u001b[0m )\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/agents/agent.py:1139\u001b[0m, in \u001b[0;36mAgentExecutor._take_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m 1130\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_take_next_step\u001b[39m(\n\u001b[1;32m 1131\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 1132\u001b[0m name_to_tool_map: Dict[\u001b[38;5;28mstr\u001b[39m, BaseTool],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1136\u001b[0m run_manager: Optional[CallbackManagerForChainRun] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 1137\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[AgentFinish, List[Tuple[AgentAction, \u001b[38;5;28mstr\u001b[39m]]]:\n\u001b[1;32m 1138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_consume_next_step(\n\u001b[0;32m-> 1139\u001b[0m [\n\u001b[1;32m 1140\u001b[0m a\n\u001b[1;32m 1141\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_iter_next_step(\n\u001b[1;32m 1142\u001b[0m name_to_tool_map,\n\u001b[1;32m 1143\u001b[0m color_mapping,\n\u001b[1;32m 1144\u001b[0m inputs,\n\u001b[1;32m 1145\u001b[0m intermediate_steps,\n\u001b[1;32m 1146\u001b[0m run_manager,\n\u001b[1;32m 1147\u001b[0m )\n\u001b[1;32m 1148\u001b[0m ]\n\u001b[1;32m 1149\u001b[0m )\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/agents/agent.py:1139\u001b[0m, in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 1130\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_take_next_step\u001b[39m(\n\u001b[1;32m 1131\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 1132\u001b[0m name_to_tool_map: Dict[\u001b[38;5;28mstr\u001b[39m, BaseTool],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1136\u001b[0m run_manager: Optional[CallbackManagerForChainRun] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 1137\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[AgentFinish, List[Tuple[AgentAction, \u001b[38;5;28mstr\u001b[39m]]]:\n\u001b[1;32m 1138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_consume_next_step(\n\u001b[0;32m-> 1139\u001b[0m [\n\u001b[1;32m 1140\u001b[0m a\n\u001b[1;32m 1141\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_iter_next_step(\n\u001b[1;32m 1142\u001b[0m name_to_tool_map,\n\u001b[1;32m 1143\u001b[0m color_mapping,\n\u001b[1;32m 1144\u001b[0m inputs,\n\u001b[1;32m 1145\u001b[0m intermediate_steps,\n\u001b[1;32m 1146\u001b[0m run_manager,\n\u001b[1;32m 1147\u001b[0m )\n\u001b[1;32m 1148\u001b[0m ]\n\u001b[1;32m 1149\u001b[0m )\n",
"File \u001b[0;32m/data1/env/py310helperbot/lib/python3.10/site-packages/langchain/agents/agent.py:1178\u001b[0m, in \u001b[0;36mAgentExecutor._iter_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m 1176\u001b[0m raise_error \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m 1177\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m raise_error:\n\u001b[0;32m-> 1178\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 1179\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAn output parsing error occurred. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 1180\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIn order to pass this error back to the agent and have it try \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 1181\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124magain, pass `handle_parsing_errors=True` to the AgentExecutor. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 1182\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThis is the error: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mstr\u001b[39m(e)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 1183\u001b[0m )\n\u001b[1;32m 1184\u001b[0m text \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(e)\n\u001b[1;32m 1185\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandle_parsing_errors, \u001b[38;5;28mbool\u001b[39m):\n",
"\u001b[0;31mValueError\u001b[0m: An output parsing error occurred. In order to pass this error back to the agent and have it try again, pass `handle_parsing_errors=True` to the AgentExecutor. This is the error: Could not parse output: No."
]
}
],
"source": [
"from langchain.agents import AgentType, Tool, initialize_agent\n",
"\n",
"instructions = \"\"\"As a helpful and rigorous retail analyst, given the provided query and a list of search results for the query, your task is to first use store name and address to identify relevant information. After that, from the relevant information, extract `store_name`, `address`, `description`, `category`, `provide_alcohol` and `phone_number` from the found relevant information. Note that `category` can only be `小吃店`, `日式料理(含居酒屋,串燒)`, `火(鍋/爐)`, `東南亞料理(不含日韓)`, `海鮮熱炒`, `特色餐廳(含雞、鵝、牛、羊肉)`, `傳統餐廳`, `燒烤`, `韓式料理(含火鍋,烤肉)`, `西餐廳(含美式,義式,墨式)`, `西餐廳(餐酒館、酒吧、飛鏢吧、pub、lounge bar)`, `西餐廳(土耳其、漢堡、薯條、法式、歐式、印度)` or `早餐`. According to our experience,`provide_alcohol` can be inferred based on whether a store is suitable for scenarios such as Gathering, Chill, Enjoying Together, Drinking Freely, Winery, Wine Cellar, Wine Storage, Relaxing, Unwinding, Lyrical, Romantic, Pleasant, Stress Relief, Wine and Dine, Light Drinking Gatherings, Birthday Celebrations, Socializing, Parties, Networking, After Work Relaxation with a Drink, Relaxing Places Suitable for Drinking, Every Dish Goes Well with Beer, Shared Dishes, Dining Together, Atmosphere Suitable for Celebratory Drinking, Places Suitable for Light Drinking Gatherings with Friends, Small Shops Suitable for Relaxing and Light Drinking. `description` is a summary of key piece of evidence and reasons that lead you decide `category` and `provide_alcohol` .\n",
"\n",
" It's very important to omit unrelated results. Do not make up any assumption.\n",
" Please think step by step, and output a single json that starts with `{` and ends with `}`. An example output json is like {\"store_name\": \"...\", \"address\": \"...\", \"description\": \"... products, service or highlights ...\", \"category\": \"...\", \"phone_number\": \"...\", \"provide_alcohol\": true or false}\n",
" If no relevant information has been found, simply output json with empty values.\"\"\"\n",
"base_prompt = hub.pull(\"langchain-ai/openai-functions-template\")\n",
"prompt = base_prompt.partial(instructions=instructions)\n",
"llm = ChatOpenAI(temperature=0, )\n",
"serp = SerpAPIWrapper() # utilities\n",
"# serp.results(\"五角味食堂\t彰化縣北斗鎮文昌里復興路臨100-1號\")\n",
"tools = [\n",
" Tool(\n",
" name=\"Intermediate Answer\",\n",
" func=serp.run,\n",
" description=\"useful for when you need to get factual information with search\",\n",
" )\n",
"]\n",
"self_ask_with_search = initialize_agent(\n",
" tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True\n",
")\n",
"self_ask_with_search.run(\"五角味食堂\t彰化縣北斗鎮文昌里復興路臨100-1號\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68b499ad-3014-4d52-a30a-d750980d030e",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "3a4c34ba-7af8-4e63-aa82-946cb27651ec",
"metadata": {},
"source": [
"### LCEL ###"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "03543ce2-1406-4534-8071-12e172b770a8",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass()\n",
"\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"model = ChatOpenAI(model=\"gpt-4\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3980df79-f7b2-465f-9c88-d6bf401eb1e2",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "4505be03-1225-41bf-a62b-9bf29784a24c",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "e48659bc-d39c-425e-a452-39f0c6e16428",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "72723ffe-4b96-4bfb-b9ae-9718b3da4ea6",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
|