Files
hermes-skills/save-q-memory/SKILL.md

138 lines
4.6 KiB
Markdown

---
name: save-q-memory
description: "Manual save to Qdrant memories collection with enforced 10-type schema. Load this skill EVERY time the user says 'save to memory' or 'save to qdrant' — it is the ONLY path for manual Qdrant writes."
version: 1.0.0
author: Hermes Agent
license: MIT
metadata:
hermes:
tags: [qdrant, memories, save, schema, manual]
related_skills: [qdrant-collection-management]
---
# Save Q Memory — Manual Write Enforcer
This skill is the ONLY path for manual Qdrant writes. Load it every time the user says "save to memory" or "save to qdrant." No write bypasses this skill.
## Trigger
User says: "save to memory", "save to qdrant", "save this to memories", or any variant directing a manual Qdrant write.
## Prerequisites
- Qdrant at `http://10.0.0.22:6333`
- Ollama at `http://localhost:11434` with `snowflake-arctic-embed2:latest`
- Collection: `memories` (1024-dim, Cosine)
## Mandatory Save Procedure
### Step 1: Classify the Content
Before embedding, classify EVERY item:
**`type`** — pick ONE of 10:
- `fact` — timeless/slow-changing world truth
- `infrastructure` — hosts, IPs, services, configs, topology
- `entity` — person, org, project, tool identity
- `preference` — user's stable likes/dislikes, style, defaults
- `procedure` — how-to: steps, commands, runbooks, fixes
- `decision` — chosen approach + rationale (the why)
- `observation` — consolidated pattern from many episodes (2nd-order)
- `reference` — external KB/docs, URLs, citations
- `event` — something that happened at a time; state change
- `experience` — raw conversation turn / interaction log
**`mem_class`** — pick ONE:
- `semantic` — for fact, infrastructure, entity, preference, decision, observation, reference
- `procedural` — for procedure
- `episodic` — for event, experience
**`entities`** — list of people, servers, IPs, tools, projects, models mentioned. Empty array `[]` if none.
**`tags`** — 2-3 lowercase category tags for filtering. Examples: `["infrastructure", "dgx"]`, `["preference", "output_style"]`.
**`importance`** — 0.0-1.0:
- 0.9+: critical (court docs, credentials, core infrastructure)
- 0.7-0.8: important (decisions, preferences, procedures)
- 0.5-0.6: useful (facts, entities, references)
- 0.3-0.4: contextual (events, observations)
- 0.1-0.2: noise (raw experiences, heartbeats)
**`confidence`**:
- 1.0 — user explicitly stated this
- 0.7 — agent inferred this from context
- 0.5 — single episode, low certainty
**`ttl_hint`**:
- `"slow"` — semantic or procedural types (long-term)
- `"medium"` — references, infrastructure
- `"fast"` — episodic types (event, experience)
### Step 2: Embed via Ollama
```bash
curl -s http://localhost:11434/api/embeddings \
-H "Content-Type: application/json" \
-d '{"model": "snowflake-arctic-embed2:latest", "prompt": "<text>"}'
```
### Step 3: Build the Point
```python
import json, hashlib, subprocess
from datetime import datetime, timezone
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
point_id = int(hashlib.sha256(text.encode()).hexdigest()[:16], 16) % (2**63)
point = {
"id": point_id,
"vector": vector, # from Step 2
"payload": {
"text": text,
"type": "<classified type>",
"mem_class": "<semantic|episodic|procedural>",
"entities": ["entity1", "entity2"],
"tags": ["tag1", "tag2"],
"importance": 0.7,
"quality_score": None, # ALWAYS null — cron computes this
"confidence": 0.7,
"created_at": now,
"updated_at": now,
"source": "agent", # "agent" for manual saves
"ttl_hint": "slow"
}
}
```
### Step 4: Upsert to Qdrant
```bash
curl -s -X PUT http://10.0.0.22:6333/collections/memories/points \
-H "Content-Type: application/json" \
-d '{"points": [<point>]}'
```
Use `subprocess.run(["curl", ...])` — NOT Python `requests` (sandbox can't reach 10.0.0.22 via requests).
### Step 5: Report
Confirm to user: what was saved, type, mem_class, point ID.
## Multi-Item Saves
If the user asks to save multiple items, classify and embed each one separately. Batch upsert all points in a single curl call (up to 100 points).
## What NOT to Do
- Do NOT save without classifying type + mem_class
- Do NOT set quality_score to anything other than null
- Do NOT use Python `requests` library — use `subprocess.run(["curl", ...])`
- Do NOT use string point IDs — must be unsigned integers
- Do NOT save to any collection other than `memories` unless explicitly directed
## Reference
Full schema documentation: `/home/n8n/workspace/general/qdrant.md`
Collection management (dedup, migration, registry): `qdrant-collection-management` skill