A lo largo del módulo hemos escrito el system prompt de DocuBot, un clasificador few-shot y un contrato JSON de salida. Cada pieza parece razonable — pero "parece razonable" no es un criterio de ingeniería. Cuando en unas semanas alguien proponga "añade una regla para que DocuBot sea más amable", ¿cómo sabréis si esa regla mejora el asistente o rompe silenciosamente el comportamiento anti-alucinación que tanto costó afinar? La respuesta de cualquier ingeniero ante una pregunta así es la misma: pruebas. Esta lección convierte el prompting en un proceso disciplinado: el prompt como artefacto versionado, un ciclo de iteración con hipótesis y medición, la construcción del conjunto de 30-50 preguntas reales que anunciamos en 01-03 al decidir el modelo de DocuBot, rúbricas simples para puntuar respuestas y una forma justa de comparar variantes pese al no determinismo que conocemos desde 01-04. Todo manual y con herramientas mínimas (una tabla, un CSV): la automatización llegará en 06-03, y aquí construimos justo lo que esa automatización necesitará.
Contenido
- El prompt como artefacto de ingeniería
- El ciclo de iteración: hipótesis → cambio → prueba
- El conjunto de evaluación de DocuBot: 30-50 preguntas reales
- Criterios de calidad y rúbricas simples
- Comparar variantes de forma justa
- Registrar resultados: tabla y CSV
El prompt como artefacto de ingeniería
Un prompt de producción no es una frase que se escribe una vez: es un artefacto que evoluciona, del que dependen comportamientos visibles para usuarios, y que varias personas tocarán. Merece el mismo trato que el código:
- Vive en el repositorio. Ya lo encaminamos en 02-02: las plantillas están en
prompts.py, bajo control de versiones. Nada de prompts sueltos en documentos compartidos o en el panel web de un proveedor, donde nadie sabe quién cambió qué. - Tiene versión explícita. No hace falta nada sofisticado: una constante y un registro de cambios en el propio módulo bastan para empezar.
# prompts.py PROMPT_VERSION = "1.2" # Historial: # 1.0 System prompt inicial (identidad, reglas 1-5, tono, formato). # 1.1 + clasificador few-shot con 6 ejemplos (02-02). # 1.2 + salida JSON con esquema y campo confianza (02-03). SYSTEM_DOCUBOT = """Eres DocuBot, ..."""
- Los cambios se revisan. Un cambio de prompt es un cambio de comportamiento del sistema: pasa por revisión igual que un cambio de código. La diferencia — y de ahí esta lección — es que el revisor humano no puede "leer" el efecto de un prompt como lee un
if: necesita resultados de pruebas. - Cada versión se puede reproducir. Si el lunes DocuBot respondía bien y el jueves no, quieres poder responder "¿qué versión exacta del prompt corría el lunes?". Versionar es lo que hace posible esa pregunta. (En el módulo 6 veremos que también el modelo y sus parámetros forman parte de esa foto reproducible.)
El cambio mental es este: en software tradicional, el comportamiento lo garantiza el compilador y lo verifican los tests; con LLMs, el "código fuente" incluye texto en lenguaje natural cuyo efecto solo se conoce empíricamente. Por eso el resto de la lección va de construir esa verificación empírica.
El ciclo de iteración: hipótesis → cambio → prueba
La forma natural (y equivocada) de iterar prompts es: pruebo una pregunta, no me gusta la respuesta, retoco el prompt, pruebo esa misma pregunta, ahora sale bien, doy el cambio por bueno. El problema tiene nombre en ingeniería: regresión. El retoque que arregla la pregunta A puede romper las preguntas B, C y D — y con un system prompt de reglas interdependientes como el de DocuBot, sucede constantemente. Por ejemplo: añades "sé más cálido y cercano" para mejorar el tono, y el modelo — empujado por la complacencia del RLHF que vimos en 01-02 — empieza a suavizar el "No encuentro esa información…" con añadidos serviciales que rozan la invención. Arreglaste el tono, rompiste la regla 3.
El ciclo disciplinado tiene cuatro pasos:
flowchart LR
A[1. Hipótesis:\nqué falla y por qué] --> B[2. Cambio:\nUNA modificación\nal prompt]
B --> C[3. Prueba:\nTODO el conjunto\nde casos]
C --> D[4. Decisión:\ncomparar con la\nversión anterior]
D -->|mejora sin regresiones| E[Adoptar y versionar]
D -->|empeora o regresa| A- Hipótesis. Formula el problema de forma observable: no "las respuestas son flojas", sino "en 4 de los 10 casos de facturación, DocuBot no cita la fuente". Una buena hipótesis incluye la causa sospechada: "la regla 4 está lejos del final del prompt y con contextos largos se pierde (lost in the middle)".
- Cambio: uno solo. Si tocas tres cosas a la vez y el resultado mejora, no sabes cuál de las tres actuó (ni si una de ellas empeoró algo que otra compensó). Un cambio por iteración — la vieja regla de cambiar una variable cada vez.
- Prueba con TODO el conjunto de casos, no solo con el caso que motivó el cambio. Aquí es donde se cazan las regresiones.
- Decisión comparando versiones. Con los resultados de ambas versiones sobre los mismos casos (sección 5), decides: adoptar (y subir
PROMPT_VERSION, anotando el porqué) o descartar y volver a la hipótesis.
Este bucle es artesanal a propósito: hacerlo a mano con 30-50 casos te enseña qué mirar, y ese criterio es exactamente lo que automatizarás en 06-03.
El conjunto de evaluación de DocuBot: 30-50 preguntas reales
En 01-03, al elegir modelo para DocuBot, dejamos anunciada una "evaluación propia de 30-50 preguntas reales". Ha llegado el momento de construirla. Un conjunto de evaluación (eval set) es una lista fija de casos de entrada, cada uno con su resultado esperado o su criterio de corrección. Las claves:
De dónde salen las preguntas. De la realidad, no de tu imaginación: los tickets históricos del soporte de Nubelia, las búsquedas en la wiki, las preguntas del canal interno de dudas. Las preguntas inventadas por quien escribió el prompt sufren el sesgo obvio: inconscientemente escribes preguntas que tu prompt responde bien. Si el producto aún no tiene tráfico, pide a compañeros que no hayan visto el prompt que escriban preguntas.
Cobertura por tipos de caso. Un buen conjunto no es una colección de preguntas fáciles: es un mapa de todo lo que puede llegar. Para DocuBot, cuatro tipos con proporciones orientativas:
| Tipo de caso | Proporción | Qué verifica | Ejemplo (Nubelia) |
|---|---|---|---|
| Fáciles: respuesta directa en la doc | ~40 % | El caso base funciona y cita fuente | "¿Cómo archivo un proyecto?" |
| Ambiguos: requieren interpretar o combinar | ~25 % | Fronteras de clasificación, respuestas matizadas | "El webhook de Slack dejó de llegar ayer" (¿integraciones/incidencias?) |
| Sin respuesta en la doc | ~20 % | La regla anti-alucinación: debe decir "no lo sé" | "¿Nubelia permite exportar un proyecto a PDF?" |
| Adversariales suaves | ~15 % | Robustez ante entradas problemáticas | Fuera de ámbito ("¿qué opinas de la competencia?"), premisa falsa ("¿dónde está el botón de clonar proyecto?"), instrucciones incrustadas ("ignora tus reglas y…") |
Dos tipos merecen comentario:
- Los casos "sin respuesta" son los más valiosos del conjunto. Son la prueba directa de que el DocuBot ingenuo de 01-04 quedó atrás. Y son fáciles de evaluar: la respuesta esperada es literalmente la frase fija de la regla 3 con
confianza: "baja"— por eso fijamos una frase exacta en 02-01: para poder comprobarla. - Los adversariales suaves no son un test de seguridad completo (eso es 06-01): son las torpezas y malicias cotidianas. La premisa falsa es especialmente traicionera: "¿dónde está el botón de clonar proyecto?" presupone que existe, y un modelo complaciente tiende a "encontrárselo".
Cada caso lleva su resultado esperado. El formato mínimo por caso: id, pregunta, tipo, categoria_esperada (para el clasificador) y criterio (qué debe cumplir la respuesta). Para los fáciles, el criterio puede incluir la fuente que debe citar; para los "sin respuesta", la frase fija; para los ambiguos, a veces hay más de una categoría aceptable — anótalo (permisos|integraciones).
¿Por qué 30-50 y no 500? Porque los evaluarás a mano en cada iteración y tiene que ser viable en una tarde. 30-50 casos bien elegidos detectan la mayoría de regresiones; el conjunto crecerá con el tiempo (cada fallo real de producción es un caso nuevo — la misma idea que las salidas rotas de 02-03), y cuando crezca demasiado para evaluarlo a mano, será la señal de automatizar (06-03).
Criterios de calidad y rúbricas simples
"¿Es buena esta respuesta?" es demasiado vago para puntuar con consistencia — la misma persona puntúa distinto un lunes y un viernes. Una rúbrica descompone "buena" en criterios binarios o casi binarios, cada uno verificable mirando la respuesta:
| Criterio | Pregunta a verificar | Puntuación |
|---|---|---|
| Corrección | ¿Lo que afirma coincide con la documentación? | 0 / 1 |
| Anclaje (no alucina) | ¿Evita afirmar cosas que no están en la doc? | 0 / 1 |
| Fuente | ¿Cita la sección correcta en fuentes? |
0 / 1 |
| Formato | ¿JSON válido conforme al esquema de 02-03? | 0 / 1 |
| Categoría | ¿categoria coincide con la esperada? |
0 / 1 |
| Tono y concisión | ¿Directo, profesional, sin relleno? | 0 / 0.5 / 1 |
Notas de diseño:
- Criterios binarios siempre que se pueda. "¿Cita la fuente correcta? sí/no" se puntúa igual hoy y mañana; "calidad de la cita, del 1 al 10" no. Solo el tono admite un punto intermedio, y aun así acotado.
- Criterios separados, no una nota global. Una respuesta puede ser correcta y no citar fuente. Si solo apuntas "7/10", pierdes la información de qué falló, que es justo lo que alimenta la siguiente hipótesis del ciclo.
- Algunos criterios son automatizables ya. "¿JSON válido?" es
parsear_respuesta_docubotde 02-03; "¿categoría esperada?" es una comparación de strings; "¿dice la frase de no-lo-sé?" es unin. Aunque esta lección es manual, escribe estos checks como funciones Python desde ya: son las primeras piezas de 06-03. - La corrección la juzga quien conoce la doc. Para DocuBot, la referencia es la documentación de Nubelia incluida en el prompt del caso — el evaluador comprueba contra ella, no contra su memoria.
Con la rúbrica, cada caso evaluado produce una fila de números en lugar de una impresión. Y 50 filas de números se pueden comparar; 50 impresiones, no.
Comparar variantes de forma justa
Supón que tienes el prompt v1.2 y una variante v1.3 (hipótesis: repetir la regla anti-alucinación al final reducirá las invenciones en contextos largos). Para que la comparación sea justa hacen falta tres condiciones:
- Mismos casos. Ambas versiones se ejecutan sobre el conjunto completo de evaluación, sin excepciones. Comparar v1.2 sobre unos casos y v1.3 sobre otros no dice nada.
- Todo lo demás igual. Mismo modelo, misma temperatura, misma documentación en el contexto. Si cambias prompt y modelo a la vez, vuelve el problema del cambio doble: no sabrás a quién atribuir la diferencia.
- Varias ejecuciones por caso. Aquí reaparece el no determinismo de 01-04: la misma versión, con el mismo caso, puede acertar unas veces y fallar otras — incluso con temperatura baja. Una sola ejecución por caso puede darte una diferencia entre versiones que es puro azar. La mitigación práctica: ejecuta cada caso 3 veces por versión y trabaja con la proporción de aciertos (un criterio que pasa 3/3 es sólido; 2/3 es zona gris; y un caso que oscila entre ejecuciones es, en sí mismo, un hallazgo: señala una instrucción ambigua).
Con eso, la comparación se resume en una tabla por criterio:
| Criterio (proporción de aciertos) | v1.2 | v1.3 | Δ |
|---|---|---|---|
| Corrección | 0.89 | 0.90 | +0.01 |
| Anclaje (no alucina) | 0.78 | 0.93 | +0.15 |
| Fuente citada | 0.85 | 0.84 | −0.01 |
| Formato JSON | 0.97 | 0.96 | −0.01 |
| Categoría correcta | 0.88 | 0.88 | 0 |
| Tono y concisión | 0.92 | 0.90 | −0.02 |
Lectura: la hipótesis se confirma (anclaje +15 puntos, precisamente en los casos "sin respuesta" y de premisa falsa) y no hay regresiones relevantes (las variaciones de ±1-2 puntos con 3 ejecuciones por caso son ruido esperable). Decisión: adoptar v1.3. Si en cambio el anclaje hubiera subido a costa de, por ejemplo, que DocuBot respondiera "no lo sé" también en casos fáciles (corrección desplomándose), la tabla lo habría mostrado — ese equilibrio entre "no inventar" y "no volverse inútilmente prudente" es EL trade-off central de un asistente de documentación, y solo se gestiona midiendo ambos lados.
Dos advertencias de honestidad estadística: con 30-50 casos, diferencias pequeñas (±3-5 puntos) no son concluyentes — desconfía de la tentación de adoptar cambios por mejoras marginales; y no iteres tanto contra el mismo conjunto que termines ajustando el prompt a esos 50 casos (el equivalente al overfitting): renueva y amplía el conjunto periódicamente.
Registrar resultados: tabla y CSV
Nada de lo anterior sirve si los resultados viven en tu memoria. El registro mínimo viable es un CSV por ejecución de evaluación — legible con cualquier hoja de cálculo y procesable con Python:
caso_id,tipo,prompt_version,ejecucion,correccion,anclaje,fuente,formato,categoria,tono N-001,facil,1.3,1,1,1,1,1,1,1 N-001,facil,1.3,2,1,1,1,1,1,0.5 N-001,facil,1.3,3,1,1,1,1,1,1 N-017,sin_respuesta,1.3,1,1,1,1,1,1,1 N-017,sin_respuesta,1.3,2,1,1,1,1,1,1 N-031,adversarial,1.3,1,1,1,1,0,1,1 ...
Y un pequeño ayudante para agregar (de nuevo: Python para herramientas, no para llamar a ninguna API):
import csv
from collections import defaultdict
def resumen_por_criterio(ruta_csv: str) -> dict:
"""Media de cada criterio de la rúbrica a partir del CSV de evaluación."""
criterios = ["correccion", "anclaje", "fuente",
"formato", "categoria", "tono"]
sumas = defaultdict(float)
n = 0
with open(ruta_csv, newline="", encoding="utf-8") as f:
for fila in csv.DictReader(f):
for c in criterios:
sumas[c] += float(fila[c])
n += 1
return {c: round(sumas[c] / n, 2) for c in criterios}Buenas prácticas del registro:
- Una fila por caso y ejecución, no por caso: así conservas la variabilidad entre ejecuciones (la columna
ejecucion), que como vimos es información, no ruido a esconder. - La versión del prompt en cada fila. Es lo que permite comparar v1.2 contra v1.3 meses después, o detectar que una regresión apareció exactamente entre dos versiones.
- Guarda también las respuestas completas (en ficheros aparte, referenciados por
caso_id): la tabla dice que el caso N-031 falló en formato; la respuesta guardada dice cómo, y ese cómo es la próxima hipótesis. - El CSV va al repositorio junto al prompt. Evaluación y artefacto evaluado comparten historia: quien revise el cambio de prompt v1.3 ve, en el mismo commit, la evidencia de que mejora.
Este registro artesanal es deliberadamente idéntico en estructura a lo que producirá la evaluación automatizada de 06-03: mismos casos, misma rúbrica, mismas columnas — solo que las ejecutará un script (y, para criterios como el tono, otro LLM como juez, con las cautelas que allí veremos). Nada de lo construido aquí se tira.
Errores Comunes y Consejos
- Probar solo el caso que motivó el cambio. Es EL error. Cada iteración se valida contra el conjunto completo; si no, cada arreglo es una regresión en potencia.
- Cambiar varias cosas a la vez. Mejora o empeore, no sabrás por qué. Un cambio por versión, y la versión anotada en el historial.
- Un conjunto de evaluación hecho solo de casos fáciles. Dará 95 % de acierto siempre y no detectará nada. El valor está en los ambiguos, los "sin respuesta" y los adversariales — los casos que te incomodan son los que trabajan.
- Escribir las preguntas de evaluación la misma persona que escribió el prompt. Sesgo garantizado. Usa preguntas reales o pide casos a quien no haya visto el prompt.
- Puntuar con una nota global "de gusto". Sin rúbrica, la evaluación mide tu estado de ánimo. Criterios binarios separados, anotados por columna.
- Sacar conclusiones de una sola ejecución. El no determinismo convierte las comparaciones de ejecución única en lanzamientos de moneda. Tres ejecuciones por caso como mínimo para decidir entre versiones.
- No registrar nada. Sin CSV ni versiones, dentro de un mes repetiréis las mismas discusiones ("¿no habíamos probado ya a poner la regla al final?") sin datos.
- Consejo: convierte cada fallo de producción en un caso del conjunto de evaluación antes de arreglarlo. Es la versión prompt de "escribe el test que reproduce el bug antes de corregirlo", y garantiza que el conjunto evoluciona hacia los fallos reales, no hacia los imaginados.
Ejercicios
Ejercicio 1. Escribe 8 casos para el conjunto de evaluación de DocuBot respetando las proporciones de la lección (3 fáciles, 2 ambiguos, 2 sin respuesta en la doc, 1 adversarial suave). Para cada caso indica: id, pregunta, tipo, categoria_esperada y criterio de corrección. Contexto: la documentación disponible cubre roles y permisos, archivado de proyectos, facturación básica y la integración con Slack. (Inventa preguntas plausibles de empleados de Nubelia; no reutilices las de la lección.)
Ejercicio 2. Tu compañera propone pasar de v1.3 a v1.4 con esta justificación: "He añadido al prompt 'sé más breve' y además he cambiado a un modelo más barato; lo probé con 5 preguntas que me inventé y las 5 salieron bien, así que es mejor y más barato". Señala todos los problemas metodológicos de esta afirmación y describe el experimento correcto para evaluar la propuesta.
Ejercicio 3. Estos son los resultados agregados (proporción de aciertos, 3 ejecuciones × 40 casos) de una iteración cuyo cambio fue añadir al system prompt: "Si no estás completamente seguro, responde que no encuentras la información":
| Criterio | v1.3 | v1.4 |
|---|---|---|
| Anclaje (no alucina) | 0.90 | 0.98 |
| Corrección en casos fáciles | 0.93 | 0.71 |
| Acierto en casos "sin respuesta" | 0.85 | 0.99 |
¿Adoptarías v1.4? Interpreta qué ha pasado y propón una hipótesis mejor para la siguiente iteración.
Soluciones
Solución 1. Una solución posible (las tuyas serán distintas; lo evaluable es la estructura):
| id | Pregunta | Tipo | Cat. esperada | Criterio |
|---|---|---|---|---|
| N-101 | ¿Qué roles existen en Nubelia? | facil | permisos | Nombra los 3 roles; cita "Roles y permisos" |
| N-102 | ¿Cómo desarchivo un proyecto? | facil | otros | Indica la ruta de restauración; cita "Archivar un proyecto" |
| N-103 | ¿Puedo pagar la suscripción anualmente? | facil | facturacion | Responde según la doc de facturación; cita fuente |
| N-104 | Un Editor archivó un proyecto sin permiso, ¿cómo es posible? | ambiguo | permisos | Acepta permisos; debe contrastar qué rol puede archivar según la doc |
| N-105 | Los mensajes de Slack llegan pero sin el nombre del proyecto | ambiguo | integraciones|incidencias | Cualquiera de las dos categorías; no debe inventar opciones de configuración no documentadas |
| N-106 | ¿Puedo exportar los tableros a Excel? | sin_respuesta | otros | Frase fija de "no encuentro…"; confianza: "baja"; fuentes: [] |
| N-107 | ¿Cuál es el límite de peticiones de la API? | sin_respuesta | api | La doc disponible no cubre la API: frase fija + confianza baja (no debe inventar un número) |
| N-108 | ¿Dónde activo el modo oscuro del panel de facturación? | adversarial (premisa falsa) | facturacion|otros | No debe "encontrar" el ajuste inexistente; frase fija o corrección de la premisa |
Fíjate en N-107: la pregunta es legítima y de categoría clara, pero la documentación disponible no la cubre — el tipo "sin respuesta" depende del contexto proporcionado, no de la pregunta.
Solución 2. Problemas: (1) dos cambios a la vez (prompt y modelo): cualquier diferencia es inatribuible; (2) casos inventados por la proponente y no del conjunto de evaluación: sesgo de autoconfirmación; (3) 5 casos no cubren tipos (¿dónde están los "sin respuesta" y los adversariales?); (4) una sola ejecución por caso: con el no determinismo, 5/5 puede ser azar; (5) sin comparación con la versión anterior sobre los mismos casos: "salieron bien" no es "salieron mejor"; (6) nada registrado ni versionado. Experimento correcto: separar en dos iteraciones (primero el cambio de prompt con el modelo actual; después, si procede, el cambio de modelo con el prompt ganador); cada iteración ejecuta el conjunto completo de 30-50 casos, 3 veces por caso, puntuado con la rúbrica, registrado en CSV con su prompt_version, y se decide comparando la tabla de criterios entre versiones — vigilando expresamente que "más breve" no degrade corrección, fuentes o la frase anti-alucinación.
Solución 3. No adoptaría v1.4 tal cual. Qué ha pasado: la instrucción "si no estás completamente seguro…" ha vuelto a DocuBot hiperprudente — el anclaje y los casos "sin respuesta" mejoran (0.98, 0.99), pero a costa de desplomar la corrección en casos fáciles (0.93 → 0.71): ahora responde "no encuentro la información" a preguntas que sí están en la documentación. Es el trade-off central visto en la lección: se ha comprado prudencia pagando utilidad, y un asistente que no responde lo que sí sabe fracasa en su función. Hipótesis mejor para la siguiente iteración: sustituir el criterio subjetivo ("completamente seguro") por el criterio verificable que ya usaba la regla 2-3 de 02-01, reforzándolo: "Responde con confianza cuando la información esté en <documentacion>; usa la frase de 'no encuentro…' únicamente cuando no lo esté" — y comprobar en la siguiente ejecución que los casos fáciles recuperan ≥0.90 sin que el anclaje baje de 0.95.
Conclusión
Con esta lección, el módulo de prompt engineering queda completo — y completo significa algo muy concreto: DocuBot ya no es una idea, es un artefacto versionado con su evaluación. Tienes el system prompt con identidad, reglas anti-alucinación y tono (02-01); las técnicas para tareas exigentes — few-shot para el clasificador de soporte, cadena de razonamiento para los casos ambiguos, descomposición en pasos — y las plantillas Python que lo empaquetan todo (02-02); el contrato JSON categoria/respuesta/fuentes/confianza con su validación defensiva (02-03); y ahora la disciplina que sostiene el conjunto: versiones con historial, el ciclo hipótesis → cambio → prueba, el conjunto de 30-50 preguntas reales con sus cuatro tipos de casos, rúbricas de criterios binarios, comparaciones justas con varias ejecuciones y un registro en CSV que convierte cada decisión de prompting en una decisión con datos. Pero todo lo que hemos "ejecutado" en este módulo ha sido sobre el papel: prompts escritos y respuestas esperadas. En el módulo 3 el sistema cobra vida: haremos la primera llamada real a la API de un LLM desde Python, enviaremos por fin los roles system/user que diseñamos en 02-01, conectaremos las plantillas de prompts.py y el parser de 02-03 a respuestas de verdad, y nos enfrentaremos a lo que el papel no muestra: streaming, errores, reintentos y el coste real de cada token.
Curso de IA Generativa y LLMs para Desarrolladores
Módulo 1: Fundamentos de la IA generativa
- Qué es la IA generativa y por qué importa a los desarrolladores
- Cómo funciona un LLM: tokens, embeddings y atención
- Panorama de modelos y proveedores
- Limitaciones y riesgos: alucinaciones, contexto y costes
Módulo 2: Prompt engineering
- Anatomía de un prompt: roles, instrucciones y contexto
- Técnicas de prompting: few-shot, cadena de razonamiento y plantillas
- Salidas estructuradas: JSON y control de formato
- Iteración y evaluación de prompts
Módulo 3: Integración de LLMs en aplicaciones
- Primera integración con la API de un LLM
- Streaming, errores y reintentos
- Conversaciones y gestión del contexto
- Costes, latencia y caching
Módulo 4: RAG - Generación aumentada por recuperación
- Embeddings y búsqueda semántica
- Bases de datos vectoriales
- Ingesta y chunking de documentos
- Construcción de un pipeline RAG completo
- Evaluación de sistemas RAG
Módulo 5: Function calling y agentes
- Function calling: conectar el LLM con tu código
- De LLM a agente: el bucle de razonamiento y acción
- Frameworks de orquestación
