MinecraftButlerAI es un backend FastAPI que da vida a un mayordomo ("Alfred") dentro de Minecraft: entiende preguntas en lenguaje natural (por texto o por voz), responde con conocimiento real del juego y ejecuta acciones en el mundo. Más que una simple llamada a un LLM, es una arquitectura agéntica donde cada pieza resuelve un problema concreto, desde el enrutado de intenciones hasta la recuperación de conocimiento y la síntesis de voz.
El butler combina un agente LangGraph con memoria persistente, un sistema RAG multilingüe sobre la documentación del juego y un pipeline de voz local, todo ello expuesto mediante una API HTTP autenticada con JWT y pensada para producción (rate-limiting, migraciones, observabilidad).
Demo
Tres preguntas en una misma sesión, cada una probando una capacidad distinta del agente.
¿Cómo se hace una espada de hierro?
Se craftea con 2 lingotes de hierro y 1 palo. Los lingotes van en los dos espacios superiores de la columna central y el palo en el espacio inferior.
¿Tengo lo necesario para hacer una?
No. Te faltan los lingotes de hierro. Tienes palos en el inventario pero ningún lingote de hierro.
¿Qué cultivos están listos para recoger?
Tienes 5 zanahorias, 2 patatas y 6 de trigo listos para cosechar.
Trazas con LangSmith


Arquitectura del agente
El butler se modela como un grafo de nodos con LangGraph: un primer nodo clasifica la intención del usuario y el grafo enruta de forma determinista (un diccionario intención → nodo, no "magia del LLM") a una de tres ramas: responder una pregunta con RAG, moverse a unas coordenadas o conversar.
El estado del grafo (ButlerState) es un TypedDict tipado cuyo campo de mensajes usa el reducer add_messages de LangGraph, lo que acumula el historial automáticamente. El grafo se compila una sola vez (singleton protegido con asyncio.Lock) con un checkpointer AsyncRedisSaver: cada sesión persiste su estado en Redis con TTL, dando memoria conversacional multi-turno por jugador sin gestión adicional en el cliente.
La clasificación de intención usa Claude Haiku 4.5 (rápido y barato) con structured output (un objeto Pydantic validado, no texto libre a parsear), mientras que la respuesta final usa Claude Sonnet 4.6. Ambos modelos se obtienen a través de un factory que abstrae por rol ("clasificador"/"respondedor") y por proveedor (Anthropic u OpenAI), de forma que el código pide capacidades, no modelos concretos.
RAG multilingüe
El conocimiento del juego se indexa en inglés a partir de PrismarineJS/minecraft-data y extractos de la Minecraft Wiki, pero los usuarios preguntan en español. Para resolver ese salto de idioma se usan embeddings cross-lingual densos (paraphrase-multilingual-MiniLM-L12-v2) con búsqueda por similitud coseno en Qdrant.
El diseño original incluía un pipeline híbrido completo (rama sparse BM42 + reranker FlashRank), que se descartó tras validar con datos reales: ambos componentes son léxicos y solo-inglés, por lo que con consultas en español el sparse devolvía ruido y el reranker no sabía reordenar resultados ES→EN. La conclusión, medida y documentada en el código, es que el denso multilingüe es superior por sí solo en ambos idiomas.
Para las mecánicas de la wiki se usa Parent Document Retrieval: se indexan chunks pequeños (~800 caracteres) que producen embeddings precisos, pero se recupera y se pasa al LLM el bloque padre completo (~2000 caracteres), resolviendo la tensión entre precisión de recuperación y suficiencia de contexto.
Voz y producción
La respuesta se emite por Server-Sent Events frase a frase (no token a token), porque el cliente la sintetiza por voz (TTS) y un TTS necesita frases completas para sonar natural; esto da percepción de inmediatez sin trocear el audio.
La transcripción de voz se realiza on-device con faster-whisper en cuantización int8 (más rápido y con la mitad de memoria que float32, sin pérdida apreciable), con el modelo precalentado en el arranque para evitar cold-start y sin enviar el audio del usuario a terceros.
El backend está pensado para producción: autenticación JWT con roles, rate-limiting con SlowAPI, migraciones Alembic, arquitectura por slices (router/schemas/service/repository) y observabilidad opcional de cada ejecución del agente con LangSmith.