Agentes de IA: ruta de aprendizaje

Agente de IA en Python: una práctica del ciclo con herramientas

Un ciclo de agente en Python conecta planificador, ejecución controlada de herramientas, observaciones y parada. Este laboratorio usa un planificador determinista para reproducir la mecánica sin una clave API. Para incorporar un modelo de lenguaje, sustituye la planificación mediante una interfaz documentada y conserva las comprobaciones de ejecución en la aplicación.

Equipo real trabajando con ordenadores portátiles

Necesitas Python 3 y nociones de funciones y diccionarios. El archivo utiliza la biblioteca estándar, un catálogo ficticio y salida por consola. No realiza solicitudes de red ni modifica archivos. Examina la traza antes de cambiar el ejemplo.

Ideas principales

  • Empieza con una herramienta de consulta y registros ficticios.
  • Valida nombre y argumentos antes de ejecutar.
  • Representa explícitamente el registro ausente.
  • Mantén el límite de pasos fuera del planificador.

Prepara entrada y criterio de aceptación

Guarda el archivo como ai-agent-lab.py y ejecuta python3 ai-agent-lab.py. La clave conocida 'ai' devuelve el registro almacenado tras una consulta y una decisión final. La traza muestra herramienta, entrada validada y resultado. Una clave ausente debe terminar con unknown, sin inventar un título. Esos resultados pertenecen al ejercicio: no son un benchmark de modelos. Escribe primero qué esperas comprobar para evaluar el comportamiento observado, en lugar de considerar correcto cualquier texto que aparezca en pantalla.

[1][2]

Entiende el planificador determinista

La función solicita una búsqueda y, después de recibir una observación, propone un resultado basado en ella. Es un simulador para estudiar el ciclo de ejecución. Sus decisiones están fijadas por código: no demuestra razonamiento ni comprensión del lenguaje de un modelo. Permite reproducir el comportamiento y observar qué cambia al modificar despacho o estado, sin variaciones de una respuesta API. Así separas las responsabilidades del controlador de una futura integración con un modelo.

Mantén estrecho el registro de herramientas

El registro contiene únicamente lookup. El despacho verifica tipo de acción, nombre registrado y un solo argumento key. La consulta comprueba que la entrada sea una cadena corta. No lo reemplaces por ejecución de código Python o comandos generados por el modelo. Un modelo futuro puede proponer la consulta estructurada, pero registro y validación siguen determinando qué se ejecuta. Examina también una propuesta rechazada: su estructura correcta no concede permiso para cualquier operación.

[3]

Inspecciona datos ausentes y límites

Lee estado y respuesta juntos. done indica un registro devuelto; unknown, una clave inexistente; stopped, presupuesto agotado. Prueba un solo paso: la consulta ocurre, pero no queda otra decisión para terminar. El resultado debe seguir detenido. Haber recibido información intermedia no equivale a completar el trabajo. Esta diferencia ayuda a informar con precisión cuando la aplicación alcanza un límite y a conservar lo que todavía necesita resolver antes de producir una respuesta final.

Práctica con Python

"""VITON13 SCHOOL: a deterministic teaching loop, without a model or network."""
import json

CATALOGUE = {
    "ai": {"title": "Applied AI", "topics": ["goals", "tools", "checks"]},
    "design": {"title": "Design", "topics": ["brief", "prototype", "review"]},
}


def lookup(key):
    if not isinstance(key, str) or not 0 < len(key) <= 32:
        raise ValueError("key must be a string of 1-32 characters")
    return CATALOGUE.get(key)


TOOLS = {"lookup": lookup}


def plan(state):
    """A simulator: replace this proposal function to study model integration."""
    if not state["observations"]:
        return {"type": "tool", "name": "lookup", "args": {"key": state["key"]}}
    return {"type": "final", "answer": state["observations"][-1]["result"]}


def run(key, planner=plan, max_steps=3):
    if type(max_steps) is not int or max_steps < 1:
        raise ValueError("max_steps must be a positive integer")
    state = {"key": key, "observations": []}
    for _ in range(max_steps):
        action = planner(state)
        if not isinstance(action, dict):
            raise ValueError("proposal must be an object")
        if action.get("type") == "final":
            if not state["observations"]:
                raise ValueError("final result requires an observation")
            result = state["observations"][-1]["result"]
            if action.get("answer") != result:
                raise ValueError("final answer must match the retrieved record")
            return {
                "status": "done" if result is not None else "unknown",
                "answer": result, "trace": state["observations"],
            }
        if action.get("type") != "tool" or action.get("name") not in TOOLS:
            raise ValueError("tool is not allowed")
        args = action.get("args")
        if not isinstance(args, dict) or set(args) != {"key"}:
            raise ValueError("lookup requires exactly one key argument")
        if args["key"] != state["key"]:
            raise ValueError("lookup is outside the requested key")
        result = TOOLS[action["name"]](**args)
        state["observations"].append({
            "tool": action["name"], "input": dict(args), "result": result,
        })
    return {"status": "stopped", "answer": None, "trace": state["observations"]}


if __name__ == "__main__":
    print(json.dumps(run("ai"), indent=2))
Descargar el ejemplo de Python ↓

Conecta el modelo después de comprobar los límites

Sustituye la planificación por un adaptador que devuelva la misma estructura utilizando la interfaz documentada del proveedor. Pasa objetivo y observaciones relevantes, valida la propuesta y ejecuta fuera del modelo. Prueba nombres incorrectos, argumentos mal formados, registro ausente y respuesta sin evidencia. El adaptador también necesita manejar errores del proveedor y límites de uso. El laboratorio aporta la base del control; la integración completa requiere otra verificación con los mismos criterios y nuevos casos representativos.

En palabras sencillas

El laboratorio es una maqueta de la maquinaria. Un planificador fijo ocupa el lugar de quien propone la acción. Puedes observar herramienta, cuaderno y parada antes de conectar un modelo que proponga acciones diferentes.

Pruébalo

Ejecuta la clave conocida, una desconocida y un presupuesto de un paso. Sustituye después el planificador por otro que solicite una herramienta no registrada. Predice las salidas y compáralas con lo ocurrido.

Resultado esperado

Un resultado con fuente, otro unknown, otro stopped y una propuesta rechazada. La herramienta prohibida nunca debe ejecutarse.

Comprueba tu respuesta: ¿Qué cambia al conectar un modelo de lenguaje?

La generación de propuestas. Permisos, validación, estado y límites siguen siendo responsabilidades del código.

Preguntas y respuestas

¿Este ejemplo exige una API de pago?

No. Utiliza planificación determinista y un diccionario local, sin cuenta ni clave API. El adaptador de modelo es una extensión aparte: requisitos y costes dependen del proveedor elegido. Su comportamiento debe probarse, aunque el ciclo educativo ya haya pasado sus comprobaciones.

¿Puedo utilizar el laboratorio en producción?

El laboratorio enseña el ciclo con registros ficticios. Una aplicación real necesita integración de modelo, autenticación, recuperación, controles de acceso, observabilidad y verificaciones de la tarea. Constrúyelas y pruébalas con casos representativos. Una ejecución de clase correcta no demuestra preparación para desplegar.

Ejecuta el ejemplo, revisa cada estado y prueba una propuesta prohibida. Conserva esos controles al añadir el modelo.

Fuentes y lecturas

  1. Python documentation — Control flow ↗Fuentes revisadas:
  2. Python documentation — Data structures ↗Fuentes revisadas:
  3. Anthropic — Writing effective tools for agents ↗Fuentes revisadas: