Curso exprés · No. 27
Un modelo de lenguaje en bruto devuelve free text — precioso para que lo lea un humano, inútil para que tu código se apoye en él. Para construir software real sobre un modelo necesitas dos cosas: una salida en la que tu programa pueda de verdad confiar (structured output), y una forma segura de que el modelo vaya más allá del texto y actúe (tool use). Juntas convierten un chatbot en un componente fiable dentro de tu sistema.
Solo lo esencial · Una imagen por idea · Ingeniería sobre magia
El primer paso para construir sobre un modelo es reconocer el desajuste: él habla en prosa, pero tu programa necesita datos y acciones. Salvar esa brecha es de lo que trata todo este curso.
La prosa es para humanos; el código necesita datos
Un párrafo escrito a mano que describe un pedido frente a un formulario rellenado con casillas etiquetadas — una persona lee el párrafo con facilidad, pero solo el formulario puede archivarlo una máquina.
Por defecto un modelo de lenguaje produce free text — un párrafo, una explicación, prosa. Eso es perfecto para un lector humano e inútil para tu código, que necesita valores predecibles y estructurados sobre los que actuar: un número aquí, una categoría allá, un sí o un no. Un programa no puede extraer de forma fiable «el cliente quiere un reembolso de 40 $» de una frase que el modelo redactó como le dio la gana. La prosa y los datos son cosas distintas, y el código funciona con datos.
Parsear prosa es frágil y se rompe
Intentar extraer el total de una carta que podría decir «40 $», «cuarenta dólares» o «un reembolso de 40 pavos» — tus reglas funcionan hasta el día en que cambia la redacción, y entonces todo se viene abajo.
El arreglo ingenuo — hacer que el modelo escriba texto y luego parsearlo con tu propio código — es quebradizo. El modelo es no determinista; expresará lo mismo de diez maneras distintas, añadirá un preámbulo amable o envolverá la respuesta en markdown. Tu parser maneja los casos que viste y se hace añicos con el que no. Construir sobre el parseo de cadenas de la prosa del modelo es construir sobre arena: funciona en la demo y falla en producción.
El objetivo: hacer del modelo una pieza fiable
Un motor solo le resulta útil a un coche cuando tiene anclajes y conectores estándar — interfaces predecibles a las que el resto de la máquina puede atornillarse con confianza.
Para construir software sobre un modelo, tienes que convertirlo de un oráculo parlanchín en un componente con interfaces predecibles — una salida en la que tu código pueda confiar y acciones que pueda tomar de forma segura. Eso es exactamente lo que son las dos mitades de este curso: structured output (datos, no prosa) y tool use (actuar, no solo hablar). Logra eso y el modelo deja de ser una demo y se convierte en una pieza fiable a la que puedes hacer ingeniería como a cualquier otra.
Un modelo habla en prosa; tu código necesita datos y acciones. Parsear free text es frágil — el objetivo es hacer del modelo un componente fiable, con una salida en la que confíes y acciones que pueda tomar.
La primera mitad de hacer del modelo un componente es conseguir que devuelva datos con la forma que define tu código, cada vez — no prosa que tengas que adivinar, sino una estructura predecible.
Pide un schema, no una frase
Entregarle a alguien un formulario con casillas etiquetadas en lugar de una página en blanco — rellena exactamente los campos que necesitas, en el orden que necesitas, sin nada de más.
Structured output significa pedirle al modelo que devuelva datos en un formato definido — normalmente JSON que coincida con un schema que tú especificas: estos campos, estos tipos, esta forma. En lugar de «háblame de este pedido», dices «devuelve {customer, amount, reason}», y recuperas datos que tu código puede usar directamente. Tú defines la forma; el modelo la rellena. Este es el único movimiento que convierte la salida del modelo de prosa en algo en lo que un programa puede apoyarse.
El modelo puede ser constrained a una salida válida
Una aguja de ferrocarril que físicamente solo puede enviar el tren por una de las vías definidas — no hay forma de que acabe en algún sitio fuera del mapa.
Los modelos modernos admiten generación constrained: se les puede forzar a producir una salida que de verdad coincida con tu schema — JSON válido, los campos correctos, los tipos correctos — en lugar de solo pedírselo educadamente. Esto cierra la brecha en la que el modelo «casi siempre» devuelve la forma correcta pero de vez en cuando se desvía. Con la salida constrained al schema, tu código puede contar con que la estructura esté ahí, que es lo que hace que el modelo sea usable como un auténtico bloque de construcción.
El structured output es el puente hacia tu código
Un traductor que convierte los deseos hablados de un huésped en un vale de pedido preciso y estandarizado sobre el que la cocina puede actuar — el mismo significado, ahora en una forma que el sistema puede usar.
El structured output es el puente entre la capacidad lingüística del modelo y la necesidad de datos de tu software. Le permite al modelo hacer aquello en lo que es brillante — entender una entrada humana desordenada — y entregarle el resultado a tu código como valores limpios y tipados. Clasificación, extracción, enrutamiento, rellenado de formularios: todo se vuelve fiable cuando la salida está estructurada. El modelo lee el caos; el schema entrega el orden. Ese traspaso es donde de verdad vive la mayoría de las funciones reales con LLM.
Structured output significa que el modelo devuelve datos que coinciden con un schema que tú defines, constrained a una forma válida — el puente que convierte su capacidad lingüística en valores tipados en los que tu código puede apoyarse.
El structured output te da una forma predecible, pero forma no es corrección. Antes de que tu código confíe en lo que el modelo devolvió, tiene que comprobarlo — la misma disciplina que con cualquier entrada no confiable.
Una forma válida no es contenido válido
Un formulario rellenado con pulcritud, cada casilla completada — pero la fecha es imposible y el total no cuadra. Ordenado no es lo mismo que correcto.
Un schema garantiza la forma — los campos y tipos correctos — pero no que los valores tengan sentido. El modelo puede devolver JSON perfectamente formado con una cantidad negativa, una categoría que no existe o un importe que alucinó. El structured output resuelve «¿puede mi código leerlo?»; no resuelve «¿está bien?». Trata una respuesta bien formada como un punto de partida que comprobar, no como la garantía de que es correcta.
Valida antes de que algo actúe sobre ello
Un control de aduanas entre países — nada cruza al siguiente sistema hasta que se ha inspeccionado contra las reglas y se ha declarado seguro.
Así que validas el structured output del modelo antes de que tu código lo use: aplica el schema de forma estricta, comprueba que los valores estén en los rangos y conjuntos permitidos, confirma que cualquier cosa referenciada de verdad existe. Esta comprobación se ejecuta en tu código, en el límite entre el modelo y el resto de tu sistema, porque el modelo es un componente no determinista en el que no puedes confiar del todo. La misma lección que en seguridad: la salida del modelo es una entrada no confiable para la siguiente etapa hasta que la hayas verificado.
Nunca canalices la salida en bruto hacia algo peligroso
No viertes una corriente sin filtrar directamente en el suministro de agua potable — lo que hubiera aguas arriba está ahora en cada grifo, sin posibilidad de atraparlo.
La regla se vuelve estricta cuando la salida fluye hacia algún sitio con consecuencias. Nunca alimentes la salida en bruto del modelo directamente a una escritura en base de datos, un comando de shell, una consulta u otro sistema sin validarla y escaparla primero — así es como una alucinación o una instrucción inyectada se convierte en un bug o una brecha real. Structured output más validación estricta es lo que te permite actuar de forma segura sobre lo que el modelo produjo. La estructura lo hace legible; la validación lo hace fiable.
Un schema válido garantiza la forma, no la corrección. Valida la salida del modelo en el límite — rangos, conjuntos, existencia — antes de que algún código actúe sobre ella, porque la salida del modelo no es confiable hasta que se comprueba.
El structured output deja que el modelo devuelva datos. La otra mitad de hacerlo un componente es dejar que haga cosas — ir más allá del texto para buscar, calcular, recuperar y actuar en el mundo real. Eso es tool use.
Dale al modelo funciones que pueda llamar
Un asistente inteligente que no puede abrir el archivador por sí mismo — pero puede decirte con precisión qué cajón y qué expediente sacar, y usar lo que le traes.
Con tool use (también llamado function calling), describes funciones que el modelo tiene permiso para solicitar — search_orders, send_email, get_weather — y cuando el modelo decide que necesita una, devuelve una llamada estructurada que nombra la función y sus argumentos. Es structured output aplicado a acciones: en lugar de datos, el modelo emite una solicitud para hacer algo. Así es como un LLM llega más allá de su propio texto hasta tus sistemas y el mundo.
El modelo decide; tu código hace
Un capataz que señala y dice exactamente qué hay que hacer — pero la cuadrilla, no el capataz, es la que de verdad opera las máquinas y mantiene el control de la obra.
La división del trabajo es la clave: el modelo decide qué hacer y con qué argumentos; tu código decide si lo hace de verdad y cómo. Cuando el modelo devuelve una tool call, tu código ejecuta la función (o no), obtiene el resultado y lo realimenta al contexto para que el modelo continúe. El modelo nunca toca tus sistemas directamente — solicita, tu código ejecuta. Ese límite es donde mantienes el control y la seguridad.
El resultado se realimenta al bucle
Un investigador pide un documento, lee lo que le traen y lo usa para decidir la siguiente pregunta — un ida y vuelta, no un único disparo.
El tool use es un ciclo: el modelo solicita una herramienta, tu código la ejecuta y devuelve el resultado al contexto, y el modelo razona a partir de esa nueva información — posiblemente llamando a otra herramienta. Este bucle es exactamente lo que convierte un modelo en un agente (el curso de agentes profundiza). Las herramientas son las manos; el bucle es la persistencia. Por ahora, la idea clave es que el tool use le permite al modelo reunir lo que necesita y actuar, paso a paso, en vez de responder a ciegas de memoria.
El tool use le permite al modelo solicitar funciones — structured output para acciones. El modelo decide qué hacer; tu código decide si hacerlo y cómo, y realimenta el resultado.
El modelo elige y usa herramientas según cómo las describes, así que el diseño de herramientas es parte de conseguir un comportamiento fiable. Unos pocos principios separan las herramientas que funcionan de las que confunden al modelo.
Nombres y descripciones claros guían la elección
Una caja de herramientas donde cada herramienta está claramente etiquetada con su uso — el trabajador agarra la correcta al instante, en lugar de adivinar entre una hilera de mangos sin marcar.
El modelo elige a qué herramienta llamar casi por completo a partir de su nombre y descripción. Así que no son documentación para humanos — son las instrucciones a partir de las que razona el modelo. Una descripción vaga o engañosa lleva a la herramienta equivocada, a los argumentos equivocados, o a una herramienta ignorada cuando hacía falta. Escribe los nombres y descripciones de herramientas con el mismo cuidado con que escribirías un prompt, porque para el modelo eso es exactamente lo que son.
Pocas herramientas afiladas le ganan a un menú gigante
Una cocina con unas pocas herramientas bien elegidas y claramente distintas trabaja más rápido que una con cincuenta artilugios solapados que el cocinero tiene que ir descartando cada vez.
Darle al modelo demasiadas herramientas — o varias que se solapan — hace que le cueste más elegir bien, en cada turno. Un conjunto pequeño de herramientas afiladas y claramente distintas es más fiable que un menú desbordado. Si dos herramientas hacen casi lo mismo, el modelo a veces elegirá la equivocada; si hay cuarenta, elegir se convierte en su propia fuente de error. Cura el conjunto de herramientas igual que curas el contexto: solo lo que la tarea necesita.
Desconfía de la descripción de la herramienta como superficie de seguridad
Un recién contratado que sigue la etiqueta de cada caja sin cuestionar nada — así que quien escribe las etiquetas controla de hecho lo que hace.
Como el modelo confía en las descripciones y en las salidas de las herramientas, son parte de tu superficie de seguridad, no fontanería neutral. Una descripción envenenada o una herramienta que devuelve texto controlado por un atacante puede dirigir el comportamiento del modelo — «tool poisoning». Examina las herramientas que conectas, acota cada una al mínimo que necesita (una herramienta de solo lectura no debería poder borrar) y trata lo que devuelve una herramienta como entrada no confiable. La capacidad que le concedes a una herramienta es capacidad que un modelo confundido o secuestrado puede usar mal.
El modelo elige herramientas a partir de sus nombres y descripciones, así que escríbelos como prompts. Mantén las herramientas pocas y afiladas, acota cada una a least privilege, y trata descripciones y salidas como una superficie de seguridad.
A medida que las herramientas se multiplican, conectar cada modelo a cada sistema a mano no escala. Ha surgido un estándar para cómo los modelos alcanzan herramientas y datos — y con él, una nueva capa que entender y asegurar.
Una forma estándar de exponer herramientas a los modelos
Antes de los enchufes y las tomas estándar, cada aparato necesitaba su propio cableado a medida — un estándar universal hizo que cualquier dispositivo pudiera conectarse a cualquier toma sin trabajo a medida.
El Model Context Protocol (MCP) es un estándar emergente para cómo los modelos se conectan a herramientas y fuentes de datos. En lugar de cablear cada modelo a cada sistema con código a medida, MCP define una forma común de exponer herramientas, de modo que cualquier modelo compatible pueda usar cualquier herramienta compatible. Es la toma universal de la era de los agentes — una capa de conectores que permite que el ecosistema de herramientas y modelos se enchufe en conjunto sin integraciones puntuales cada vez.
Estandariza la fontanería de los agentes
Una red eléctrica: estandarizada para que un aparato nuevo simplemente se enchufe y funcione, y una nueva fuente de energía simplemente alimente la misma red — el estándar es lo que hace que toda la red se componga.
MCP importa porque hace que las herramientas y los datos sean componibles: una herramienta construida una vez puede ser usada por muchos modelos y agentes, y un nuevo agente puede usar de inmediato todo el ecosistema de herramientas existentes. Esto es gran parte de por qué los agentes se volvieron potentes tan rápido — la fontanería se estandarizó, así que las capacidades encajan unas con otras. Cuando hoy le das a un agente acceso a tus sistemas, MCP es cada vez más la capa que lo hace.
La capa de conectores es una superficie de ataque
Fontanería nueva tendida por toda la casa a toda prisa — y una inspección descubre que a una buena parte de las válvulas nunca se les puso una llave.
Esta nueva capa es también un nuevo lugar por el que sufrir una brecha. Los conectores MCP exponen acciones y datos reales, y la prisa por adoptarlos ha dejado muchos desplegados con seguridad débil o inexistente — una buena parte de los servidores MCP remotos se han lanzado sin ninguna autenticación en absoluto. Así que trata un conector como la puerta que es: autentícalo, acota lo que expone, mantenlo fuera de la internet pública salvo que tenga que estar ahí, e inventaría lo que has conectado. La fontanería potente exige las cerraduras básicas.
MCP estandariza cómo los modelos alcanzan herramientas y datos, haciendo el ecosistema componible. Esa misma capa de conectores es una superficie de ataque real — autentícala, acótala e inventaríala.
El structured output y el tool use son las herramientas que hacen de un modelo un componente, pero recurrir a ellas bien sigue significando subir la escalera — usar la pieza menos potente que resuelve tu problema.
Structured output primero, herramientas cuando deba actuar
No le entregas a alguien las llaves del coche cuando todo lo que necesitabas era una respuesta — le das justo la capacidad que requiere la tarea, nada más.
Hay una escalera de capacidad. Un prompt simple responde; el structured output hace que esa respuesta sea usable por el código; las herramientas dejan que el modelo recupere y actúe; un bucle de agente completo le deja perseguir un objetivo de varios pasos. Cada peldaño añade potencia y nuevas formas de fallar. Sube solo tan alto como la tarea necesite: si solo necesitas datos limpios, el structured output basta — no le des herramientas al modelo, y desde luego no un bucle, cuando una respuesta constrained lo resuelve. La mayoría de las funciones nunca necesitan el peldaño más alto.
Valida todo lo que cruza de vuelta
Un mostrador de devoluciones que inspecciona cada artículo que vuelve antes de que pase al estante — nada reentra al sistema sin comprobar, por muy de fiar que pareciera el cliente.
El hábito que unifica ambas mitades es la desconfianza en el límite: valida el structured output del modelo antes de que tu código lo use, y mantén tu código en control de si ejecutar una herramienta que el modelo solicitó. El modelo es un componente brillante y no determinista, y tratas todo lo que cruza de él hacia tu sistema como entrada que verificar. Esa disciplina de límite es lo que te deja construir de forma fiable sobre algo que es fundamentalmente falible.
- ¿Necesita mi código datos — estoy obteniendo structured output según un schema, no parseando prosa? - ¿Está validada la salida — los valores comprobados, no solo bien formados, antes de que algo actúe sobre ella? - ¿Necesita actuar — y lo he expuesto como una herramienta, con mi código en control de su ejecución? - ¿Son las herramientas pocas, afiladas y bien descritas, y acotadas a least privilege? - Si uso MCP, ¿está cada conector autenticado, acotado e inventariado? - ¿Estoy en el peldaño más bajo que funciona — salida, herramientas, o un bucle completo solo si hace falta?
- free text / structured output — prosa para humanos, frente a datos en los que tu código puede apoyarse. - schema / JSON / constrained — la forma que defines y fuerzas a que el modelo coincida. - validation / boundary — comprobar que los valores son correctos antes de que algún código confíe en ellos. - tool use / function calling — dejar que el modelo solicite acciones que tu código ejecuta. - tool description / tool poisoning — cómo elige el modelo las herramientas, y el riesgo de seguridad que hay en ellas. - MCP — la capa de conectores estándar para exponer herramientas y datos a los modelos. - least privilege — acotar cada herramienta al mínimo que necesita.
- Obtienes structured output según un schema en lugar de parsear la prosa del modelo. - Validas la salida en el límite antes de que algún código actúe sobre ella. - El modelo solicita herramientas y tu código mantiene el control de su ejecución. - Tus herramientas son pocas, afiladas, bien descritas y de least privilege. - Subes solo hasta el peldaño que la tarea necesita, y tratas los conectores MCP como una puerta asegurada.
Para construir sobre un modelo, hazlo un componente: structured output en el que tu código pueda confiar, validado en el límite, y herramientas que él solicita pero tu código controla — el peldaño menos potente que resuelve el trabajo.