Files
agents_and_robots/docs/creating-agents.md
T
egutierrez bcbbd974e3 docs: add agent creation guide and LLM policies index
Documentación y políticas para la creación de agentes:

- docs/creating-agents.md: guía completa paso a paso para humanos
  (scaffold, config, registro Matrix, avatar, verificación E2EE, arranque,
  troubleshooting)
- .claude/policies/create_agent.md: policy para LLMs con estructura de
  archivos, convenciones y reglas a seguir al crear agentes
- .claude/policies/index.md: índice de todas las policies disponibles
- .claude/policies/create_tool.md: movido desde .claude/rules/ (misma policy)
- CLAUDE.md: añadida sección de políticas, actualizada tabla de agentes
  con asistente-2, y actualizado el flujo de "Cómo añadir un nuevo bot"
  con pasos de avatar y verificación E2EE

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:39:11 +00:00

9.3 KiB

Guía completa: Crear un nuevo agente

Esta guía documenta todos los pasos para crear, registrar, configurar y poner en marcha un nuevo bot/agente en el sistema.

Requisitos previos

  • Go 1.23+ instalado (/usr/local/go/bin)
  • Acceso al homeserver Matrix (MATRIX_HOMESERVER y MATRIX_ADMIN_TOKEN en .env)
  • Variables de entorno cargadas (.env con todos los secretos)

Paso 1: Crear el scaffold del agente

Opción A: Script automático

./dev-scripts/new-agent.sh <agent-id> "Display Name"
# Ejemplo: ./dev-scripts/new-agent.sh mi-bot "Mi Bot"

Esto crea la estructura base en agents/<agent-id>/.

Opción B: Manual

Crear la estructura de directorios:

agents/<agent-id>/
├── agent.go                # Reglas puras de decisión
├── config.yaml             # Configuración completa del agente
├── prompts/
│   └── system.md           # System prompt para el LLM
└── data/                   # Runtime (auto-generado, en .gitignore)
    └── crypto/             # Store E2EE

1.1 Crear agents/<agent-id>/agent.go

Archivo de reglas puras. El package debe exportar una función Rules() []decision.Rule.

package mibot

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

// Rules returns the decision rules for this agent.
func Rules() []decision.Rule {
    return []decision.Rule{
        // !help — comando de ayuda explícito
        {
            Name:  "help",
            Match: decision.MatchCommand("help"),
            Actions: []decision.Action{{
                Kind: decision.ActionKindReply,
                Reply: &decision.ReplyAction{
                    Content: "Soy mi-bot. Escríbeme lo que necesitas.",
                },
            }},
        },

        // Catch-all: DMs y menciones → 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 importantes:

  • Este archivo es puro — sin imports de I/O, sin side effects
  • Solo usa types de pkg/decision
  • Las reglas se evalúan en orden; la primera que matchea gana

1.2 Crear agents/<agent-id>/config.yaml

Configuración completa del agente. Referencia: internal/config/schema.go.

Secciones principales:

Sección Descripción
agent Identidad: id, name, version, enabled, description, tags
personality Tono, verbosidad, idioma, templates, comportamiento
llm Provider (openai/anthropic), modelo, tokens, temperature, tool_use
tools SSH, HTTP, scripts, file_ops, MCP — cada uno con su enabled/config
matrix Homeserver, user_id, token, device_id, encryption, rooms, filters
agents Peers conocidos, delegación, protocolo inter-agente
ssh Configuración SSH (solo si aplica)
security Roles, audit, secrets provider
schedules Tareas programadas (cron)
observability Logging, metrics, health, tracing
resilience Circuit breaker, retry, shutdown, queue
storage State backend, cache, history

Campos críticos en matrix:

matrix:
  homeserver: "https://matrix-af2f3d.organic-machine.com"
  user_id: "@<agent-id>:matrix-af2f3d.organic-machine.com"
  access_token_env: MATRIX_TOKEN_<AGENT_UPPER>   # nombre de la env var
  device_id: "<se obtiene al registrar>"

  encryption:
    enabled: true
    store_path: "./data/crypto/"
    trust_mode: tofu

Para habilitar tool-use:

llm:
  tool_use:
    enabled: true          # DEBE ser true
    max_iterations: 5
    parallel_calls: false

1.3 Crear agents/<agent-id>/prompts/system.md

System prompt que recibe el LLM. Debe incluir:

  • Identidad y rol del bot
  • Capacidades disponibles
  • Herramientas disponibles (si tool_use está habilitado)
  • Estilo de respuesta
  • Limitaciones

Usar como referencia: agents/assistant/prompts/assistant-system.md o agents/asistente2/prompts/system.md.

Paso 2: Registrar el agente en el launcher

Editar cmd/launcher/main.go:

  1. Añadir import del package del agente:
mibotAgent "github.com/enmanuel/agents/agents/mibot"
  1. Añadir entrada en rulesRegistry:
var rulesRegistry = map[string]func() []decision.Rule{
    "assistant-bot": assistantagent.Rules,
    "mi-bot":        mibotAgent.Rules,    // ← nuevo
    "devops-bot":    devopsagent.Rules,
}

Nota: El ID aquí debe coincidir exactamente con agent.id en el config.yaml.

Paso 3: Registrar en Matrix

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

Este comando:

  1. Crea el usuario en Synapse via admin API
  2. Genera una contraseña aleatoria
  3. Hace login para obtener un access token
  4. Guarda MATRIX_TOKEN_<AGENT> en .env

Guardar la contraseña manualmente — se necesita para la verificación E2EE:

# Añadir al .env manualmente si no se guardó:
MATRIX_PASSWORD_<AGENT>=<password_generada>

Importante: El script register.sh imprime la password en la salida. Copiarla y guardarla.

Actualizar device_id en config.yaml

El registro crea un device_id nuevo. Actualizarlo en agents/<agent-id>/config.yaml:

matrix:
  device_id: "<DEVICE_ID del output de register>"

Paso 4: Configurar avatar y display name

Colocar la imagen del bot en static/:

# Subir avatar y sincronizar displayname desde el config
./dev-scripts/avatar.sh <agent-id> static/<imagen>.jpg

Esto hace:

  1. Sube la imagen al homeserver Matrix (obtiene una URL mxc://)
  2. Establece el avatar del usuario bot
  3. Sincroniza el displayname desde agent.name del config.yaml

Formatos soportados: JPG, PNG. Recomendado: cuadrado, 256x256 o superior.

Paso 5: Verificación E2EE (cross-signing)

Sin este paso, los mensajes del bot mostrarán: "Encrypted by a device not verified by its owner".

go run -tags goolm ./cmd/verify \
  --homeserver "https://matrix-af2f3d.organic-machine.com" \
  --username "<agent-id>" \
  --password "<password_del_bot>" \
  --token "<access_token>" \
  --store "./agents/<agent-id>/data/crypto/"

Qué hace:

  1. Inicializa el crypto helper de mautrix
  2. Genera claves de cross-signing (master + self-signing)
  3. Las sube al homeserver usando UIA con la password del bot
  4. Firma el device del bot con la self-signing key

Después de verificar: Limpiar el crypto store temporal si se usó uno diferente al del agente.

Importante: Si se cambia la password del bot (admin API), el token anterior se invalida. Hay que:

  1. Re-login para obtener nuevo token
  2. Actualizar MATRIX_TOKEN_<AGENT> en .env
  3. Actualizar device_id en config.yaml
  4. Borrar el crypto store viejo (data/crypto/)
  5. Re-ejecutar cmd/verify

Paso 6: Arrancar el agente

./dev-scripts/start.sh <agent-id>

Verificar que arrancó correctamente:

# Ver logs
tail -f run/<agent-id>.log

# Verificar proceso
./dev-scripts/ps.sh <agent-id>

# Estado general
./dev-scripts/list.sh

Logs esperados al arrancar correctamente:

{"level":"INFO","msg":"initializing e2ee","store":"data/crypto/crypto.db"}
{"level":"INFO","msg":"e2ee ready"}
{"level":"INFO","msg":"agent starting","id":"<agent-id>","tools":["current_time","matrix_send"]}
{"level":"INFO","msg":"starting matrix sync"}

Paso 7: Verificar funcionamiento

  1. Abrir Element u otro cliente Matrix
  2. Enviar un DM al bot: @<agent-id>:matrix-af2f3d.organic-machine.com
  3. Verificar que responde
  4. Verificar que no aparece el warning de "device not verified"
  5. Si tiene tools, probar que las usa (e.g., preguntar la hora)

Resumen de comandos (en orden)

# 1. Crear scaffold
./dev-scripts/new-agent.sh <id> "Nombre"

# 2. Editar reglas, config, prompt
#    agents/<id>/agent.go
#    agents/<id>/config.yaml
#    agents/<id>/prompts/system.md

# 3. Registrar en launcher
#    Editar cmd/launcher/main.go → import + rulesRegistry

# 4. Registrar en Matrix
./dev-scripts/register.sh <id> "Nombre"

# 5. Avatar y displayname
./dev-scripts/avatar.sh <id> static/<imagen>.jpg

# 6. Verificación E2EE
go run -tags goolm ./cmd/verify \
  --homeserver "$MATRIX_HOMESERVER" \
  --username "<id>" \
  --password "$MATRIX_PASSWORD_<AGENT>" \
  --token "$MATRIX_TOKEN_<AGENT>"

# 7. Arrancar
./dev-scripts/start.sh <id>

# 8. Verificar
tail -f run/<id>.log

Troubleshooting

Problema Causa Solución
env var ... is not set La regex del .env loader no matchea Verificar que el nombre de la var solo usa [A-Z0-9_]
M_UNKNOWN_TOKEN Token invalidado (password cambiada) Re-login, actualizar .env
mismatching device ID Crypto store con device viejo Borrar data/crypto/, actualizar device_id en config
"Encrypted by device not verified" Falta cross-signing Ejecutar cmd/verify
Bot no responde Reglas no matchean Verificar que hay regla catch-all para DMs/mentions
no rules registered for agent ID no está en rulesRegistry Añadir en cmd/launcher/main.go
Bot muere al arrancar Revisar logs tail -f run/<id>.log

Compilación

Siempre usar la tag goolm para soporte E2EE puro (sin CGO):

go build -tags goolm ./cmd/launcher
go build -tags goolm ./cmd/verify
go run -tags goolm ./cmd/verify --help