# 018 — Shared Knowledge: base de conocimiento compartida entre agentes ## Objetivo Crear un sistema de conocimiento compartido (`knowledges/` en la raiz del proyecto) donde multiples agentes pueden leer, escribir y buscar documentos en comun. Esto permite colaboracion entre agentes: uno puede registrar informacion que otros consultan. ## Contexto - Cada agente ya tiene su **knowledge privado** en `agents//knowledge/` con SQLite FTS5 index (`shell/knowledge/store.go`). - Los tipos puros ya existen: `pkg/knowledge.Document`, `SearchResult`, `Store` interface. - Las tools de knowledge ya existen: `tools/knowledgetools/` (search, read, write, list). - El `FileStore` en `shell/knowledge/` ya implementa todo el CRUD + FTS5. - Lo que falta es una **instancia compartida** de `FileStore` apuntando a `knowledges/` con tools dedicadas que multiples agentes puedan usar. ## Arquitectura ``` knowledges/ ← carpeta raiz, documentos .md compartidos knowledges/data/knowledge.db ← SQLite FTS5 index compartido (en .gitignore) pkg/knowledge/ ← sin cambios, los tipos puros ya cubren shell/knowledge/store.go ← sin cambios, FileStore ya es reutilizable tools/knowledgetools/shared.go ← NEW: tools prefijadas shared_knowledge_* agents/runtime.go ← instanciar shared store + registrar tools internal/config/schema.go ← config para habilitar shared knowledge ``` ### Patron pure core / impure shell - `pkg/` — sin cambios, `knowledge.Store` interface ya sirve - `shell/knowledge/` — sin cambios, `FileStore` ya funciona con cualquier directorio - `tools/knowledgetools/` — nuevas tools que wrappean el store compartido - `agents/runtime.go` — composicion: crea shared store y registra tools ## Tareas ### Fase 1: Config - [ ] **1.1** Agregar seccion `shared_knowledge` al config en `internal/config/schema.go`: ```go type SharedKnowledgeCfg struct { Enabled bool `yaml:"enabled"` // default false Dir string `yaml:"dir"` // default "knowledges" DBPath string `yaml:"db_path"` // default "knowledges/data/knowledge.db" } ``` - [ ] **1.2** Agregar campo `SharedKnowledge SharedKnowledgeCfg` al `ToolsCfg` (o al `AgentConfig` directamente). ### Fase 2: Tools compartidas en `tools/knowledgetools/` - [ ] **2.1** Crear `tools/knowledgetools/shared.go` con tools prefijadas `shared_knowledge_*`: - `shared_knowledge_search` — buscar en la base compartida - `shared_knowledge_read` — leer un documento compartido por slug - `shared_knowledge_write` — crear/actualizar un documento compartido - `shared_knowledge_list` — listar todos los documentos compartidos - Reutilizar `KnowledgeStore` interface y la misma logica de las tools privadas pero con nombres y descripciones que indican "shared across all agents" - [ ] **2.2** Cada tool debe incluir en su descripcion que es conocimiento **compartido** entre agentes: ``` "Search the shared knowledge base accessible by all agents. Use this to find information other agents have recorded." ``` - [ ] **2.3** Funcion constructora: ```go // NewSharedKnowledgeTools creates all shared knowledge tools backed by the given store. func NewSharedKnowledgeTools(store KnowledgeStore) []tools.Tool ``` ### Fase 3: Integracion en runtime - [ ] **3.1** En `agents/runtime.go`, si `cfg.Tools.SharedKnowledge.Enabled` (o donde se ponga en config): - Crear un `shellknowledge.New(dir, dbPath, logger)` con la ruta compartida - Llamar `Sync(ctx)` al arrancar - Registrar las tools de `NewSharedKnowledgeTools(sharedStore)` en el registry - Guardar referencia para cerrar en defer - [ ] **3.2** El shared store debe ser **una instancia por agente** (cada proceso abre su propia conexion SQLite al mismo archivo DB). SQLite soporta lecturas concurrentes y escrituras serializadas con WAL mode. - [ ] **3.3** Habilitar WAL mode en el shared store para mejor concurrencia entre procesos: ```go db.Exec("PRAGMA journal_mode=WAL") ``` Esto puede ir en `shell/knowledge/store.go` `New()` para beneficiar tambien al store privado. ### Fase 4: Carpeta `knowledges/` - [ ] **4.1** Crear `knowledges/` en la raiz del proyecto con un `README.md` explicando su proposito. - [ ] **4.2** Agregar `knowledges/data/` a `.gitignore` (la DB no se commitea, los .md si). ### Fase 5: Coexistencia con knowledge privado - [ ] **5.1** Un agente puede tener **ambos** habilitados: knowledge privado (`agents//knowledge/`) y shared (`knowledges/`). Las tools se distinguen por nombre: - `knowledge_search` / `knowledge_read` / `knowledge_write` / `knowledge_list` → privado - `shared_knowledge_search` / `shared_knowledge_read` / `shared_knowledge_write` / `shared_knowledge_list` → compartido - [ ] **5.2** Documentar en el system prompt de los agentes la diferencia: - Knowledge privado: "tu base de conocimiento personal, solo tu puedes ver" - Knowledge compartido: "base compartida entre todos los agentes, usa para colaborar" ### Fase 6: Tests - [ ] **6.1** Test de `NewSharedKnowledgeTools` — verificar que genera 4 tools con nombres `shared_knowledge_*`. - [ ] **6.2** Test de integracion: dos stores apuntando al mismo directorio pueden leer lo que el otro escribe (simula dos agentes). - [ ] **6.3** Test de concurrencia basico con WAL mode. ### Fase 7: Cleanup y docs - [ ] **7.1** Actualizar `CLAUDE.md` — agregar `knowledges/` a la estructura de directorios. - [ ] **7.2** Actualizar `.gitignore` con `knowledges/data/`. - [ ] **7.3** Ejemplo de config habilitando shared knowledge en un agente existente. --- ## Ejemplo de config ```yaml tools: knowledge: enabled: true # knowledge privado del agente dir: "knowledge" # relativo a agents// shared_knowledge: enabled: true # knowledge compartido dir: "knowledges" # relativo a la raiz del proyecto db_path: "knowledges/data/knowledge.db" ``` ## Ejemplo de flujo ``` 1. agente-A recibe: "investiga X y guarda lo que encuentres" → LLM usa shared_knowledge_write(slug: "investigacion-x", content: "...") → Se escribe knowledges/investigacion-x.md + actualiza FTS5 2. agente-B recibe: "que sabemos sobre X?" → LLM usa shared_knowledge_search(query: "X") → Encuentra el documento que escribio agente-A → shared_knowledge_read(slug: "investigacion-x") → Responde con la informacion 3. Agentes colaboran acumulando conocimiento en la misma base ``` ## Decisiones de diseno - **Reusar FileStore**: no crear un store nuevo. `shell/knowledge.FileStore` ya tiene todo (CRUD, FTS5, Sync). Solo se instancia con una ruta diferente. - **WAL mode**: permite que multiples procesos lean/escriban concurrentemente. Es la forma estandar de compartir SQLite entre procesos. - **Prefix `shared_knowledge_`**: diferencia claramente las tools compartidas de las privadas. El LLM sabe cual usar segun contexto. - **Los .md se commitean, la DB no**: los documentos compartidos forman parte del repo (versionados). La DB FTS5 se reconstruye con `Sync()` al arrancar. - **Sin control de acceso por agente**: cualquier agente con shared_knowledge habilitado puede leer y escribir. Simplicidad primero; RBAC se puede agregar despues si hace falta. ## Prerequisitos - Knowledge privado ya funcional (pkg/knowledge, shell/knowledge, tools/knowledgetools) — ya implementado. - No tiene dependencias externas nuevas. ## Riesgos - **Contention en escritura**: si muchos agentes escriben simultaneamente, SQLite serializa las escrituras. Con WAL mode esto es manejable para el volumen esperado. - **Sync al arrancar**: si hay muchos documentos, el Sync inicial puede tardar. No deberia ser problema con volumenes pequenos. - **Conflictos de slug**: dos agentes podrian sobreescribir el mismo documento. Esto es intencional (ultimo gana), pero el LLM debe ser consciente via el system prompt.