Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"What are Tools?","local":"what-are-tools","sections":[{"title":"What are AI Tools?","local":"what-are-ai-tools","sections":[],"depth":2},{"title":"How do tools work?","local":"how-do-tools-work","sections":[],"depth":2},{"title":"How do we give tools to an LLM?","local":"how-do-we-give-tools-to-an-llm","sections":[{"title":"Auto-formatting Tool sections","local":"auto-formatting-tool-sections","sections":[],"depth":3},{"title":"Generic Tool implementation","local":"generic-tool-implementation","sections":[],"depth":3},{"title":"Model Context Protocol (MCP): a unified tool interface","local":"model-context-protocol-mcp-a-unified-tool-interface","sections":[],"depth":3}],"depth":2}],"depth":1}"> | |
| <link href="/docs/agents-course/pr_545/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/entry/start.1596c81c.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/scheduler.37c15a92.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/singletons.8a3d92bd.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/index.18351ede.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/paths.5b2602e7.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/entry/app.856a784e.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/index.2bf4358c.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/nodes/0.1cd5790a.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/nodes/32.d516e9b6.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/CodeBlock.4e987730.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/Heading.8ada512a.js"> | |
| <link rel="modulepreload" href="/docs/agents-course/pr_545/en/_app/immutable/chunks/getInferenceSnippets.031140c2.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"What are Tools?","local":"what-are-tools","sections":[{"title":"What are AI Tools?","local":"what-are-ai-tools","sections":[],"depth":2},{"title":"How do tools work?","local":"how-do-tools-work","sections":[],"depth":2},{"title":"How do we give tools to an LLM?","local":"how-do-we-give-tools-to-an-llm","sections":[{"title":"Auto-formatting Tool sections","local":"auto-formatting-tool-sections","sections":[],"depth":3},{"title":"Generic Tool implementation","local":"generic-tool-implementation","sections":[],"depth":3},{"title":"Model Context Protocol (MCP): a unified tool interface","local":"model-context-protocol-mcp-a-unified-tool-interface","sections":[],"depth":3}],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <h1 class="relative group"><a id="what-are-tools" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-are-tools"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>What are Tools?</span></h1> <img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/whiteboard-check-2.jpg" alt="Unit 1 planning"> <p data-svelte-h="svelte-12q0l6c">One crucial aspect of AI Agents is their ability to take <strong>actions</strong>. As we saw, this happens through the use of <strong>Tools</strong>.</p> <p data-svelte-h="svelte-vccz0n">In this section, we’ll learn what Tools are, how to design them effectively, and how to integrate them into your Agent via the System Message.</p> <p data-svelte-h="svelte-g748wk">By giving your Agent the right Tools—and clearly describing how those Tools work—you can dramatically increase what your AI can accomplish. Let’s dive in!</p> <h2 class="relative group"><a id="what-are-ai-tools" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-are-ai-tools"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>What are AI Tools?</span></h2> <p data-svelte-h="svelte-d0memu">A <strong>Tool is a function given to the LLM</strong>. This function should fulfill a <strong>clear objective</strong>.</p> <p data-svelte-h="svelte-1bnicmb">Here are some commonly used tools in AI agents:</p> <table data-svelte-h="svelte-1r7ovsn"><thead><tr><th>Tool</th> <th>Description</th></tr></thead> <tbody><tr><td>Web Search</td> <td>Allows the agent to fetch up-to-date information from the internet.</td></tr> <tr><td>Image Generation</td> <td>Creates images based on text descriptions.</td></tr> <tr><td>Retrieval</td> <td>Retrieves information from an external source.</td></tr> <tr><td>API Interface</td> <td>Interacts with an external API (GitHub, YouTube, Spotify, etc.).</td></tr></tbody></table> <p data-svelte-h="svelte-1fuccdy">Those are only examples, as you can in fact create a tool for any use case!</p> <p data-svelte-h="svelte-178hc7g">A good tool should be something that <strong>complements the power of an LLM</strong>.</p> <p data-svelte-h="svelte-1redoxr">For instance, if you need to perform arithmetic, giving a <strong>calculator tool</strong> to your LLM will provide better results than relying on the native capabilities of the model.</p> <p data-svelte-h="svelte-1v1ck09">Furthermore, <strong>LLMs predict the completion of a prompt based on their training data</strong>, which means that their internal knowledge only includes events prior to their training. Therefore, if your agent needs up-to-date data you must provide it through some tool.</p> <p data-svelte-h="svelte-mz2far">For instance, if you ask an LLM directly (without a search tool) for today’s weather, the LLM will potentially hallucinate random weather.</p> <img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/weather.jpg" alt="Weather"> <ul data-svelte-h="svelte-gj3em1"><li><p>A Tool should contain:</p> <ul><li>A <strong>textual description of what the function does</strong>.</li> <li>A <em>Callable</em> (something to perform an action).</li> <li><em>Arguments</em> with typings.</li> <li>(Optional) Outputs with typings.</li></ul></li></ul> <h2 class="relative group"><a id="how-do-tools-work" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#how-do-tools-work"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>How do tools work?</span></h2> <p data-svelte-h="svelte-12sfw6d">LLMs, as we saw, can only receive text inputs and generate text outputs. They have no way to call tools on their own. When we talk about providing tools to an Agent, we mean teaching the LLM about the existence of these tools and instructing it to generate text-based invocations when needed.</p> <p data-svelte-h="svelte-17ojdf7">For example, if we provide a tool to check the weather at a location from the internet and then ask the LLM about the weather in Paris, the LLM will recognize that this is an opportunity to use the “weather” tool. Instead of retrieving the weather data itself, the LLM will generate text that represents a tool call, such as call weather_tool(‘Paris’).</p> <p data-svelte-h="svelte-1ym7xfc">The <strong>Agent</strong> then reads this response, identifies that a tool call is required, executes the tool on the LLM’s behalf, and retrieves the actual weather data.</p> <p data-svelte-h="svelte-16cdakx">The Tool-calling steps are typically not shown to the user: the Agent appends them as a new message before passing the updated conversation to the LLM again. The LLM then processes this additional context and generates a natural-sounding response for the user. From the user’s perspective, it appears as if the LLM directly interacted with the tool, but in reality, it was the Agent that handled the entire execution process in the background.</p> <p data-svelte-h="svelte-1gym7on">We’ll talk a lot more about this process in future sessions.</p> <h2 class="relative group"><a id="how-do-we-give-tools-to-an-llm" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#how-do-we-give-tools-to-an-llm"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>How do we give tools to an LLM?</span></h2> <p data-svelte-h="svelte-1m76tol">The complete answer may seem overwhelming, but we essentially use the system prompt to provide textual descriptions of available tools to the model:</p> <img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/Agent_system_prompt.png" alt="System prompt for tools"> <p data-svelte-h="svelte-e466s4">For this to work, we have to be very precise and accurate about:</p> <ol data-svelte-h="svelte-12vrnnv"><li><strong>What the tool does</strong></li> <li><strong>What exact inputs it expects</strong></li></ol> <p data-svelte-h="svelte-1lxlzbg">This is the reason why tool descriptions are usually provided using expressive but precise structures, such as computer languages or JSON. It’s not <em>necessary</em> to do it like that, any precise and coherent format would work.</p> <p data-svelte-h="svelte-1p033lp">If this seems too theoretical, let’s understand it through a concrete example.</p> <p data-svelte-h="svelte-1if40sb">We will implement a simplified <strong>calculator</strong> tool that will just multiply two integers. This could be our Python implementation:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">def</span> <span class="hljs-title function_">calculator</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -> <span class="hljs-built_in">int</span>: | |
| <span class="hljs-string">"""Multiply two integers."""</span> | |
| <span class="hljs-keyword">return</span> a * b<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-somofk">So our tool is called <code>calculator</code>, it <strong>multiplies two integers</strong>, and it requires the following inputs:</p> <ul data-svelte-h="svelte-1qi2vj"><li><strong><code>a</code></strong> (<em>int</em>): An integer.</li> <li><strong><code>b</code></strong> (<em>int</em>): An integer.</li></ul> <p data-svelte-h="svelte-z90coj">The output of the tool is another integer number that we can describe like this:</p> <ul data-svelte-h="svelte-1rd1o27"><li>(<em>int</em>): The product of <code>a</code> and <code>b</code>.</li></ul> <p data-svelte-h="svelte-1gl47rm">All of these details are important. Let’s put them together in a text string that describes our tool for the LLM to understand.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->Tool Name: calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: int<!-- HTML_TAG_END --></pre></div> <blockquote data-svelte-h="svelte-jn5onw"><p><strong>Reminder:</strong> This textual description is <em>what we want the LLM to know about the tool</em>.</p></blockquote> <p data-svelte-h="svelte-dd2uu2">When we pass the previous string as part of the input to the LLM, the model will recognize it as a tool, and will know what it needs to pass as inputs and what to expect from the output.</p> <p data-svelte-h="svelte-1ec16zo">If we want to provide additional tools, we must be consistent and always use the same format. This process can be fragile, and we might accidentally overlook some details.</p> <p data-svelte-h="svelte-xhigt1">Is there a better way?</p> <h3 class="relative group"><a id="auto-formatting-tool-sections" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#auto-formatting-tool-sections"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Auto-formatting Tool sections</span></h3> <p data-svelte-h="svelte-xwh6nk">Our tool was written in Python, and the implementation already provides everything we need:</p> <ul data-svelte-h="svelte-1mufwba"><li>A descriptive name of what it does: <code>calculator</code></li> <li>A longer description, provided by the function’s docstring comment: <code>Multiply two integers.</code></li> <li>The inputs and their type: the function clearly expects two <code>int</code>s.</li> <li>The type of the output.</li></ul> <p data-svelte-h="svelte-6ogn9l">There’s a reason people use programming languages: they are expressive, concise, and precise.</p> <p data-svelte-h="svelte-2908e6">We could provide the Python source code as the <em>specification</em> of the tool for the LLM, but the way the tool is implemented does not matter. All that matters is its name, what it does, the inputs it expects and the output it provides.</p> <p data-svelte-h="svelte-1nshzlk">We will leverage Python’s introspection features to leverage the source code and build a tool description automatically for us. All we need is that the tool implementation uses type hints, docstrings, and sensible function names. We will write some code to extract the relevant portions from the source code.</p> <p data-svelte-h="svelte-1iag2er">After we are done, we’ll only need to use a Python decorator to indicate that the <code>calculator</code> function is a tool:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">@tool</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">calculator</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -> <span class="hljs-built_in">int</span>: | |
| <span class="hljs-string">"""Multiply two integers."""</span> | |
| <span class="hljs-keyword">return</span> a * b | |
| <span class="hljs-built_in">print</span>(calculator.to_string())<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1xfdhk0">Note the <code>@tool</code> decorator before the function definition.</p> <p data-svelte-h="svelte-hj3bkt">With the implementation we’ll see next, we will be able to retrieve the following text automatically from the source code via the <code>to_string()</code> function provided by the decorator:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->Tool Name: calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: int<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-ah55dy">As you can see, it’s the same thing we wrote manually before!</p> <h3 class="relative group"><a id="generic-tool-implementation" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#generic-tool-implementation"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Generic Tool implementation</span></h3> <p data-svelte-h="svelte-1g4lbet">We create a generic <code>Tool</code> class that we can reuse whenever we need to use a tool.</p> <blockquote data-svelte-h="svelte-17jlnyo"><p><strong>Disclaimer:</strong> This example implementation is fictional but closely resembles real implementations in most libraries.</p></blockquote> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> typing <span class="hljs-keyword">import</span> <span class="hljs-type">Callable</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">Tool</span>: | |
| <span class="hljs-string">""" | |
| A class representing a reusable piece of code (Tool). | |
| Attributes: | |
| name (str): Name of the tool. | |
| description (str): A textual description of what the tool does. | |
| func (callable): The function this tool wraps. | |
| arguments (list): A list of arguments. | |
| outputs (str or list): The return type(s) of the wrapped function. | |
| """</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, | |
| name: <span class="hljs-built_in">str</span>, | |
| description: <span class="hljs-built_in">str</span>, | |
| func: <span class="hljs-type">Callable</span>, | |
| arguments: <span class="hljs-built_in">list</span>, | |
| outputs: <span class="hljs-built_in">str</span></span>): | |
| self.name = name | |
| self.description = description | |
| self.func = func | |
| self.arguments = arguments | |
| self.outputs = outputs | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">to_string</span>(<span class="hljs-params">self</span>) -> <span class="hljs-built_in">str</span>: | |
| <span class="hljs-string">""" | |
| Return a string representation of the tool, | |
| including its name, description, arguments, and outputs. | |
| """</span> | |
| args_str = <span class="hljs-string">", "</span>.join([ | |
| <span class="hljs-string">f"<span class="hljs-subst">{arg_name}</span>: <span class="hljs-subst">{arg_type}</span>"</span> <span class="hljs-keyword">for</span> arg_name, arg_type <span class="hljs-keyword">in</span> self.arguments | |
| ]) | |
| <span class="hljs-keyword">return</span> ( | |
| <span class="hljs-string">f"Tool Name: <span class="hljs-subst">{self.name}</span>,"</span> | |
| <span class="hljs-string">f" Description: <span class="hljs-subst">{self.description}</span>,"</span> | |
| <span class="hljs-string">f" Arguments: <span class="hljs-subst">{args_str}</span>,"</span> | |
| <span class="hljs-string">f" Outputs: <span class="hljs-subst">{self.outputs}</span>"</span> | |
| ) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">__call__</span>(<span class="hljs-params">self, *args, **kwargs</span>): | |
| <span class="hljs-string">""" | |
| Invoke the underlying function (callable) with provided arguments. | |
| """</span> | |
| <span class="hljs-keyword">return</span> self.func(*args, **kwargs)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1m24zfs">It may seem complicated, but if we go slowly through it we can see what it does. We define a <strong><code>Tool</code></strong> class that includes:</p> <ul data-svelte-h="svelte-1aoag7f"><li><strong><code>name</code></strong> (<em>str</em>): The name of the tool.</li> <li><strong><code>description</code></strong> (<em>str</em>): A brief description of what the tool does.</li> <li><strong><code>function</code></strong> (<em>callable</em>): The function the tool executes.</li> <li><strong><code>arguments</code></strong> (<em>list</em>): The expected input parameters.</li> <li><strong><code>outputs</code></strong> (<em>str</em> or <em>list</em>): The expected outputs of the tool.</li> <li><strong><code>__call__()</code></strong>: Calls the function when the tool instance is invoked.</li> <li><strong><code>to_string()</code></strong>: Converts the tool’s attributes into a textual representation.</li></ul> <p data-svelte-h="svelte-9jg0w0">We could create a Tool with this class using code like the following:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->calculator_tool = Tool( | |
| <span class="hljs-string">"calculator"</span>, <span class="hljs-comment"># name</span> | |
| <span class="hljs-string">"Multiply two integers."</span>, <span class="hljs-comment"># description</span> | |
| calculator, <span class="hljs-comment"># function to call</span> | |
| [(<span class="hljs-string">"a"</span>, <span class="hljs-string">"int"</span>), (<span class="hljs-string">"b"</span>, <span class="hljs-string">"int"</span>)], <span class="hljs-comment"># inputs (names and types)</span> | |
| <span class="hljs-string">"int"</span>, <span class="hljs-comment"># output</span> | |
| )<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-imjo5d">But we can also use Python’s <code>inspect</code> module to retrieve all the information for us! This is what the <code>@tool</code> decorator does.</p> <blockquote data-svelte-h="svelte-5gslq7"><p>If you are interested, you can disclose the following section to look at the decorator implementation.</p></blockquote> <details><summary data-svelte-h="svelte-14wmf42">decorator code</summary> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> inspect | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">tool</span>(<span class="hljs-params">func</span>): | |
| <span class="hljs-string">""" | |
| A decorator that creates a Tool instance from the given function. | |
| """</span> | |
| <span class="hljs-comment"># Get the function signature</span> | |
| signature = inspect.signature(func) | |
| <span class="hljs-comment"># Extract (param_name, param_annotation) pairs for inputs</span> | |
| arguments = [] | |
| <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> signature.parameters.values(): | |
| annotation_name = ( | |
| param.annotation.__name__ | |
| <span class="hljs-keyword">if</span> <span class="hljs-built_in">hasattr</span>(param.annotation, <span class="hljs-string">'__name__'</span>) | |
| <span class="hljs-keyword">else</span> <span class="hljs-built_in">str</span>(param.annotation) | |
| ) | |
| arguments.append((param.name, annotation_name)) | |
| <span class="hljs-comment"># Determine the return annotation</span> | |
| return_annotation = signature.return_annotation | |
| <span class="hljs-keyword">if</span> return_annotation <span class="hljs-keyword">is</span> inspect._empty: | |
| outputs = <span class="hljs-string">"No return annotation"</span> | |
| <span class="hljs-keyword">else</span>: | |
| outputs = ( | |
| return_annotation.__name__ | |
| <span class="hljs-keyword">if</span> <span class="hljs-built_in">hasattr</span>(return_annotation, <span class="hljs-string">'__name__'</span>) | |
| <span class="hljs-keyword">else</span> <span class="hljs-built_in">str</span>(return_annotation) | |
| ) | |
| <span class="hljs-comment"># Use the function's docstring as the description (default if None)</span> | |
| description = func.__doc__ <span class="hljs-keyword">or</span> <span class="hljs-string">"No description provided."</span> | |
| <span class="hljs-comment"># The function name becomes the Tool name</span> | |
| name = func.__name__ | |
| <span class="hljs-comment"># Return a new Tool instance</span> | |
| <span class="hljs-keyword">return</span> Tool( | |
| name=name, | |
| description=description, | |
| func=func, | |
| arguments=arguments, | |
| outputs=outputs | |
| )<!-- HTML_TAG_END --></pre></div></details> <p data-svelte-h="svelte-1pxgdsn">Just to reiterate, with this decorator in place we can implement our tool like this:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">@tool</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">calculator</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -> <span class="hljs-built_in">int</span>: | |
| <span class="hljs-string">"""Multiply two integers."""</span> | |
| <span class="hljs-keyword">return</span> a * b | |
| <span class="hljs-built_in">print</span>(calculator.to_string())<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-oh725x">And we can use the <code>Tool</code>’s <code>to_string</code> method to automatically retrieve a text suitable to be used as a tool description for an LLM:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->Tool Name: calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: int<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1gsasw4">The description is <strong>injected</strong> in the system prompt. Taking the example with which we started this section, here is how it would look like after replacing the <code>tools_description</code>:</p> <img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/Agent_system_prompt_tools.png" alt="System prompt for tools"> <p data-svelte-h="svelte-14h2jbz">In the <a href="actions">Actions</a> section, we will learn more about how an Agent can <strong>Call</strong> this tool we just created.</p> <h3 class="relative group"><a id="model-context-protocol-mcp-a-unified-tool-interface" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#model-context-protocol-mcp-a-unified-tool-interface"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Model Context Protocol (MCP): a unified tool interface</span></h3> <p data-svelte-h="svelte-123mz07">Model Context Protocol (MCP) is an <strong>open protocol</strong> that standardizes how applications <strong>provide tools to LLMs</strong>. | |
| MCP provides:</p> <ul data-svelte-h="svelte-jdb0o1"><li>A growing list of pre-built integrations that your LLM can directly plug into</li> <li>The flexibility to switch between LLM providers and vendors</li> <li>Best practices for securing your data within your infrastructure</li></ul> <p data-svelte-h="svelte-v0j64b">This means that <strong>any framework implementing MCP can leverage tools defined within the protocol</strong>, eliminating the need to reimplement the same tool interface for each framework.</p> <p data-svelte-h="svelte-ki6njs">If you want to dive deeper about MCP, you can check our <a href="https://huggingface.co/learn/mcp-course/" rel="nofollow">free MCP Course</a>.</p> <hr> <p data-svelte-h="svelte-yaz9vn">Tools play a crucial role in enhancing the capabilities of AI agents.</p> <p data-svelte-h="svelte-1mncb1b">To summarize, we learned:</p> <ul data-svelte-h="svelte-1lbaznq"><li><p><em>What Tools Are</em>: Functions that give LLMs extra capabilities, such as performing calculations or accessing external data.</p></li> <li><p><em>How to Define a Tool</em>: By providing a clear textual description, inputs, outputs, and a callable function.</p></li> <li><p><em>Why Tools Are Essential</em>: They enable Agents to overcome the limitations of static model training, handle real-time tasks, and perform specialized actions.</p></li></ul> <p data-svelte-h="svelte-16mxhlc">Now, we can move on to the <a href="agent-steps-and-structure">Agent Workflow</a> where you’ll see how an Agent observes, thinks, and acts. This <strong>brings together everything we’ve covered so far</strong> and sets the stage for creating your own fully functional AI Agent.</p> <p data-svelte-h="svelte-1w2njod">But first, it’s time for another short quiz!</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/agents-course/blob/main/units/en/unit1/tools.mdx" target="_blank"><span data-svelte-h="svelte-1kd6by1"><</span> <span data-svelte-h="svelte-x0xyl0">></span> <span data-svelte-h="svelte-1dajgef"><span class="underline ml-1.5">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_17hovx6 = { | |
| assets: "/docs/agents-course/pr_545/en", | |
| base: "/docs/agents-course/pr_545/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/agents-course/pr_545/en/_app/immutable/entry/start.1596c81c.js"), | |
| import("/docs/agents-course/pr_545/en/_app/immutable/entry/app.856a784e.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 32], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 44.9 kB
- Xet hash:
- b0eb750feaf7b828f67a0fece0d456f9527c8459786cf18269aa38952f431c5a
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.