Retrato de Santiago Fernández

CubeLabs

IA · Fintech · Agentes · Automatización
🧠 IA

OpenViking: Base de Datos de Contexto para Agentes de IA

Memoria, recursos y skills organizados como un filesystem bajo el protocolo viking://

⏱ 40 min 📊 Intermedio 📝 10 lecciones

Los agentes de IA se olvidan. OpenViking (30K+ estrellas, trending de GitHub) resuelve la gestión de contexto convirtiéndolo en un sistema de archivos virtual: tu agente explora su propia memoria con ls, tree y find en vez de consultar un vector store de caja negra. Aprende a instalar el servidor, alimentar recursos, crear skills, usar las capas L0/L1/L2 para recortar tokens, convertir sesiones en memoria a largo plazo e integrarlo con Claude Code, Codex, MCP y LangChain.

OpenViking — The Context Database for AI Agents
Fuente: github.com/volcengine/OpenViking

Contenido

  1. El problema del contexto en los agentes
  2. Arquitectura: el contexto como filesystem
  3. Instalación y configuración
  4. La CLI ov en acción
  5. Tipos de contexto: recursos, memoria y skills
  6. Capas L0/L1/L2: contexto progresivo
  7. Recuperación: find, search e intención
  8. Sesiones: de la conversación a la memoria
  9. Integraciones: Claude Code, MCP y LangChain
  10. VikingBot y despliegue en producción

1. El problema del contexto en los agentes

Cuando construyes agentes de IA te topas con cinco dolores constantes:

ProblemaQué significa
FragmentaciónMemoria en código, recursos en vectordb, skills dispersas. Imposible gestionar de forma unificada.
Explosión de contextoTareas largas generan contexto en cada ejecución; truncar o comprimir pierde información.
RAG pobreEl RAG tradicional usa almacenamiento plano, sin visión global del contexto.
OpacidadEl pipeline de recuperación es una caja negra imposible de depurar.
Memoria sin iterarLos sistemas de memoria solo guardan preferencias del usuario, no experiencia de tareas del agente.

OpenViking ataca exactamente estos puntos con un cambio de paradigma: en lugar de una base de datos plana, todo el contexto se organiza como un sistema de archivos virtual con URIs deterministas (viking://), capas de resumen L0/L1/L2 y recuperación por directorios que deja una trayectoria auditable.

💡 Tip

No necesitas migrar tu stack de golpe. OpenViking funciona como servicio HTTP independiente y se conecta a tus agentes existentes por plugins o MCP.

2. Arquitectura: el contexto como filesystem

OpenViking es una base de datos de contexto: unifica memoria, recursos y skills bajo un mismo árbol viking://.

viking://
├── resources/              # Recursos: docs de proyecto, repos, webs
│   └── my_project/
├── user/
│   └── {user_id}/          # Contexto privado del usuario
│       ├── memories/       # Memorias del usuario
│       ├── resources/      # Recursos privados
│       ├── skills/         # Skills privadas
│       └── peers/
└── agent/
    └── skills/             # Skills compartidas de la cuenta

La arquitectura interna separa la lógica en módulos claros:

MóduloResponsabilidad
ClientEntrada unificada; delega en la capa de servicio.
ServiceLógica de negocio: FSService, SearchService, SessionService, ResourceService…
RetrieveAnálisis de intención, recuperación jerárquica y rerank.
SessionMensajes, uso de contexto, compresión y commit de memoria.
ParseParseo de documentos (PDF/MD/HTML), construcción de árbol y generación semántica L0/L1/L2.
CompressorExtracción de memoria con esquemas y deduplicación por LLM.
StorageAlmacenamiento dual: AGFS (contenido) + índice vectorial.

El flujo de escritura es Input → Parser → TreeBuilder → AGFS → SemanticQueue → Vector Index. El flujo de lectura es Query → Intent Analysis → Hierarchical Retrieval → Rerank → Results.

⚠️ Error común

No pienses en OpenViking como "otro vector store". El índice vectorial solo guarda referencias; el contenido vive en AGFS. La recuperación empieza por directorios, no por fragmentos sueltos.

3. Instalación y configuración

Requisitos: Python 3.10+. Puedes instalarlo como paquete Python o levantarlo con Docker.

Opción A: paquete Python

pip install openviking --upgrade
# o con uv (recomendado)
uv tool install openviking --upgrade

Tras instalar, tienes dos comandos: ov (cliente) y openviking-server (servidor).

Opción B: Docker Compose

mkdir -p ~/.openviking && touch ~/.openviking/ov.conf
# docker-compose.yml
services:
  openviking:
    image: ghcr.io/volcengine/openviking:latest
    ports:
      - "1933:1933"
    volumes:
      - ~/.openviking:/app/.openviking
    restart: unless-stopped

Configuración con init y doctor

1

Inicializa el asistente

openviking-server init te guía por proveedores, modelos y escribe ~/.openviking/ov.conf. Soporta Volcengine, OpenAI, Codex OAuth, Kimi, GLM y Ollama local.

2

Valida el setup

openviking-server doctor comprueba el config, la versión de Python, la conectividad de los proveedores y el espacio en disco.

3

Arranca el servidor

openviking-server escucha por defecto en 127.0.0.1:1933. En otro terminal ya puedes usar ov.

Necesitas dos capacidades de modelo: un VLM (para entender imágenes y contenido) y un embedding (para vectorización). El config mínimo es:

{
  "embedding": {
    "dense": {
      "provider": "volcengine",
      "model": "doubao-embedding-vision-251215",
      "api_base": "https://ark.cn-beijing.volces.com/api/v3",
      "api_key": "<tu-ark-api-key>",
      "dimension": 1024,
      "input": "multimodal"
    }
  },
  "vlm": {
    "provider": "volcengine",
    "model": "doubao-seed-2-0-code-preview-260215",
    "api_base": "https://ark.cn-beijing.volces.com/api/v3",
    "api_key": "<tu-ark-api-key>",
    "temperature": 0
  },
  "storage": { "workspace": "./data" },
  "server": { "host": "127.0.0.1", "port": 1933 }
}
💡 Tip

Para probar sin APIs de pago, Ollama local puede servir tanto el embedding como el VLM. El asistente init detecta e instala el runtime si es necesario.

4. La CLI ov en acción

Con el servidor corriendo, la CLI ov te da control total del contexto:

$ ov status
# servidor conectado, health OK
$ ov add-resource https://github.com/volcengine/OpenViking --wait
$ ov ls viking://resources/
$ ov tree viking://resources/volcengine -L 2
$ ov find "what is openviking"
$ ov grep "openviking" --uri viking://resources/volcengine/OpenViking/docs/en

El árbol de comandos cubre todo el ciclo de vida:

GrupoComandos
Escrituraadd-resource, add-skill, write, mkdir, rm, mv, add-memory
Lecturals, tree, stat, read, abstract, overview, find, search, grep, glob
Skillsskills add/list/find/show/update/remove/validate
Sesionessession new/list/get/delete/commit/add-message(s)
Import/exportexport, backup, import, restore, snapshot
Observabilidadhealth, status, observer, task status/watch

add-resource acepta URLs, ficheros locales, directorios, repos Git, sitemaps y RSS. El parámetro --wait espera a que termine el procesamiento semántico antes de devolver el control.

💡 Tip

Prueba ov tui para un explorador de archivos a pantalla completa con previsualización de imágenes y vista vectorial.

5. Tipos de contexto: recursos, memoria y skills

OpenViking abstrae todo el contexto en tres tipos básicos:

TipoPropósitoCiclo de vidaIniciativa
ResourceConocimiento y reglas (docs, repos, FAQs)Largo plazo, estáticoEl usuario lo añade
MemoryCognición del agente (preferencias, experiencia)Largo plazo, se actualizaEl agente lo registra
SkillCapacidades invocables (herramientas, MCP)Largo plazo, estáticoUsuario o sistema

Las memorias tienen tipos integrados que se escriben en el namespace del usuario:

TipoUbicaciónDescripción
profilememories/profile.mdInformación básica del usuario
preferencesmemories/preferences/Preferencias por tema
entitiesmemories/entities/Personas, proyectos, organizaciones
eventsmemories/events/Decisiones e hitos
identitymemories/identity.mdNombre, persona y temperamento del asistente
soulmemories/soul.mdPrincipios, límites y estilo
cases / trajectories / experiencesmemories/cases|trajectories|experiences/Aprendizaje de tareas y experiencia reutilizable

Una skill se guarda como directorio con su SKILL.md:

viking://user/skills/search-web/
├── .abstract.md          # L0: descripción corta
├── .overview.md          # L1: resumen del directorio
├── SKILL.md              # L2: definición de la skill
└── scripts               # L2: implementación
⚠️ Error común

No confundas el tipo Skill con las memorias skills/ deshabilitadas. Las skills vivas viven en viking://user/skills/{name}/SKILL.md y son independientes de la extracción de memoria.

6. Capas L0/L1/L2: contexto progresivo

Meter todo el contexto en el prompt es caro y ruidoso. OpenViking procesa cada directorio en tres niveles:

NivelNombreLímite por defectoPropósito
L0Abstract256 caracteresBúsqueda vectorial y filtrado rápido
L1Overview4000 caracteresRerank y navegación de contenido
L2DetailSin límiteContenido completo, carga bajo demanda
viking://resources/docs/auth/
├── .abstract.md          # L0: "Guía de autenticación: OAuth 2.0, JWT y API keys"
├── .overview.md          # L1: estructura y puntos clave del directorio
├── oauth.md              # L2: contenido completo
├── jwt.md                # L2: contenido completo
└── api-keys.md           # L2: contenido completo

L0 y L1 son sidecars de directorio (no por archivo). El generador semántico procesa de abajo arriba: resúmenes de archivos → L1 hoja → L0 hoja → directorios padre. El ls normal los oculta, pero los accessors los leen:

ov abstract viking://resources/docs/auth
ov overview viking://resources/docs/auth
ov read viking://resources/docs/auth/oauth.md

La estrategia recomendada: para comprobar relevancia usa L0; para entender el alcance de un directorio, L1; y solo cuando haga falta, carga L2. Así construyes el contexto inicial del LLM con L1 y profundizas bajo demanda.

💡 Tip

Los benchmarks de OpenViking muestran caídas de tokens de entrada del 34–91% frente a la memoria nativa de los agentes, manteniendo precisión de memoria del 80%+.

7. Recuperación: find, search e intención

OpenViking usa recuperación en dos fases: análisis de intención + recuperación jerárquica + rerank. Tiene dos APIs principales:

Featurefind()search()
Contexto de sesiónNo necesarioRequerido
Análisis de intenciónNoSí (LLM)
Consultas generadasUna0–5 TypedQueries
LatenciaBajaMayor
Caso de usoConsultas simplesTareas complejas

El análisis de intención convierte la consulta en TypedQueries tipadas por contexto:

# Skill: verbo primero → "Crear documento RFC", "Extraer tablas de PDF"
# Resource: sintagma nominal → "Plantilla de documento RFC"
# Memory: "preferencias de X del usuario" → "Preferencias de estilo de código del usuario"

La recuperación jerárquica funciona con una cola de prioridad: primero localiza los directorios con mayor score, luego desciende recursivamente propagando el score del padre (parámetro score_propagation_alpha), y converge cuando el top-k no cambia en 3 rondas.

# find(): consulta simple
ov find "OAuth authentication" --uri viking://resources/

# search(): tarea compleja con contexto de sesión
ov search "Ayúdame a crear un documento RFC" --session-id chat_001

El rerank se activa en modo THINKING (por defecto en search()) cuando hay credenciales configuradas; si falla, cae a los scores vectoriales. La gran ventaja: cada consulta conserva su trayectoria de navegación, así que cuando un resultado es raro puedes ver exactamente qué camino lo produjo.

⚠️ Error común

0 consultas generadas no es un fallo: para chitchat o saludos que no necesitan recuperación, el planificador devuelve vacío a propósito.

8. Sesiones: de la conversación a la memoria

El ciclo de vida de una sesión es Create → Interact → Commit. Al hacer commit, OpenViking comprime, archiva y extrae memoria a largo plazo en segundo plano.

from openviking_sdk import SyncHTTPClient, TextPart, ContextPart

client = SyncHTTPClient(url="http://localhost:1933")
client.initialize()

session = client.session(session_id="chat_001")
session.add_message("user", [TextPart("Prefiero el modo oscuro")])
session.add_message("assistant", [
    TextPart("Entendido, lo recordaré."),
    ContextPart(uri="viking://user/memories/profile.md"),
])
session.used(contexts=["viking://user/memories/profile.md"])

result = session.commit()          # devuelve task_id, archiva al momento
task = client.get_task(result["task_id"])  # poll hasta "completed"

El commit tiene dos fases:

1

Fase síncrona

Incrementa el índice de compresión, escribe los mensajes en messages.jsonl del archivo y devuelve el task_id.

2

Fase asíncrona

Genera el resumen estructurado (L0/L1), extrae memorias a largo plazo, escribe memory_diff.json (auditoría de cambios) y marca .done.

El flujo de extracción de memoria es: Mensajes → LLM Extract → Candidatos → Pre-filtro vectorial → Decisión de deduplicación → Write AGFS + vectorizar. La deduplicación decide entre skip, create, merge o delete de memorias existentes, así que no se acumulan duplicados.

💡 Tip

Cada commit genera un memory_diff.json con adds/updates/deletes. Úsalo como auditoría y para hacer rollback de cambios de memoria si un commit extrajo algo incorrecto.

9. Integraciones: Claude Code, MCP y LangChain

OpenViking se conecta a casi cualquier agente. La vía más universal es su endpoint MCP integrado (/mcp), compatible con Cursor, Trae, Claude Desktop, ChatGPT y más:

{
  "mcpServers": {
    "openviking": {
      "url": "https://tu-servidor.com/mcp",
      "headers": { "Authorization": "Bearer tu-api-key" }
    }
  }
}

Para Claude Code, el plugin de memoria inyecta recuerdo automático en cada prompt y hace commit de la sesión antes de la compactación:

bash <(curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/memory-plugin-shared/install.sh)

El plugin conecta además el /mcp de OpenViking, exponiendo herramientas como find, search, read y remember. Con LangChain/LangGraph, usa el paquete independiente:

pip install langchain-openviking                 # adaptadores LangChain
pip install "langchain-openviking[langgraph]"    # middleware LangGraph
from langchain_openviking import create_openviking_tools, OpenVikingRetriever, with_openviking_context

# Herramientas explícitas para el agente
tools = create_openviking_tools(url="http://localhost:1933", profile="agent")
# viking_find, viking_search, viking_browse, viking_read, viking_grep, viking_store...

# Retriever RAG
retriever = OpenVikingRetriever(url="http://localhost:1933")
docs = retriever.invoke("¿Qué decidió el usuario sobre el despliegue?")

# Backend de contexto con ciclo de vida completo
with with_openviking_context(runnable, url="http://localhost:1933") as chain:
    result = chain.invoke({"messages": [...]})

Otras integraciones nativas: Hermes Agent (hermes memory setup openviking), Codex (plugin de memoria con hooks), OpenClaw, Cursor, OpenCode y TRAE.

⚠️ Error común

Si usas Hermes, no instales OpenViking dentro del entorno de Hermes con --force-reinstall: las versiones de dependencias pueden chocar. Corre el servidor en su propio venv o contenedor y conéctate por HTTP.

10. VikingBot y despliegue en producción

VikingBot es un framework de agente construido sobre OpenViking. Con un comando tienes un agente que chatea con memoria persistente:

pip install "openviking[bot]"
openviking-server --with-bot
# en otro terminal
ov chat

La imagen Docker oficial incluye VikingBot y arranca el servidor + consola por defecto (desactívalo con command: ["--without-bot"] si no lo necesitas).

Despliegue en producción

1

Servicio HTTP independiente

Corre openviking-server como proceso standalone; los clientes se conectan por HTTP en cualquier lenguaje.

2

Seguridad

Modo dev para local, api_key para producción, trusted si un gateway inyecta identidad. Define root_api_key y activa cifrado AES con encryption.enabled si es necesario.

3

Observabilidad

ov observer queue, ov observer vikingdb y ov observer models te dan colas, colecciones vectoriales y salud de modelos.

4

Backups

Formato .ovpack para export/import y backup/restore, más snapshot para versionado del workspace.

La edición open-source no está limitada: AGPLv3 sin feature gates, sin cuenta y sin claves de activación. Los benchmarks oficiales (LoCoMo y tau2-bench) muestran que con OpenViking la precisión de memoria de agentes como OpenClaw, Hermes o Claude Code sube de 24–57% a 80–83%, con menos tokens.

💡 Tip

Antes de ir a producción, revisa server.workers, los límites de semantic.abstract_max_chars/overview_max_chars y el backend de vectordb (local, cuvs, vikingdb…). Cambiar modelo o dimensión de embedding puede exigir reindexar.

Preguntas frecuentes

¿OpenViking sustituye a un vector store como Pinecone o pgvector?

No exactamente: lo envuelve. OpenViking usa un índice vectorial internamente (local, cuvs, vikingdb…), pero añade la capa de filesystem, las capas L0/L1/L2 y la recuperación por directorios que un vector store plano no tiene.

¿Necesito sí o sí Volcengine?

No. Los modelos se configuran por proveedor: OpenAI, Kimi, GLM, Ollama local o cualquier servicio compatible con la API de OpenAI.

¿Puedo usar OpenViking sin navegador ni UI?

Sí, toda la funcionalidad está en la CLI ov y en el SDK Python (openviking_sdk). La UI Web Studio en /studio es opcional.

¿Qué licencia tiene?

El proyecto principal es AGPLv3; la CLI (ov_cli) y los ejemplos son Apache 2.0. La edición open-source no tiene gates de funcionalidad.