Files
agents_and_robots/dev/issues/0014-template-agent-standardize.md
T
egutierrez 2756557498 chore: renombrar issues a formato 4 dígitos (NNNN)
Se estandariza la numeración de todos los issues de 3 dígitos a 4 dígitos
(e.g. 005 → 0005, 010 → 0010) para mantener consistencia con la convención
definida en create_issue.md. Se actualiza el README con los nuevos nombres
y links. No hay cambios de contenido en los issues, solo renombrado.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:39:33 +00:00

465 lines
20 KiB
Markdown

# 014 — Agente plantilla + sistema de personalidades + estandarizacion
## Objetivo
Crear un agente plantilla (no lanzable) que sirva como referencia canonica para la configuracion de todos los agentes. Incluir un sistema de personalidades rico que permita definir agentes con caracteres distintos. Enriquecer `!info` para mostrar metadata completa. Estandarizar los config.yaml existentes integrando las nuevas capacidades del proyecto: skills, shared-knowledge, cron jobs.
## Contexto
- El launcher descubre agentes via `agents/*/config.yaml` (glob en cmd/launcher/main.go)
- `!info` existe como built-in en `agents/commands.go` pero solo muestra: nombre, ID, version, descripcion
- No hay herencia de configs ni template base — cada config.yaml es autocontenido
- Agentes actuales: assistant-bot, asistente-2
- La seccion `personality` actual es basica: tone, verbosity, emoji_style, templates, behavior
- Nuevas capacidades en desarrollo: skills (016), shared-knowledge (018), cron jobs (005)
---
## Tareas
### Fase 1: Sistema de personalidades enriquecido
El sistema actual (`pkg/personality/traits.go` + `PersonalityCfg` en schema.go) define tone, verbosity, emoji, error_style, templates y behavior. Esto es funcional pero plano — todos los agentes terminan sonando igual con variaciones menores.
El objetivo es ampliar la personalidad para que cada agente tenga un **caracter unico** que se refleje en como habla, piensa y actua.
- [ ] **1.1** Ampliar `PersonalityCfg` en `internal/config/schema.go` con nuevos campos:
```go
type PersonalityCfg struct {
// --- campos existentes (sin cambios) ---
Tone string `yaml:"tone"`
Verbosity string `yaml:"verbosity"`
Language string `yaml:"language"`
LanguagesSupported []string `yaml:"languages_supported"`
EmojiStyle string `yaml:"emoji_style"`
Prefix string `yaml:"prefix"`
ErrorStyle string `yaml:"error_style"`
Templates TemplatesCfg `yaml:"templates"`
Behavior BehaviorCfg `yaml:"behavior"`
// --- NUEVOS campos ---
// Identidad narrativa
Role string `yaml:"role"` // rol principal: "asistente general", "devops engineer", "analista de datos"
Backstory string `yaml:"backstory"` // breve historia/contexto del personaje (1-3 frases)
Expertise []string `yaml:"expertise"` // areas de experiencia: ["linux", "docker", "monitoring"]
Limitations []string `yaml:"limitations"` // que NO sabe o no debe intentar
// Estilo de comunicacion
Communication CommunicationCfg `yaml:"communication"`
// Directivas de comportamiento en texto libre
CustomDirectives []string `yaml:"custom_directives"` // instrucciones adicionales para el system prompt
}
// CommunicationCfg define como se expresa el agente mas alla del tone basico.
type CommunicationCfg struct {
Formality string `yaml:"formality"` // formal | semiformal | casual | coloquial
Humor string `yaml:"humor"` // none | subtle | moderate | frequent
Personality string `yaml:"personality"` // analytical | creative | pragmatic | empathetic | assertive
ResponseStyle string `yaml:"response_style"` // structured | conversational | bullet_points | narrative
Quirks []string `yaml:"quirks"` // rasgos unicos: ["usa analogias de cocina", "cita a Linus Torvalds"]
AvoidTopics []string `yaml:"avoid_topics"` // temas que evita o redirige
Catchphrases []string `yaml:"catchphrases"` // frases tipicas que usa ocasionalmente
}
```
- [ ] **1.2** Ampliar tipos puros en `pkg/personality/traits.go`:
```go
type Formality string
const (
FormalityFormal Formality = "formal"
FormalitySemiformal Formality = "semiformal"
FormalityCasual Formality = "casual"
FormalityColoquial Formality = "coloquial"
)
type Humor string
const (
HumorNone Humor = "none"
HumorSubtle Humor = "subtle"
HumorModerate Humor = "moderate"
HumorFrequent Humor = "frequent"
)
type PersonalityType string
const (
PersonalityAnalytical PersonalityType = "analytical"
PersonalityCreative PersonalityType = "creative"
PersonalityPragmatic PersonalityType = "pragmatic"
PersonalityEmpathetic PersonalityType = "empathetic"
PersonalityAssertive PersonalityType = "assertive"
)
type ResponseStyle string
const (
ResponseStructured ResponseStyle = "structured"
ResponseConversational ResponseStyle = "conversational"
ResponseBulletPoints ResponseStyle = "bullet_points"
ResponseNarrative ResponseStyle = "narrative"
)
```
Ampliar el struct `Personality` con los nuevos campos correspondientes.
- [ ] **1.3** Crear funcion `BuildPersonalityPrompt(cfg PersonalityCfg) string` en `pkg/personality/` que genere un bloque de system prompt a partir de la config de personalidad. Esta funcion es **pura** — recibe config, devuelve string. El runtime la usa para inyectar personalidad en el prompt del LLM.
El prompt generado debe incluir:
- Rol y backstory
- Expertise y limitaciones
- Estilo de comunicacion (formality, humor, personality, response_style)
- Quirks y catchphrases
- Custom directives
- Todo redactado como instrucciones naturales para el LLM
Ejemplo de output:
```
## Tu personalidad
Eres un ingeniero DevOps senior con 10 anos de experiencia en Linux y containers.
**Rol**: DevOps engineer especializado en infraestructura y monitoring.
**Expertise**: Linux, Docker, Kubernetes, Prometheus, bash scripting.
**Limitaciones**: No das consejos de frontend ni diseno UI.
**Como te comunicas**:
- Tono semiformal, directo pero amable
- Humor sutil — algun comentario ironico cuando algo falla de forma obvia
- Estilo pragmatico — siempre priorizas la solucion sobre la teoria
- Respuestas estructuradas con comandos claros
- A veces citas a Linus Torvalds o usas analogias mecanicas
**Directivas especiales**:
- Siempre sugiere verificar con un dry-run antes de ejecutar cambios destructivos
- Cuando algo falla, muestra el log relevante antes de diagnosticar
```
- [ ] **1.4** Integrar `BuildPersonalityPrompt` en `agents/runtime.go` — concatenar el bloque de personalidad al system prompt leido del archivo. El orden debe ser: system prompt del archivo + bloque de personalidad generado.
### Fase 2: Agente plantilla con personalidades de ejemplo
- [ ] **2.1** Anadir campo `Template bool` a `AgentMeta` en `internal/config/schema.go`
- [ ] **2.2** Filtrar agentes template en `cmd/launcher/main.go` — skip si `cfg.Agent.Template == true`
- [ ] **2.3** Crear `agents/_template/config.yaml` — referencia canonica con TODAS las secciones. Incluir:
**Identidad**:
```yaml
agent:
id: "_template"
name: "Template Agent"
version: "0.0.0"
enabled: true
template: true # el launcher ignora este agente
description: "Agente plantilla. No se lanza. Sirve como referencia para crear nuevos agentes."
tags: [template]
```
**Personalidad completa** (con todos los campos nuevos documentados):
```yaml
personality:
# --- Identidad narrativa ---
role: "asistente general"
backstory: "Un asistente amigable creado para ayudar con tareas cotidianas."
expertise: [general]
limitations: []
# --- Estilo basico ---
tone: friendly # direct | friendly | formal | casual | technical
verbosity: concise # minimal | concise | detailed | verbose
language: es
languages_supported: [es, en]
emoji_style: minimal # none | minimal | moderate | heavy
prefix: ""
error_style: helpful # terse | helpful | detailed
# --- Comunicacion avanzada ---
communication:
formality: semiformal # formal | semiformal | casual | coloquial
humor: none # none | subtle | moderate | frequent
personality: pragmatic # analytical | creative | pragmatic | empathetic | assertive
response_style: structured # structured | conversational | bullet_points | narrative
quirks: [] # rasgos unicos del personaje
avoid_topics: [] # temas a evitar
catchphrases: [] # frases tipicas
# --- Directivas libres ---
custom_directives: [] # instrucciones extra para el system prompt
# --- Templates de respuesta ---
templates:
greeting: "Hola, soy {name}. En que puedo ayudarte?"
unknown_command: "No entiendo ese comando. Usa !help."
permission_denied: "No tienes permiso para eso."
error: "Algo salio mal: {{.Error}}"
success: "{{.Summary}}"
busy: "Estoy procesando otra solicitud, un momento..."
# --- Comportamiento ---
behavior:
proactive: false
ask_confirmation: false
show_reasoning: false
thread_replies: true
typing_indicator: true
acknowledge_receipt: false
```
**Skills** (nueva seccion):
```yaml
skills:
enabled: false
path: "skills/" # ruta base de skills (relativa al proyecto)
categories: [] # vacio = todas las categorias | ["devops", "system"] = filtradas
```
**Shared knowledge** (nueva seccion):
```yaml
# Dentro de tools:
tools:
# ... tools existentes ...
shared_knowledge:
enabled: false
dir: "knowledges" # directorio compartido
db_path: "knowledges/data/knowledge.db"
```
**Schedules con ejemplos**:
```yaml
schedules:
# - name: "buenos-dias"
# cron: "0 9 * * 1-5"
# action:
# kind: llm_prompt
# target: "Buenos dias equipo. Dame un resumen rapido del estado de los servicios."
# output_room: "!roomid:server.com"
# on_failure:
# notify_room: ""
# escalate_to: ""
```
Incluir TODAS las demas secciones (llm, matrix, agents, ssh, security, observability, resilience, storage, memory) con valores por defecto documentados.
- [ ] **2.4** Crear `agents/_template/agent.go` minimo con `Rules()` retornando slice vacio
- [ ] **2.5** Crear `agents/_template/prompts/system.md` con un system prompt plantilla que muestre donde va cada seccion (instrucciones base, personalidad inyectada automaticamente, tools disponibles, etc.)
- [ ] **2.6** Actualizar `dev-scripts/agent/new-agent.sh` para copiar desde `_template/` en lugar de generar inline
### Fase 3: Ejemplos de personalidades distintas
Para demostrar que el sistema funciona, definir perfiles de personalidad que se puedan usar como punto de partida. Estos van como comentarios/documentacion en el template, NO como agentes reales.
- [ ] **3.1** Documentar en `agents/_template/PERSONALITIES.md` al menos 4 perfiles de ejemplo:
**Perfil: DevOps pragmatico**
```yaml
personality:
role: "ingeniero DevOps senior"
backstory: "Veterano de infraestructura con cicatrices de guerra de incidentes en produccion."
expertise: [linux, docker, kubernetes, monitoring, bash, networking]
limitations: ["no da consejos de frontend", "no hace diseno UI"]
tone: direct
verbosity: concise
communication:
formality: semiformal
humor: subtle
personality: pragmatic
response_style: structured
quirks: ["usa analogias mecanicas", "siempre pide ver los logs primero"]
catchphrases: ["primero los logs, despues las teorias", "en produccion no se experimenta"]
custom_directives:
- "Siempre sugiere dry-run antes de cambios destructivos"
- "Incluye el comando exacto, no solo la descripcion"
```
**Perfil: Analista meticuloso**
```yaml
personality:
role: "analista de datos"
backstory: "Obsesionado con los patrones y las anomalias. Nada escapa a su atencion."
expertise: [analisis de logs, metricas, estadistica, patrones de errores]
limitations: ["no ejecuta cambios en produccion", "no toma decisiones operativas"]
tone: technical
verbosity: detailed
communication:
formality: formal
humor: none
personality: analytical
response_style: structured
quirks: ["siempre cuantifica", "pide rango de fechas antes de analizar"]
catchphrases: ["los datos no mienten", "correlacion no implica causalidad"]
```
**Perfil: Asistente amigable**
```yaml
personality:
role: "asistente personal"
backstory: "Siempre dispuesto a ayudar, paciente y claro en sus explicaciones."
expertise: [tareas generales, redaccion, organizacion, resumen]
limitations: ["no tiene acceso a servidores", "no ejecuta codigo"]
tone: friendly
verbosity: concise
communication:
formality: casual
humor: subtle
personality: empathetic
response_style: conversational
quirks: ["pregunta si quieres mas detalle", "celebra cuando termina una tarea"]
catchphrases: ["listo!", "algo mas en lo que pueda ayudar?"]
```
**Perfil: Guardian de seguridad**
```yaml
personality:
role: "especialista en seguridad"
backstory: "Paranoico profesional. Asume que todo esta comprometido hasta demostrar lo contrario."
expertise: [seguridad, auditoria, permisos, CVEs, hardening]
limitations: ["no implementa features", "no optimiza performance"]
tone: formal
verbosity: detailed
communication:
formality: formal
humor: none
personality: assertive
response_style: bullet_points
quirks: ["siempre menciona el principio de minimo privilegio", "pide MFA para todo"]
catchphrases: ["confiar pero verificar", "eso necesita un CVE review"]
custom_directives:
- "Nunca sugieras deshabilitar firewalls o SELinux como solucion"
- "Siempre recomienda rotar credenciales despues de un incidente"
```
### Fase 4: Enriquecer `!info`
- [ ] **4.1** Modificar el handler de `!info` en `agents/commands.go` para que devuelva:
- Nombre, ID, version, descripcion
- Personalidad: role, tone, formality, personality type, humor
- LLM: provider + modelo
- Tools habilitadas (lista de nombres)
- Skills habilitadas (si/no + categorias + cantidad)
- Knowledge: privado (si/no), compartido (si/no)
- Memoria: si/no + window size
- Schedules: cantidad de cron jobs configurados
- Uptime del agente
- [ ] **4.2** Formatear como markdown legible con secciones
- [ ] **4.3** No exponer datos sensibles (tokens, API keys, paths internos, passwords)
### Fase 5: Estandarizar configs existentes
- [ ] **5.1** Definir convenciones estandar obligatorias para todo config.yaml:
- `agent.version` siempre presente (semver)
- `agent.tags` siempre presente (al menos un tag)
- `personality.role` siempre presente
- `personality.language` y `personality.languages_supported` siempre explicitos
- `personality.communication` siempre presente (al menos formality y personality)
- `personality.behavior` siempre con las 6 claves
- `llm.tool_use` siempre explicito (enabled true/false, max_iterations)
- `tools.memory` y `tools.knowledge` siempre presentes (enabled true/false)
- `matrix.homeserver` y `matrix.encryption` siempre presentes
- `observability.logging.level` siempre explicito
- Si `skills.enabled: true`, al menos `skills.path` definido
- Si `schedules` tiene entradas, cada una con `name` y `cron` validos
- [ ] **5.2** Actualizar `agents/assistant-bot/config.yaml` — anadir personalidad rica:
```yaml
personality:
role: "asistente general"
backstory: "Asistente polivalente, siempre listo para ayudar con cualquier tarea."
expertise: [general, redaccion, resumen, consultas]
limitations: []
communication:
formality: semiformal
humor: subtle
personality: empathetic
response_style: conversational
quirks: []
avoid_topics: []
catchphrases: []
custom_directives: []
# ... mas secciones nuevas (skills, shared_knowledge, etc.)
```
- [ ] **5.3** Actualizar `agents/asistente-2/config.yaml` — idem, personalidad diferenciada
- [ ] **5.4** Validar que ambos agentes arrancan correctamente tras los cambios
### Fase 6: Integracion con nuevas capacidades en config
Las tasks 005 (cron), 016 (skills) y 018 (shared-knowledge) definen nuevos sistemas. El template debe incluir sus secciones de config para que nuevos agentes ya las tengan disponibles.
- [ ] **6.1** Anadir `SkillsCfg` al `AgentConfig` en schema.go (si no lo hizo la task 016):
```go
type SkillsCfg struct {
Enabled bool `yaml:"enabled"`
Path string `yaml:"path"` // default: "skills/"
Categories []string `yaml:"categories"` // filtro de categorias
}
```
- [ ] **6.2** Anadir `SharedKnowledgeCfg` al `ToolsCfg` en schema.go (si no lo hizo la task 018):
```go
type SharedKnowledgeCfg struct {
Enabled bool `yaml:"enabled"`
Dir string `yaml:"dir"` // default: "knowledges"
DBPath string `yaml:"db_path"` // default: "knowledges/data/knowledge.db"
}
```
- [ ] **6.3** Verificar que `ScheduleCfg` soporta los 3 tipos de accion (send_message, run_tool, llm_prompt) — el schema actual ya los tiene pero validar completitud
- [ ] **6.4** Actualizar el template con las secciones de skills, shared_knowledge y schedules de ejemplo
### Fase 7: Documentacion y tooling
- [ ] **7.1** Anadir validacion en `internal/config/loader.go` que emita warnings si faltan secciones recomendadas (no bloquear, solo log):
- personality.role vacio
- personality.communication sin definir
- skills.enabled true pero sin path
- schedules con entradas sin name
- [ ] **7.2** Actualizar `.claude/rules/create_agent.md` para:
- Referenciar el template como punto de partida
- Incluir paso de definir personalidad rica
- Incluir paso de decidir skills y shared-knowledge
- [ ] **7.3** Actualizar `docs/creating-agents.md` con la seccion de personalidades
- [ ] **7.4** Actualizar `CLAUDE.md` — agregar `SkillsCfg` y `SharedKnowledgeCfg` a la descripcion del schema
---
## Orden de ejecucion recomendado
1. **Fase 1** (sistema de personalidades) — tipos puros + BuildPersonalityPrompt + integracion runtime
2. **Fase 2** (template) — config.yaml canonica con todo documentado
3. **Fase 3** (ejemplos de personalidades) — PERSONALITIES.md como referencia
4. **Fase 5** (estandarizar configs) — aplicar nuevos campos a agentes existentes
5. **Fase 4** (info) — mostrar la metadata enriquecida
6. **Fase 6** (nuevas capacidades) — integrar skills/knowledge/cron en schema si no existen
7. **Fase 7** (docs) — cuando todo este estable
## Dependencias con otras tasks
| Task | Relacion |
|------|----------|
| 005 (cron) | El template incluye schedules de ejemplo. Si 005 no esta implementado, los schedules son solo config sin efecto. |
| 016 (skills) | El template incluye `skills:` config. Si 016 no esta implementado, el runtime ignora la seccion. |
| 018 (shared-knowledge) | El template incluye `shared_knowledge:` config. Si 018 no esta implementado, el runtime la ignora. |
Esta task puede ejecutarse **antes** que 005/016/018 — solo define el schema y template. Las otras tasks implementan la funcionalidad real.
## Decisiones de diseno
- **Personalidad en config, no en codigo**: la personalidad se define 100% en YAML y se transforma a prompt via `BuildPersonalityPrompt`. Cero logica de personalidad en Go.
- **BuildPersonalityPrompt es pura**: vive en `pkg/personality/`, recibe datos, devuelve string. Sin side effects.
- **Personalidad se concatena al system prompt**: no reemplaza el archivo `prompts/system.md`, se anade despues. El archivo define instrucciones base, la personalidad anade caracter.
- **Template parseable**: el config.yaml del template es YAML valido con `template: true`. Sirve como test de que el schema esta completo.
- **Backwards compatible**: los campos nuevos son opcionales. Agentes existentes sin `communication` o `role` siguen funcionando — `BuildPersonalityPrompt` genera un bloque vacio/minimo si no hay datos.
- **PERSONALITIES.md como catalogo**: no son agentes reales, son perfiles de referencia. Al crear un agente nuevo, se copia un perfil y se ajusta.