Sesión 4 · Tool Use

Crea la herramienta findCourses

Define el catálogo didáctico, valida las entradas con Zod y devuelve coincidencias por título y nivel.

30 min aprox.5 pasosPráctica + comprobación
Qué aprenderás
  • Separar descripción, esquema de entrada y ejecución de una herramienta.
  • Permitir filtros opcionales de texto y nivel.
  • Devolver datos del catálogo y un recuento sin inventar resultados.

Referencias de código

Índice de esta lección

Paso 1

Toma el catálogo del gist

El gist de Klerith aporta cinco cursos con ID, título, horas, precio, nivel y alumnos. Trata estos datos como una base local del ejercicio.

Las búsquedas de TypeScript tienen dos coincidencias: TypeScript desde cero y Agentes de IA con TypeScript. No elijas una automáticamente si la petición es ambigua.

La versión adaptada separa el catálogo en catalog.ts y las herramientas en tools.ts. Mantiene el patrón del material y permite probar las reglas sin llamar a un modelo.

src/patterns/01-tool-use/catalog.ts
Paso 1 · typescript
// Catálogo didáctico adaptado del gist de Klerith (Fernando Herrera).// https://gist.github.com/Klerith/1f32130c61219bbe7be68e72d0626c40// Estos valores son datos del ejercicio, no precios comerciales actuales.export type Course = {  id: string;  title: string;  hours: number;  priceUSD: number;  level: "basic" | "intermediate" | "advanced";  students: number;}; export const COURSE_CATALOG: Course[] = [  { id: "ts-01", title: "TypeScript desde cero", hours: 22, priceUSD: 19.99, level: "basic", students: 48_120 },  { id: "nest-02", title: "NestJS: API REST modular", hours: 31, priceUSD: 24.99, level: "intermediate", students: 22_450 },  { id: "flu-03", title: "Flutter: apps multiplataforma", hours: 46, priceUSD: 29.99, level: "intermediate", students: 61_300 },  { id: "agt-04", title: "Agentes de IA con TypeScript", hours: 18, priceUSD: 34.99, level: "advanced", students: 1_890 },  { id: "dkr-05", title: "Docker para desarrolladores", hours: 14, priceUSD: 17.99, level: "basic", students: 35_770 },];

Qué deberías observar

El catálogo contiene IDs y datos explícitos que podrán devolver las herramientas.

Paso 2

Define filtros que se pueden omitir

text y level son opcionales. La transcripción primero deja level obligatorio y lo corrige después; aquí incorporamos la corrección desde el inicio.

Zod describe la forma válida de los argumentos. Las descripciones ayudan a seleccionar entradas, pero no garantizan que el modelo escoja el curso correcto.

src/patterns/01-tool-use/tools.ts
Paso 2 · typescript
import { tool } from "ai";import { z } from "zod";import { COURSE_CATALOG } from "./catalog.js"; export const searchSchema = z.object({  text: z.string().optional().describe("Texto incluido en el título del curso"),  level: z.enum(["basic", "intermediate", "advanced"]).optional()    .describe("Nivel del curso; omitir para buscar en todos los niveles"),});

Qué deberías observar

Una búsqueda por texto no exige inventar un nivel.

Paso 4

Envuelve la función con tool

tool recibe una descripción, inputSchema y execute. El modelo propone argumentos y la aplicación ejecuta la operación con datos del catálogo.

La función devuelve un objeto con found y courses. Una ejecución asíncrona permite sustituir la búsqueda local por una consulta externa después; una función puramente síncrona también es válida.

src/patterns/01-tool-use/tools.ts
Paso 4 · typescript
export const findCourses = tool({  description: "Busca cursos por texto en el título y/o nivel. Consulta esta herramienta antes de responder sobre cursos, precios, horas o alumnos.",  inputSchema: searchSchema,  execute: async (input) => findCoursesData(input),});

Qué deberías observar

La herramienta está definida, pero solo estará disponible al registrarla en tools.

Paso 5

Comprueba las reglas sin gastar tokens

Antes de integrar el modelo, llama a la función local. Estas pruebas no requieren claves ni una API.

Para TypeScript sin nivel hay dos coincidencias; con basic hay ts-01. Una búsqueda ausente devuelve found: 0 y courses: []. Un nivel fuera de la enumeración falla en la validación.

Pruebas locales de tools.ts
Paso 5 · typescript
findCoursesData({ text: " TYPESCRIPT " }); // found: 2findCoursesData({ text: "TypeScript", level: "basic" }); // ts-01findCoursesData({ text: "no-existe" }); // found: 0findCoursesData({}); // los cinco cursos

Qué deberías observar

Puedes separar errores de la función de errores de integración con el proveedor.

Ahora te toca

Prueba la idea por tu cuenta

Busca TypeScript sin filtro de nivel y después con basic. Explica por qué aparecen dos resultados en la primera búsqueda y cómo tratarías esa ambigüedad antes de cotizar.

Necesito una pista

Examina los títulos del catálogo; dos incluyen la palabra TypeScript.

Comparar con una solución

Sin level aparecen ts-01 y agt-04. Con basic solo ts-01. Si el usuario no ha precisado el curso, pide una aclaración o el ID antes de calcular.

Antes de seguir

Comprueba lo que aprendiste

No es una nota. Es una pausa para comprobar que la idea quedó clara.

1. ¿Por qué level es opcional?
2. Si llegan text y level, ¿qué se exige?
3. ¿Qué devuelve una búsqueda sin coincidencias?

¿Terminaste la práctica?

Haz el ejercicio y comprueba tus respuestas antes de marcar la lección como completada.

Apuntes y código de esta lección