122 lines
5.3 KiB
Markdown
122 lines
5.3 KiB
Markdown
---
|
||||
|
|
name: save
|
|||
|
|
description: "Use when user types 'save'. Write to Brain (Cognee) and/or Vault (Qdrant ai_vault_kb)."
|
|||
|
|
version: 1.3.0
|
|||
|
|
author: Hermes Agent
|
|||
|
|
license: MIT
|
|||
|
|
platforms: [linux]
|
|||
|
|
metadata:
|
|||
|
|
hermes:
|
|||
|
|
tags: [memory, brain, vault, cognee, qdrant, save]
|
|||
|
|
related_skills: [cognee-brain, ai-vault-kb]
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Save — write to Brain and/or Vault
|
|||
|
|
|
|||
|
|
Triggered when the user types "save". Route the current session's content to the
|
|||
|
|
right store and write it.
|
|||
|
|
|
|||
|
|
## Routing
|
|||
|
|
|
|||
|
|
- **Brain** (Cognee) = durable facts, decisions, preferences, relationships, status changes, corrections. Short atomic statements with time context.
|
|||
|
|
- **Vault** (Qdrant `ai_vault_kb`) = longer context, notes, research, summaries, excerpts — for semantic "find similar" recall.
|
|||
|
|
- **Both** = when something is a clean fact AND rich context: clean version to Brain, fuller version to Vault.
|
|||
|
|
- Be conservative. Only store what's worth remembering. Don't write every message.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## BRAIN — Cognee (Kuzu + LanceDB on brain 10.0.0.23)
|
|||
|
|
|
|||
|
|
The brain is Cognee, reachable via the auto-discovered MCP tools `mcp__cognee__*`
|
|||
|
|
(no CLI needed). Endpoints: API `http://10.0.0.23:8080`, MCP `http://10.0.0.23:8001/mcp`.
|
|||
|
|
|
|||
|
|
### Write (permanent memory)
|
|||
|
|
|
|||
|
|
Use the `mcp__cognee__remember` tool. ALWAYS pass `dataset_name="homelab-stack"`.
|
|||
|
|
|
|||
|
|
- `data` = the text to store (atomic facts, one per statement where possible).
|
|||
|
|
- Omit `session_id` — that makes it permanent memory (add + cognify, builds the graph).
|
|||
|
|
- `remember` returns `status: completed` synchronously — the graph is built, no polling.
|
|||
|
|
|
|||
|
|
### Read
|
|||
|
|
|
|||
|
|
Use the `mcp__cognee__recall` tool. `query` (required), `datasets="homelab-stack"`,
|
|||
|
|
optional `search_type` (HYBRID_COMPLETION default; CHUNKS for LLM-free retrieval).
|
|||
|
|
|
|||
|
|
### Write rules
|
|||
|
|
|
|||
|
|
- **One dataset:** `homelab-stack`. Never create a second dataset.
|
|||
|
|
- **No group_id, no triplet, no temporal supersession.** Cognee uses datasets. To correct a fact, `remember` the corrected statement; Cognee
|
|||
|
|
merges entities by name.
|
|||
|
|
- **Don't re-ingest the same content twice** — `remember` is not idempotent.
|
|||
|
|
- **Embed dim is 1024** (qwen3-embedding:0.6b on mini) — never let it default to 3072.
|
|||
|
|
|
|||
|
|
### Verify the write
|
|||
|
|
|
|||
|
|
- `recall` a distinctive phrase from the content; a correct answer proves the graph has it.
|
|||
|
|
- `docker logs cognee-backend` should show zero `api.openai.com` / `ProviderConfigMismatch` hits.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## VAULT — Qdrant `ai_vault_kb`
|
|||
|
|
|
|||
|
|
CLI: `python3 /home/n8n/bin/ai_vault_kb.py` (zero deps, urllib only). Qdrant `http://10.0.0.22:6333`, collection `ai_vault_kb`. Embeddings: `snowflake-arctic-embed2` on `10.0.0.30:11434`.
|
|||
|
|
|
|||
|
|
### Write (the ONLY sanctioned path)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
python3 /home/n8n/bin/ai_vault_kb.py add --type <t> --title "..." --content "..." [flags]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Long documents: `--file /abs/path/report.md` instead of `--content` (auto-chunked, one shared `doc_id`). `--json` prints `{"doc_id":…, "chunks":N}`.
|
|||
|
|
|
|||
|
|
| Flag | Meaning |
|
|||
|
|
|---|---|
|
|||
|
|
| `--type` **(required)** | `tool` `setting` `workflow` `host` `model` `technique` `issue` `decision` `research` `asset` `prompt` `finding` |
|
|||
|
|
| `--title` **(required)** | headline a future search reads |
|
|||
|
|
| `--content` / `--file` | body text, or a file to chunk |
|
|||
|
|
| `--stage` | `story` `script` `character` `keyframe` `t2v` `i2v` `upscale` `interpolate` `tts` `lipsync` `music` `assembly` `publish` `infra` |
|
|||
|
|
| `--tool` `--host` `--path` `--url` `--version` | provenance; `--host` is the box the fact is about |
|
|||
|
|
| `--status` | `active` `candidate` `deprecated` `broken` `planned` (default `active`) |
|
|||
|
|
| `--trust` | `official` `github` `community` `social` (default `official`) |
|
|||
|
|
| `--tags` | comma-separated; exact-match keyword index — put slug, filename, error code here |
|
|||
|
|
| `--importance` | 0.0–1.0 |
|
|||
|
|
| `--doc-id` | append more chunks to an existing document |
|
|||
|
|
|
|||
|
|
Unknown vocabulary values warn but are accepted — the schema is faceted, not strict.
|
|||
|
|
|
|||
|
|
### Dedup-first (mandatory before every write)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
python3 /home/n8n/bin/ai_vault_kb.py search --query "<the thing you are about to save>"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- score **≥ 0.85** — already recorded, skip
|
|||
|
|
- **0.70–0.84** — add only if meaningfully new
|
|||
|
|
- **< 0.70** — always add
|
|||
|
|
|
|||
|
|
### Host records
|
|||
|
|
|
|||
|
|
`--type host`, one stable `--doc-id` per box. Re-add with the same `--doc-id` to update/append a dated chunk.
|
|||
|
|
|
|||
|
|
### Verify the write landed (both legs)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
D=<doc_id from --json>
|
|||
|
|
python3 /home/n8n/bin/ai_vault_kb.py search --query "<distinctive phrase>" --mode bm25 --doc-id $D
|
|||
|
|
python3 /home/n8n/bin/ai_vault_kb.py list --type <the type you used> --doc-id $D
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Zero hits on the BM25 leg means something other than `ai_vault_kb.py` wrote it.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Pitfalls
|
|||
|
|
|
|||
|
|
- **Brain writes are not idempotent** — don't re-ingest the same content twice.
|
|||
|
|
- **Vault writes MUST go through `ai_vault_kb.py`** — never a bare Qdrant upsert or `mcp__better_qdrant__add_documents` (missing bm25/doc_type makes the point unfindable). Never hand-roll raw Qdrant HTTP for a write.
|
|||
|
|
- **Collection name is exact** — `ai_vault_kb`, not `ai-vault-kb`. Don't create topic-specific collections.
|
|||
|
|
- **On correction:** update Brain (remember the corrected fact) and store the correction.
|
|||
|
|
- **`fact_store` and the `memories` collection are not the vault** — research findings, model configs, prompt guides, infra facts go here.
|
|||
|
|
- **A search that returns nothing is a real answer** — say "not in the vault" and go research it.
|