…
Módulo 1 · Parte A de 3

Agente

Un agente es una entidad que interactúa con un entorno determinado a cualquier nivel significativo. Una persona en su día a día es un agente en este sentido, así como también lo son un termostato que mantiene la temperatura de una sala o un coche autónomo que se desplaza por el tránsito.

Todos ellos perciben el entorno por medio de sensores y actúan sobre él por medio de actuadores. Cada acción influye, por tanto, en la siguiente observación del entorno formando un bucle continuo: el bucle de percibir, razonar y actuar, que dura mientras el agente interactúa en dicho entorno. Todos los agentes construidos en el curso siguen este bucle. Lo que cambia es cuánto pueden entender el entorno y hasta dónde llegan sus acciones.

Las tres etapas del bucle de un agente

Cada iteración pasa por tres etapas, con nombres simples y funciones distintas.

El agente percibe el entorno mediante observaciones y actúa sobre él mediante acciones. El paso de decisión entre ambas puede cambiar.

La percepción reúne lo que el agente puede conocer, el razonamiento decide qué hacer y la acción cambia el entorno. La percepción y la acción suelen proceder de un modelo de interacción existente, ya controle una aspiradora, automatización web, una entidad de juego o un humanoide. El razonamiento puede cambiar sin alterar ese límite, lo que separa la capacidad del alcance.

¿Explorar el ciclo y las arquitecturas clásicas?

Abre esta sección para consultar ejemplos concretos y una taxonomía más completa de arquitecturas.

  • La percepción proporciona todo lo que el agente sabe sobre el entorno. Un termostato solo lee un número: la temperatura actual. Un vehículo autónomo combina cámaras, radar y un mapa en un modelo de la carretera. Un agente solo trabaja con lo que captura la percepción, porque las etapas siguientes no acceden al entorno directamente. Cualquier aspecto no detectado durante la percepción permanece invisible para el resto del agente.
  • El razonamiento transforma una percepción en una decisión. Un termostato compara la temperatura con un objetivo, mientras que un motor de ajedrez evalúa millones de movimientos y un vehículo autónomo ejecuta una política aprendida. Los agentes de este curso razonan mediante un modelo de lenguaje. Las herramientas, la memoria y la planificación se apoyan en este paso.
  • Una acción modifica el entorno para el propio agente y para otros participantes del mismo. Esta puede ser tan pequeña como accionar un relé o tan compleja como conducir un coche. Más adelante en este curso, el modelo de lenguaje realiza llamadas a diferentes funciones de software que han sido expuestas de alguna forma para dicho modelo. Estas funciones reciben el nombre de herramientas (del inglés tool) ya que para el modelo representan acciones disponibles. Llamar a una herramienta significa solicitar que el código de esa función sea ejecutado como acción. El conjunto de acciones también define el alcance máximo del agente: por bueno que sea el razonamiento, el agente solo afecta al mundo mediante las acciones permitidas.
El razonamiento puede ser reemplazado. Percepción y acción son independientes de la función de decisión usada entre ellas. Una regla simple, un árbol de decisión, una rutina de búsqueda o una red neuronal pueden ejecutar el mismo bucle. Construir el bucle de un agente como una plantilla con dichos componentes plantea una pregunta doble: ¿qué capacidad tiene el razonamiento y hasta dónde llegan las acciones?

Las implementaciones clásicas de agentes difieren en la etapa de decisión (que como indicamos anteriormente tiene lugar durante la etapa de razonamiento). El libro Artificial Intelligence: A Modern Approach, de Russell y Norvig, organiza estas implementaciones en un espectro que va del agente basado en reflejo a un agente de aprendizaje capaz de mejorar sus propias reglas. Este curso comienza con lógica rígida y después añade un modelo de lenguaje y contexto proyectado, acercando el bucle al de un agente orientado a objetivos y basado en un modelo. En los módulos siguientes, el bucle continúa sobre un estado cambiante, siguiendo el patrón que sirve de base para los agentes de aprendizaje.

Cuatro arquitecturas con estructura creciente: desde un agente de reflejo que asigna acciones directamente a las entradas hasta un agente de aprendizaje que modifica sus propias reglas. Adaptado de Artificial Intelligence: A Modern Approach, de Russell y Norvig (capítulo 1).
¿Ejecutar el ciclo de agente basado en reglas más pequeño?

Un agente sin modelo de lenguaje

La función de decisión más simple es la instrucción if. En el siguiente ejemplo, dicha instrucción guía una pista unidimensional limitada por paredes entre las posiciones 0 y 9. Pulsa Ejecutar y observa cómo la posición de la pista rebota entre las paredes mientras el bucle se ejecuta.

Dos aspectos del código anterior merecen especial atención:

  • El entorno (las paredes y la posición actual) vive en state.env, mientras que el estado interno del agente (su dirección) vive en state.agent. Mantenerlos separados permite que otros agentes operen en el mismo entorno con un estado interno distinto.
  • El paso de razonamiento es una sola instrucción if. Sustituirla por un árbol de decisión, una red neuronal o un modelo de lenguaje solo cambiará lo que ocurre entre percepción y acción. La estructura del bucle, el estado y la acción permanecerían iguales.

Lo que cambia cuando el razonamiento llama a un LLM

La interfaz de Chat Completions se invoca como cualquier otra función: recibe una lista de mensajes y el nombre de un modelo, y devuelve el mensaje generado por el modelo junto con metadatos.

Acerca de chat(). Es la función auxiliar del curso que se ejecutará más adelante en esta página. El fragmento siguiente muestra el formato de la llamada y los campos devueltos.
const reply = await chat({
  model:    "nvidia/nemotron-3.5-lightning-30b-a3b",
  messages: [{ role: "user", content: "Hi" }],
});
// reply.choices[0].message  → { content, reasoning_content }
// reply.choices[0].finish_reason → "stop" | "tool_calls" | "length"

Tres aspectos de esta función determinan cómo deben funcionar los agentes construidos sobre ella:

¿Comparar dónde conservan las API el estado de la conversación?

Este curso usa la Chat Completions API que mantiene la conversación como un array messages[] en el código y reenvía el array completo en cada llamada. La API más reciente, Respuestas API puede, en cambio, mantener la conversación en el servidor: se envían solo la nueva entrada y una referencia a la llamada anterior. En ambos casos, el modelo sigue sin estado. La conversación vive fuera de él, en un estado que se conserva en el código o el servidor.

Las dos interfaces realizan la misma llamada sin estado. Solo cambia quién conserva la conversación entre llamadas.

Un ejemplo real en el navegador

Pulsa Ejecutar para enviar una única solicitud. No hay un bucle alrededor ni se conserva nada de una llamada anterior.

¿Inspeccionar la solicitud y la respuesta HTTP sin procesar?

Lo que chat() realmente envía

chat() es una función auxiliar que envuelve un único POST HTTP común en un formato compatible con OpenAI. Esta solicitud añade tres cosas:

  • el endpoint donde el modelo acepta peticiones,
  • las cabeceras de la solicitud; un endpoint personalizado puede requerir una cabecera Authorization,
  • y como contenido un JSON con model y messages.

La siguiente celda construye esa llamada manualmente. Abre request para examinar la URL, las cabeceras y el cuerpo, con cualquier valor de autorización oculto. Abre raw response para examinar el objeto completo devuelto por chat().

El endpoint del modelo utiliza este formato. El gateway de OpenClaw del módulo 3 expone un protocolo distinto para los turnos del agente, las sesiones y las operaciones del entorno de ejecución.

Configura un endpoint compatible en el panel del modelo antes de ejecutar la celda. Los endpoints alojados por NVIDIA requieren una clave de API de NVIDIA. Comprueba el acceso y la cuota del servicio seleccionado. El panel muestra el endpoint activo y la configuración de credenciales; examina la solicitud con los datos sensibles ocultos que aparece abajo antes de enviarla.

La ruta seleccionada determina qué servicio recibe la solicitud y su credencial. Una llamada desde el navegador requiere que el endpoint permita el origen del curso. El curso puede usar su servicio de retransmisión configurado si el proveedor no permite esa solicitud directa desde el navegador. Examina la ruta activa y las cabeceras de la solicitud en el panel del modelo.

Examina el helper de streaming. chatStream() procesa el texto de la respuesta, cualquier texto de razonamiento devuelto, los metadatos de uso y la señal de fin de la transmisión. Conecta la respuesta con el panel de la lección y el botón Stop. Abre el código fuente del helper desde el menú de la celda para examinar la solicitud y el manejo de eventos.
¿Comparar formas de razonar sobre el laberinto dentro de un ciclo fijo?

Cambiar la función de decisión sin cambiar el bucle

Los siguientes ejemplos mantienen el ciclo de percibir, razonar y actuar y varían su función de decisión. Compara reglas fijas y algoritmos de búsqueda antes de usar chat() para elegir un movimiento.

Ejecuta los nodos en orden. Cada uno aplica una regla de decisión diferente al mismo bucle que resuelve el laberinto:

  • La regla constante "siempre este" alcanza el objetivo en un pasillo recto, después se bloquea en la primera pared del laberinto, ya que un rumbo fijo no puede girar.
  • La búsqueda en profundidad (DFS) sigue una rama hasta el final antes de retroceder.
  • búsqueda en anchura (BFS) explora la frontera por niveles y encuentra el camino más corto en una rejilla sin pesos en sus celdas.
  • El A* utiliza una heurística de distancia para priorizar caminos prometedores sin perder la garantía de encontrar el camino más corto.
Solamente la etapa de decisión varía. DFS, BFS y A* leen el estado actual del laberinto y devuelven un movimiento. Una línea en el último nodo elige la función, mientras el bucle permanece igual para cada elección. En el siguiente ejemplo, el modelo elige entre varias ramas mientras un controlador registra las celdas exploradas y la ruta de regreso.

Cómo usar un modelo de lenguaje para elegir movimientos

El controlador registra las celdas visitadas y una ruta de regreso, descarta las ramas visitadas y recorre los pasillos. En los cruces, el modelo lee el mapa y elige el orden de las ramas mediante choose_direction. El controlador gestiona la exploración en profundidad; no proporciona al modelo una ruta resuelta.

Ejecuta las celdas en este orden y luego cambia un control cada vez:

  1. Comienza por el nodo motor. Este exporta las utilidades y un resolutor compartido state.runMaze, que recorre los pasillos del laberinto automáticamente y que llama al modelo solamente en las bifurcaciones.
  2. Ejecuta el nodo editable del agente de laberinto que aparece a continuación. DIRECTIVE es la instrucción principal del sistema; el objeto de opciones controla el modelo, el tamaño del laberinto, el mapa textual, el historial de movimientos, la ruta de coordenadas y la repetición del esquema de la herramienta.
  3. Comienza con los valores predeterminados que funcionan. Después, cambia model para comparar rutas con capacidades verificadas, elimina el historial o utiliza advanced para ampliar el laberinto cuando el caso sencillo ya funcione.
Valida la acción solicitada. El esquema de choose_direction declara los valores de dirección permitidos. El modelo solicita una dirección y el controlador comprueba el nombre de la herramienta y sus argumentos antes de moverse. Examina la solicitud y la respuesta para distinguir el esquema declarado de la validación que realiza tu código.

El bucle en detalle

En el ejemplo del laberinto, el controlador construye una solicitud para chat() y valida el movimiento devuelto antes de aplicarlo. Las etapas siguientes muestran ese intercambio.

  • Muestra local. El código lee una parte del entorno. Aquí lee la celda actual del laberinto y sus movimientos válidos. La solicitud también puede incluir el mapa completo y los turnos anteriores, según los controles seleccionados.
  • Percepción local. Esta parte se convierte en un contexto completo y preparado: el prompt de sistema, el historial acumulado de messages[], los resultados anteriores de herramientas y la parte que acabas de muestrear. En este ejemplo, el laberinto se representa como texto en los mensajes enviados al modelo.
  • Actuación local. El modelo transforma este texto en otro texto: una señal de intención, idealmente una llamada a herramienta tipada como { "move": "east" } en vez de prosa libre. La intención solo solicita una acción, y nunca ejecuta una. El código leará y aplicará una actualización en el entorno (doMove(...)), validándolo primero.
  • Impacto local. La actualización cambia el entorno. Nada permanece dentro del modelo. El estado permanente está en el entorno y en el contexto que el código reconstruirá. En la siguiente iteración, el muestreo local leerá el nuevo entorno y el bucle comienza de nuevo.

En este ejemplo, chat() recibe texto que describe el laberinto y devuelve una solicitud de movimiento. El controlador proporciona las observaciones, valida la solicitud y cambia el estado del laberinto. La llamada al modelo no ejecuta el movimiento.

Examina ambos límites: el contexto que recibe el modelo y la validación que realiza tu código antes de aplicar una acción solicitada.

Mostrar → entender → (texto → texto) → actuar → impactar
La solicitud del laberinto puede incluir el mapa completo y los turnos anteriores. Abre los detalles de la solicitud para ver qué contexto contiene. El módulo 1b construye el bucle de herramientas con un array explícito de mensajes.

Antes de continuar

Puedes responder cada pregunta ajustando el control en la celda anterior del laberinto con LLM y ejecutándola de nuevo.

  1. Compara el historial de conversación. Configura includeHistory:false y vuelve a ejecutar con el mismo perfil y laberinto. Compara el orden de las ramas, las decisiones en los cruces y el tiempo transcurrido con el historial activado. El controlador conserva las celdas visitadas y la ruta de regreso en ambas ejecuciones.
  2. Elimina la pista de estrategia de DIRECTIVE. Borra la línea que indica preferir las ramas sin explorar a las celdas visitadas y vuelve a ejecutar con el mismo perfil y laberinto. Compara el orden de las ramas, las decisiones en los cruces y el tiempo transcurrido. El controlador sigue descartando las ramas visitadas; repite las ejecuciones para comprobar si las diferencias persisten.
  3. Compara perfiles de modelo. Empieza con model:"direct" y luego compara model:"reasoning" y model:"omni" en el mismo laberinto. Examina el modelo, el presupuesto de tokens, la temperatura y los ajustes de razonamiento de cada solicitud. Estos perfiles cambian varios ajustes; compara el orden de las ramas y la latencia sin atribuir todas las diferencias únicamente a la identidad del modelo.

Pruébalo · compara el historial de conversación

Este chat comienza con el historial de conversación activado. Dile tu nombre y luego pregúntale cómo te llamas. Desactiva el control de memoria y vuelve a preguntar. Cada llamada a chat() recibe los mensajes que prepara la interfaz; con la memoria desactivada, se omiten los turnos anteriores. Compara las respuestas y examina cómo el código construye la solicitud.

Preferencias