Files
agents_and_robots/.claude/rules/create_agent.md
T
egutierrez 6e1b820ecf chore: actualizar script y docs para auto-registro de agentes
- new-agent.sh: reemplaza edicion del rulesRegistry map con insercion
  de un blank import simple. Ahora tambien sustituye AGENT_ID_PLACEHOLDER
  en agent.go con el ID real del agente.
- create_agent.md: actualiza template de agent.go con patron init() +
  agents.Register(), secciones de registro en launcher y checklist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:21:15 +00:00

7.8 KiB

Policy: Crear un nuevo agente

Guía ejecutable para Claude. Seguir paso a paso sin desviarse.

Inputs — preguntar al usuario si no los da

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

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

Ruta rápida — script automatizado

./dev-scripts/agent/create-full.sh <agent-id> "Display Name"

Este script ejecuta en orden: scaffold → build → register Matrix → verify E2EE. Crea todos los archivos, registra en el launcher, genera todas las env vars en .env.

Después del script, personalizar los 3 archivos del agente (ver sección siguiente).

Archivos a personalizar después del scaffold

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/agents"
    "github.com/enmanuel/agents/pkg/decision"
)

func init() {
    agents.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 agents.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 acción disponibles:

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

2. agents/<agent-id>/config.yaml — Configuración

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

Identidad (siempre editar):

agent:
  description: "<la descripción del agente>"

LLM (si quieres cambiar provider/model):

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

Claude-code provider (si usa claude-code como provider):

llm:
  primary:
    provider: claude-code
    claude_code:
      working_dir: "/tmp/claude-agents/<agent-id>"  # SIEMPRE configurar, nunca dejar vacío
      permission_mode: "bypassPermissions"

Importante: working_dir debe apuntar fuera del repositorio para evitar que el subproceso claude -p acceda al código fuente. Si se deja vacío, se usará 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 automático por cada conversación 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: quién es, cómo se llama
  • Rol: qué hace, para qué sirve
  • Capacidades: qué puede hacer (incluir tools si tool_use.enabled: true)
  • Estilo: idioma, tono, formato de respuestas
  • Restricciones: qué 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 automáticamente. Si falla, hacer manualmente:

Blank import (en la sección de blank imports de agentes):

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

Las reglas se registran automáticamente via init() en el paquete del agente. No se necesita editar ningún map ni registry manualmente. El ID en agents.Register() DEBE coincidir exactamente con agent.id en config.yaml.

Convención de env vars — REGLA CRÍTICA

Normalización: normalize_id() → mayúsculas, 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$//').

Verificación post-creación

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

Arranque y verificación

# Arrancar (reconstruye y lanza todos los agentes habilitados)
./dev-scripts/server/start.sh

# Verificar logs
tail -f run/launcher.log

# Logs esperados al arrancar correctamente:
# {"level":"INFO","msg":"e2ee ready"}
# {"level":"INFO","msg":"agent running"}
# {"level":"INFO","msg":"starting matrix sync"}

Troubleshooting E2EE

Problema Solución
"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 Añadir 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, agents.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/