El bucle ReAct
Un agente basado en un modelo de lenguaje ejecuta el mismo bucle de percibir, razonar y actuar que cualquier otro agente, con un detalle que da nombre al patrón: el modelo razona con palabras entre las acciones que aplica. Este patrón de comportamiento fue denominado por Yao et al. (2022) como ReAct, por razonamiento y acción (del inglés Reason and Action). Dichos autores observaron que intercalar pasos breves de razonamiento con el uso de herramientas permite resolver muchas tareas con mayor fiabilidad que planificar todo de antemano o actuar sin razonar.
Una herramienta es código que un motor de ejecución puede ejecutar para el modelo: una función con nombre, descripción, esquema de entrada y un valor de retorno. Una llamada a herramienta es la solicitud estructurada que genera el modelo. El motor de ejecución interpreta la solicitud, ejecuta la función, y vuelve a llamar al modelo añadiendo el resultado devuelto por la función.
Este bucle sirve de base para la mayoría de los frameworks de agentes de propósito general,
incluido createReactAgent
de LangChain. El resto de este capítulo profundiza paso a paso en sus componentes.
El campo que decide el siguiente paso
Cada respuesta de Chat Completions incluye un campo finish_reason que indica por qué
el modelo dejó de generar tokens. Dentro del bucle del agente, esta señal basta para decidir el paso
siguiente: ejecutar una herramienta, devolver la respuesta al usuario o gestionar un error. Antes de revisar
el significado de cada valor, ejecuta dos llamadas y observa cómo cambia dicho campo.
La primera llamada pudo generar una respuesta directamente y devolvió "stop". En la segunda, el
modelo recibió una herramienta y una pregunta cuya respuesta no está en los datos de entrenamiento.
En vez de finalizar, devolvió "tool_calls" junto con el nombre de la función que debía
ejecutarse. Dichos valores cubren la mayoría de los casos habituales. Los demás valores indican situaciones que el
motor de ejecución debe gestionar, por ejemplo, reintentar la llamada o transferir la conversación
a una persona.
"stop"indica que el modelo ya generó la respuesta final y el bucle puede devolvercontental usuario."tool_calls"indica que el modelo solicita la ejecución de una función determinada; el código debe añadir el resultado antes de volver a invocar el modelo."length"significa que el presupuesto de tokens se agotó antes de completar la respuesta."content_filter"significa que un mecanismo de control de seguridad detuvo la salida.
En una implementación moderna de ReAct, un enrutador sencillo o router lee este campo. Si el modelo solicita una herramienta, el router ejecuta la función, añade el resultado al historial y vuelve a llamar al modelo. Si el modelo finaliza, el router devuelve la respuesta.
Este diseño funciona porque el modelo no queda atado a un único plan inicial. Cuando una herramienta devuelve algo inesperado, el resultado entra en la siguiente ronda de razonamiento y el modelo puede reevaluar la situación.
Aplicado · Anatomía¿Relacionar el modelo, la memoria, las herramientas y el enrutador?
Componentes de un agente basado en un LLM
Al examinar el agente con más detalle aparece la descomposición que Lilian Weng presentó en 2023. El modelo de lenguaje ocupa el centro; a su alrededor se organizan la memoria, la planificación, las herramientas y las acciones que interactúan con el entorno.
El agente mínimo presentado en este curso implementa dichos componentes con el mecanismo más sencillo que cumpla su función:
- La memoria es un array
messages[]. - La planificación reside en el router que interpreta
finish_reason. - Las herramientas son las funciones expuestas por el motor de ejecución.
- La acción es la llamada a herramienta que ejecuta dicho motor.
Ninguno de estos componentes reside dentro del modelo. Todos pertenecen al motor de ejecución construido alrededor de un único proceso que consiste en transformar texto de entrada en texto de salida.
Esta independencia también facilita la lectura de código escrito por otra persona. Con independencia del framework utilizado, cualquier agente basado en un LLM debe contener estas cuatro piezas. Cuando algo falla, la causa suele encontrarse en una de ellas:
- el modelo devuelve un valor incorrecto de
finish_reason; - falta alguna parte de la conversación (que llamaremos turno) en el array de mensajes;
- una herramienta devuelve un valor inesperado;
- el router interpreta la señal de forma incorrecta.
Esta estructura proporciona una lista de comprobación aplicable con independencia de cómo esté organizado el código que la rodea.
Construir el bucle del agente desde cero con una herramienta
Construyamos un ejemplo sencillo desde cero. Solo necesitamos la herramienta get_current_time, un prompt para el sistema y un bucle while. Empieza preguntando «¿Qué hora es en UTC?» y luego prueba otras preguntas:
El flujo de ejecución es breve: el modelo solicita llamar a la herramienta, el ejecutor añade la marca de tiempo como un
mensaje con el rol tool, el modelo lee el resultado y el bucle termina cuando
finish_reason contiene "stop".
Durante el bucle se añadieron cuatro elementos a
state.messages: - el prompt del sistema (turno 0);
- la pregunta del usuario (turno 1);
- un mensaje del asistente con un
campo
tool_calls(turno 2, la solicitud); - y un
mensaje con el rol
toolque contiene el valor devuelto por la función (turno 3).
Aplicado · Operación¿Revisar evidencias y mitigaciones de la degradación del contexto?
Degradación del contexto: por qué un bucle más largo puede experimentar problemas de comprensión
Este problema se vuelve más probable a medida que crece el contexto (o cantidad de mensajes que guardamos en el array). La degradación del contexto ocurre cuando aparecen contradicciones, observaciones obsoletas y convenciones deficientes que se acumulan en el historial y que pueden perjudicar la siguiente decisión. El efecto también tiene un componente posicional: Liu et al. (2023) mostraron que los modelos pueden desaprovechar información situada en la zona intermedia de un contexto largo. Cuanto más se aleja una señal importante del mensaje o turno actual, mayor es la probabilidad de que el bucle la ignore o la contradiga.
Los mecanismos de contención habituales ante este problema consisten en mantener cada decisión lo más cercana a la evidencia que necesita:
- planificar antes de que el bucle acumule observaciones;
- delegar subtareas para que cada subagente trabaje con un contexto breve;
- resumir las conversaciones anteriores antes de que empiecen a degradar las decisiones.
Cada posible medida de contención añade costes de latencia, fidelidad o complejidad y debe evaluarse según la tarea.
El mismo bucle, preconfigurado para trabajar con el curso
El bucle anterior tiene una única herramienta fijada directamente en el código. La función
createReactAgent
de LangChain generaliza esta estructura para admitir varias herramientas, interfaces estándar e
integraciones de observabilidad o monitorización. El ejemplo siguiente expone una sola herramienta,
read_course_page, que entrega al agente cualquier página de este curso como Markdown. El
modelo decide qué páginas necesita consultar para responder.
Ejecuta la celda para construir el panel y conversar con el agente. Fija una o más páginas mediante los marcadores del menú Páginas para basar cada respuesta en dichas páginas, o no fijes ninguna y deja que el agente elija qué leer. La respuesta se presenta como Markdown y cada fuente consultada aparece en un pequeño menú; expándelo para ver el texto recuperado. El panel también muestra las trazas de razonamiento y el uso de tokens, y conserva la conversación. Edita la celda y ejecútala de nuevo para reconstruir el artefacto.
Antes de continuar
Responde a cada pregunta modificando las entradas del ejercicio y volviendo a ejecutarlo.
- Fuerza al modelo a llamar a la herramienta aunque no la necesite.
Intenta una pregunta que la herramienta realmente no pueda responder («¿capital de Francia?»)
y observa
finish_reason. ¿Fue"stop"o"tool_calls"? Ahora edita el prompt del sistema para exigir una llamada antes de responder («Debes llamar siempre una vez a get_current_time y responder después»). ¿Cumple el modelo la instrucción? ¿Qué indica el resultado sobre la capacidad del prompt de sistema para dirigir un modelo que confía en sus datos de entrenamiento? - Cuenta los pasos en una pregunta que realmente necesita una herramienta.
«¿Cuántos minutos faltan para las 17:00 UTC?» puede requerir más de una llamada a herramienta.
Ejecuta el ejemplo varias veces. ¿El modelo llama a
get_current_timeuna, dos o tres veces? ¿Por qué volvería a solicitar una herramienta cuyo resultado ya figura en el historial? ¿Cómo podrías evitarlo mediante el prompt del sistema?
Profundo · Fuentes¿Rastrear estos mecanismos hasta sus fuentes primarias?
Referencias
- Yao et al., ReAct: Synergizing Reasoning and Acting in Language Models (2022). El trabajo original sobre la alternancia entre razonamiento, acción y observación.
- Wei et al., Chain-of-Thought Prompting (2022). Fundamenta la parte de razonamiento de ReAct y ayuda a interpretar lo que ocurre en
reasoning_contentantes de actuar. - Lilian Weng, LLM Powered Autonomous Agents (2023). La figura anterior adapta su descomposición: un modelo de lenguaje como controlador central, rodeado por memoria, planificación y uso de herramientas.
- Xu et al., ReWOO: Decoupling Reasoning from Observations (2023). Un contraste con ReAct: el modelo escribe el plan de antemano y un ejecutor separado lo completa sin consultar de nuevo al modelo entre etapas.
- Schick et al., Toolformer (2023). El módulo 1c retoma este trabajo para explicar el mecanismo de uso de herramientas que aprovecha el bucle ReAct.
Consulta la lista completa en Para ir más lejos · Referencias.