simon mersich

C3PO, parte 2: un agente de verdad y una interfaz de chat

c3po/2

En la parte 1, Claude Code manejaba un Unitree G1 simulado a través de un servidor MCP, desde mi terminal. Eso demostró que el loop funciona, y también dejó claros los límites. Todo corría solo en mi máquina, adentro de una herramienta hecha para editar código, así que nadie más podía hablarle al robot.

Este mes fue convertir a C3PO en un sistema en vez de un hack.

El agente se muda al backend

C3PO ya era un monorepo con un frontend en SvelteKit y un backend en Elysia sobre Bun, pero nada del trabajo del robot los había tocado todavía. Ahora el backend corre su propio agente. Es un loop con streaming sobre el Vercel AI SDK, con Claude como modelo, thinking habilitado y un tope de una docena de pasos de herramientas por turno.

Nada del robot cambió. Las habilidades viven en un registro con esquemas JSON. El backend las convierte en herramientas para el modelo y manda cada llamada por MCP al mismo bridge de Python de la parte 1, esta vez con streamable HTTP en vez de stdio. La capa de habilidades no depende de quién maneja, así que sacar el agente de Claude Code no cambió las habilidades, el bridge ni el protocolo.

Me alegra haber metido dos detalles temprano. Primero, el backend devuelve las fallas de herramientas al modelo como errores en vez de matar el stream, así el modelo puede reaccionar y reintentar. Segundo, el system prompt tiene una regla de honestidad, porque en el simulador algunas habilidades solo escriben una línea de log y no mueven nada: nunca afirmar que el robot se movió cuando no lo hizo.

Una interfaz de chat

Me gusta trabajar en la terminal, pero “tipear en una CLI en mi laptop” no es la forma de hablarle a un robot. C3PO ahora tiene una consola de verdad. Las respuestas llegan en streaming a un chat, y cada llamada a una habilidad aparece como una pastillita monoespaciada marcada como pendiente, lista o fallida. El chat tiene un botón de stop. Al lado, un mapa en vivo consulta la pose, el rumbo, el recorrido, la batería y la latencia del robot cada un par de segundos. Una vista de cámara llega por WebRTC desde las cámaras de cabeza y muñecas del simulador. Un gran botón rojo de PARAR llama directo a stop_everything.

La parte que más me entusiasma

Hasta ahora todo corrió en el simulador. Eso cambia en unas semanas, cuando llegue un Unitree G1 real. El repo ya está preparado. El robot real usa topics de DDS distintos a los del simulador, así que hay un catálogo completo del protocolo que mapea cada habilidad a la API del firmware real, y un decodificador para sus códigos de falla, incluida la parada de emergencia.

Voy a escribir la parte 3 al lado de un robot.

Código: github.com/mercho40/C3PO.

enes