Files
egutierrez fc86edd94c chore: auto-commit (27 archivos)
- .claude/CLAUDE.md
- .claude/rules/create_agent.md
- agents/_specials/father-bot/prompts/system.md
- agents/_template/config.yaml
- agents/_template_robot/config.yaml
- cmd/agentctl/autoavatar.go
- cmd/launcher/sqlite.go
- dev-scripts/_common.sh
- dev-scripts/agent/create-full.sh
- dev-scripts/agent/delete-full.sh
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:38:16 +02:00

13 KiB

Policy: Crear un nuevo agente o robot

Guia ejecutable para Claude. Seguir paso a paso sin desviarse.

Pipeline formalizado (12 pasos)

Todo agente o robot creado debe pasar por TODOS estos pasos, en orden estricto:

 1. SCAFFOLD         → crear archivos base desde template
 2. BUILD            → go build -tags goolm ./...
 3. REGISTER         → crear usuario Matrix + token
 4. VERIFY E2EE      → cross-signing + recovery key
 5. CONVERT (robot)  → eliminar LLM/prompts si type=robot
 6. AUTO-AVATAR      → generar y aplicar foto de perfil
 7. DISPLAY NAME     → configurar nombre visible en Matrix
 8. PERSONALIZE      → config.yaml, agent.go, system prompt
 9. REBUILD          → recompilar tras personalizacion
10. START/RESTART    → arrancar el launcher con el bot
11. HEALTH CHECK     → verificar que el bot esta activo
12. SELF-INTRODUCE   → el bot envia bienvenida a los devs

Pasos 1-7: ejecutados por ./dev-scripts/agent/create-full.sh Paso 8: personalizar manualmente agent.go, config.yaml, prompts/system.md Paso 9: go build -tags goolm ./... Paso 10: ./dev-scripts/server/start.sh (o restart.sh) Paso 11: ./dev-scripts/agent/health-check.sh <id> Paso 12: ./dev-scripts/agent/notify-developer.sh <id> <type> "<display-name>" (requiere DEVELOPER_MATRIX_USERS en .env)

Robot vs Agent — decidir primero

Agent Robot
Cuando usar Necesita LLM, reglas, memoria, tools Solo responde comandos (!xxx)
Runtime devagents.New() — completo devagents.NewRobot() — ligero
Config type type: agent (default) type: robot
LLM Si No
Reglas Si (agent.go con Rules()) No (sin agent.go)
Memoria/Knowledge/Skills Si (opcionales) No
Tools Si (opcionales) No
System prompt Si (prompts/system.md) No necesario
Comandos built-in help, ping, tools, tool, status, info, clear, prompts, version help, ping, status, info, version
Comandos custom Si (RegisterCommand) Si (RegisterCommand)
Template agents/_template/ agents/_template_robot/
Config ejemplo ~260 lineas ~55 lineas

Regla: si el bot necesita entender lenguaje natural, es un Agent. Si solo necesita comandos directos, es un Robot.

Inputs — preguntar al usuario si no los da

Input Requerido Default Ejemplo
agent-id si monitor-bot
display-name si "Monitor Agent"
description si "Monitorea servicios y reporta estado"
type no agent agent o robot
llm.provider no (N/A para robots) claude-code claude-code (default), openai, anthropic
llm.model no (N/A para robots) sonnet sonnet (claude-code), gpt-4o (openai), claude-sonnet-4-20250514 (anthropic)
tool_use no (N/A para robots) false true si necesita herramientas
System prompt si (N/A para robots) Texto describiendo rol y capacidades

Si el usuario da todos los inputs, ir directo a la Ruta Rapida. Si faltan, preguntar antes de empezar.

Ruta rapida — script automatizado (pasos 1-8)

Si tienes todos los datos del agente (description + system prompt), el Paso 8 puede hacerse automaticamente:

./dev-scripts/agent/create-full.sh <agent-id> "Display Name" \
  --description "<descripcion>" \
  --system-prompt "<system prompt con seccion de seguridad>" \
  [--provider <claude-code|openai|anthropic>] \
  [--tone <friendly|professional|casual|technical>] \
  [--prefix "<emoji>"] \
  [--tool-use] \
  [--avatar <URL_o_ruta_local>]

Este script ejecuta en orden: scaffold, build, register Matrix, verify E2EE, auto-avatar, display name, personalizar (auto), notify. Crea todos los archivos, registra en el launcher, genera todas las env vars en .env.

Si se omiten los flags de personalización, el script se comporta como antes (pasos 1-7) y el Paso 8 queda pendiente de edición manual.

Personalización independiente (sobre agente ya creado):

./dev-scripts/agent/personalize.sh <agent-id> --description "..." --system-prompt "..."

REGLA DE PROYECTO — Provider default = claude-code: TODOS los agentes nuevos usan claude-code (subprocess claude -p) por defecto. NO requiere API key, autentica via el CLI claude ya instalado. Solo cambiar a openai/anthropic si hay razon explicita (modelo no disponible en claude-code, requisitos de latencia distintos, etc.). detect-provider.sh ya prioriza claude-code si el binario claude esta en PATH.

Despues del script, continuar con pasos 9-12 (rebuild, start, health check, self-introduce).

Archivos a personalizar despues del scaffold (paso 8)

1. agents/<agent-id>/agent.go — Reglas puras

Template base (generado por el scaffold):

package <pkgname>  // sin guiones: "monitor-bot" → package monitor (strip hyphens, strip _bot)

import (
    "github.com/enmanuel/agents/devagents"
    "github.com/enmanuel/agents/pkg/decision"
)

func init() {
    devagents.Register("<agent-id>", Rules)
}

func Rules() []decision.Rule {
    return []decision.Rule{
        // Any DM or mention → LLM
        {
            Name: "llm-all",
            Match: func(ctx decision.MessageContext) bool {
                return ctx.IsDirectMsg || ctx.IsMention
            },
            Actions: []decision.Action{{
                Kind: decision.ActionKindLLM,
                LLM:  &decision.LLMAction{},
            }},
        },
    }
}

Reglas estrictas:

  • PURO: solo imports de pkg/decision y agents (para Register), cero I/O, cero side effects
  • Auto-registro: cada agente se registra via init() con devagents.Register("<agent-id>", Rules)
  • Package name = ID sin guiones ni _bot (e.g. monitor-botpackage monitor)
  • No usar reglas para comandos (!help, !ping, etc.) — los comandos se gestionan via RegisterCommand (ver policy create_command.md)
  • Las reglas solo aplican a mensajes normales (sin prefijo !)

Tipos de accion disponibles:

  • ActionKindReply — respuesta estatica (con ReplyAction{Content: "..."})
  • ActionKindLLM — pasa al LLM (con LLMAction{})

2. agents/<agent-id>/config.yaml — Configuracion

El scaffold genera un config completo con defaults sensatos. Solo personalizar estas secciones:

Identidad (siempre editar):

agent:
  description: "<la descripcion del agente>"

LLM — DEFAULT claude-code (subproceso claude -p, sin API key):

llm:
  primary:
    provider: claude-code        # DEFAULT — usar SIEMPRE salvo razon explicita
    model: "sonnet"
    api_key_env: ""              # claude-code no usa api key
    claude_code:
      working_dir: "/tmp/claude-agents/<agent-id>"  # SIEMPRE fuera del repo
      permission_mode: "bypassPermissions"
      model: "sonnet"
      fallback_model: "haiku"
      streaming: true
      show_tool_progress: true

Override a API providers (solo si claude-code no encaja):

llm:
  primary:
    provider: openai             # o anthropic
    model: gpt-4o                # o claude-sonnet-4-20250514
    api_key_env: OPENAI_API_KEY  # o ANTHROPIC_API_KEY

Importante: working_dir debe apuntar fuera del repositorio para evitar que el subproceso claude -p acceda al codigo fuente. Si se deja vacio, se usara un directorio temporal (con WARN en logs).

Tool use (si el agente necesita herramientas):

llm:
  tool_use:
    enabled: true               # cambiar de false a true
    max_iterations: 5

Personalidad (ajustar tono):

personality:
  tone: friendly                # friendly | professional | casual | technical
  language: es                  # es | en
  prefix: "🤖"                 # emoji del bot

Threads (habilitado por defecto en el scaffold):

matrix:
  threads:
    enabled: true               # responder en threads cuando el mensaje viene de un thread
    auto_thread: false          # true para crear thread automatico por cada conversacion nueva

Referencia completa del schema: internal/config/schema.go

3. agents/<agent-id>/prompts/system.md — System prompt

Escribir el system prompt completo. Debe incluir:

  • Identidad: quien es, como se llama
  • Rol: que hace, para que sirve
  • Capacidades: que puede hacer (incluir tools si tool_use.enabled: true)
  • Estilo: idioma, tono, formato de respuestas
  • Restricciones: que NO debe hacer
  • Seguridad (obligatorio): copiar la seccion de .claude/templates/security-prompt.md al final del prompt. Esta seccion protege contra prompt injection.

Ejemplo de referencia: agents/asistente-2/prompts/system.md

Registro en el launcher — cmd/launcher/main.go

El script new-agent.sh (ejecutado por create-full.sh) hace esto automaticamente. Si falla, hacer manualmente:

Blank import (en la seccion de blank imports de agentes):

_ "github.com/enmanuel/agents/agents/<agent-id>"

Las reglas se registran automaticamente via init() en el paquete del agente. No se necesita editar ningun map ni registry manualmente. El ID en devagents.Register() DEBE coincidir exactamente con agent.id en config.yaml.

Convencion de env vars — REGLA CRITICA

Normalizacion: normalize_id() → mayusculas, guiones → underscores. Sin eliminar sufijos.

Agent ID Normalizado Env vars
assistant-bot ASSISTANT_BOT MATRIX_TOKEN_ASSISTANT_BOT, MATRIX_PASSWORD_ASSISTANT_BOT, PICKLE_KEY_ASSISTANT_BOT, SSSS_RECOVERY_KEY_ASSISTANT_BOT
mi-bot MI_BOT MATRIX_TOKEN_MI_BOT, ...

NUNCA aplicar transformaciones que eliminen partes del ID (no sed 's/_BOT$//').

Pasos 9-12: post-personalizacion

Paso 9 — REBUILD

go build -tags goolm ./...

Si falla, corregir y reintentar. Nunca arrancar el launcher si la compilacion falla.

Paso 10 — START/RESTART

./dev-scripts/server/start.sh      # primera vez
./dev-scripts/server/restart.sh    # si ya estaba corriendo

Paso 11 — HEALTH CHECK

./dev-scripts/agent/health-check.sh <agent-id>

Verifica en los logs del launcher que el agente arranco correctamente (busca "e2ee ready", "runner started", etc.). Timeout: 30 segundos (configurable como segundo argumento).

No continuar al paso 12 si el health check falla. Diagnosticar primero.

Paso 12 — SELF-INTRODUCE

./dev-scripts/agent/notify-developer.sh <agent-id> <type> "<display-name>"

El propio bot envia DM de bienvenida a cada developer en DEVELOPER_MATRIX_USERS. Incluye:

  • Nombre y tipo (agent/robot)
  • Descripcion (leida de config.yaml)
  • Tools habilitadas (si aplica)
  • Instrucciones de uso

Reintenta hasta 3 veces con backoff si el envio falla. Si DEVELOPER_MATRIX_USERS no esta definida en .env, se salta con warning.

Verificacion post-creacion

Checklist a verificar antes de considerar el agente listo:

  • go build -tags goolm ./... compila sin errores
  • agents/<id>/agent.go exporta Rules() y es puro (sin I/O)
  • agents/<id>/config.yaml tiene agent.id = nombre del directorio
  • cmd/launcher/main.go tiene blank import del paquete del agente
  • .env contiene: MATRIX_TOKEN_<NORM>, MATRIX_PASSWORD_<NORM>, PICKLE_KEY_<NORM>, SSSS_RECOVERY_KEY_<NORM>
  • prompts/system.md tiene contenido real (no el stub)
  • prompts/system.md incluye la seccion de seguridad anti-injection (de .claude/templates/security-prompt.md)
  • Si tool_use.enabled: true, el prompt menciona las tools disponibles
  • Health check pasa (./dev-scripts/agent/health-check.sh <id>)
  • Bot envio bienvenida a los devs (o DEVELOPER_MATRIX_USERS no esta configurado)

Troubleshooting E2EE

Problema Solucion
"device not verified by its owner" ./dev-scripts/agent/verify.sh <id> y reiniciar
"self-signing private key not in cache" Recovery key incorrecta → re-ejecutar verify.sh
"received update for device with different signing key" Recompilar launcher: go build -tags goolm -o bin/launcher ./cmd/launcher
Recovery key sin comillas en .env Anadir comillas: SSSS_RECOVERY_KEY_*="EsXX YYYY ..."

Reglas generales

  • Nunca side effects en agent.go
  • Siempre compilar con -tags goolm
  • Siempre que agent.id coincida entre config.yaml, devagents.Register() y directorio
  • No crear data/ manualmente — se auto-genera
  • No commitear tokens ni passwords
  • No compartir crypto stores entre agentes
  • Referencia de agente con tools: agents/asistente-2/
  • Referencia de agente simple: agents/assistant-bot/