e8c15d9e92
- .claude/rules/create_agent.md: sección "Ruta rápida" actualizada con los flags de personalización y mención de personalize.sh standalone y detect-provider.sh para auto-detección de provider. - .claude/skills/create-agent/SKILL.md: Paso 2 reescrito para mostrar el comando completo con flags opcionales. Añadidas notas sobre personalize.sh y auto-detección de provider. - .claude/skills/create-bot/SKILL.md: Paso 3 actualizado para mencionar personalize.sh (robots: solo --description y --prefix aplican). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
309 lines
12 KiB
Markdown
309 lines
12 KiB
Markdown
# Policy: Crear un nuevo agente o robot
|
|
|
|
Guia ejecutable para Claude. Seguir paso a paso sin desviarse.
|
|
|
|
## Pipeline formalizado (12 pasos)
|
|
|
|
Todo agente o robot creado debe pasar por TODOS estos pasos, en orden estricto:
|
|
|
|
```
|
|
1. SCAFFOLD → crear archivos base desde template
|
|
2. BUILD → go build -tags goolm ./...
|
|
3. REGISTER → crear usuario Matrix + token
|
|
4. VERIFY E2EE → cross-signing + recovery key
|
|
5. CONVERT (robot) → eliminar LLM/prompts si type=robot
|
|
6. AUTO-AVATAR → generar y aplicar foto de perfil
|
|
7. DISPLAY NAME → configurar nombre visible en Matrix
|
|
8. PERSONALIZE → config.yaml, agent.go, system prompt
|
|
9. REBUILD → recompilar tras personalizacion
|
|
10. START/RESTART → arrancar el launcher con el bot
|
|
11. HEALTH CHECK → verificar que el bot esta activo
|
|
12. SELF-INTRODUCE → el bot envia bienvenida a los devs
|
|
```
|
|
|
|
**Pasos 1-7**: ejecutados por `./dev-scripts/agent/create-full.sh`
|
|
**Paso 8**: personalizar manualmente agent.go, config.yaml, prompts/system.md
|
|
**Paso 9**: `go build -tags goolm ./...`
|
|
**Paso 10**: `./dev-scripts/server/start.sh` (o `restart.sh`)
|
|
**Paso 11**: `./dev-scripts/agent/health-check.sh <id>`
|
|
**Paso 12**: `./dev-scripts/agent/notify-developer.sh <id> <type> "<display-name>"` (requiere `DEVELOPER_MATRIX_USERS` en `.env`)
|
|
|
|
## 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 rapida — script automatizado (pasos 1-8)
|
|
|
|
Si tienes todos los datos del agente (description + system prompt), el Paso 8 puede hacerse automaticamente:
|
|
|
|
```bash
|
|
./dev-scripts/agent/create-full.sh <agent-id> "Display Name" \
|
|
--description "<descripcion>" \
|
|
--provider <openai|anthropic> \
|
|
--system-prompt "<system prompt con seccion de seguridad>" \
|
|
[--tone <friendly|professional|casual|technical>] \
|
|
[--prefix "<emoji>"] \
|
|
[--tool-use]
|
|
```
|
|
|
|
Este script ejecuta en orden: scaffold, build, register Matrix, verify E2EE, auto-avatar, display name, **personalizar (auto)**, notify.
|
|
Crea todos los archivos, registra en el launcher, genera todas las env vars en `.env`.
|
|
|
|
**Si se omiten los flags de personalización**, el script se comporta como antes (pasos 1-7) y el Paso 8 queda pendiente de edición manual.
|
|
|
|
**Personalización independiente** (sobre agente ya creado):
|
|
```bash
|
|
./dev-scripts/agent/personalize.sh <agent-id> --description "..." --system-prompt "..."
|
|
```
|
|
|
|
**Auto-detección de provider**: omitir `--provider` para que `detect-provider.sh` elija automáticamente según `.env`.
|
|
|
|
Despues del script, continuar con pasos 9-12 (rebuild, start, health check, self-introduce).
|
|
|
|
## Archivos a personalizar despues del scaffold (paso 8)
|
|
|
|
### 1. `agents/<agent-id>/agent.go` — Reglas puras
|
|
|
|
Template base (generado por el scaffold):
|
|
|
|
```go
|
|
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() {
|
|
devagents.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-bot` → `package 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 accion disponibles:
|
|
- `ActionKindReply` — respuesta estatica (con `ReplyAction{Content: "..."}`)
|
|
- `ActionKindLLM` — pasa al LLM (con `LLMAction{}`)
|
|
|
|
### 2. `agents/<agent-id>/config.yaml` — Configuracion
|
|
|
|
El scaffold genera un config completo con defaults sensatos. Solo personalizar estas secciones:
|
|
|
|
**Identidad** (siempre editar):
|
|
```yaml
|
|
agent:
|
|
description: "<la descripcion del agente>"
|
|
```
|
|
|
|
**LLM** (si quieres cambiar provider/model):
|
|
```yaml
|
|
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):
|
|
```yaml
|
|
llm:
|
|
primary:
|
|
provider: claude-code
|
|
claude_code:
|
|
working_dir: "/tmp/claude-agents/<agent-id>" # SIEMPRE configurar, nunca dejar vacio
|
|
permission_mode: "bypassPermissions"
|
|
```
|
|
|
|
**Importante**: `working_dir` debe apuntar fuera del repositorio para evitar que el subproceso `claude -p` acceda al codigo fuente. Si se deja vacio, se usara un directorio temporal (con WARN en logs).
|
|
|
|
**Tool use** (si el agente necesita herramientas):
|
|
```yaml
|
|
llm:
|
|
tool_use:
|
|
enabled: true # cambiar de false a true
|
|
max_iterations: 5
|
|
```
|
|
|
|
**Personalidad** (ajustar tono):
|
|
```yaml
|
|
personality:
|
|
tone: friendly # friendly | professional | casual | technical
|
|
language: es # es | en
|
|
prefix: "🤖" # emoji del bot
|
|
```
|
|
|
|
**Threads** (habilitado por defecto en el scaffold):
|
|
```yaml
|
|
matrix:
|
|
threads:
|
|
enabled: true # responder en threads cuando el mensaje viene de un thread
|
|
auto_thread: false # true para crear thread automatico por cada conversacion 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**: quien es, como se llama
|
|
- **Rol**: que hace, para que sirve
|
|
- **Capacidades**: que puede hacer (incluir tools si `tool_use.enabled: true`)
|
|
- **Estilo**: idioma, tono, formato de respuestas
|
|
- **Restricciones**: que 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 automaticamente.
|
|
Si falla, hacer manualmente:
|
|
|
|
**Blank import** (en la seccion de blank imports de agentes):
|
|
```go
|
|
_ "github.com/enmanuel/agents/agents/<agent-id>"
|
|
```
|
|
|
|
Las reglas se registran automaticamente via `init()` en el paquete del agente.
|
|
No se necesita editar ningun map ni registry manualmente.
|
|
**El ID en `devagents.Register()` DEBE coincidir exactamente con `agent.id` en config.yaml.**
|
|
|
|
## Convencion de env vars — REGLA CRITICA
|
|
|
|
Normalizacion: `normalize_id()` → mayusculas, 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$//'`).
|
|
|
|
## Pasos 9-12: post-personalizacion
|
|
|
|
### Paso 9 — REBUILD
|
|
|
|
```bash
|
|
go build -tags goolm ./...
|
|
```
|
|
|
|
Si falla, corregir y reintentar. **Nunca arrancar el launcher si la compilacion falla.**
|
|
|
|
### Paso 10 — START/RESTART
|
|
|
|
```bash
|
|
./dev-scripts/server/start.sh # primera vez
|
|
./dev-scripts/server/restart.sh # si ya estaba corriendo
|
|
```
|
|
|
|
### Paso 11 — HEALTH CHECK
|
|
|
|
```bash
|
|
./dev-scripts/agent/health-check.sh <agent-id>
|
|
```
|
|
|
|
Verifica en los logs del launcher que el agente arranco correctamente (busca `"e2ee ready"`, `"runner started"`, etc.). Timeout: 30 segundos (configurable como segundo argumento).
|
|
|
|
**No continuar al paso 12 si el health check falla.** Diagnosticar primero.
|
|
|
|
### Paso 12 — SELF-INTRODUCE
|
|
|
|
```bash
|
|
./dev-scripts/agent/notify-developer.sh <agent-id> <type> "<display-name>"
|
|
```
|
|
|
|
El propio bot envia DM de bienvenida a cada developer en `DEVELOPER_MATRIX_USERS`. Incluye:
|
|
- Nombre y tipo (agent/robot)
|
|
- Descripcion (leida de config.yaml)
|
|
- Tools habilitadas (si aplica)
|
|
- Instrucciones de uso
|
|
|
|
Reintenta hasta 3 veces con backoff si el envio falla.
|
|
Si `DEVELOPER_MATRIX_USERS` no esta definida en `.env`, se salta con warning.
|
|
|
|
## Verificacion post-creacion
|
|
|
|
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
|
|
- [ ] Health check pasa (`./dev-scripts/agent/health-check.sh <id>`)
|
|
- [ ] Bot envio bienvenida a los devs (o `DEVELOPER_MATRIX_USERS` no esta configurado)
|
|
|
|
## Troubleshooting E2EE
|
|
|
|
| Problema | Solucion |
|
|
|----------|----------|
|
|
| "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 | Anadir 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/`
|