Files
agents_and_robots/.claude/rules/create_agent.md
T
egutierrez bd0c8c0dd3 refactor: mover runtime Go de agents/ a devagents/
agents/ ahora solo contiene carpetas de agentes (config, reglas, prompts).
El runtime (Agent, Robot, Runner, registry, handler, commands, llm, memory)
vive en devagents/ como package devagents.

Cambios:
- git mv agents/*.go → devagents/*.go
- package agents → package devagents en todos los archivos movidos
- Actualizar imports en agents/*/agent.go, cmd/launcher/, dev-scripts/
- Actualizar docs: CLAUDE.md, rules/, docs/e2ee.md, issues pendientes

Build y tests pasan sin errores.

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

8.9 KiB

Policy: Crear un nuevo agente o robot

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

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) openai openai o anthropic
llm.model no (N/A para robots) gpt-4o gpt-4o, claude-sonnet-4-20250514
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 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/devagents"
    "github.com/enmanuel/agents/pkg/decision"
)

func init() {
    devdevagents.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 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 devagents.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, 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/