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>
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 |
sí | — | monitor-bot |
display-name |
sí | — | "Monitor Agent" |
description |
sí | — | "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 | sí | — | 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-bot→package monitor) - No usar reglas para comandos (
!help,!ping, etc.) — los comandos se gestionan viaRegisterCommand(ver policycreate_command.md) - Las reglas solo aplican a mensajes normales (sin prefijo
!)
Tipos de acción disponibles:
ActionKindReply— respuesta estática (conReplyAction{Content: "..."})ActionKindLLM— pasa al LLM (conLLMAction{})
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.mdal 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 erroresagents/<id>/agent.goexportaRules()y es puro (sin I/O)agents/<id>/config.yamltieneagent.id= nombre del directoriocmd/launcher/main.gotiene import + entry en rulesRegistry con el mismo ID.envcontiene:MATRIX_TOKEN_<NORM>,MATRIX_PASSWORD_<NORM>,PICKLE_KEY_<NORM>,SSSS_RECOVERY_KEY_<NORM>prompts/system.mdtiene contenido real (no el stub)prompts/system.mdincluye 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.idcoincida 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/