Ir al contenido

Memoria y conocimiento

Sin memoria, cada conversación con un agente empieza desde cero: la misma convención hay que volver a explicarla, la misma decisión volver a debatirla, el mismo callejón sin salida volver a explorarlo. La memoria es el almacén con ámbito de espacio de trabajo que sobrevive a las ejecuciones, y existe para que otro agente pueda encontrar más tarde el conocimiento que produjo uno.

Tiene tres capas y cada una responde a una pregunta distinta:

  1. Hechos: lo que es cierto (una convención, un resultado, una decisión).
  2. Políticas: lo que los agentes deben hacer al respecto (una regla normativa).
  3. Memoria de trabajo: aquello que un agente tenía entre manos.

La distinción importa porque llegan al agente por vías distintas. Los hechos se buscan. Las políticas se empujan. La memoria de trabajo es privada.

Un MemoryFact es una unidad de conocimiento con ámbito de un espacio de trabajo y un dominio.

Atributo Qué es
domain El dominio de conocimiento (“conventions”, “decisions”, “codebase”)
topic Una etiqueta breve de tema
content El texto del conocimiento
confidence 0,0–1,0, se inicializa a partir de la procedencia y sube con cada nueva mención
memoryType El tipo de hecho: determina su curva de decaimiento temporal
veracity Cómo se llegó a saber: inicializa la confianza y define el tamaño de cada incremento por mención
sourceObservationIds Qué observaciones dieron lugar a él
supersededBy El hecho más reciente que lo reemplazó, si lo hay
validUntil, recallCount, mentionCount Señales de caducidad y uso que se aplican en la recuperación

Las dos últimas filas son las que la gente pasa por alto, y son las que deciden qué hecho sale a la superficie. memoryType lleva parámetros de decaimiento de Weibull por tipo, así que un compromiso con plazo se desvanece rápido mientras que un hecho de perfil estable no lo hace. veracity registra la procedencia —indicada por una persona (peso 1,0), inferida por un agente (0,7), producida por una herramienta (0,5), importada (0,6)— y ese peso inicializa la confianza inicial del hecho.

Los hechos nunca se editan en su lugar cuando se contradicen. Escribir un hecho ejecuta una detección de conflictos contra los hechos del mismo dominio y el mismo tema, y reemplaza al perdedor registrando una fila de conflicto. El rastro de auditoría es el objetivo: siempre puedes ver qué se creía antes y qué lo reemplazó.

Una MemoryPolicy es una regla normativa derivada de los hechos, con ámbito de un espacio de trabajo y un dominio, con un indicador de activa y un requiredRole opcional.

Todas las políticas activas del espacio de trabajo se inyectan en todos los despachos, sin filtrar: no se filtra por dominio, rol, tarea ni espacio. Conviene saberlo antes de escribir tu vigésima política, porque las políticas comptien por la misma ventana de contexto que la tarea. También es la razón de que requiredRole en una política sea meramente indicativo: describe a quién va dirigida la regla, pero no impide que la regla llegue a todos los demás.

Un MemoryDomain agrupa hechos y políticas dentro de un espacio de trabajo. Los dominios dan estructura organizativa al conocimiento y son la unidad sobre la que se escriben los permisos de acceso, pero consulta la precaución que aparece más abajo antes de tratar un dominio como un límite de confidencialidad.

Un dominio es o bien de todo el espacio de trabajo (architecture) o bien está acotado a un repositorio (repo:<slug>/architecture). El mismo nombre en ambos ámbitos son dos almacenes independientes: un hecho cierto para una base de código no sobrescribe el de todo el espacio de trabajo. search_memory y el preámbulo de despacho priorizan la memoria acotada al repositorio cuando el agente trabaja en ese repositorio; no filtran el resto. Pasa repo en propose_fact / propose_policy / search_memory para escribir en ese ámbito o reforzarlo.

El control de acceso es fail-open para las lecturas

Sección titulada «El control de acceso es fail-open para las lecturas»

MemoryAccessGrant asigna un rol de agente y un dominio a uno de tres niveles de permiso:

Permiso Significado
none Sin acceso
read Puede buscar y recuperar hechos
write Lo requiere propose_policy. Las escrituras de hechos (propose_fact, supersede_fact) no están sujetas a permisos

La asimetría —flexible con las lecturas, estricta con las escrituras de políticas— es una decisión deliberada. La memoria es más útil cuando circula, y una denegación de lectura produce un agente que sabe menos en silencio en lugar de uno que reporta un problema. Una denegación de escritura de política, en cambio, es ruidosa y corregible, así que ahí es donde reside la aplicación de la norma. Un dominio recién creado inicializa write para todos los roles; restringirlo después es una edición solo por RPC, porque no hay interfaz de permisos.

Cada agente tiene un AgentWorkingMemory: un bloc de notas de texto libre indexado por espacio de trabajo y agente. Persiste entre ejecuciones, es privado para ese agente y se inyecta en su prompt en cada despacho. Es donde vive «me quedé a medio camino refactorizando la autenticación»: el estado que vale la pena arrastrar a la siguiente ejecución, pero no ascenderlo a hecho duradero.

En el despacho, el preámbulo de memoria se compone de exactamente tres cosas:

  • Todas las políticas activas del espacio de trabajo, como líneas - [domain] rule.
  • La propia memoria de trabajo del agente, literal.
  • Una lista corta de hechos coincidentes por palabra clave para esta tarea: como máximo cinco, dentro de un presupuesto de ~1.200 caracteres y solo cuando la descripción de la tarea tiene al menos 20 caracteres. Las tareas más cortas no reciben ningún hecho.

La lista corta es solo FTS/palabras clave y está limitada a propósito. Generar el embedding de una consulta es lento, y la ruta de despacho es el único lugar donde la latencia se nota de inmediato, así que la ruta semántica lenta se mantiene deliberadamente al margen. El preámbulo termina indicándole al agente que verifique los elementos críticos con search_memory, que es donde vive el modelo de recuperación completo.

En esta ruta no se consulta ningún permiso de acceso. Lo que encuentre la lista corta es lo que ve el agente.

La herramienta search_memory orientada al agente tiene tres modos que son búsquedas realmente distintas:

  • keyword: solo FTS5.
  • semantic: resultados de BM25 y vectoriales fusionados mediante reciprocal rank fusion.
  • hybrid (el predeterminado): recuperación polifónica, cuatro voces ordenadas por relevancia que se fusionan entre sí y luego se diversifican.

Las cuatro voces son léxica (FTS), semántica (KNN de vectores), temporal (hechos activos recientes) y de grafo: un recorrido de dos saltos por las aristas episódicas desde las semillas léxicas y semánticas más fuertes. La voz de grafo es la razón de que existan las aristas episódicas: saca a la superficie el hecho que está conectado con tu respuesta sin coincidir con ninguna de tus palabras. Las voces se ponderan según una intención de consulta clasificada (la semántica es la que más peso tiene por defecto, luego el grafo y la léxica, y después la recencia), la puntuación de cada candidato se escala según su decaimiento de Weibull y el conjunto de resultados se diversifica con MMR para que cinco reformulaciones de un mismo hecho no desplacen a otros cuatro distintos.

La búsqueda de memoria en escritorio y web es una ruta aparte y más sencilla: la operación RPC memory_fact.search es solo FTS5, porque un cliente ligero no puede enviar el embedding de una consulta y la ruta híbrida se queda dentro del host. Así que la clasificación que ves en el explorador de memoria no es la que obtiene un agente de search_memory. Es lo esperado, no un error, pero implica que «busqué y no lo encontré» en la interfaz no es prueba de que el agente no vaya a encontrarlo.

El explorador de memoria está en Ajustes → Espacio de trabajo → Memoria (/workspaces/<id>/settings/memory), con las pestañas Hechos, Políticas y Grafo de conocimiento.

Ahí hay una asimetría que sorprende a la gente: puedes editar y borrar memoria, pero no puedes crearla. Ni la pestaña Hechos ni la pestaña Políticas tienen un control para agregar. La creación es cosa del agente, mediante propose_fact y propose_policy (supersede_fact / supersede_policy para reemplazarlos). remember escribe un elemento de la capa caliente acotado a la sesión que consolidate_memory puede ascender después a hecho; record_observation y update_my_notes escriben el bloc privado que se inyecta en el despacho. El explorador sirve para revisar y corregir, no para crear, así que si quieres un hecho en la memoria, la forma de meterlo ahí es decírselo a un agente.

Dos operaciones de mantenimiento también las invoca el agente en lugar de ejecutarse según un calendario: consolidate_memory fusiona y poda los hechos acumulados, y harmonize_memory reconcilia las creencias que divergieron entre agentes. list_memory_conflicts muestra lo que ya ha registrado la detección de conflictos. Nada las ejecuta por ti con un temporizador. Las decisiones de reunión se recogen en el dominio decisions cuando un paso de persistencia de reunión las registra; eso no es un temporizador sobre ejecuciones de agente completadas.