Files
agenticSystem/README.md
2026-04-01 23:16:45 +01:00

336 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agentic Microservice
Microservicio de orquestación agéntica con context engineering avanzado, multi-agent orchestration, integración MCP, SSE streaming y knowledge base. Diseñado como backend para Acai Code.
## Arquitectura
```
Client → API (FastAPI) → Orchestrator → Subagents (planner/coder/collector/reviewer)
↓ ↓
Context Engine Model Adapter (Claude / OpenAI)
↓ ↓
Memory Store + KB MCP Client (stdio)
Redis (sessions, events, knowledge)
```
**Principios:**
- **Context over chat history** — el modelo recibe estado estructurado, nunca raw tool outputs
- **Knowledge filtering** — solo los docs relevantes al task entran en contexto (keyword scoring)
- **Compaction** — extracción de facts, eliminación de redundancia, prioridades por sección
- **Artifact summarization** — outputs de tools resumidos antes de entrar al contexto
- **Error recovery** — steps fallidos se saltan, timeout global, sesión nunca se queda en executing
- **Concurrency lock** — Redis SETNX impide ejecución simultánea en la misma sesión
## Quick Start
### Con Docker Compose
```bash
# 1. Configurar
cp .env.example .env
# Editar .env — al menos una API key (ANTHROPIC o OPENAI)
# 2. Levantar todo (Redis + microservicio)
docker compose up --build
# 3. Solo Redis (para desarrollo local)
docker compose up redis -d
```
### Desarrollo local
```bash
# 1. Redis
docker compose up redis -d
# 2. Dependencias
pip install -r requirements.txt
# 3. Configurar .env
AGENTIC_OPENAI_API_KEY=sk-...
AGENTIC_DEFAULT_MODEL_PROVIDER=openai
AGENTIC_DEFAULT_MODEL_ID=gpt-4o
AGENTIC_REDIS_PORT=6380
# 4. Arrancar
python3 -m uvicorn src.main:app --reload --port 8001
# 5. Dashboard en http://localhost:8001/dashboard/
```
### Cargar Knowledge Base
```bash
# Cargar docs desde el directorio docs/
curl -X POST http://localhost:8001/api/v1/knowledge/load \
-H "Content-Type: application/json" \
-d '{"docs_path": "docs"}'
```
## Dashboard
Interfaz web para testing integrada en el microservicio. Se accede en `/dashboard/`.
**Features:**
- Gestión de sesiones (crear, eliminar, seleccionar)
- Chat con envío sync (Send) o streaming (Stream)
- Event Log en tiempo real con filtros por categoría y export JSON
- Inspector de estado (task, plan, facts, constraints, timeline)
- Context Debug — muestra exactamente qué recibe cada agente (secciones, tokens, previews)
- Dark/light mode
- Responsive (3 columnas → 1 columna en móvil)
**Atajos de teclado:**
- `Enter` → Send
- `Ctrl+Enter` → Stream
- `Shift+Enter` → Nueva línea
## API Reference
Base URL: `/api/v1`
### Sesiones
```bash
# Crear sesión
curl -X POST http://localhost:8001/api/v1/sessions \
-H "Content-Type: application/json" \
-d '{
"project_profile": {"name": "mi-proyecto", "tech_stack": ["python", "twig"]},
"immutable_rules": ["Responde siempre en español", "Usa Tailwind CSS"],
"metadata": {}
}'
# → {"session_id": "abc123...", "status": "idle"}
# Obtener estado
curl http://localhost:8001/api/v1/sessions/{session_id}
# Eliminar
curl -X DELETE http://localhost:8001/api/v1/sessions/{session_id}
```
### Mensajes
```bash
# Sync — espera la respuesta completa
curl -X POST http://localhost:8001/api/v1/sessions/{session_id}/messages \
-H "Content-Type: application/json" \
-d '{"message": "Crea un módulo FAQ con acordeón"}'
# Streaming — retorna inmediatamente, resultados vía SSE
curl -X POST http://localhost:8001/api/v1/sessions/{session_id}/messages \
-H "Content-Type: application/json" \
-d '{"message": "Crea un módulo FAQ con acordeón", "stream": true}'
```
Respuesta sync:
```json
{
"session_id": "...",
"task_id": "...",
"content": "### Step 1\n...\n### Review\n...",
"steps_completed": 5,
"steps_failed": [],
"artifacts_count": 0,
"review": "...",
"status": "completed"
}
```
### SSE Streaming
```bash
curl -N http://localhost:8001/api/v1/sessions/{session_id}/stream
```
Tipos de evento:
| Evento | Cuándo |
|--------|--------|
| `session.created` | Sesión inicializada |
| `execution.started` | Pipeline arranca |
| `subagent.assigned` | Step ruteado a un agente |
| `agent.delta` | Chunk de texto del agente |
| `tool.started` | Herramienta MCP ejecutándose |
| `tool.completed` | Herramienta terminó |
| `execution.completed` | Task completado |
| `error` | Error en step, planning, o timeout |
### Knowledge Base
```bash
# Cargar docs desde directorio
curl -X POST http://localhost:8001/api/v1/knowledge/load \
-H "Content-Type: application/json" \
-d '{"docs_path": "docs"}'
# Cargar desde ruta absoluta
curl -X POST http://localhost:8001/api/v1/knowledge/load \
-H "Content-Type: application/json" \
-d '{"docs_path": "/ruta/a/mis/docs"}'
# Listar docs cargados
curl http://localhost:8001/api/v1/knowledge
# Eliminar un doc
curl -X DELETE http://localhost:8001/api/v1/knowledge/{doc_id}
```
Los docs se cargan como `*.md` del directorio. Se sobreescriben si ya existen. No requiere reinicio — la siguiente conversación usa los docs actualizados.
### Debug
```bash
# Historial de eventos (persistidos en Redis)
curl http://localhost:8001/api/v1/sessions/{session_id}/events
# Context debug — qué recibió cada agente
curl http://localhost:8001/api/v1/sessions/{session_id}/context-debug
# Health check
curl http://localhost:8001/health
```
## Context Engine
El componente más crítico del sistema. Ensambla el prompt que recibe el modelo con secciones priorizadas:
| Sección | Prioridad | Contenido |
|---------|-----------|-----------|
| `immutable_rules` | 100 | System prompt del agente + reglas de sesión. Nunca se recorta |
| `project_profile` | 80 | Perfil del proyecto (nombre, tech stack) |
| `knowledge_base` | 60 | Docs relevantes filtrados por keywords del task |
| `task_state` | 70 | Objetivo, plan, step actual, facts, constraints |
| `artifact_memory` | 50 | Resúmenes de outputs de herramientas |
| `working_context` | 30 | Items de trabajo recientes entre steps |
**Knowledge filtering:** no carga todos los docs. Extrae keywords del objetivo y step actual, puntúa cada doc (título ×10, tags ×5, contenido ×1), y selecciona los más relevantes dentro de un budget de 15k tokens. Los docs que no caben entran como summary de una línea.
**Token counting:** usa `tiktoken` (encoding `cl100k_base`) para conteo real. Fallback a estimación si tiktoken no está instalado.
**Compaction:** si el total excede el context window (120k tokens default), las secciones de menor prioridad se comprimen o eliminan. `immutable_rules` nunca se toca.
## Orchestrator Pipeline
```
mensaje → planner → [step₁ → step₂ → ... → stepₙ] → reviewer → respuesta
```
1. **Planner** descompone el mensaje en pasos con agent role asignado
2. **Router** rutea cada step al agente apropiado (keyword matching: implement→coder, buscar→collector, etc.)
3. **Subagent** ejecuta el step con su propio contexto controlado
4. Si un step **falla**, se marca como failed y el pipeline continúa con el siguiente
5. **Reviewer** valida el trabajo si hubo >1 step
6. **Timeout global** de 5 min (configurable) — si se excede, la sesión pasa a error
**Concurrency:** Redis lock (SETNX) con TTL de 5 min. Si llega un segundo mensaje mientras uno se ejecuta → `{"status": "busy"}`. El lock se libera automáticamente si el proceso muere.
## MCP (Model Context Protocol)
Cliente stdio que se conecta a un servidor MCP al arrancar:
```bash
# En .env
AGENTIC_MCP_SERVER_COMMAND=node
AGENTIC_MCP_SERVER_ARGS=["mcp-server/stdio.js"]
# Variables del MCP server (se heredan al subproceso)
ACAI_WEB_URL=http://localhost:8080
ACAI_WEBSITE=mi-sitio
ACAI_PROJECT_DIR=/ruta/al/proyecto
```
El cliente descubre tools automáticamente vía `tools/list`, y los agentes las usan durante la ejecución. Los resultados de tools **nunca** entran al contexto como raw output — se resumen como artifacts.
## Configuración
Variables de entorno con prefijo `AGENTIC_`:
| Variable | Default | Descripción |
|----------|---------|-------------|
| `AGENTIC_ANTHROPIC_API_KEY` | — | API key de Anthropic |
| `AGENTIC_OPENAI_API_KEY` | — | API key de OpenAI |
| `AGENTIC_DEFAULT_MODEL_PROVIDER` | `claude` | `claude` o `openai` |
| `AGENTIC_DEFAULT_MODEL_ID` | `claude-sonnet-4-20250514` | Modelo por defecto |
| `AGENTIC_REDIS_HOST` | `localhost` | Host de Redis |
| `AGENTIC_REDIS_PORT` | `6379` | Puerto de Redis |
| `AGENTIC_REDIS_DB` | `0` | Base de datos Redis |
| `AGENTIC_REDIS_PASSWORD` | — | Password de Redis |
| `AGENTIC_MAX_TOKENS` | `4096` | Max tokens de salida por llamada |
| `AGENTIC_CONTEXT_MAX_TOKENS` | `120000` | Max context window |
| `AGENTIC_MAX_EXECUTION_STEPS` | `25` | Max steps por task |
| `AGENTIC_MAX_EXECUTION_TIMEOUT_SECONDS` | `300` | Timeout global (5 min) |
| `AGENTIC_SUBAGENT_MAX_STEPS` | `10` | Max iterations por subagent |
| `AGENTIC_MCP_SERVER_COMMAND` | — | Comando del servidor MCP |
| `AGENTIC_MCP_SERVER_ARGS` | `[]` | Argumentos del servidor MCP |
| `AGENTIC_MCP_TIMEOUT_SECONDS` | `30` | Timeout por tool call |
| `AGENTIC_DEBUG` | `false` | Logging verbose |
## Redis Key Structure
```
agentic:session:{id} → SessionState JSON (TTL 24h)
agentic:session:{id}:artifacts → Hash de ArtifactSummary
agentic:session:{id}:events → Lista de SSE events (cap 500)
agentic:session:{id}:lock → Execution lock (SETNX, TTL 5min)
agentic:sessions:index → Set de session IDs activos
agentic:memory:knowledge:{doc_id} → MemoryDocument JSON
agentic:memory:knowledge:_index → Set de doc IDs
agentic:memory:_tag:{tag} → Set de doc IDs por tag
agentic:memory:_type:{type} → Set de doc IDs por tipo
```
## Project Structure
```
.
├── src/
│ ├── main.py # FastAPI app, lifecycle, wiring
│ ├── config.py # Pydantic settings
│ ├── models/ # Pydantic v2 data models
│ │ ├── session.py # SessionState, TaskState, TaskStep
│ │ ├── context.py # ContextPackage, MemoryDocument
│ │ ├── agent.py # AgentProfile, SubAgentDefinition
│ │ ├── artifacts.py # ArtifactSummary
│ │ └── tools.py # ToolExecution, ToolDefinition
│ ├── context/ # Context Engine (core)
│ │ ├── engine.py # Prompt assembly, knowledge filtering, debug
│ │ └── compactor.py # Compaction, summarization, tiktoken
│ ├── memory/ # Persistent memory
│ │ └── store.py # Redis-backed memory + embeddings
│ ├── adapters/ # Model provider adapters
│ │ ├── base.py # ModelAdapter interface
│ │ ├── claude_adapter.py # Anthropic Claude (streaming)
│ │ └── openai_adapter.py # OpenAI GPT (streaming)
│ ├── mcp/ # MCP client
│ │ └── client.py # stdio transport, tool registry
│ ├── orchestrator/ # Agent orchestration
│ │ ├── engine.py # Pipeline + error recovery + timeout
│ │ ├── router.py # Step-to-agent routing
│ │ └── agents/
│ │ ├── base.py # Shared execution loop
│ │ ├── planner.py # Plan decomposition
│ │ ├── coder.py # Implementation
│ │ ├── collector.py # Context gathering
│ │ └── reviewer.py # Validation
│ ├── streaming/ # SSE streaming
│ │ └── sse.py # Event emitter + Redis persistence
│ ├── storage/ # Persistence
│ │ └── redis.py # Sessions, events, locks
│ └── api/ # REST endpoints
│ └── routes.py # Sessions, messages, knowledge, debug
├── dashboard/ # Testing UI (vanilla JS, zero build)
│ ├── index.html
│ ├── css/main.css
│ └── js/
│ ├── app.js # State, SSE handlers
│ ├── api.js # Fetch + EventSource
│ └── components/ # Sidebar, chat, event log, inspector, timeline
├── mcp-server/ # Acai MCP server (Node.js, stdio)
├── docs/ # Knowledge base documents (*.md)
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── .env.example
```