7.8 KiB
name, description, version, author, license, platforms, metadata
| name | description | version | author | license | platforms | metadata | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ai-vault-kb | Use when writing or searching the ai_vault_kb Qdrant vault. | 2.0.0 | Hermes Agent | MIT |
|
|
AI Vault KB — the fleet's one vault
ai_vault_kb is the single Qdrant collection holding all AI/ML knowledge: research,
pipeline state, model configs, prompts, decisions, bugs, hardware facts. One vault,
one collection — never a topic-specific collection.
THE ONE RULE — writes go through ai_vault_kb.py, nothing else
python3 /home/n8n/bin/ai_vault_kb.py add --type <t> --title "..." --content "..." [flags]
That helper is the only interface that produces a usable, searchable record.
Why mcp__better_qdrant__add_documents is FORBIDDEN for this collection
It performs a bare-vector upsert. For every chunk it writes it produces:
ai_vault_kb.py add |
mcp__better_qdrant__add_documents |
|
|---|---|---|
| dense vector (unnamed slot) | yes | yes |
bm25 sparse vector |
yes | NO |
doc_type / title / tags |
yes | NO |
trust / host / path / doc_id / pipeline_stage |
yes | NO |
A point with no bm25 slot cannot be returned by a keyword/BM25 search — paste an
exact error string, model filename or node name and it will never match. A point with
no doc_type cannot be returned by any typed search (--type research,
--type issue, …) or by any faceted list. It survives only in the dense half of a
hybrid query and renders as [?] (untitled).
It looks ingested and it cannot be found. This is not a style preference — roughly 4,700 points in this collection were created that way and had to be repaired. Do not create more. There is no file size, no hurry and no MCP convenience that justifies it.
If you catch yourself reaching for add_documents because the helper is awkward for a
big file: the helper takes --file and chunks it itself, with no MCP 120 s timeout.
Writing
python3 /home/n8n/bin/ai_vault_kb.py add \
--type finding --title "LTX 2.3 audio desync above 121 frames" \
--content "..." \
--stage t2v --tool ltx-video --host 10.0.0.202 \
--trust official --importance 0.7 --tags "ltx-2.3,audio,desync"
Long documents: --file /abs/path/report.md instead of --content (auto-chunked,
one shared doc_id across the chunks). --json prints {"doc_id":…, "chunks":N}.
| Flag | Meaning |
|---|---|
--type (required) |
tool setting workflow host model technique issue decision research asset prompt finding |
--title (required) |
what a future search will read as the headline |
--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; tags are an exact-match keyword index — put the slug, the filename, the 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. A warning is not a failure; do not switch to the MCP tool because of one.
Mandatory before every write: dedup-first
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
or append a dated chunk, rather than creating a second record for the same machine.
Reading
# hybrid (dense + BM25, RRF fusion) — the default, use it
python3 /home/n8n/bin/ai_vault_kb.py search --query "ltx 2.3 native audio"
# pure keyword — exact filenames, error strings, node names
python3 /home/n8n/bin/ai_vault_kb.py search --query "ltxv-097-dev-fp8.safetensors" --mode bm25
# typed / faceted
python3 /home/n8n/bin/ai_vault_kb.py list --type issue --tool comfyui --limit 20
python3 /home/n8n/bin/ai_vault_kb.py list --tag 2026-08-09-horizon-scan
python3 /home/n8n/bin/ai_vault_kb.py facet --field tool
python3 /home/n8n/bin/ai_vault_kb.py stats # points, doc_type inventory, health
python3 /home/n8n/bin/ai_vault_kb.py stale --days 30
python3 /home/n8n/bin/ai_vault_kb.py get --id <point-id>
mcp__better_qdrant__search is read-only and therefore allowed, but it is
dense-only — it silently misses anything a keyword query would have found. Prefer the
helper's search. Use the MCP one only when you have no shell.
Deleting
python3 /home/n8n/bin/ai_vault_kb.py delete --doc-id <uuid> --yes # a whole document
python3 /home/n8n/bin/ai_vault_kb.py delete --id <point-id> --yes # one chunk
Per-document delete exists. Never
mcp__better_qdrant__delete_collection(collection="ai_vault_kb") — that destroys the
fleet's entire brain and there is no undo. Earlier versions of this skill described the
nuke as the only option; that was wrong.
Verify the write landed
A write is not done until it is retrievable both ways. The BM25 leg is the one a bare upsert cannot pass, so it is the real test:
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.
Deep-research reports
Do not ingest them by hand. publish_report.py (in the deep-web-research skill) is
the only sanctioned path — it publishes, ingests via this helper, verifies hybrid+BM25,
and writes the .meta.json receipt in one action.
A .meta.json sidecar is a receipt written after verification, not proof. Sidecars
written before that rule exists claim doc_ids that were never upserted. If you need
to know whether a report is in the vault, ask the vault (list --tag <slug>), never the
directory listing.
Infrastructure
| Setting | Value |
|---|---|
| Qdrant | http://10.0.0.22:6333, collection ai_vault_kb |
| Embeddings | snowflake-arctic-embed2 on mini, 10.0.0.30:11434 — the vault's embedder (mini also hosts qwen3-embedding:0.6b for the Cognee brain; the two are separate) |
| Helper | /home/n8n/bin/ai_vault_kb.py (zero deps, urllib only) |
| Vectors | unnamed dense 1024-dim + named sparse bm25 |
The CARE rule for mini: every vault ingest embeds there, and mini also serves the
Cognee brain's embedder (qwen3-embedding:0.6b). Batch your writes, keep them bounded,
never hammer it.
Pitfalls
- Never hand-roll raw Qdrant HTTP for a write. A
PUT /collections/ai_vault_kb/pointswith a bare vector reproduces the exact defect the MCP tool causes. Reads (GET /collections/...,POST .../points/scroll,.../points/count) are fine. - Absolute paths for
--file/--path. - Collection name is exact —
ai_vault_kb, notai-vault-kb. - Don't create topic-specific collections. No
ltx-research, nocomfyui-workflows. fact_storeand thememoriescollection are not the vault. Research findings, model configs, prompt guides and infra facts all go here.- A search that returns nothing is a real answer. Say "not in the vault" and go research it — do not assume the record exists but is hiding.