Buckets:

rtrm's picture
download
raw
44.4 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;¿Qué son las Herramientas?&quot;,&quot;local&quot;:&quot;qué-son-las-herramientas&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;¿Qué son las Herramientas de IA?&quot;,&quot;local&quot;:&quot;qué-son-las-herramientas-de-ia&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;¿Cómo funcionan las herramientas?&quot;,&quot;local&quot;:&quot;cómo-funcionan-las-herramientas&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;¿Cómo proporcionamos herramientas a un LLM?&quot;,&quot;local&quot;:&quot;cómo-proporcionamos-herramientas-a-un-llm&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Auto-formateo de secciones de Herramientas&quot;,&quot;local&quot;:&quot;auto-formateo-de-secciones-de-herramientas&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Implementación genérica de Herramienta&quot;,&quot;local&quot;:&quot;implementación-genérica-de-herramienta&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2}],&quot;depth&quot;:1}">
<link href="/docs/agents-course/pr_545/es/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/entry/start.63ebcd5b.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/scheduler.37c15a92.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/singletons.4b25defb.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/index.18351ede.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/paths.6deaf1b7.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/entry/app.b37467ae.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/index.2bf4358c.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/nodes/0.147ec314.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/each.e59479a4.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/nodes/32.f4bb2f10.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/CodeBlock.4e987730.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/Heading.8ada512a.js">
<link rel="modulepreload" href="/docs/agents-course/pr_545/es/_app/immutable/chunks/getInferenceSnippets.031140c2.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;¿Qué son las Herramientas?&quot;,&quot;local&quot;:&quot;qué-son-las-herramientas&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;¿Qué son las Herramientas de IA?&quot;,&quot;local&quot;:&quot;qué-son-las-herramientas-de-ia&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;¿Cómo funcionan las herramientas?&quot;,&quot;local&quot;:&quot;cómo-funcionan-las-herramientas&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;¿Cómo proporcionamos herramientas a un LLM?&quot;,&quot;local&quot;:&quot;cómo-proporcionamos-herramientas-a-un-llm&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Auto-formateo de secciones de Herramientas&quot;,&quot;local&quot;:&quot;auto-formateo-de-secciones-de-herramientas&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Implementación genérica de Herramienta&quot;,&quot;local&quot;:&quot;implementación-genérica-de-herramienta&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <h1 class="relative group"><a id="qué-son-las-herramientas" 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="#qué-son-las-herramientas"><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>¿Qué son las Herramientas?</span></h1> <img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/whiteboard-check-2.jpg" alt="Planificación de la Unidad 1"> <p data-svelte-h="svelte-11v5lbd">Un aspecto crucial de los Agentes de IA es su capacidad para realizar <strong>acciones</strong>. Como vimos, esto sucede a través del uso de <strong>Herramientas</strong>.</p> <p data-svelte-h="svelte-yzryio">En esta sección, aprenderemos qué son las Herramientas, cómo diseñarlas de manera efectiva y cómo integrarlas en tu Agente a través del Mensaje del Sistema.</p> <p data-svelte-h="svelte-ldqc23">Al proporcionar a tu Agente las Herramientas adecuadas —y describir claramente cómo funcionan esas Herramientas— puedes aumentar dramáticamente lo que tu IA puede lograr. ¡Vamos a profundizar!</p> <h2 class="relative group"><a id="qué-son-las-herramientas-de-ia" 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="#qué-son-las-herramientas-de-ia"><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>¿Qué son las Herramientas de IA?</span></h2> <p data-svelte-h="svelte-3spete">Una <strong>Herramienta es una función proporcionada al LLM</strong>. Esta función debe cumplir un <strong>objetivo claro</strong>.</p> <p data-svelte-h="svelte-19u4e87">Aquí hay algunas herramientas comúnmente utilizadas en agentes de IA:</p> <table data-svelte-h="svelte-x2anqg"><thead><tr><th>Herramienta</th> <th>Descripción</th></tr></thead> <tbody><tr><td>Búsqueda Web</td> <td>Permite al agente obtener información actualizada de internet.</td></tr> <tr><td>Generación de Imágenes</td> <td>Crea imágenes basadas en descripciones textuales.</td></tr> <tr><td>Recuperación</td> <td>Recupera información de una fuente externa.</td></tr> <tr><td>Interfaz de API</td> <td>Interactúa con una API externa (GitHub, YouTube, Spotify, etc.).</td></tr></tbody></table> <p data-svelte-h="svelte-1rhr6un">¡Esos son solo ejemplos, ya que de hecho puedes crear una herramienta para cualquier caso de uso!</p> <p data-svelte-h="svelte-1f5lua9">Una buena herramienta debería ser algo que <strong>complemente el poder de un LLM</strong>.</p> <p data-svelte-h="svelte-axh2sd">Por ejemplo, si necesitas realizar operaciones aritméticas, proporcionar una <strong>herramienta de calculadora</strong> a tu LLM proporcionará mejores resultados que confiar en las capacidades nativas del modelo.</p> <p data-svelte-h="svelte-uajc2b">Además, <strong>los LLMs predicen la finalización de un prompt basándose en sus datos de entrenamiento</strong>, lo que significa que su conocimiento interno solo incluye eventos anteriores a su entrenamiento. Por lo tanto, si tu agente necesita datos actualizados, debes proporcionarlos a través de alguna herramienta.</p> <p data-svelte-h="svelte-qgie3k">Por ejemplo, si le preguntas directamente a un LLM (sin una herramienta de búsqueda) sobre el clima de hoy, el LLM potencialmente alucinará un clima aleatorio.</p> <img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/weather.jpg" alt="Clima"> <ul data-svelte-h="svelte-nvr74z"><li><p>Una Herramienta debe contener:</p> <ul><li>Una <strong>descripción textual de lo que hace la función</strong>.</li> <li>Un <em>Callable</em> (algo para realizar una acción).</li> <li><em>Argumentos</em> con tipos.</li> <li>(Opcional) Salidas con tipos.</li></ul></li></ul> <h2 class="relative group"><a id="cómo-funcionan-las-herramientas" 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="#cómo-funcionan-las-herramientas"><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>¿Cómo funcionan las herramientas?</span></h2> <p data-svelte-h="svelte-1vf9x86">Los LLMs, como vimos, solo pueden recibir entradas de texto y generar salidas de texto. No tienen forma de llamar a herramientas por sí mismos. Lo que queremos decir cuando hablamos de <em>proporcionar herramientas a un Agente</em>, es que <strong>enseñamos</strong> al LLM sobre la existencia de herramientas, y pedimos al modelo que genere texto que invocará herramientas cuando las necesite. Por ejemplo, si proporcionamos una herramienta para verificar el clima en una ubicación desde Internet, y luego preguntamos al LLM sobre el clima en París, el LLM reconocerá esa pregunta como una oportunidad relevante para usar la herramienta “clima” que le enseñamos. El LLM generará <em>texto</em>, en forma de código, para invocar esa herramienta. Es responsabilidad del <strong>Agente</strong> analizar la salida del LLM, reconocer que se requiere una llamada a una herramienta e invocar la herramienta en nombre del LLM. La salida de la herramienta luego se enviará de vuelta al LLM, que compondrá su respuesta final para el usuario.</p> <p data-svelte-h="svelte-1jfsjsz">La salida de una llamada a una herramienta es otro tipo de mensaje en la conversación. Los pasos de llamada a herramientas típicamente no se muestran al usuario: el Agente recupera la conversación, llama a la(s) herramienta(s), obtiene las salidas, las agrega como un nuevo mensaje de conversación y envía la conversación actualizada al LLM nuevamente. Desde el punto de vista del usuario, es como si el LLM hubiera usado la herramienta, pero de hecho fue nuestro código de aplicación (el <strong>Agente</strong>) quien lo hizo.</p> <p data-svelte-h="svelte-w3s9nu">Hablaremos mucho más sobre este proceso en sesiones futuras.</p> <h2 class="relative group"><a id="cómo-proporcionamos-herramientas-a-un-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="#cómo-proporcionamos-herramientas-a-un-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>¿Cómo proporcionamos herramientas a un LLM?</span></h2> <p data-svelte-h="svelte-1iuucst">La respuesta completa puede parecer abrumadora, pero esencialmente usamos el prompt del sistema para proporcionar descripciones textuales de las herramientas disponibles al modelo:</p> <img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/Agent_system_prompt.png" alt="Prompt del sistema para herramientas"> <p data-svelte-h="svelte-1auxopn">Para que esto funcione, tenemos que ser muy precisos y exactos sobre:</p> <ol data-svelte-h="svelte-nxsu3i"><li><strong>Lo que hace la herramienta</strong></li> <li><strong>Qué entradas exactas espera</strong></li></ol> <p data-svelte-h="svelte-14ua9gl">Esta es la razón por la que las descripciones de herramientas generalmente se proporcionan utilizando estructuras expresivas pero precisas, como lenguajes de computadora o JSON. No es <em>necesario</em> hacerlo así, cualquier formato preciso y coherente funcionaría.</p> <p data-svelte-h="svelte-1ruj9h1">Si esto parece demasiado teórico, vamos a entenderlo a través de un ejemplo concreto.</p> <p data-svelte-h="svelte-50x2n7">Implementaremos una herramienta <strong>calculadora</strong> simplificada que solo multiplicará dos enteros. Esta podría ser nuestra implementación en Python:</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_">calculadora</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:
<span class="hljs-string">&quot;&quot;&quot;Multiplica dos enteros.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> a * b<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1t933sx">Así que nuestra herramienta se llama <code>calculadora</code>, <strong>multiplica dos enteros</strong>, y requiere las siguientes entradas:</p> <ul data-svelte-h="svelte-1hgz7n1"><li><strong><code>a</code></strong> (<em>int</em>): Un entero.</li> <li><strong><code>b</code></strong> (<em>int</em>): Un entero.</li></ul> <p data-svelte-h="svelte-1p1ymq5">La salida de la herramienta es otro número entero que podemos describir así:</p> <ul data-svelte-h="svelte-x64alw"><li>(<em>int</em>): El producto de <code>a</code> y <code>b</code>.</li></ul> <p data-svelte-h="svelte-ogtujw">Todos estos detalles son importantes. Vamos a juntarlos en una cadena de texto que describe nuestra herramienta para que el LLM la entienda.</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 -->Nombre de Herramienta: calculadora, Descripción: Multiplica dos enteros., Argumentos: a: int, b: int, Salidas: int<!-- HTML_TAG_END --></pre></div> <blockquote data-svelte-h="svelte-jgxyv0"><p><strong>Recordatorio:</strong> Esta descripción textual es <em>lo que queremos que el LLM sepa sobre la herramienta</em>.</p></blockquote> <p data-svelte-h="svelte-1simtbd">Cuando pasamos la cadena anterior como parte de la entrada al LLM, el modelo la reconocerá como una herramienta, y sabrá qué necesita pasar como entradas y qué esperar de la salida.</p> <p data-svelte-h="svelte-1f18wsz">Si queremos proporcionar herramientas adicionales, debemos ser consistentes y siempre usar el mismo formato. Este proceso puede ser frágil, y podríamos pasar por alto accidentalmente algunos detalles.</p> <p data-svelte-h="svelte-1aeb213">¿Hay una mejor manera?</p> <h3 class="relative group"><a id="auto-formateo-de-secciones-de-herramientas" 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-formateo-de-secciones-de-herramientas"><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-formateo de secciones de Herramientas</span></h3> <p data-svelte-h="svelte-umx0z8">Nuestra herramienta fue escrita en Python, y la implementación ya proporciona todo lo que necesitamos:</p> <ul data-svelte-h="svelte-4mn1a5"><li>Un nombre descriptivo de lo que hace: <code>calculadora</code></li> <li>Una descripción más larga, proporcionada por el comentario docstring de la función: <code>Multiplica dos enteros.</code></li> <li>Las entradas y su tipo: la función claramente espera dos <code>int</code>s.</li> <li>El tipo de la salida.</li></ul> <p data-svelte-h="svelte-1vcqfuv">Hay una razón por la que la gente usa lenguajes de programación: son expresivos, concisos y precisos.</p> <p data-svelte-h="svelte-14fd26j">Podríamos proporcionar el código fuente de Python como la <em>especificación</em> de la herramienta para el LLM, pero la forma en que se implementa la herramienta no importa. Todo lo que importa es su nombre, lo que hace, las entradas que espera y la salida que proporciona.</p> <p data-svelte-h="svelte-d1jwkz">Aprovecharemos las características de introspección de Python para aprovechar el código fuente y construir una descripción de herramienta automáticamente para nosotros. Todo lo que necesitamos es que la implementación de la herramienta use sugerencias de tipo, docstrings y nombres de función sensatos. Escribiremos algo de código para extraer las partes relevantes del código fuente.</p> <p data-svelte-h="svelte-12rpj5d">Después de terminar, solo necesitaremos usar un decorador de Python para indicar que la función <code>calculadora</code> es una herramienta:</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_">calculadora</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:
<span class="hljs-string">&quot;&quot;&quot;Multiplica dos enteros.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> a * b
<span class="hljs-built_in">print</span>(calculadora.to_string())<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-sc3whw">Nota el decorador <code>@tool</code> antes de la definición de la función.</p> <p data-svelte-h="svelte-zq1sjc">Con la implementación que veremos a continuación, podremos recuperar el siguiente texto automáticamente del código fuente a través de la función <code>to_string()</code> proporcionada por el decorador:</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 -->Nombre de Herramienta: calculadora, Descripción: Multiplica dos enteros., Argumentos: a: int, b: int, Salidas: int<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1nnyzya">Como puedes ver, ¡es lo mismo que escribimos manualmente antes!</p> <h3 class="relative group"><a id="implementación-genérica-de-herramienta" 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="#implementación-genérica-de-herramienta"><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>Implementación genérica de Herramienta</span></h3> <p data-svelte-h="svelte-1ggdx7a">Creamos una clase genérica <code>Tool</code> que podemos reutilizar siempre que necesitemos usar una herramienta.</p> <blockquote data-svelte-h="svelte-zpb818"><p><strong>Descargo de responsabilidad:</strong> Esta implementación de ejemplo es ficticia pero se parece mucho a implementaciones reales en la mayoría de las bibliotecas.</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">class</span> <span class="hljs-title class_">Tool</span>:
<span class="hljs-string">&quot;&quot;&quot;
Una clase que representa un fragmento de código reutilizable (Herramienta).
Atributos:
name (str): Nombre de la herramienta.
description (str): Una descripción textual de lo que hace la herramienta.
func (callable): La función que esta herramienta envuelve.
arguments (list): Una lista de argumentos.
outputs (str or list): El tipo(s) de retorno de la función envuelta.
&quot;&quot;&quot;</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-built_in">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>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;
Devuelve una representación en cadena de la herramienta,
incluyendo su nombre, descripción, argumentos y salidas.
&quot;&quot;&quot;</span>
args_str = <span class="hljs-string">&quot;, &quot;</span>.join([
<span class="hljs-string">f&quot;<span class="hljs-subst">{arg_name}</span>: <span class="hljs-subst">{arg_type}</span>&quot;</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&quot;Nombre de Herramienta: <span class="hljs-subst">{self.name}</span>,&quot;</span>
<span class="hljs-string">f&quot; Descripción: <span class="hljs-subst">{self.description}</span>,&quot;</span>
<span class="hljs-string">f&quot; Argumentos: <span class="hljs-subst">{args_str}</span>,&quot;</span>
<span class="hljs-string">f&quot; Salidas: <span class="hljs-subst">{self.outputs}</span>&quot;</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">&quot;&quot;&quot;
Invoca la función subyacente (callable) con los argumentos proporcionados.
&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> self.func(*args, **kwargs)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1pqprji">Puede parecer complicado, pero si lo recorremos lentamente podemos ver lo que hace. Definimos una clase <strong><code>Tool</code></strong> que incluye:</p> <ul data-svelte-h="svelte-ndkw87"><li><strong><code>name</code></strong> (<em>str</em>): El nombre de la herramienta.</li> <li><strong><code>description</code></strong> (<em>str</em>): Una breve descripción de lo que hace la herramienta.</li> <li><strong><code>function</code></strong> (<em>callable</em>): La función que ejecuta la herramienta.</li> <li><strong><code>arguments</code></strong> (<em>list</em>): Los parámetros de entrada esperados.</li> <li><strong><code>outputs</code></strong> (<em>str</em> o <em>list</em>): Las salidas esperadas de la herramienta.</li> <li><strong><code>__call__()</code></strong>: Llama a la función cuando se invoca la instancia de la herramienta.</li> <li><strong><code>to_string()</code></strong>: Convierte los atributos de la herramienta en una representación textual.</li></ul> <p data-svelte-h="svelte-1342fh5">Podríamos crear una Herramienta con esta clase usando código como el siguiente:</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 -->calculadora_tool = Tool(
<span class="hljs-string">&quot;calculadora&quot;</span>, <span class="hljs-comment"># nombre</span>
<span class="hljs-string">&quot;Multiplica dos enteros.&quot;</span>, <span class="hljs-comment"># descripción</span>
calculadora, <span class="hljs-comment"># función a llamar</span>
[(<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;int&quot;</span>), (<span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;int&quot;</span>)], <span class="hljs-comment"># entradas (nombres y tipos)</span>
<span class="hljs-string">&quot;int&quot;</span>, <span class="hljs-comment"># salida</span>
)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-n2m443">¡Pero también podemos usar el módulo <code>inspect</code> de Python para recuperar toda la información por nosotros! Esto es lo que hace el decorador <code>@tool</code>.</p> <blockquote data-svelte-h="svelte-uzxbeb"><p>Si estás interesado, puedes revelar la siguiente sección para ver la implementación del decorador.</p></blockquote> <details><summary data-svelte-h="svelte-1u34veb">código del decorador</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">def</span> <span class="hljs-title function_">tool</span>(<span class="hljs-params">func</span>):
<span class="hljs-string">&quot;&quot;&quot;
Un decorador que crea una instancia de Tool a partir de la función dada.
&quot;&quot;&quot;</span>
<span class="hljs-comment"># Obtener la firma de la función</span>
signature = inspect.signature(func)
<span class="hljs-comment"># Extraer pares (param_name, param_annotation) para entradas</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">&#x27;__name__&#x27;</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"># Determinar la anotación de retorno</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">&quot;Sin anotación de retorno&quot;</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">&#x27;__name__&#x27;</span>)
<span class="hljs-keyword">else</span> <span class="hljs-built_in">str</span>(return_annotation)
)
<span class="hljs-comment"># Usar el docstring de la función como descripción (por defecto si es None)</span>
description = func.__doc__ <span class="hljs-keyword">or</span> <span class="hljs-string">&quot;No se proporcionó descripción.&quot;</span>
<span class="hljs-comment"># El nombre de la función se convierte en el nombre de la Herramienta</span>
name = func.__name__
<span class="hljs-comment"># Devolver una nueva instancia de Tool</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-i0tl7x">Solo para reiterar, con este decorador en su lugar podemos implementar nuestra herramienta así:</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_">calculadora</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:
<span class="hljs-string">&quot;&quot;&quot;Multiplica dos enteros.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> a * b
<span class="hljs-built_in">print</span>(calculadora.to_string())<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-ovqblh">Y podemos usar el método <code>to_string</code> de la <code>Tool</code> para recuperar automáticamente un texto adecuado para ser utilizado como descripción de herramienta para un 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 -->Nombre de Herramienta: calculadora, Descripción: Multiplica dos enteros., Argumentos: a: int, b: int, Salidas: int<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-gdec90">La descripción se <strong>inyecta</strong> en el prompt del sistema. Tomando el ejemplo con el que comenzamos esta sección, así es como se vería después de reemplazar el <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="Prompt del sistema para herramientas"> <p data-svelte-h="svelte-1n9jyyn">En la sección <a href="actions.mdx">Acciones</a>, aprenderemos más sobre cómo un Agente puede <strong>Llamar</strong> a esta herramienta que acabamos de crear.</p> <hr> <p data-svelte-h="svelte-1ezmtbd">Las herramientas juegan un papel crucial en la mejora de las capacidades de los agentes de IA.</p> <p data-svelte-h="svelte-2xuet7">Para resumir, aprendimos:</p> <ul data-svelte-h="svelte-1m3sl14"><li><p><em>Qué son las Herramientas</em>: Funciones que dan a los LLMs capacidades adicionales, como realizar cálculos o acceder a datos externos.</p></li> <li><p><em>Cómo Definir una Herramienta</em>: Proporcionando una descripción textual clara, entradas, salidas y una función invocable.</p></li> <li><p><em>Por qué las Herramientas son Esenciales</em>: Permiten a los Agentes superar las limitaciones del entrenamiento estático del modelo, manejar tareas en tiempo real y realizar acciones especializadas.</p></li></ul> <p data-svelte-h="svelte-1rb6wl2">Ahora, podemos pasar al <a href="agent-steps-and-structure.mdx">Flujo de Trabajo del Agente</a> donde verás cómo un Agente observa, piensa y actúa. Esto <strong>reúne todo lo que hemos cubierto hasta ahora</strong> y prepara el escenario para crear tu propio Agente de IA completamente funcional.</p> <p data-svelte-h="svelte-1u8pkw1">Pero primero, ¡es hora de otro cuestionario corto!</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/es/unit1/tools.mdx" target="_blank"><span data-svelte-h="svelte-1kd6by1">&lt;</span> <span data-svelte-h="svelte-x0xyl0">&gt;</span> <span data-svelte-h="svelte-1dajgef"><span class="underline ml-1.5">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_1k0olmh = {
assets: "/docs/agents-course/pr_545/es",
base: "/docs/agents-course/pr_545/es",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/agents-course/pr_545/es/_app/immutable/entry/start.63ebcd5b.js"),
import("/docs/agents-course/pr_545/es/_app/immutable/entry/app.b37467ae.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 32],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
44.4 kB
·
Xet hash:
ca7f12f4eeed6de14afa63c90ed832089e0dcb418a3a3fa70b70fb5b71563ec1

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.