Files
hermes-skills/save/SKILL.md
T

122 lines
5.3 KiB
Markdown
Raw Normal View History

---
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.01.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.700.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.