{"id":2663,"date":"2025-03-27T07:02:23","date_gmt":"2025-03-27T07:02:23","guid":{"rendered":"https:\/\/mailitics.com\/index.php\/2025\/03\/27\/ai-agents-from-zero-to-hero-part-2\/"},"modified":"2025-03-27T07:02:23","modified_gmt":"2025-03-27T07:02:23","slug":"ai-agents-from-zero-to-hero-part-2","status":"publish","type":"post","link":"https:\/\/mailitics.com\/index.php\/2025\/03\/27\/ai-agents-from-zero-to-hero-part-2\/","title":{"rendered":"AI Agents from Zero to Hero \u2014 Part 2"},"content":{"rendered":"<p>    AI Agents from Zero to Hero \u2014 Part 2<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n    <!-- no image --><br \/>\n \t<BR><br \/>\n<BR><\/BR><\/p>\n<div>\n<h2 class=\"wp-block-heading\"><strong><mdspan datatext=\"el1743017574199\" class=\"mdspan-comment\">Intro<\/mdspan><\/strong><\/h2>\n<p class=\"wp-block-paragraph\">In <a href=\"https:\/\/towardsdatascience.com\/ai-agents-from-zero-to-hero-part-1\/\">Part 1<\/a> of this tutorial series, we introduced <strong>AI Agents<\/strong>, autonomous programs that perform tasks, make decisions, and communicate with others.\u00a0<\/p>\n<p class=\"wp-block-paragraph\">Agents perform actions through Tools. It might happen that a Tool doesn\u2019t work on the first try, or that multiple Tools must be activated in sequence. Agents should be able to organize tasks into a logical progression and change their strategies in a dynamic environment.<\/p>\n<p class=\"wp-block-paragraph\">To put it simply, the Agent\u2019s structure must be solid, and the behavior must be reliable. The most common way to do that is through:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">\n<strong>Iterations \u2013<\/strong> repeating a certain action multiple times, often with slight changes or improvements in each cycle. Every time might involve the Agent revisiting certain steps to refine its output or reach an optimal solution.<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Chains<\/strong> <strong>\u2013<\/strong> a series of actions that are linked together in a sequence. Each step in the chain is dependent on the previous one, and the output of one action becomes the input for the next.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">In this tutorial, I\u2019m going to show how to use <strong>iterations and chains for Agents<\/strong>. I will present some useful Python code that can be easily applied in other similar cases (just copy, paste, run) and walk through every line of code with comments so that you can replicate this example (link to full code at the end of the article).<\/p>\n<h2 class=\"wp-block-heading\"><strong>Setup<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">Please refer to <a href=\"https:\/\/towardsdatascience.com\/ai-agents-from-zero-to-hero-part-1\/\">Part 1<\/a> for the setup of <a href=\"https:\/\/ollama.com\/\"><strong><em>Ollama<\/em><\/strong><\/a> and the main LLM.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">import <a href=\"https:\/\/towardsdatascience.com\/tag\/ollama\/\" title=\"Ollama\">Ollama<\/a>\nllm = \"qwen2.5\"\u00a0<\/code><\/pre>\n<p class=\"wp-block-paragraph\">We will use the <a href=\"https:\/\/yfinance-python.org\/\"><em>YahooFinance<\/em> public APIs<\/a> with the <a href=\"https:\/\/towardsdatascience.com\/tag\/python\/\" title=\"Python\">Python<\/a> library (<code>pip install yfinance==0.2.55<\/code>) to download financial data.\u00a0<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">import yfinance as yf\n\nstock = \"MSFT\"\nyf.Ticker(ticker=stock).history(period='5d') #1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max<\/code><\/pre>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXfouSXPRKeUie50ngD0nNH4_1KURTjDjhbUwqeJ9EyKVlTJbwoHiHlukNP57Ymg4afc4aD9A-kZCUqwJp4QmbWawEI1a27aRnPF2j3Ji9OvZ3b4WgvnPl32x-ZM2ImsBCA_0CNp4g?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">Let\u2019s embed that into a Tool.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">import matplotlib.pyplot as plt\n\ndef get_stock(ticker:str, period:str, col:str):\n\u00a0 \u00a0 data = yf.Ticker(ticker=ticker).history(period=period)\n\u00a0 \u00a0 if len(data) &gt; 0:\n\u00a0 \u00a0 \u00a0 \u00a0 data[col].plot(color=\"black\", legend=True, xlabel='', title=f\"{ticker.upper()} ({period})\").grid()\n\u00a0 \u00a0 \u00a0 \u00a0 plt.show()\n\u00a0 \u00a0 \u00a0 \u00a0 return 'ok'\n\u00a0 \u00a0 else:\n\u00a0 \u00a0 \u00a0 \u00a0 return 'no'\n\ntool_get_stock = {'type':'function', 'function':{\n\u00a0 'name': 'get_stock',\n\u00a0 'description': 'Download stock data',\n\u00a0 'parameters': {'type': 'object',\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'required': ['ticker','period','col'],\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'properties': {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'ticker': {'type':'str', 'description':'the ticker symbol of the stock.'},\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'period': {'type':'str', 'description':\"for 1 month input '1mo', for 6 months input '6mo', for 1 year input '1y'. Use '1y' if not specified.\"},\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'col': {'type':'str', 'description':\"one of 'Open','High','Low','Close','Volume'. Use 'Close' if not specified.\"},\n}}}}\n\n## test\nget_stock(ticker=\"msft\", period=\"1y\", col=\"Close\")<\/code><\/pre>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXer7QmZmL87alB3T7kc4ICvz2vPMX-Hehfj2o0JqKIOMZp8RE4-TAqOxTJmQvPQHCZaTokm8vpZBvvSM5x7lPJtCE3sr01Jwl33rBnmshRGisjah1_oajy3VdVMyPqdHh49d4urMA?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">Moreover, taking the code from the previous article as a reference, I shall write a general function to process the model response, such as when the Agent wants to use a Tool or when it just returns text.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">def use_tool(agent_res:dict, dic_tools:dict) -&gt; dict:\n\u00a0 \u00a0 ## use tool\n\u00a0 \u00a0 if \"tool_calls\" in agent_res[\"message\"].keys():\n\u00a0 \u00a0 \u00a0 \u00a0 for tool in agent_res[\"message\"][\"tool_calls\"]:\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 t_name, t_inputs = tool[\"function\"][\"name\"], tool[\"function\"][\"arguments\"]\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if f := dic_tools.get(t_name):\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ### calling tool\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 print('<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f527.png?ssl=1\" alt=\"\ud83d\udd27\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"> &gt;', f\"x1b[1;31m{t_name} -&gt; Inputs: {t_inputs}x1b[0m\")\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ### tool output\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 t_output = f(**tool[\"function\"][\"arguments\"])\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 print(t_output)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ### final res\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 res = t_output\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 else:\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 print('<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f92c.png?ssl=1\" alt=\"\ud83e\udd2c\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"> &gt;', f\"x1b[1;31m{t_name} -&gt; NotFoundx1b[0m\")\n\u00a0 \u00a0 ## don't use tool\n\u00a0 \u00a0 if agent_res['message']['content'] != '':\n\u00a0 \u00a0 \u00a0 \u00a0 res = agent_res[\"message\"][\"content\"]\n\u00a0 \u00a0 \u00a0 \u00a0 t_name, t_inputs = '', ''\n\u00a0 \u00a0 return {'res':res, 'tool_used':t_name, 'inputs_used':t_inputs}<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Let\u2019s start a quick conversation with our Agent. For now, I\u2019m going to use a simple generic prompt.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">prompt = '''You are a financial analyst, assist the user using your available tools.'''\nmessages = [{\"role\":\"system\", \"content\":prompt}]\ndic_tools = {'get_stock':get_stock}\n\nwhile True:\n\u00a0 \u00a0 ## user input\n\u00a0 \u00a0 try:\n\u00a0 \u00a0 \u00a0 \u00a0 q = input('<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f642.png?ssl=1\" alt=\"\ud83d\ude42\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"> &gt;')\n\u00a0 \u00a0 except EOFError:\n\u00a0 \u00a0 \u00a0 \u00a0 break\n\u00a0 \u00a0 if q == \"quit\":\n\u00a0 \u00a0 \u00a0 \u00a0 break\n\u00a0 \u00a0 if q.strip() == \"\":\n\u00a0 \u00a0 \u00a0 \u00a0 continue\n\u00a0 \u00a0 messages.append( {\"role\":\"user\", \"content\":q} )\n\u00a0 \u00a0\n\u00a0 \u00a0 ## model\n\u00a0 \u00a0 agent_res = ollama.chat(model=llm, messages=messages,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 tools=[tool_get_stock])\n\u00a0 \u00a0 dic_res = use_tool(agent_res, dic_tools)\n\u00a0 \u00a0 res, tool_used, inputs_used = dic_res[\"res\"], dic_res[\"tool_used\"], dic_res[\"inputs_used\"]\n\u00a0 \u00a0\n\u00a0 \u00a0 ## final response\n\u00a0 \u00a0 print(\"<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f47d.png?ssl=1\" alt=\"\ud83d\udc7d\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"> &gt;\", f\"x1b[1;30m{res}x1b[0m\")\n\u00a0 \u00a0 messages.append( {\"role\":\"assistant\", \"content\":res} )<\/code><\/pre>\n<p class=\"wp-block-paragraph\">As you can see, I started by asking an \u201ceasy\u201d question. The LLM already knows that the symbol of Microsoft stock is MSFT, therefore the Agent was able to activate the Tool with the right inputs. But what if I ask something that might not be included in the LLM knowledge base?\u00a0<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXeW3QY-K1AhycyHXzTJopnBRUkcjq4GVYNB54hK2BwOKIiEptNCj-7nuxXBWC2UtgdoEMsneoYuwBEpNeSP3aceDoEz6Afm-eSuTPL8tx7qa8GGtO4k83gKEmzPr6lg22OGRrkgng?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">Seems that the LLM doesn\u2019t know that Facebook changed its name to META, so it used the Tool with the wrong inputs. I will enable the Agent to try an action several times through iterations.<\/p>\n<h2 class=\"wp-block-heading\"><strong>Iterations<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">Iterations refer to the repetition of a process until a certain condition is met. We can let the Agent try a specific number of times, but we need to let it know that the previous parameters didn\u2019t work, by adding the details in the message history.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">\u00a0 \u00a0 max_i, i = 3, 0\n\u00a0 \u00a0 while res == 'no' and i &lt; max_i:\n\u00a0 \u00a0 \u00a0 \u00a0 comment = f'''I used tool '{tool_used}' with inputs {inputs_used}. But it didn't work, so I must try again with different inputs'''\n\u00a0 \u00a0 \u00a0 \u00a0 messages.append( {\"role\":\"assistant\", \"content\":comment} )\n\u00a0 \u00a0 \u00a0 \u00a0 agent_res = ollama.chat(model=llm, messages=messages,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 tools=[tool_get_stock])\n\u00a0 \u00a0 \u00a0 \u00a0 dic_res = use_tool(agent_res, dic_tools)\n\u00a0 \u00a0 \u00a0 \u00a0 res, tool_used, inputs_used = dic_res[\"res\"], dic_res[\"tool_used\"], dic_res[\"inputs_used\"]\n\u00a0 \u00a0 \u00a0 \u00a0\n\u00a0 \u00a0 \u00a0 \u00a0 i += 1\n\u00a0 \u00a0 \u00a0 \u00a0 if i == max_i:\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 res = f'I tried {i} times but something is wrong'\n\n\u00a0 \u00a0 ## final response\n\u00a0 \u00a0 print(\"<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f47d.png?ssl=1\" alt=\"\ud83d\udc7d\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"> &gt;\", f\"x1b[1;30m{res}x1b[0m\")\n\u00a0 \u00a0 messages.append( {\"role\":\"assistant\", \"content\":res} )<\/code><\/pre>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXdDHRUSjNVxMPGTYocuK6zW6l7YyTQJ7xDTY69YiGUe0yulhLIFKyRk1CtTDKBHdpus0TViK45Bdyegvs-9vOda4OwTCjnD_2jDKaTkG0LV4lhrZ_7uk1f_JkgCGbNvxbdqyEkyXA?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">The Agent tried 3 times with different inputs but it couldn\u2019t find a solution because there is a gap in the LLM knowledge base. In this case, the model needed human input to understand how to use the Tool.<\/p>\n<p class=\"wp-block-paragraph\">Next, we\u2019re going to enable the Agent to fill the knowledge gap by itself.<\/p>\n<h2 class=\"wp-block-heading\"><strong>Chains<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">A chain refers to a linear sequence of actions where the output of one step is used as the input for the next step. In this example, I will add another Tool that the Agent can use in case the first one fails.<\/p>\n<p class=\"wp-block-paragraph\">We can use the web-searching Tool from the previous article.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">from langchain_community.tools import DuckDuckGoSearchResults\n\ndef search_web(query:str) -&gt; str:\n\u00a0 return DuckDuckGoSearchResults(backend=\"news\").run(query)\n\ntool_search_web = {'type':'function', 'function':{\n\u00a0 'name': 'search_web',\n\u00a0 'description': 'Search the web',\n\u00a0 'parameters': {'type': 'object',\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'required': ['query'],\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'properties': {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'query': {'type':'str', 'description':'the topic or subject to search on the web'},\n}}}}\n\n## test\nsearch_web(query=\"facebook stock\")<\/code><\/pre>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXc9Wxl7SAI5E-ewj0D_MDk0Onx7AsMlEnvqMVxuXz--C6vEmNU7cMPO3jrb5viL9_PHwp4r2TQW2H_fjfuoy-6SLHdLgY_L7Z0jKxfVUklvxYjtjJoWdr1JNubJlIfuDyHbMe8VjQ?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">So far, I\u2019ve always used very generic prompts as the tasks were relatively simple. Now, I want to make sure that the Agent understands how to use the Tools in the right order, so I\u2019m going to write a <strong>proper prompt<\/strong>. This is how a prompt should be done:<\/p>\n<ol class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">The goal of the Agent<\/li>\n<li class=\"wp-block-list-item\">What it must return (i.e. format, content)<\/li>\n<li class=\"wp-block-list-item\">Any relevant warnings that might affect the output<\/li>\n<li class=\"wp-block-list-item\">Context dump<\/li>\n<\/ol>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">prompt = '''\n[GOAL] You are a financial analyst, assist the user using your available tools.\n\n[RETURN] You must return the stock data that the user asks for.\n\n[WARNINGS] In order to retrieve stock data, you need to know the ticker symbol of the company.\n\n[CONTEXT] First ALWAYS try to use the tool 'get_stock'.\nIf it doesn't work, you can use the tool 'search_web' and search 'company name stock'.\nGet information about the stock and deduct what is the right ticker symbol of the company.\nThen, you can use AGAIN the tool 'get_stock' with the ticker you got using the previous tool.\n'''<\/code><\/pre>\n<p class=\"wp-block-paragraph\">We can simply add the chain to the iteration loop that we already have. This time the Agent has two Tools, and when the first fails, the model can decide whether to retry or to use the second one. Then, if the second Tool is used, <strong>the Agent must process the output and learn<\/strong> what\u2019s the right input for the first Tool that initially failed.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">\u00a0 \u00a0 max_i, i = 3, 0\n\u00a0 \u00a0 while res in ['no',''] and i &lt; max_i:\n\u00a0 \u00a0 \u00a0 \u00a0 comment = f'''I used tool '{tool_used}' with inputs {inputs_used}. But it didn't work, so I must try a different way.'''\n\u00a0 \u00a0 \u00a0 \u00a0 messages.append( {\"role\":\"assistant\", \"content\":comment} )\n\u00a0 \u00a0 \u00a0 \u00a0 agent_res = ollama.chat(model=llm, messages=messages,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 tools=[tool_get_stock, tool_search_web])\n\u00a0 \u00a0 \u00a0 \u00a0 dic_res = use_tool(agent_res, dic_tools)\n\u00a0 \u00a0 \u00a0 \u00a0 res, tool_used, inputs_used = dic_res[\"res\"], dic_res[\"tool_used\"], dic_res[\"inputs_used\"]\n\n\u00a0 \u00a0 \u00a0 \u00a0 ## chain: output of previous tool = input of next tool\n\u00a0 \u00a0 \u00a0 \u00a0 if tool_used == 'search_web':\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 query = q+\". You must return just the compay ticker.nContext: \"+res\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 llm_res = ollama.generate(model=llm, prompt=query)[\"response\"]\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 messages.append( {\"role\":\"user\", \"content\":f\"try ticker: {llm_res}\"} )\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 print(\"<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f47d.png?ssl=1\" alt=\"\ud83d\udc7d\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"> &gt;\", f\"x1b[1;30mI can try with {llm_res}x1b[0m\")\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 agent_res = ollama.chat(model=llm, messages=messages, tools=[tool_get_stock])\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 dic_res = use_tool(agent_res, dic_tools)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 res, tool_used, inputs_used = dic_res[\"res\"], dic_res[\"tool_used\"], dic_res[\"inputs_used\"]\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0i += 1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if i == max_i:\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0res = f'I tried {i} times but something is wrong'\n\u00a0\u00a0\u00a0\u00a0\n ## final response\u00a0\u00a0\u00a0\u00a0\n print(\"<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f47d.png?ssl=1\" alt=\"\ud83d\udc7d\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"> &gt;\", f\"x1b[1;30m{res}x1b[0m\")\u00a0\u00a0\u00a0\u00a0\n messages.append( {\"role\":\"assistant\", \"content\":res} )<\/code><\/pre>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXffM1UV48YR7WN5jNrjnEob3TEI6rdiYZkhdbfYLtgIZ_B128Gtal5FThAl8I2U42UvHlKHZQFv-LeKtJ4EKqMYF6i6OntUFZymhVFKfRWkCCT_ulB3lC_bdn2s_MjZVsE-zYg?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">As expected, the Agent tried to use the first Tool with the wrong inputs, but instead of trying the same action again as before, it decided to use the second Tool. By consuming information, it should understand the solution without the need for human input.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXeL9Ur7fIGQfqipNtH6HdTBIoeNKAOlbe-6jbpMhsucr8-8kkTPwnviSTeVpHxVuI1K2oxqiIjsI23Q_KlOkUHx9KQ0VyifBZMFPvxZPGaYabCIAD7h9cBjkcrFEdy3D5Uk1PaOkg?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">In summary, the AI tried to do an action but failed due to a gap in its knowledge base. So it activated Tools to fill that gap and deliver the output requested by the user\u2026 that is indeed the true essence of AI Agents.\u00a0<\/p>\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">This article has covered more structured ways to make Agents more reliable, using iterations and chains. With these building blocks in place, you are already equipped to start developing your own Agents for different use cases.\u00a0<\/p>\n<p class=\"wp-block-paragraph\"><strong>Stay tuned for Part 3<\/strong>, where we will dive deeper into more advanced examples.<\/p>\n<p class=\"wp-block-paragraph\">Full code for this article: <a href=\"https:\/\/github.com\/mdipietro09\/GenerativeAI\/blob\/main\/Agents_ZeroToHero\/notebook.ipynb\"><strong>GitHub<\/strong><\/a><\/p>\n<p class=\"wp-block-paragraph\">I hope you enjoyed it! Feel free to contact me for questions and feedback or just to share your interesting projects.<\/p>\n<p class=\"has-text-align-center wp-block-paragraph\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f449.png?ssl=1\" alt=\"\ud83d\udc49\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\">\u00a0<a href=\"https:\/\/maurodp.carrd.co\/\"><strong>Let\u2019s Connect<\/strong><\/a>\u00a0<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f448.png?ssl=1\" alt=\"\ud83d\udc48\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\"><\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXfFcYBOAVagch7S-aKbCzR0P021yn4JnlWJpjLFXfWu7ui3X7AVBQA5pu7zZDuPhhTgWF5nn8kJIxU3NrsEkh6pH3TmfiT2S3S4_PnThnPDjoO3sNMcoqKpaeKGUyOYUyyOdvR5zA?key=2eqZbEnNxwakht1Lz2efc-lr\" alt=\"\"><\/figure>\n<p>The post <a href=\"https:\/\/towardsdatascience.com\/ai-agents-from-zero-to-hero-part-2\/\">AI Agents from Zero to Hero \u2014 Part 2<\/a> appeared first on <a href=\"https:\/\/towardsdatascience.com\/\">Towards Data Science<\/a>.<\/p>\n<\/div>\n<p> \t<BR><br \/>\n <BR><\/BR><br \/>\n    Mauro Di Pietro<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n<a href=\"https:\/\/towardsdatascience.com\/ai-agents-from-zero-to-hero-part-2\/\">Go to original source<\/a><br \/>\n \t<BR><br \/>\n <BR><\/BR><\/p>\n","protected":false},"excerpt":{"rendered":"<p>AI Agents from Zero to Hero \u2014 Part 2 Intro In Part 1 of this tutorial series, we introduced AI Agents, autonomous programs that perform tasks, make decisions, and communicate with others.\u00a0 Agents perform actions through Tools. It might happen that a Tool doesn\u2019t work on the first try, or that multiple Tools must be [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[678,799,62,69,722,1771,157],"tags":[1140,2136,2135],"class_list":["post-2663","post","type-post","status-publish","format-standard","hentry","category-agentic-ai","category-ai-agent","category-aimldsaimlds","category-artificial-intelligence","category-ollama","category-prompt-engineering","category-python","tag-agents","tag-period","tag-ticker"],"_links":{"self":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/2663"}],"collection":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/comments?post=2663"}],"version-history":[{"count":0,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/2663\/revisions"}],"wp:attachment":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/media?parent=2663"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/categories?post=2663"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/tags?post=2663"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}