Construí Thousand Token Wood para el Build Small Hackathon. Es una pequeña economía: cinco criaturas del bosque, cada una un agente ejecutado con Qwen2.5-3B, comercian cinco bienes por guijarros, chismes, acumulación y pánico. Toca el bosque y aparecen burbujas, quiebras y una brecha de riqueza que se amplía por sí sola.
Qué es y por qué importa
Thousand Token Wood es un experimento de ingeniería pensado para quienes construyen con modelos pequeños. La pila es sencilla: el modelo se sirve con vLLM en Modal, y la ventana hacia el bosque es una app en Gradio. Además hay un dataset de trazas abiertas donde cada fila guarda el prompt, la respuesta cruda, las acciones parseadas y el pensamiento privado del agente.
La idea práctica: una economía viva requiere muchos agentes pensando varias veces por paso. Usar un modelo de frontera para eso sale caro y lento; un 3B te permite hacer un consejo de comerciantes en tiempo razonable porque cada criatura decide en una sola llamada GPU batcheada por turno.
Lecciones de ingeniería (lo que realmente funciona)
-
Formato confiable, razonamiento incierto.
Qwen2.5-3Bgeneró JSON válido en el 100% de las llamadas, pero su juicio económico era pobre. Un agente que produce bellotas llegó a colocar una orden para comprar bellotas. ¿La solución? No subir de tamaño, sino afinar la señal: prompt sharper y estructura. -
Escasez diseñada. En la versión naive la producción superaba al consumo y nadie tenía incentivos para comerciar. Para generar intercambio introduje tres mecánicas sencillas:
- Dieta variada: una criatura solo puede comer una unidad de un mismo alimento por comida, así debe comprar lo que no cultiva.
- Podrido (spoiling): los alimentos perecederos se echan a perder si se acumulan, obligando a vender excedente.
- Crisis de leña invernal: cada criatura necesita quemar leña por turno, la demanda sube y solo una criatura fabrica leña. Esa última regla crea el drama económico.
-
Prompt engineering pragmático. En vez de escalar el modelo, instruí a cada agente sobre lo que produce y nunca debe comprar, calculé la lista exacta de bienes en déficit y le di un ejemplo trabajado. La calidad de las decisiones mejoró drásticamente.
-
Tolerancia al parseo. La capa de parse-and-repair transforma respuestas JSON malformadas en
no-opseguros en lugar de romper la simulación. Eso mantiene la experiencia fluida. -
Bienestar como estado estable. Modelé el bienestar inicialmente como un acumulador: los déficits crónicos llevaban a una espiral de muerte poco divertida. Lo reescribí como una mood media-revertible: mejora con comida y calor y nunca cae a cero. Las apuestas deben estar en guijarros, precios y estatus, no en el hambre absoluta.
-
Choques históricos como eventos jugables. Puedes dibujar una "Wood Legend": Tulip Mania vira a Gran Mania de la Bellota, South Sea Bubble a Compañía del Tronco Hueco, o la corrida de 1929 a la Corrida contra la Reserva de Oona. Esos relatos disparan choques reales en la economía y los agentes reaccionan sin scripting específico.
Un ejemplo concreto: la corrida de Oona
En una corrida reskinada, el rumor de que la bóveda del búho Oona estaba vacía provocó que Oona liquidara miel. La oferta inundó el mercado y el precio de la miel cayó de 10 a 3 en unas pocas rondas. No fue un guion: emergió de las decisiones locales bajo la mecánica de escasez y la deriva del precio.
¿Por qué se movieron los precios y antes no? Originalmente los agentes replicaban el precio de referencia que les mostraba el prompt. La corrección fue permitir que la referencia driftara con el residuo de oferta y demanda después de cada ronda: compras no satisfechas empujan el precio hacia arriba, un excedente lo baja. Con eso los precios trazan tendencias durante la escasez y permanecen estables cuando el mercado está balanceado.
Métricas representativas (corrida de 15 turnos)
| Métrica | Resultado |
|---|---|
| Valid JSON actions | 100% (75 de 75 llamadas) |
| Trades por turno | sostenidos 3 a 9, nunca silente |
| Precio de la miel | se desplomó 10 a 3 durante la leyenda de corrida |
| Precio de la leña | subió 4 a 7 cuando la escasez invernal pegó |
| Brecha de riqueza (Gini) | se amplió 0.14 a 0.38 |
| Resultado | el leñador terminó más rico, el acaparador quebró |
Esos movimientos están documentados en las trazas abiertas: cada decisión, prompt y parseo queda registrado para reproducir o estudiar.
Arquitectura y patrones de diseño (práctico)
- Servido con
vLLMenModalpara latencia y costo manejables. - Frontend en
Gradiopara iteración rápida y accesibilidad. - Batched inference: todos los agentes se evalúan en una sola llamada GPU por turno. Eso hace viable una simulación en tiempo real con un modelo pequeño.
- Parse-and-repair: cada respuesta pasa por un validador JSON. Si falla, la acción se convierte en
no-opy se anota para análisis.
Un ejemplo de regla de actualización de precios (pseudocódigo simple):
price += alpha * (unfilled_buy_orders - unfilled_sell_orders) / total_market_volume
Con alpha pequeño (por ejemplo 0.05) los precios trendan suavemente sin volverse erráticos por una sola orden grande.
Reflexiones técnicas y prácticas
La moraleja para quien construye con modelos pequeños es clara: los 3B son excelentes generadores de formato y muy prácticos para sistemas multiagente en tiempo real, pero su razonamiento requiere estructura. En la práctica eso significa:
- Diseñar escasez si quieres interacción.
- Restringir el espacio de decisión con prompts precisos y ejemplos.
- Aceptar y manejar respuestas imperfectas con tolerancia en el parseo.
- Poner las consecuencias en precios y estatus, no en fallos irreversibles.
Pequeños modelos, grandes aventuras: no necesitas un LLM gigantesco para observar comportamientos de mercado convincentes. A veces la historia económica ya contiene el drama; solo hace falta un sistema con limitaciones bien diseñadas para jugarlo.
Fuente original
https://huggingface.co/blog/build-small-hackathon/thousand-token-wood-sim
