Kimi K3 en Moonshot como agente de programación: integración en OpenClaw, evaluación comparativa con dsh y solicitud de un widget de logotipo en estilo pixel art.
- Categoría
- IA y LLM Local
- Publicado
- 12 septiembre 2026
- Actualizado
- 12 septiembre 2026
- Por
- Jacob Lloyd — escrito con ayuda de IA, después del proyecto
- Tiempo de lectura
- 30 min de lectura
En palabras simples: Conecté el modelo de razonamiento Kimi K3 de Moonshot al software de agentes que ejecuto en casa; le di las mismas cinco tareas de programación que utilicé en agosto para probar el asistente de codificación de DeepSeek (dsh), y le pedí que creara una versión en pixel art del logotipo de este sitio, basándose en la misma descripción escrita. Superó las cinco tareas, pero tardó unas nueve veces más y costó unas 48 veces más que dsh con el modelo rápido de DeepSeek. Para generar el widget del logotipo fueron necesarios tres intentos: el primero tardó unos nueve minutos sin producir ningún resultado; el segundo sí creó un widget funcional, pero lo colocó en la carpeta equivocada y se quedó sin tiempo antes de avisarme; solo lo encontré más tarde. El tercer intento tuvo éxito, después de acortar la descripción y pedirle que omitiera la fase de planificación.
Apunté mi agente trabajador OpenClaw hacia Kimi K3, el modelo de razonamiento estrella de Moonshot, y lo sometí a las mismas cinco tareas de programación que utilicé en agosto para hacer el benchmark del DeepSeek Harness (dsh). Kimi superó las cinco pruebas. En comparación con dsh ejecutándose sobre DeepSeek V4-Flash, que realizó esas mismas tareas el mismo día, Kimi tardó aproximadamente 9 veces más (309,9 s frente a 35,7 s) y costó alrededor de 48 veces más ($0,531 frente a $0,011). Luego le entregué el mismo brief de diseño de logo en pixel art que dsh había utilizado para generar su widget. Kimi necesitó tres intentos: el primero, con el brief sin modificar, no produjo ningún widget; el segundo, con el mismo brief, escribió un widget completo de 323 líneas en la carpeta equivocada y se interrumpió por el límite de tiempo antes de notificármelo; el tercer intento, tras acortar el brief y pedirle que omitiera la fase de planificación, funcionó correctamente.
Resumen rápido
- ¿Qué es? Kimi K3 a través de la API compatible con OpenAI de Moonshot, impulsando el bucle agente nativo de OpenClaw (lo llamo “Camino A”). No se trata de la aplicación Codex: el plugin del harness de Codex solo acepta rutas de proveedores OpenAI (comprobado en el propio código de OpenClaw 2026.9.2).
- Configuración: plugin del proveedor Moonshot (
@openclaw/moonshot-provider2026.9.2), URL basehttps://api.moonshot.ai/v1, y variable de entornoMOONSHOT_API_KEYen la puerta de enlace. Mi configuración del modelo permite niveles de esfuerzo de razonamientolow,highymax; rechaza el parámetrotemperaturey limita el contexto a 262.144 tokens, de los 1.048.576 anunciados. - Benchmark: cinco tareas en carpetas nuevas. Kimi K3: 5/5, 309,9 s, $0,531. dsh sobre V4-Flash, en una segunda ejecución (ya “caliente”) de las mismas tareas: 5/5, 35,7 s, $0,011.
- El widget: tres intentos. El primero se detuvo tras 8,8 minutos sin generar código. El segundo escribió un widget completo de 323 líneas y sus propias pruebas, pero en el área de trabajo del agente en lugar de la carpeta que yo supervisaba; además, excedió el límite de tiempo de 15 minutos antes de notificarlo. El tercer intento, con un brief acortado que decía
TARGETED — write the widget file in one tool call, no exploration, no planning, no verification loop., finalizó en 7,4 minutos y costó $0,47. El widget que ven aquí proviene de ese tercer intento; cumple connode --checky se monta sin errores. - Costos y caché: el 80% de los tokens de entrada de Kimi provinieron del caché. Sin él, la misma ejecución habría costado unos $1,49 en lugar de $0,53. Las tarifas son $3 por millón de tokens de entrada, $15 por millón de tokens de salida y $0,30 por cada millón de tokens leídos del caché.
- Posición actual de Kimi: Kimi fue el modelo utilizado por mi agente para este benchmark. A fecha de 2026-09-11, mi agente trabajador usa MiniMax-M3; sin embargo, Kimi K3 sigue respaldando a mi agente de revisión.
Camino A vs Camino B, sinceramente
Todo lo que se describe aquí corresponde al Camino A: Kimi K3 ejecuta el bucle de agente propio de OpenClaw a través del proveedor Moonshot. En mi equipo, el proveedor ya estaba configurado, así que cambiar el modelo a Kimi fue simplemente un cambio en la configuración.
El Camino B consistiría en poner a Kimi detrás del propio servidor de aplicaciones Codex, el cual es gestionado por el plugin Codex de OpenClaw (el plugin controla @openai/codex 0.153.4). Yo no lo desarrollé, y nada en este artículo se ejecuta mediante Codex. La razón está en el código del plugin: su función de verificación de rutas, configuredModelRouteNeedsCodex, devuelve false para cualquier proveedor cuyo ID normalizado no sea openai. El ID del proveedor Moonshot es moonshot; por eso, una ruta como moonshot/kimi-k3 nunca llega al entorno de ejecución de Codex.
La solución conocida es codex-router, un puente local que redirige las solicitudes de Codex a un endpoint en 127.0.0.1:4202 y luego las reenvía a Kimi (según su README). Para que el harness detecte esta configuración, el parámetro appServer.homeScope del plugin debe ser "user"; esto hace que el entorno ~/.codex (o $CODEX_HOME) se comparta entre el harness y Codex, en lugar de aislar el estado de Codex por cada agente de OpenClaw. Aún no he decidido si me parece aceptable este enfoque; por eso el Camino B sigue siendo solo teórico.
El Camino A tiene ciertas limitaciones que conviene conocer. Los informes de turno muestran agentHarnessId: "openclaw", igual que cualquier otro modelo nativo de OpenClaw. No se dispone de funcionalidades como la reanudación de hilos en Codex, su mecanismo de compactación, el puente de herramientas dinámicas ni el modelo de ejecución del servidor de aplicaciones. Si necesita esas características, el Camino B es la única opción.
Configuración: en qué entorno lo ejecuté
Estos son los comandos que ejecuté en mi equipo el 11 de septiembre de 2026, junto con sus resultados reales:
$ node -v
v24.18.0
$ openclaw --version
OpenClaw 2026.9.2 (3928bad)
$ dsh --version
0.1.1-rc.2
$ openclaw plugins list --json | jq -c '.plugins[] | select(.id=="moonshot") | {id, enabled, version}'
{"id":"moonshot","enabled":true,"version":"2026.9.2"}
$ openclaw config get models.providers.moonshot.models.0.compat
{
"supportsReasoningEffort": true,
"supportsTemperature": false,
"supportedReasoningEfforts": [
"low",
"high",
"max"
]
}
$ openclaw config get models.providers.moonshot.models.0.contextTokens
262144
Tres cosas que vale la pena saber antes de ejecutar cualquier cosa:
- K3 siempre realiza razonamiento. El plugin envía por defecto
reasoning_effort: "max"y acepta los valoreslow,highymax; yo ejecuté el benchmark con--thinking max. Además, elimina cualquier configuración de muestreo (temperature,top_py similares) ya que K3 las fija automáticamente; mi entrada de modelo indica lo mismo mediantesupportsTemperature: false. Incluso el comando “Responda exactamente: PONG.” consumió 53 tokens de razonamiento. - Se anuncia un contexto de 1 millón de tokens; yo lo limito. El catálogo Moonshot de OpenClaw indica que K3 admite hasta 1,048,576 tokens de contexto. Sin embargo, he configurado
contextTokens: 262144en la entrada del modelo para que las sesiones se compriman al mismo punto que con mis otros modelos. En la práctica, con ese límite se usarán unos 256k tokens, no 1 millón. - La caché es clave para reducir costos. Cada tarea comienza con aproximadamente 15k tokens provenientes del prompt del sistema y de las definiciones de herramientas. Tras el primer paso, la mayor parte de esos datos se lee desde la caché a un costo de $0.30 por millón de tokens, en lugar de $3. En la tarea de renombrado, solo las lecturas desde la caché sumaron 157,952 tokens.
El proceso: desde lo básico hasta lo avanzado
Los pasos del 1 al 3 le permitirán tener un modelo funcional. Los pasos 4 y 5 son lo que hice a continuación.
Paso 1: instale el plugin y proporcione la clave
Estos son los pasos que se indican en la documentación oficial de OpenClaw. En mi sistema, el plugin y la clave ya estaban configurados; por eso solo ejecuté la comprobación de la última línea (su salida aparece en el bloque de configuración anterior).
openclaw plugins install @openclaw/moonshot-provider
openclaw gateway restart
openclaw plugins list --json | jq -c '.plugins[] | select(.id=="moonshot") | {id, enabled, version}'
El plugin lee la clave desde MOONSHOT_API_KEY. Yo la guardo en el archivo de entorno que carga mi servicio de gateway; además, mi archivo openclaw.json no contiene ninguna clave. La documentación también sugiere usar openclaw onboard --auth-choice moonshot-api-key si prefiere que el proceso se realice paso a paso. El endpoint por defecto es https://api.moonshot.ai/v1; para la región de China, se utiliza https://api.moonshot.cn/v1 (opción de autenticación: moonshot-api-key-cn).
El catálogo del plugin incluye K3, K2.7 Code y K2.7 Code HighSpeed. El plugin se encarga automáticamente de gestionar las particularidades de Kimi: para K2.7 es necesario omitir tanto thinking como reasoning_effort en la solicitud, algo que el plugin hace por usted. Tenga cuidado con los nombres de las variables de entorno: MOONSHOT_API_KEY corresponde a la plataforma abierta de Moonshot; por su parte, KIMI_API_KEY pertenece al servicio independiente Kimi Code (kimi/kimi-for-coding).
Paso 2: apunte su agente trabajador a K3
Las partes relevantes de mi archivo openclaw.json durante el benchmark, con mi agente trabajador renombrado como worker:
{
agents: {
entries: {
worker: {
model: {
primary: "moonshot/kimi-k3",
fallbacks: ["deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-pro"],
},
},
},
},
models: {
providers: {
moonshot: {
baseUrl: "https://api.moonshot.ai/v1",
api: "openai-completions",
timeoutSeconds: 1200,
models: [
{
id: "kimi-k3",
name: "Kimi K3",
reasoning: true,
input: ["text", "image"],
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 131072,
contextTokens: 262144,
compat: {
supportsTemperature: false,
supportsReasoningEffort: true,
supportedReasoningEfforts: ["low", "high", "max"],
},
},
],
},
},
},
}
Un error me causó una regresión silenciosa: en OpenClaw 2026.9.2, un bloque compat dentro de la entrada del modelo sustituye al objeto compat propio del plugin. No se realiza ninguna fusión de datos. En una versión anterior, mi entrada solo contenía supportsTemperature: false, lo cual eliminó silenciosamente la compatibilidad con el parámetro reasoning-effort del plugin. Si decide incluir un bloque compat, escriba todo el objeto, tal como se muestra arriba.
La línea contextTokens: 262144 representa el límite indicado en las instrucciones de configuración. Si lo aumenta, tenga en cuenta que el costo por lecturas de caché y la latencia por turno también aumentarán a medida que dure la sesión.
Paso 3: la prueba de verificación y el JSON que genera
Cada tarea de referencia consistió en una llamada como esta, utilizando una clave de sesión nueva cada vez:
openclaw agent --agent <your-agent-id> --model moonshot/kimi-k3 --thinking max \
--session-key "<fresh-key>" --message-file prompt.txt --json > out.json
Estos son los campos importantes, extraídos del paquete de datos guardado de la tarea PONG:
$ jq '.result | {harness: .meta.agentMeta.agentHarnessId, model: .meta.executionTrace.winnerModel, usage: .meta.agentMeta.usage}' out.json
{
"harness": "openclaw",
"model": "kimi-k3",
"usage": {
"input": 15068,
"output": 70,
"reasoningTokens": 53,
"total": 15138,
"cost": {
"total": 0.046254
}
}
}
harness: "openclaw" es la firma característica de la Ruta A. Una ejecución a través del servidor de aplicaciones Codex mostraría "codex". winnerModel: "kimi-k3" indica que la ejecución realmente se realizó en K3 y no se recurrió a un modelo más económico. reasoningTokens se cuentan dentro de output (el total es la suma de input y output); por lo tanto, los 53 tokens de razonamiento forman parte de los 70 totales.
Comparativa: Kimi K3 en OpenClaw vs dsh
Ambos son bucles de agente que leen archivos, ejecutan comandos del shell y cobran por cada token procesado. La diferencia radica en quién desarrolla cada uno y en cómo se controlan.
| Kimi K3 en OpenClaw (Ruta A) | dsh | |
|---|---|---|
| Desarrollador | Modelo: Moonshot AI. Bucle de agente: OpenClaw | DeepSeek (modelo y entorno), MIT |
| Llamarlo desde un script | openclaw agent --agent <id> --model moonshot/kimi-k3 -m "…" --json | dsh --profile headless "…" |
| Cambiar de modelo | El parámetro model.primary en el archivo openclaw.json | ~/.dsh/settings.yaml |
| Prueba de rendimiento sin interfaz, 5 tareas pequeñas | 309,9 s, ≈ $0,531, 5/5 | 35,7 s, ≈ $0,011, 5/5 (V4-Flash; la segunda ejecución fue más rápida) |
| Creación de un widget de pixel art, con las mismas instrucciones | 3 intentos; dos de ellos generaron un widget. El que se muestra aquí tardó 7,4 minutos y costó ≈ $0,47 | 2 intentos; el que tuvo éxito tomó 25 minutos y costó ≈ 49 centavos |
| Versión probada | OpenClaw 2026.9.2, plugin de Moonshot 2026.9.2 | 0.1.1-rc.2 (versión preliminar para desarrolladores) |
En comparativas anteriores en este sitio aparecía una columna de Reasonix. El 9 de septiembre de 2026 eliminé Reasonix de mi máquina, por eso no figura aquí; su artículo de julio permanece como registro histórico. También probé MiniMax M3 con el mismo conjunto de pruebas; MiniMax es una empresa distinta a Moonshot, y ese experimento cuenta con su propio análisis.
El punto de referencia: las mismas 5 tareas
Estas son las mismas cinco tareas que se ejecutaron en el artículo sobre dsh; cada una se realizó en una carpeta temporal nueva, con una sesión distinta para cada tarea de Kimi. Ese mismo día volví a ejecutar dsh en V4-Flash con esas mismas cinco tareas, fijando deepseek-v4-flash en un archivo de configuración temporal. La redacción de los prompts no fue idéntica. dsh se ejecuta desde la carpeta donde se inicia, por lo que sus prompts hacían referencia al “directorio actual”. Los prompts de Kimi indicaban la ruta absoluta de cada carpeta de tarea; además, el prompt de corrección de errores de Kimi incluía el siguiente texto: “Si pytest no está disponible, instálelo primero con ‘pip install --user pytest’”. En realidad, pytest ya estaba instalado y Kimi nunca llegó a ejecutar ese comando. Esa columna corresponde a la segunda ejecución: la primera tomó 44.8 segundos y costó $0.024 con una caché vacía; la segunda es la que comparo en todo este artículo. Las columnas de V4-Pro y Gemma-4-26B provienen del artículo sobre dsh publicado en agosto, y no se volvieron a ejecutar. El tiempo total incluye todo el proceso. Los datos de tokens y costos de Kimi provienen del archivo JSON generado por OpenClaw; los de dsh, de su propio registro de sesión.
| Tarea | Kimi K3 (Ruta A) | dsh V4-Flash (mismo día) | dsh V4-Pro (agosto, datos históricos) | Gemma-4-26B (agosto, datos históricos) |
|---|---|---|---|---|
| Responder “PONG” (arranque + una llamada) | ✅ 6.1 s · 0 herramientas | ✅ 1.7 s · 0 herramientas | ✅ 2.8 s | ✅ 13.2 s* |
| Escribir y ejecutar FizzBuzz | ✅ 22.8 s · 2 herramientas (write, exec) | ✅ 5.3 s · 3 herramientas | ✅ 8.4 s · 2 herramientas | ✅ 4.9 s · 2 herramientas |
| Corregir 2 errores para que las pruebas unitarias pasen (las pruebas no se modificaron) | ✅ 86.6 s · 6 herramientas (exec, write, edit) | ✅ 11.3 s · 7 herramientas | ✅ 15.8 s · 7 herramientas | ✅ 10.4 s · 8 herramientas |
| Resumir un código de 6 módulos (menos de 150 palabras) | ✅ 65.5 s · 10 herramientas (read, exec, write) | ✅ 5.1 s · 7 herramientas | ✅ 10.9 s · 7 herramientas | ✅ 12.1 s · 7 herramientas |
| Cambiar el nombre de una función en 3 archivos y sus pruebas; verificar que todo funciona | ✅ 128.9 s · 9 herramientas (exec, write; un solo sed en todos los archivos) | ✅ 12.3 s · 11 herramientas | ✅ 18.2 s · 12 herramientas | ✅ 12.2 s · 11 herramientas |
| Tiempo total | 309.9 s | 35.7 s | 56.1 s | 52.8 s |
| Tokens: entrada sin caché / lectura desde caché / salida (razonamiento) | 91,470 / 355,328 / 9,990 (4,053) | 6,141 / 147,328 / 4,697 (1,984) | 41.4k / 107k / 3.2k | 40.5k / 237k / 5.6k |
| Costo | ≈ $0.531 ($3 / $15 / $0.30 por millón) | ≈ $0.011 ($0.44 / $1.32 / $0.014 por millón) | ≈ $0.072 | $0 (solo costo de electricidad) |
El número de herramientas corresponde a las llamadas realizadas. Los datos de Kimi provienen de toolSummary.calls en el archivo JSON generado por OpenClaw; los tipos de herramientas aparecen entre paréntesis. Los datos de dsh provienen de su registro de sesión. *Primera llamada después de que el modelo se cargó en el sistema. Las tarifas de Kimi son las que figuran en mi entrada del catálogo de OpenClaw, que éste utiliza para calcular el costo de cada tarea; consulte la página de precios de Moonshot para ver las cifras actuales. El costo de dsh V4-Flash se calcula usando las mismas tarifas máximas que en el artículo sobre dsh (tarifas de DeepSeek); los datos de V4-Pro y Gemma provienen del mencionado artículo.
Lo que indica la tabla:
- 5/5 en todas las columnas. Ninguna de estas tareas supuso un problema para Kimi. La corrección de errores no modificó las pruebas, y el cambio de nombre se logró con un único comando
seden cuatro archivos; posteriormente se ejecutaron las pruebas sin problemas y se realizó ungreppara confirmar que el nombre antiguo ya no aparecía. - Kimi dedica más tiempo al razonamiento. K3 utilizó 53, 241, 315, 1,586 y 1,858 tokens de razonamiento en las cinco tareas (4,053 en total). dsh en V4-Flash también razona, pero en menor medida: 0, 52, 834, 5 y 1,093 tokens (1,984 en total). La mayor parte del tiempo adicional empleado por Kimi se debe a su proceso de razonamiento y a los pasos adicionales que realiza.
- La caché influye mucho en el costo. En las cinco tareas, Kimi envió 91,470 tokens de entrada sin caché y leyó 355,328 tokens desde la caché; esto significa que el 80 % de sus tokens de entrada provinieron de la caché. Si todos esos tokens se hubieran considerado como entrada sin caché, el costo total habría sido de aproximadamente $1.49 en lugar de $0.53.
- Para tareas pequeñas, V4-Flash es la mejor opción. El conjunto completo de tareas se ejecutó en 35.7 segundos y costó unos $0.011; esto representa un tiempo aproximadamente 9 veces menor y un costo 48 veces más bajo que los valores obtenidos por Kimi, con el mismo resultado. Solo el cambio de nombre tomó 128.9 segundos y $0.180 en Kimi, mientras que dsh lo hizo en 12.3 segundos y $0.0043.
La prueba divertida: el mismo encargo para crear un widget, Kimi vs dsh
En el artículo de dsh, la “prueba divertida” consistía en crear un widget de arte pixelado con el logo de este sitio, elaborado por dsh mediante V4-Flash a partir de un encargo escrito. Le entregué a Kimi ese mismo encargo, sin modificaciones, y cronometré el proceso. El encargo era el siguiente:
Encargo: widget interactivo de arte pixelado con el logo de LaserLloyd
Elabore una versión de arte pixelado del logo de LaserLloyd (véase
reference-logo.png: un anillo azul grueso, color #1f3f8f sobre fondo blanco, que contiene dos letras “L” mayúsculas inclinadas; el pie de la “L” superior izquierda se ubica debajo del tallo de la “L” inferior derecha, como si las letras estuvieran apiladas en diagonal).Entregables (todos en esta carpeta)
ll-pixel-logo.js: UN único archivo de JavaScript puro, sin dependencias, sin pasos de compilación ni solicitudes de red. Cualquier página puede integrarlo con:<div class="ll-pixel-logo" data-size="320"></div>+<script src="ll-pixel-logo.js"></script>. El código busca todos los elementos.ll-pixel-logoy monta un<canvas>dentro de ellos. Es responsivo: el canvas ocupa todo el ancho del contenedor (formato cuadrado) y se muestra nítido en pantallas HiDPI (según devicePixelRatio). Debe exponer la funciónwindow.LLPixelLogo.mount(el).index.html: una página de demostración que muestra el widget en 3 tamaños, acompañada de una breve descripción de sus interacciones.README.md: instrucciones para integrar el widget, explicación de sus interacciones y detalles sobre los atributos personalizables.El diseño artístico
- Una cuadrícula de píxeles de 40×40 celdas. NO dibuje a mano el bitmap (evite usar cadenas de caracteres tipo ‘#’ o ‘.’; este método es lento y propenso a errores). En su lugar, genere el diseño mediante algoritmos procedimentales a partir de geometría: implemente una función
isLit(col,row)que devuelva true para: (a) los puntos dentro del anillo: distancia desde el centro entre 0.82R y R; y (b) para las dos letras “L” inclinadas, cada una compuesta por dos paralelogramos (un tallo inclinado unos 20° y un pie). El pie de la “L” superior izquierda debe quedar justo debajo del tallo de la “L” inferior derecha, tal como muestra el logo de referencia. Ajuste las pocas constantes necesarias para que el resultado se parezca al logo original a escala 200px. Calcule previamente las celdas iluminadas durante el montaje del widget.- Paleta de colores: azul del logo #1f3f8f; azul de resaltado #2ea8ff; ámbar #ffb64a; cian #00e6cf; fondo transparente.
Interacciones (el objetivo principal: que sean agradables)
- Pasar el ratón o tocar la pantalla: los píxeles cercanos al cursor reaccionan físicamente; por ejemplo, son empujados lejos del cursor como si fueran fluidos o estuvieran sometidos a repulsión magnética, para luego regresar a su posición original con amortiguación. Mientras se desplazan, brillan en los tonos #2ea8ff/#00e6cf. Todo debe ejecutarse a 60fps mediante requestAnimationFrame; sin ralentizaciones.
- Hacer clic o tocar: implemente un efecto llamativo y satisfactorio. Elija UN solo efecto y hágalo bien: por ejemplo, que todo el logo se fragmente en píxeles que vuelan hacia afuera bajo la influencia de la gravedad y el rebote, para luego volver a formarse como logo (aprox. 1.5–2 segundos); o bien, que un “láser” recorra el espacio grabando nuevamente el logo píxel por píxel con chispas brillantes. Los clics repetidos deben sentirse gratificantes (no interrumpa la animación en curso).
- Estado de reposo: añada un leve movimiento ambiental (un titileo lento o el parpadeo ocasional de algún píxel) para que el widget nunca parezca inactivo, pero sin resultar molesto.
- Respete la directiva
prefers-reduced-motion: reduce: muestre únicamente el logo estático y mantenga solo el efecto de resplandor al pasar el ratón.- Debe funcionar tanto con ratón como con pantallas táctiles. No interfiera con el desplazamiento vertical de la página.
Criterios de calidad
- Código limpio y bien comentado; no se deben usar variables globales, salvo
LLPixelLogo. El ancho de tabulación debe ser 2. El código total no debe superar las 400 líneas.- Debe ejecutarse correctamente desde
file://sin generar errores en la consola. Usted mismo puede probarlo: escriba un pequeño script de Node o ábralo con cualquier herramienta disponible para verificar su sintaxis y el correcto funcionamiento del módulo (no dispone de jsdom; utilicenode --checky realice una comprobación unitaria independiente del DOM, por ejemplo, contando las celdas iluminadas y asegurándose de que el anillo y las dos letras “L” aparezcan en los cuadrantes correctos).- Al final, imprima un breve informe: qué ha creado, cómo integrar el widget y qué validaciones realizó.
Cómo lo manejó Kimi:
- Intento 1 (el encargo original, sin modificaciones): se detuvo tras 8.8 minutos; no generó código para el widget; costo ≈ $0.31. K3 analizó el logo de referencia, reflexionó sobre la geometría y las herramientas necesarias, pero no escribió ninguno de los entregables. El primer intento de dsh también fracasó de forma similar (una rutina de 10 minutos para dibujar mentalmente un bitmap), aunque en ese momento el encargo aún permitía el dibujo manual de bitmaps.
- Intento 2 (nuevo inicio, mismo encargo): produjo un widget completo, pero en una ubicación equivocada; costo ≈ $0.72. A los ocho minutos aproximadamente escribió un archivo
ll-pixel-logo.jsde 323 líneas, además de una página de demostración, un README y dos archivos de prueba; ejecutó dichas pruebas y las ajustó hasta que pasaron, y finalmente redactó un informe breve. Todo este contenido se guardó en el espacio de trabajo del agente, no en la carpeta que mi script monitoreaba; la sesión agotó su límite de 15 minutos antes de enviar respuesta alguna. Desde mi perspectiva, el intento 2 no generó resultados visibles, por lo que no esperé más: inicié el intento 3 unos siete minutos después. - Intento 3 (encargo abreviado y con instrucciones específicas): duró 7.4 minutos; generó los tres archivos requeridos; costo ≈ $0.47. Conservé los requisitos de entregables, diseño e interacciones; coloqué al inicio del texto
TARGETED — write the widget file in one tool call, no exploration, no planning, no verification loop.Reemplacé la sección de pruebas por una frase que finalizaba así:Do NOT do a "node --check" or playwright test — just write the files and print a short report listing what you wrote.El widget resultante incluye repulsión de píxeles ante el cursor, efecto de fragmentación y reensamblaje al hacer clic, titileo ambiental en estado de reposo y modo de movimiento reducido. Mis comprobaciones se detallan en la siguiente sección.
Así, los tres intentos consumieron 8.8, 15 y 7.4 minutos respectivamente, con costos de $0.31, $0.72 y $0.47; es decir, aproximadamente $1.50 por dos widgets. El costo del intento 3 proviene de su propio recibo JSON; los intentos 1 y 2 no generaron recibos, por lo que sus costos se calcularon sumando las tarifas por mensaje de OpenClaw en cada sesión; esa suma coincide con el monto indicado para el intento 3.
Una hora después, el widget creado en el intento 2 reapareció: un ejecución de MiniMax M3 en el mismo entorno detectó los archivos, ejecutó sus pruebas y reportó dichos resultados como propios. Este episodio se describe en el informe sobre MiniMax M3; ambos widgets de Kimi se exhiben junto al de dsh en la comparativa de widgets de arte pixelado.
El código generado por Kimi: primeras 30 líneas del archivo ll-pixel-logo.js:
/*!
* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
*
* Self-contained vanilla JS: no dependencies, no build step, no network.
* Embed on any page with:
*
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
*
* Every .ll-pixel-logo element gets a <canvas> mounted inside it at load.
* Programmatic API: window.LLPixelLogo.mount(el) -> instance.
*
* Art: 40x40 pixel grid, rasterised procedurally from geometry (ring + two
* interlocking italic Ls). Interactions: pointer repulsion with spring-back,
* click/tap shatter-and-reassemble, idle shimmer/twinkle, reduced-motion
* support. Mouse and touch. No scroll hijacking (all listeners passive).
*/
(function () {
'use strict';
// -- constants ------------------------------------------------------------
var VERSION = '1.0.0';
var GRID = 40; // logical grid: GRID x GRID cells
var BLUE = [31, 63, 143]; // #1f3f8f logo blue
var HILITE = [46, 168, 255]; // #2ea8ff highlight blue
var AMBER = [255, 182, 74]; // #ffb64a twinkle amber
var CYAN = [0, 230, 207]; // #00e6cf max-displacement glow
var CENTER = GRID / 2; // grid centre coordinate (20)
var R_OUT = 19; // ring outer radius (cells)
var R_IN = 0.82 * R_OUT; // ring inner radius
var SLANT = Math.tan(20 * Math.PI / 180); // ~20 deg italic shear
A continuación, se muestra el widget en acción: la versión creada por Kimi K3, sin modificaciones:
prefers-reduced-motion.Kimi genera cada letra “L” mediante dos paralelogramos (un tallo inclinado y un pie) usando una pequeña función auxiliar makeL; para determinar si un punto pertenece al diseño, emplea la función inPara dentro de isLit. Todas las constantes de ajuste (radio del anillo entre 0.82R y R, ángulo de inclinación de 20° calculado mediante Math.tan, parámetros de elasticidad y amortiguación) se agrupan en un único bloque al inicio del archivo.
Los archivos creados por Kimi (ll-pixel-logo.js con 397 líneas, index.html de 40 líneas y README.md de 79 líneas) se encuentran en /assets/uploads/2026/09/kimi-codex/, junto al texto del encargo, disponible como BRIEF.md.
Como comparación, aquí se muestran las primeras 30 líneas del widget de dsh, alojado en /assets/uploads/2026/08/deepseek-harness/ll-pixel-logo.js:
/*!
* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
* Vanilla JS, zero dependencies, no network requests, works from file://.
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
* Auto-mounts on .ll-pixel-logo elements; window.LLPixelLogo.mount(el) too.
* Knobs: data-size, data-speed, data-static.
*/
(function (global) {
'use strict';
// ---- 0. palette -----------------------------------------------------
var BLUE = [31, 63, 143]; // #1f3f8f — logo blue
var HI = [46, 168, 255]; // #2ea8ff — hover / repulsion glow
var AMBER = [255, 182, 74]; // #ffb64a — twinkle spark
var CYAN = [0, 230, 207]; // #00e6cf — deep glow
// ---- 1. art: procedural 40x40 raster (no hand-drawn bitmap) ----------
// A cell is lit when it belongs to the ring or to one of the two slanted
// interlocking Ls. Each L is two parallelograms (stem + foot), described by
// top-left (ax,ay), width w, height h, sheared by SLANT (bottom edge shifts
// left): TL=(ax,ay) TR=(ax+w,ay) BL=(ax-SLANT*h,ay+h). The upper-left L's
// foot runs right and tucks under the lower-right L's stem, like the ref.
var GRID = 40; // cells per side
var RING_R = 19.7; // outer ring radius (cells)
var RING_IN = 0.80 * RING_R; // inner ring radius (reference ~0.808R)
var SLANT = 0.453; // shear of stems/feet (~24deg)
var LETTERS = [
{ ax: 15.0, ay: 5.2, w: 4.2, h: 10.6 }, // upper-left L: stem
{ ax: 10.2, ay: 15.8, w: 15.0, h: 3.8 }, // upper-left L: foot
{ ax: 24.7, ay: 13.8, w: 4.2, h: 14.7 }, // lower-right L: stem
{ ax: 18.0, ay: 28.5, w: 15.0, h: 3.8 } // lower-right L: foot
];
Ambos widgets se generan de idéntica manera: ambos crean un anillo y dos letras “L” inclinadas a partir de cálculos geométricos; ambos exponen la función window.LLPixelLogo.mount y respetan la directiva prefers-reduced-motion. No obstante, sus constantes difieren: dsh utiliza un radio exterior de 19.7, un radio interior de 0.80R y una inclinación de 0.453 (aprox. 24°); Kimi emplea 19, 0.82R y 20°. Además, los trazos en el widget de Kimi son más delgados: sus tallos y pies miden 3 celdas de grosor, mientras que en el de dsh los tallos alcanzan 4.2 celdas de ancho y los pies 3.8 celdas de altura. Por ello, el logo de Kimi activa 510 celdas frente a las 656 del de dsh. Ninguno reproduce el logo de referencia con exactitud absoluta, aunque ambos resultan reconocibles a simple vista. El segundo intento de dsh incluyó además un test unitario en Node y, sin solicitarlo, un script Playwright; en cambio, al tercer intento de Kimi se le indicó omitir cualquier tipo de prueba, y así lo hizo.
Comandos de verificación que ejecuté en el widget de Kimi
Los volví a ejecutar el 11-09-2026 sobre la copia que sirve esta página, desde dentro de /assets/uploads/2026/09/kimi-codex/:
$ wc -l ll-pixel-logo.js
397 ll-pixel-logo.js
$ node --check ll-pixel-logo.js && echo "node --check passed"
node --check passed
Otras dos comprobaciones fueron propias y privadas; las realicé con dos pequeños scripts auxiliares (de menos de 20 líneas cada uno) que no he publicado. Por eso aquí les indico el método en lugar de comandos que puedan copiar directamente:
- Conteo de celdas iluminadas. Cargué el archivo del widget en Node utilizando un DOM simulado (objetos canvas, window y document sin funcionalidad real). Luego capturé la función
isLit(col, row)definida en el propio archivo y la llamé para cada celda de la cuadrícula 40×40, contando las celdas iluminadas por cuadrante. El resultado fue 510 celdas: 124 en la parte superior izquierda, 103 en la superior derecha, 160 en la inferior izquierda y 123 en la inferior derecha. - Comprobación de montaje. Con el mismo DOM simulado, verifiqué que el archivo define
window.LLPixelLogocomo un objeto, y que al llamar amount()sobre un elemento simulado se obtiene un objeto en lugar de producirse un error.
Solo el anillo (celdas cuyos centros se encuentran entre 0,82R y R, siendo R = 19) abarca 352 de las 510 celdas totales; eso deja 158 celdas para formar las dos letras “L”. Los scripts auxiliares son míos, no de Kimi; además, sirven solo como pruebas preliminares, no como ejecuciones en navegador: la página que está leyendo ahora es el resultado de dicha ejecución en el navegador.
Pitfalls (los que yo realmente he experimentado)
- “Compatible con OpenAI” no significa “compatible con el plugin Codex”. El endpoint
/v1/chat/completionsde Moonshot funciona bien como proveedor para OpenClaw, pero el plugin Codex solo acepta rutas cuyo ID de proveedor seaopenai. Si necesitas específicamente la función de reanudación de hilos de Codex y el puente de herramientas dinámicas, la Ruta B (el puente codex-router) es la única opción. Consulta la comparación entre Ruta A y Ruta B más arriba. - K3 siempre realiza razonamientos, incluso en respuestas triviales. Para responder exactamente “PONG”, el modelo consumió 53 tokens de razonamiento. Esto es por diseño y es predecible; tenlo en cuenta al calcular tu presupuesto.
- El bloque
compatreemplaza, no fusiona. Si añadescompata la entrada del modelo para rechazar el parámetrotemperature, también debes copiar los campos relacionados con el esfuerzo de razonamiento del plugin; de lo contrario, estos se perderán sin aviso. - El contexto de 1 millón de tokens se anuncia, pero no es lo que obtienes con mi límite actual. El catálogo indica 1,048,576 tokens; sin embargo, mi configuración
contextTokens: 262144limita las sesiones a 256k tokens. Debes ajustarlo intencionadamente, no por casualidad. - El descuento por uso de caché es real, pero las tarifas aplicadas son las estándar para servicios premium. El coste de $0.30 por millón de tokens leídos desde la caché equivale a unas 21 veces el precio de $0.014 que cobra dsh V4-Flash. Aun así, el uso de caché redujo el coste total a aproximadamente un tercio del precio sin caché.
- Los encargos creativos abiertos pueden bloquear el razonamiento del modelo; además, un tiempo de espera agotado puede ocultar un éxito. En el primer intento, el modelo tardó 8.8 minutos en pensar sin llegar a generar código alguno. En el segundo intento, sí produjo un widget funcional, pero se agotó el tiempo y los archivos quedaron en una carpeta incorrecta; por eso pareció otro fallo. Lo que finalmente me dio el widget esperado fue un encargo más corto que decía:
TARGETED — write the widget file in one tool call, no exploration, no planning, no verification loop., además de indicar claramente la carpeta destino. K3 sigue razonando con ese tipo de instrucciones; simplemente no planifica indefinidamente. Independientemente del estado de salida que indique el sistema, revisa siempre lo que el modelo haya escrito durante la sesión. - Un código de error al finalizar no implica necesariamente un fracaso; verifica los archivos generados. La primera ejecución del programa FizzBuzz terminó con código 1, indicando que no se encontró modelo adecuado, y el mensaje final era “⚠️ Se alcanzó el límite de uso de la API. Por favor, inténtelo más tarde.” No obstante, ya había creado el archivo
fizz.py, que funcionaba correctamente. El segundo intento respondió “Ya se creó y ejecutó.”; solo ese mensaje indicaba que la tarea se completó. Mi script guardaba el JSON de cada ejecución en el mismo archivo, por lo que el registro del fallo se sobrescribió; sin embargo, su código de salida y mensaje final quedaron registrados en la sesión posterior. La tabla muestra los resultados de una ejecución posterior, sin errores. - No copies carpetas de trabajo de otra ejecución realizada con otro plugin. Configuré la carpeta de corrección de errores para Kimi copiando los archivos de la carpeta terminada por dsh, cuando este ya había corregido los problemas; por eso la primera ejecución de Kimi simplemente verificó que todo estaba correcto. Tuve que reiniciar la carpeta y volver a ejecutar el proceso en una sesión nueva; la tabla refleja esa segunda ejecución. Por otro lado, dsh trabaja siempre en el directorio desde el cual se inicia: mi primer script no ejecutó
cdhacia la carpeta correspondiente, por lo que los archivos se generaron en el lugar equivocado; tuve que volver a ejecutar las cinco tareas. - Ninguno de los dos widgets se asemeja exactamente al logo de referencia. El encargo pedía ajustar las constantes para que el widget se viera como el logo a 200 píxeles. Antes de lanzar cualquiera de ellos, dedicaría unos diez minutos a calibrar los anchos de trazo y la inclinación.
¿Qué significa esto para mí?
En estas cinco tareas, Kimi K3 dio respuestas correctas, pero fue lento y costoso. Para tareas sencillas, dsh en V4-Flash realizó el mismo trabajo en aproximadamente una novena parte del tiempo y por solo 1/48 del precio. Tras este test de rendimiento, trasladé mi agente de trabajo de Kimi a MiniMax-M3; Kimi K3, por su parte, permaneció donde ya estaba: detrás de mi agente de revisión, donde una respuesta más lenta y cuidadosa justifica el costo adicional.
El Camino B, que consiste en usar el puente codex-router para conectar con el servidor de la aplicación Codex, sigue siendo solo un plan teórico hasta que me sienta cómodo con lo que comparte homeScope: "user". Hasta entonces, “Kimi como agente de programación” en mi sistema significa que Kimi controla el bucle nativo de OpenClaw, al igual que cualquier otro modelo nativo de OpenClaw.
Relacionado: DeepSeek Harness (dsh) (el sistema con el que hice la comparación; de ahí provienen el test y las instrucciones), MiniMax M3 (el mismo entorno, pero con el modelo que utiliza mi agente de trabajo desde el 11 de septiembre de 2026), Reasonix (versión histórica; retirado de mi sistema el 9 de septiembre de 2026), y Cuánto cuestan realmente mis agentes de IA (una comparativa más amplia de precios).