{"id":1486,"date":"2026-01-17T09:56:41","date_gmt":"2026-01-17T09:56:41","guid":{"rendered":"https:\/\/bogdanburuiana.com\/?p=1486"},"modified":"2026-04-27T10:23:57","modified_gmt":"2026-04-27T10:23:57","slug":"giving-your-ai-agent-hands-a-practical-guide-to-tools","status":"publish","type":"post","link":"https:\/\/bogdanburuiana.com\/index.php\/2026\/01\/17\/giving-your-ai-agent-hands-a-practical-guide-to-tools\/","title":{"rendered":"Giving Your AI Agent Hands: A Practical Guide to Tools"},"content":{"rendered":"\n<p>An LLM without tools is like a brilliant consultant locked in a room with no phone, no computer, and no access to any system. Smart? Yes. Useful in practice? Limited I would say&#8230;<br>Tools are what transform an AI agent from a very sophisticated chatbot into something that can actually do things in the world. In this article I&#8217;ll walk through what tools are, the difference between built-in and custom tools, how the agent decides which tool to use, and where this can go wrong.<\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>What Is a Tool, Exactly?<\/strong><br>In the context of AI agents, a tool is a callable function &#8211; something the agent can invoke to interact with the world beyond its training data and conversation context.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"569\" src=\"\/wp-content\/uploads\/2026\/04\/image-9-1024x569.png\" alt=\"\" class=\"wp-image-1487\" srcset=\"\/wp-content\/uploads\/2026\/04\/image-9-1024x569.png 1024w, \/wp-content\/uploads\/2026\/04\/image-9-300x167.png 300w, \/wp-content\/uploads\/2026\/04\/image-9-768x427.png 768w, \/wp-content\/uploads\/2026\/04\/image-9.png 1440w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>The critical point<\/strong>: the agent decides which tool to use, and when. You register the tools. The LLM figures out the orchestration. This is both the power and the risk of agentic systems.<\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Built-In Tools: Start Here<\/strong><br>Azure AI Foundry Agent Service ships with three built-in tools that cover a significant portion of common use cases:<\/p>\n\n\n\n<ol>\n<li><strong>Code Interpreter<\/strong><br><em>Executes Python code in a sandboxed environment. Useful for:<\/em><\/li>\n<\/ol>\n\n\n\n<ul>\n<li>Mathematical calculations<\/li>\n\n\n\n<li>Data analysis and transformation<\/li>\n\n\n\n<li>Chart generation<\/li>\n\n\n\n<li>File format conversions<\/li>\n<\/ul>\n\n\n\n<p>Real example: a user uploads a CSV of sales figures and asks &#8220;what was the month-over-month growth rate?&#8221; The agent writes Python to parse the CSV, calculate the rates, and return a formatted answer -without you writing a line of backend code.<\/p>\n\n\n\n<ol start=\"2\">\n<li><strong>File Search<\/strong><br><em>Searches through documents you&#8217;ve provided as knowledge sources. Useful for:<\/em><\/li>\n<\/ol>\n\n\n\n<ul>\n<li>Policy document lookup<\/li>\n\n\n\n<li>Product documentation Q&amp;A<\/li>\n\n\n\n<li>Contract analysis<\/li>\n\n\n\n<li>Knowledge base search<\/li>\n<\/ul>\n\n\n\n<p>This is powered by Azure AI Search under the hood. You upload documents, they get indexed, and the agent can retrieve relevant chunks to ground its answers. This is the Retrieval-Augmented Generation (RAG) pattern &#8211; but abstracted.<\/p>\n\n\n\n<ol start=\"3\">\n<li><strong>Web Search<\/strong><br><em>Retrieves live information from the internet. Useful for:<\/em><\/li>\n<\/ol>\n\n\n\n<ul>\n<li>Current events and news<\/li>\n\n\n\n<li>Pricing lookups<\/li>\n\n\n\n<li>Competitor monitoring<\/li>\n\n\n\n<li>Anything that changes faster than your data<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Tool<\/strong><\/td><td><strong>Best For<\/strong><\/td><td><strong>Latency<\/strong><\/td><td><strong>Cost Impact<\/strong><\/td><\/tr><tr><td>Code Interpreter<\/td><td>Computation, analysis<\/td><td>Medium<\/td><td>Low-Medium<\/td><\/tr><tr><td>File Search<\/td><td>Document Q&amp;A, knowledge retrieval<\/td><td>Low-Medium<\/td><td>Medium (Search SKU)<\/td><\/tr><tr><td>Web Search<\/td><td>Live\/current information<\/td><td>Medium-High<\/td><td>Low-Medium<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Custom Function Tools: When Built-Ins Aren&#8217;t Enough<\/strong><\/p>\n\n\n\n<p>The real power comes when you connect your agent to your own systems. Custom function tools let you expose any capability as something the agent can call.<\/p>\n\n\n\n<p><br>In the Microsoft Agent Framework (Python SDK), the pattern looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from azure.ai.agents import tool\n\n@tool\ndef get_customer_account(customer_id: str) -&gt; dict:\n    \"\"\"\n    Retrieve customer account details from the CRM system.\n    \n    Args:\n        customer_id: The unique customer identifier\n        \n    Returns:\n        Dictionary containing account details and status\n    \"\"\"\n    # Your actual CRM API call here\n    response = crm_api.get_account(customer_id)\n    return response.to_dict()<\/code><\/pre>\n\n\n\n<p>Three things that matter here:<\/p>\n\n\n\n<ol>\n<li>The <strong>@tool<\/strong> <strong>decorator<\/strong> tells the framework this function is available to the agent<\/li>\n\n\n\n<li><strong>The docstring <\/strong>is critical &#8211; the LLM reads it to understand what the tool does and when to use it<\/li>\n\n\n\n<li><strong>Type annotations<\/strong> help the LLM understand what inputs to provide<\/li>\n<\/ol>\n\n\n\n<p>Once registered, the agent automatically discovers and invokes this function when it determines it&#8217;s the right tool for the job. No manual routing logic on your part.<\/p>\n\n\n\n<p><strong>How the Agent Picks the Right Tool<\/strong><\/p>\n\n\n\n<p>This is where I see the most confusion in training sessions. &#8220;How does the agent know to use File Search vs. Web Search?&#8221;<\/p>\n\n\n\n<p>The answer: <strong>it reads your tool descriptions and reasons about which fits the current request.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"540\" src=\"\/wp-content\/uploads\/2026\/04\/image-10-1024x540.png\" alt=\"\" class=\"wp-image-1488\" srcset=\"\/wp-content\/uploads\/2026\/04\/image-10-1024x540.png 1024w, \/wp-content\/uploads\/2026\/04\/image-10-300x158.png 300w, \/wp-content\/uploads\/2026\/04\/image-10-768x405.png 768w, \/wp-content\/uploads\/2026\/04\/image-10.png 1440w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This is why your <strong>docstrings and tool names matter enormously<\/strong>. The LLM uses them as a mental map of available capabilities. A poorly named tool or a missing description leads to wrong tool selection &#8211; and wrong tool selection leads to wrong answers.<\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Connecting Tools to Azure Functions<\/strong><br>For enterprise scenarios, you&#8217;ll typically implement custom tools as Azure Functions. This pattern gives you:<\/p>\n\n\n\n<ul>\n<li>Serverless execution &#8211; no infrastructure to manage<\/li>\n\n\n\n<li>Full access to Azure services and your internal systems<\/li>\n\n\n\n<li>Isolated execution environment with managed identity<\/li>\n\n\n\n<li>Easy integration with Key Vault for secrets<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"398\" src=\"\/wp-content\/uploads\/2026\/04\/image-11-1024x398.png\" alt=\"\" class=\"wp-image-1489\" srcset=\"\/wp-content\/uploads\/2026\/04\/image-11-1024x398.png 1024w, \/wp-content\/uploads\/2026\/04\/image-11-300x117.png 300w, \/wp-content\/uploads\/2026\/04\/image-11-768x299.png 768w, \/wp-content\/uploads\/2026\/04\/image-11.png 1440w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The Function handles authentication, connection management, error handling, and retry logic. The agent just gets clean results.<\/p>\n\n\n\n<p class=\"has-vivid-red-color has-cyan-bluish-gray-background-color has-text-color has-background has-link-color has-medium-font-size wp-elements-04bb42e45fef22934f7f051884c7e25a\"><strong>Security: The Part That Gets Skipped in Demos<\/strong><br>Every tool is a potential attack surface. I&#8217;m going to say that again because it&#8217;s important.<br><strong>Every tool is a potential attack surface.<\/strong><br>When you give an agent a tool that can write to a database, you&#8217;ve created a code path where an LLM &#8211; which can be manipulated through prompt injection in user inputs &#8211; has write access to your database.<br><\/p>\n\n\n\n<p class=\"has-black-color has-white-background-color has-text-color has-background has-link-color has-medium-font-size wp-elements-9656ea14706c15f5d32a6f1d3a1ca54e\"><strong>Mitigation strategies I implement on every production agent:<\/strong><\/p>\n\n\n\n<ul>\n<li><strong>Principle of least privilege<\/strong> &#8211; tools should only do exactly what&#8217;s needed. No admin access when read access is sufficient.<\/li>\n\n\n\n<li><strong>Input validation in tool functions<\/strong> &#8211; don&#8217;t trust the LLM&#8217;s parameters blindly. Validate before you execute.<\/li>\n\n\n\n<li><strong>Rate limiting<\/strong> &#8211; prevent runaway tool calls from burning through API quotas or triggering accidental bulk operations<\/li>\n\n\n\n<li><strong>Audit logging<\/strong> &#8211; log every tool call with inputs and outputs. You need this for debugging and compliance.<\/li>\n\n\n\n<li><strong>Human-in-the-loop for destructive operations<\/strong> &#8211; anything that deletes, overwrites, or sends externally should require confirmation<\/li>\n<\/ul>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Pros and Cons of Giving Agents Tools<\/strong><br><strong>Pros:<\/strong><\/p>\n\n\n\n<ul>\n<li>Dramatically expands what an agent can accomplish<\/li>\n\n\n\n<li>Custom tools integrate AI into existing business systems without rebuilding them<\/li>\n\n\n\n<li>Tool-based architecture is modular &#8211; add, remove, update tools independently<\/li>\n\n\n\n<li>The agent handles orchestration &#8211; you don&#8217;t write routing logic<\/li>\n<\/ul>\n\n\n\n<p><strong>Cons:<\/strong><\/p>\n\n\n\n<ul>\n<li>More tools = more complexity = harder to reason about agent behaviour<\/li>\n\n\n\n<li>Tool descriptions need maintaining &#8211; outdated descriptions cause tool misuse<\/li>\n\n\n\n<li>Latency compounds &#8211; if an agent calls four tools sequentially, you feel each one<br>Security surface grows with each new tool<\/li>\n\n\n\n<li>Debugging tool call chains requires good logging infrastructure<\/li>\n<\/ul>\n\n\n\n<p>One of the most common mistakes I see in production: giving the agent too many tools.<br>There&#8217;s a cognitive load equivalent for LLMs. When you register 25 tools, the model has to reason about all 25 before selecting one. This increases latency, increases token consumption, and paradoxically reduces accuracy because the model has more ways to go wrong.<br>My rule of thumb: <strong>start with the minimum viable toolset.<\/strong> Three to five tools for most use cases. Add more only when you have evidence the agent needs them.<\/p>\n\n\n\n<p>Next: I&#8217;ll cover how Foundry IQ (knowledge-enhanced agents) works &#8211; the deeper integration between your documents and your agent that goes beyond basic file search.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An LLM without tools is like a brilliant consultant locked in a room with no phone, no computer, and no access to any system. Smart? Yes. Useful in practice? Limited I would say&#8230;Tools are what transform an AI agent from a very sophisticated chatbot into something that can actually do things in the world. In [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/posts\/1486"}],"collection":[{"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/comments?post=1486"}],"version-history":[{"count":3,"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/posts\/1486\/revisions"}],"predecessor-version":[{"id":1492,"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/posts\/1486\/revisions\/1492"}],"wp:attachment":[{"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/media?parent=1486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/categories?post=1486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bogdanburuiana.com\/index.php\/wp-json\/wp\/v2\/tags?post=1486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}