Este curso es un taller guiado para leer y adaptar un bot de catálogo Python ya escrito. No vas a construir un agente autónomo desde cero ni a dejar una integración lista para producción. El navegador del curso es determinista: el mismo texto y el mismo catálogo producen la misma respuesta. El ejemplo repetido es una tienda ficticia, Tienda Luna, que recibe muchas preguntas de precio y disponibilidad; aquí solo veremos una copia de sus datos demo.
Objetivo: al terminar podrás extraer el kit, ejecutar sus pruebas y explicar qué ocurrió en una consulta.
Requisitos y vocabulario
Los comandos usan Bash (macOS, Linux o WSL en Windows), no PowerShell. Necesitas Python 3.10 o superior, y saber lo básico de funciones (una entrada y un retorno), diccionarios/listas de Python, JSON y rutas de archivos. No necesitas Telegram, Kapso, una cuenta de modelo ni una clave.
En este taller usaremos estas palabras:
- SKU: identificador del artículo (
A-100), no una cantidad de stock. - Traza: lista de operaciones que sí ejecutó el programa, por ejemplo
lookup_item. - Tool/herramienta: función permitida que consulta datos; en este kit es de solo lectura.
Extrae y ubícate
Descarga agente-catalogo.zip. Ajusta Downloads si tu navegador lo guardó en otra carpeta. El cd es importante: el ZIP contiene una carpeta superior llamada agente-catalogo. unzip -n conserva archivos que ya existan: no borres tu trabajo al repetir el taller.
mkdir -p "$HOME/Downloads" &&
unzip -n -q "$HOME/Downloads/agente-catalogo.zip" -d "$HOME/Downloads/agente-catalogo-trabajo" &&
cd "$HOME/Downloads/agente-catalogo-trabajo/agente-catalogo" &&
[ -f catalogo_core.py ] && [ -f catalogo.json ] &&
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -v
Si tu sistema no tiene unzip, abre el ZIP con su explorador; entra luego en la carpeta que contiene catalogo_core.py. La suite usa fixtures y transportes falsos: no hace llamadas de proveedor.
Ejercicio: texto plano frente a JSON
Estas dos consultas hacen operaciones distintas de presentación:
python3 -c 'from catalogo_core import respond; print(respond("stock A-100")["text"])'
python3 catalogo_core.py "stock A-100"
La primera imprime solo el campo text, por eso es texto plano: A-100: hay 23 unidades disponibles.. La segunda ejecuta la interfaz de línea de comandos y serializa la respuesta completa como JSON, con status, items y trace. No compares como si ambas salidas fueran JSON.
python3 -c 'from catalogo_core import respond; r=respond("stock A-100"); assert r["text"] == "A-100: hay 23 unidades disponibles."; print(r["text"])'
python3 catalogo_core.py "stock C-300" > respuesta.json
python3 - <<'PY'
import json
r=json.load(open("respuesta.json", encoding="utf-8"))
assert r["status"] == "out_of_stock"
assert r["items"] == ["C-300"]
assert any(step["op"] == "read_stock" for step in r["trace"])
print("JSON comprobado: agotado, SKU C-300 y traza local")
PY
Ejemplo de Tienda Luna
Imagina que una persona pregunta: «¿Cuánto cuesta y queda stock del teclado A-100?». Aquí tú traduces esa pregunta al comando ficha A-100: el programa base no interpreta esa frase completa. La respuesta sale de catalogo.json, un archivo ficticio versionado dentro del kit. No significa que Tienda Luna tenga ese inventario hoy: un hecho almacenado no es una medición fresca de un sistema externo.
Prueba también:
python3 catalogo_core.py "listar"
python3 catalogo_core.py "stock X-999"
C-300 es un artículo agotado; X-999 es un SKU desconocido. La diferencia importa: ausencia de registro no equivale a stock cero.
Resultado observable
Queda demostrado que el núcleo local carga un JSON conocido, valida la consulta y devuelve un contrato reproducible. No queda demostrado que Telegram o Kapso entreguen mensajes, que el proveedor de modelo esté disponible, ni que una tienda real esté sincronizada. El curso no hace llamadas de red en este taller.
Terminas cuando puedes señalar la carpeta extraída, explicar por qué una salida es texto y la otra JSON, y ver el OK de las pruebas.
Error habitual y recuperación
ModuleNotFoundError: No module named 'catalogo_core' suele indicar que ejecutaste desde otra carpeta. Comprueba pwd y que ls catalogo_core.py encuentra el archivo; después repite la consulta desde allí. Si necesitas contrastar contra el kit limpio, extrae el ZIP en otra carpeta nueva, sin borrar la copia donde trabajaste. Si python3 no existe, instala o selecciona Python 3.10+ en el entorno Bash antes de continuar.