Files
agents_and_robots/.claude/rules/create_agent.md
T
egutierrez 65223e8da2 docs: añadir threads al scaffold y guia de creacion de agentes
Actualiza el template de new-agent.sh para que agentes nuevos se creen
con matrix.threads.enabled: true por defecto. Tambien documenta la
seccion threads en create_agent.md para que la guia de creacion
incluya la configuracion de threads como opcion personalizable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:55:55 +00:00

7.6 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/pkg/decision"

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, cero I/O, cero side effects
  • 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:

Import (después de los imports de agentes existentes):

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

rulesRegistry (dentro del map):

"<agent-id>": <pkg>agent.Rules,

El <pkg> es el package name del agent.go (sin guiones, sin _bot). El ID en rulesRegistry 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 import + entry en rulesRegistry con el mismo ID
  • .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, rulesRegistry 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/