All files live under ~/.openclaw/skills/rag-memory/ — the single source of truth.
FilePurposeconfig.envCredentials and tuning (gitignored)config.env.exampleTemplate with no secrets (tracked in git)sync_to_qdrant.pyIngest pipeline: Postgres + .md files → Qdrantrequirements.txtPython deps for sync scriptvenv/Python virtualenv (gitignored)plugin/index.jsOpenClaw plugin — registers vector_search tool and before_prompt_build hookplugin/package.jsonPlugin manifestplugin/openclaw.plugin.jsonPlugin config schemasystemd/Source-of-truth copies of systemd units (deploy with sudo cp + daemon-reload)references/config-paths.example.mdFile and credential location template (copy to config-paths.md and fill in)references/operational.mdWhen/how to use vector_search
Plugin is installed at ~/.openclaw/extensions/rag-memory/ and configured in ~/.openclaw/openclaw.json under plugins.entries.rag-memory.
Qdrant collections: {QDRANT_COLLECTION_PREFIX}_memory (daily logs + facts) and {QDRANT_COLLECTION_PREFIX}_docs (tools + skill docs). 768-dim, nomic-embed-text via OpenAI-compatible embedding endpoint.
Always prefer vector_search over reading full memory files:
scope: memoryscope: docsscope: allOnly fall back to reading the file directly if vector_search returns no results.
TaskCommandIncremental sync (unsynced rows only)~/.openclaw/skills/rag-memory/venv/bin/python ~/.openclaw/skills/rag-memory/sync_to_qdrant.pyFull resync (rebuild all vectors)... sync_to_qdrant.py --fullSingle file... sync_to_qdrant.py --file /path/to/file.md
Incremental sync also fires automatically when any .md file changes in ~/.openclaw/workspace/memory/ (via sysclaw-rag-watch.path). Nightly full sync runs at 03:00 ( sysclaw-rag-sync.timer).
If plugin/index.js is changed:
bash
SKILL=~/.openclaw/skills/rag-memory
openclaw plugins install $SKILL/plugin
openclaw gateway restart
If config.env tuning values change, also update the matching values in plugins.entries.rag-memory.config in openclaw.json (especially score_threshold and top_k).
Edit files in systemd/ (source of truth), then deploy using the included script — it substitutes the correct username automatically:
bash
sudo ~/.openclaw/skills/rag-memory/systemd/deploy.sh
Or manually, replacing youruser with the local OpenClaw user:
bash
sudo sed "s/User=openclaw/User=youruser/g" ~/.openclaw/skills/rag-memory/systemd/*.service \
| sudo tee /etc/systemd/system/sysclaw-rag-{sync,watch}.service > /dev/null
sudo cp ~/.openclaw/skills/rag-memory/systemd/sysclaw-rag-sync.timer /etc/systemd/system/
sudo cp ~/.openclaw/skills/rag-memory/systemd/sysclaw-rag-watch.path /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl restart sysclaw-rag-sync.timer sysclaw-rag-watch.path
KeyExample / DefaultQDRANT_HOST``https://qdrant.example.com``EMBED_BASE_URL``https://litellm.example.com``EMBED_MODEL``nomic-embed-text``QDRANT_COLLECTION_PREFIXany UUID or unique prefix stringMEMORY_DIR``~/.openclaw/workspace/memory``score_threshold``0.70 (in both config.env and openclaw.json plugin config)top_k``5
curl $QDRANT_HOST/readyzDo not activate this skill for:
This skill sends data to three external services configured via config.env:
ServiceVariableWhat is sentEmbedding endpoint (OpenAI-compatible)EMBED_BASE_URLText chunks from memory files and Postgres records, for vector embeddingQdrantQDRANT_HOSTEmbedded vectors + metadata for storage and search queriesPostgresPOSTGRES_DSNRead-only queries against memory_entries, daily_logs, tools tables
No data is sent to any Anthropic or third-party endpoint by this skill.
Memory content (daily logs, facts, tool descriptions) leaves the local machine in two ways:
EMBED_BASE_URL) to generate vectorsQDRANT_HOST)Both services are self-hosted and configured by the user. No data is sent to any external party by this skill.
Environment variables accessed:
QDRANT_HOST, QDRANT_API_KEY, QDRANT_COLLECTION_PREFIXEMBED_BASE_URL, EMBED_API_KEY, EMBED_MODELPOSTGRES_DSNMEMORY_DIR, CHUNK_SIZE, CHUNK_OVERLAP, TOP_K_DEFAULT, SYNC_BATCH_SIZE, EMBED_BATCH_DELAY_MSFiles read:
.md files under MEMORY_DIRconfig.env (loaded at sync script startup)Files written:
Database writes (Postgres):
memory_entries.qdrant_synced_at — updated after successful vector upsertdaily_logs.qdrant_synced_at — sametools.qdrant_synced_at — sameqdrant_sync_log — one row inserted per sync run (records_synced, duration_ms)Network:
EMBED_BASE_URL (embedding)QDRANT_HOST (vector storage/search)POSTGRES_DSNBy installing this skill, text from your memory files and database will be sent to the embedding endpoint configured in EMBED_BASE_URL. Vectors are stored in the Qdrant instance at QDRANT_HOST. Both are self-hosted services you configure. Only install if you trust those services with your memory contents.
When auto_inject is enabled (default: true), Qdrant search results are prepended to every prompt context. This data originates from your own self-hosted Qdrant instance — no external party supplies it. The content is sanitized of session boilerplate before storage but is otherwise injected as-is; only enable auto_inject if you trust your Qdrant data as prompt input.
MIT-0 — no attribution required.