agent-memory-systems-postgres
Original:🇺🇸 English
Translated
15 scriptsChecked / no sensitive code detected
Persistent shared memory for AI agents backed by PostgreSQL (fts + pg_trgm, optional pgvector). Includes compaction logging and maintenance scripts.
7installs
Sourcearthur0824hao/skills
Added on
NPX Install
npx skill4agent add arthur0824hao/skills agent-memory-systems-postgresTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Agent Memory Systems (PostgreSQL)
Persistent shared memory for all AI agents. PostgreSQL 14+ on Linux or Windows.
Memory failures look like intelligence failures — this skill ensures the right memory is retrieved at the right time.
Quick Start
Database and all functions are created by in this skill directory.
agent_memoryinit.sqlbash
# Linux
psql -U postgres -c "CREATE DATABASE agent_memory;"
psql -U postgres -d agent_memory -f init.sql
# Windows (adjust path to your psql.exe)
& "C:\Program Files\PostgreSQL\18\bin\psql.exe" -U postgres -c "CREATE DATABASE agent_memory;"
& "C:\Program Files\PostgreSQL\18\bin\psql.exe" -U postgres -d agent_memory -f init.sqlVerify:
SELECT * FROM memory_health_check();Pure Skill Mode (default)
This skill works without installing any plugin. In pure skill mode:
- you manually run scripts when you want (progressive disclosure)
- no global OpenCode config is modified automatically
Optional bootstrap (asks + records choices + tries to install)
Notes:
- Interactive mode defaults to NOT installing heavy optional components.
- Use /
-InstallAllonly when you're ready to install everything.--install-all
Run the bootstrap script to choose optional components (pgpass, local embeddings, pgvector) and record decisions.
Windows:
powershell
# run from the skill directory
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "scripts\bootstrap.ps1"Linux/macOS:
bash
# run from the skill directory
bash "scripts/bootstrap.sh"The selection record is stored at:
~/.config/opencode/agent-memory-systems-postgres/setup.json
Agent rule:
- If this file does not exist, ask the user if they want to enable optional components.
- Recommended: run bootstrap with all options enabled (then fix any failures it reports).
On Windows, pgvector installation follows the official pgvector instructions (Visual Studio C++ + ). The bootstrap will attempt to install prerequisites via .
nmake /F Makefile.winwingetOptional automation: compaction logging (OpenCode plugin)
If you want automatic compaction logging, install the OpenCode plugin template shipped with this skill.
- Copy to
plugins/agent-memory-systems-postgres.js~/.config/opencode/plugins/ - Restart OpenCode
Credentials (psql)
Do NOT hardcode passwords in scripts, skill docs, or config files.
Recommended options for non-interactive :
psql- /
.pgpass(recommended)pgpass.conf- Linux/macOS: (must be
~/.pgpassor libpq will ignore it)chmod 0600 ~/.pgpass - Windows: (example:
%APPDATA%\postgresql\pgpass.conf)C:\Users\<you>\AppData\Roaming\postgresql\pgpass.conf - Format:
hostname:port:database:username:password - Docs: https://www.postgresql.org/docs/current/libpq-pgpass.html
- Linux/macOS:
- (optional override): point to a custom location for the password file
PGPASSFILE - (not recommended): only for quick local testing; environment variables can leak on some systems
PGPASSWORD
Tip: set connection defaults once (per shell) to shorten commands:
bash
export PGHOST=localhost
export PGPORT=5432
export PGDATABASE=agent_memory
export PGUSER=postgresOne-time setup helper scripts
This skill ships helper scripts (relative paths):
scripts/setup-pgpass.ps1scripts/setup-pgpass.sh
OpenCode usage: run them from the skill directory.
Windows run:
powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "scripts\setup-pgpass.ps1"Linux/macOS run:
bash
bash "scripts/setup-pgpass.sh"Memory Types
| Type | Lifespan | Use When |
|---|---|---|
| 24h auto-expire | Current conversation context (requires |
| Permanent + decay | Problem-solving experiences, debugging sessions |
| Permanent | Extracted facts, knowledge, patterns |
| Permanent | Step-by-step procedures, checklists (importance >= 7) |
Core Functions
store_memory(type, category, tags[], title, content, metadata, agent_id, session_id, importance)
store_memory(type, category, tags[], title, content, metadata, agent_id, session_id, importance)Auto-deduplicates by content hash. Duplicate inserts bump and .
access_countimportance_scoresql
SELECT store_memory(
'semantic',
'windows-networking',
ARRAY['ssh', 'tunnel', 'port-conflict'],
'SSH Tunnel Port Conflict Resolution',
'Fix: 1) taskkill /F /IM ssh.exe 2) Use processId not pid 3) Wait 3s',
'{"os": "Windows 11"}',
'sisyphus',
NULL,
9.0
);search_memories(query, types[], categories[], tags[], agent_id, min_importance, limit)
search_memories(query, types[], categories[], tags[], agent_id, min_importance, limit)Hybrid search: full-text (tsvector) + trigram similarity (pg_trgm) + tag filtering.
Accepts plain English queries — no tsquery syntax needed.
Relevance scoring: .
text_score * decay * recency * importancesql
-- Natural language
SELECT * FROM search_memories('ssh tunnel port conflict', NULL, NULL, NULL, NULL, 7.0, 5);
-- Filter by type + tags
SELECT * FROM search_memories(
'troubleshooting steps',
ARRAY['procedural']::memory_type[],
NULL,
ARRAY['ssh'],
NULL, 0.0, 5
);Returns:
Where is one of: , , , .
id, memory_type, category, title, content, importance_score, relevance_score, match_typematch_typefulltexttrigram_titletrigram_contentmetadatamemory_health_check()
memory_health_check()Returns: for , , .
metric | value | statustotal_memoriesavg_importancestale_countapply_memory_decay()
apply_memory_decay()Decays episodic memories by . Run daily.
0.9999^days_since_accessprune_stale_memories(age_days, max_importance, max_access_count)
prune_stale_memories(age_days, max_importance, max_access_count)Soft-deletes old episodic memories below thresholds. Default: 180 days, importance <= 3, never accessed.
Agent Workflow
Before a task
sql
SELECT id, title, content, relevance_score
FROM search_memories('keywords from user request', NULL, NULL, NULL, NULL, 5.0, 5);If relevant memories found, reference them: "Based on past experience (memory #1)..."
After solving a problem
sql
SELECT store_memory(
'semantic',
'category-name',
ARRAY['tag1', 'tag2', 'tag3'],
'One-line problem summary',
'Detailed problem + solution',
'{"os": "...", "tools": [...]}',
'agent-name',
NULL,
8.0
);When delegating to subagents
Include in prompt:
MUST DO FIRST:
Search agent_memories: SELECT * FROM search_memories('relevant keywords', NULL, NULL, NULL, NULL, 5.0, 5);
MUST DO AFTER:
If you solved something new, store it with store_memory(...)Task Memory Layer (optional)
This skill also ships a minimal task/issue layer inspired by Beads: graph semantics + deterministic "ready work" queries.
Objects:
- : tasks (status, priority, assignee)
agent_tasks - : typed links (
task_links,blocks,parent_child, etc.)related - : materialized cache to make ready queries fast
blocked_tasks_cache - : link tasks to memories (
task_memory_links) for outcomes/notesagent_memories
Create tasks:
sql
INSERT INTO agent_tasks(title, description, created_by, priority)
VALUES ('Install pgvector', 'Windows build + enable extension', 'user', 1);Add dependencies:
sql
-- Task 1 blocks task 2
INSERT INTO task_links(from_task_id, to_task_id, link_type)
VALUES (1, 2, 'blocks');
-- Task 2 is parent of task 3 (used for transitive blocking)
INSERT INTO task_links(from_task_id, to_task_id, link_type)
VALUES (2, 3, 'parent_child');Rebuild blocked cache (usually auto via triggers):
sql
SELECT rebuild_blocked_tasks_cache();Ready work query:
sql
SELECT id, title, priority
FROM agent_tasks t
WHERE t.deleted_at IS NULL
AND t.status IN ('open','in_progress')
AND NOT EXISTS (SELECT 1 FROM blocked_tasks_cache b WHERE b.task_id = t.id)
ORDER BY priority ASC, updated_at ASC
LIMIT 50;Claim a task (atomic):
sql
SELECT claim_task(2, 'agent-1');Link a task to a memory:
sql
INSERT INTO task_memory_links(task_id, memory_id, link_type)
VALUES (2, 123, 'outcome');Optional add-on: (not implemented yet)
conditional_blocks- This is intentionally deferred until the core workflow feels solid.
- If you need it now, store a condition in (e.g.,
task_links.metadata) and treat it as documentation.{ "os": "windows" }
Wrapper scripts (recommended)
To avoid re-typing SQL, use the wrapper scripts shipped with this skill:
Windows:
powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "scripts\tasks.ps1" ready 50
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "scripts\tasks.ps1" create "Install pgvector" 1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "scripts\tasks.ps1" claim 2 agent-1Linux/macOS:
bash
bash "scripts/tasks.sh" ready 50
bash "scripts/tasks.sh" create "Install pgvector" 1
bash "scripts/tasks.sh" claim 2 agent-1Compaction Log (high value)
Compaction can delete context. Treat every compaction as an important event and record it.
If you're using OpenCode, prefer the OpenCode plugin route for automatic compaction logging.
OpenCode plugin (experimental.session.compacting)
- Copy to
plugins/agent-memory-systems-postgres.js~/.config/opencode/plugins/ - Restart OpenCode
It writes local compaction events to:
~/.config/opencode/agent-memory-systems-postgres/compaction-events.jsonl
And will also attempt a best-effort Postgres write (requires pgpass).
store_memory(...)Verify
sql
SELECT id, title, relevance_score
FROM search_memories('compaction', NULL, NULL, NULL, NULL, 0, 10);If nothing is inserted, set up / so can authenticate without prompting.
.pgpasspgpass.confpsqlDaily Compaction Consolidation
Raw compaction events are noisy. Run a daily consolidation job that turns many compaction events into 1 daily memory.
The consolidation scripts default to the OpenCode plugin event log path and will fall back to Claude Code paths if needed.
- OpenCode events:
~/.config/opencode/agent-memory-systems-postgres/compaction-events.jsonl - Output directory:
~/.config/opencode/agent-memory-systems-postgres/compaction-daily/
Windows run (manual):
powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "scripts\consolidate-compactions.ps1"Linux/macOS run (manual):
bash
bash "scripts/consolidate-compactions.sh"Scheduling:
- Windows Task Scheduler: create a daily task that runs the PowerShell command above
- Linux cron example:
bash
# every day at 02:10 UTC
10 2 * * * bash "<skill-dir>/scripts/consolidate-compactions.sh" >/dev/null 2>&1Appendix: Claude Code compatibility (optional)
This repository also includes Claude Code hook scripts under . They are not required for OpenCode usage.
hooks/Friction Log (turn pain into tooling)
Whenever something is annoying, brittle, or fails:
- Store an memory with category
episodicand tags for the tool/OS/error.friction - If it repeats (2+ times), promote it to memory (importance >= 7) with a checklist.
procedural - Update this skill doc when the fix becomes a stable rule/workflow (so every agent learns it).
Schema Overview
agent_memoriesmemory_linksworking_memoryKey columns: , , , , , (auto), (JSONB), , , , (auto).
memory_typecategorytags[]titlecontentcontent_hashmetadataimportance_scoreaccess_countrelevance_decaysearch_vectorAnti-Patterns
| Don't | Do Instead |
|---|---|
| Store everything | Only store non-obvious solutions |
| Skip tags | Tag comprehensively: tech, error codes, platform |
Use | |
| One type for all data | Use correct memory_type per content |
| Forget importance rating | Rate honestly: 9-10 battle-tested, 5-6 partial |
Sharp Edges
| Issue | Severity | Mitigation |
|---|---|---|
| Chunks lose context | Critical | Store full problem+solution as one unit |
| Old tech memories | High | |
| Duplicate memories | Medium | |
| No vector search | Info | pg_trgm provides fuzzy matching; pgvector can be added later |
Cross-Platform Notes
- PostgreSQL 14-18 supported (no partitioning, no GENERATED ALWAYS)
- pg_trgm is the only required extension (ships with all PG distributions)
- Linux:
psql -U postgres -d agent_memory -f init.sql - Windows: Use full path to psql.exe or add PG bin to PATH
- MCP postgres_query: Works for read operations; DDL requires psql
Maintenance
sql
SELECT apply_memory_decay(); -- daily
SELECT prune_stale_memories(180, 3.0, 0); -- monthly
DELETE FROM working_memory WHERE expires_at < NOW(); -- daily
SELECT * FROM memory_health_check(); -- anytimeOptional: pgvector Semantic Search
If pgvector is installed on your PostgreSQL server, will:
init.sql- create extension (non-fatal if missing)
vector - add (variable dimension)
agent_memories.embedding vector - create
search_memories_vector(p_embedding, p_embedding_dim, ...)
Notes:
- This does NOT generate embeddings. You must populate yourself.
agent_memories.embedding - Once embeddings exist, you can do nearest-neighbor search:
sql
-- p_embedding is a pgvector literal; pass it from your app.
-- Optionally filter by dimension (recommended when using multiple models).
SELECT id, title, similarity
FROM search_memories_vector('[0.01, 0.02, ...]'::vector, 768, NULL, NULL, NULL, NULL, 0.0, 10);Note: variable-dimension vectors cannot be indexed with pgvector indexes. This is a tradeoff to support local models with different embedding sizes.
If pgvector is not installed, everything else still works (fts + pg_trgm).
Embedding Ingestion Pipeline
pgvector search only works after you populate .
agent_memories.embeddingThis skill ships ingestion scripts (relative paths). Run from the skill directory:
scripts/ingest-embeddings.ps1scripts/ingest-embeddings.sh
They:
- find memories with
embedding IS NULL - call an OpenAI-compatible embeddings endpoint (including Ollama)
- write vectors into
agent_memories.embedding vector
Requirements:
- pgvector installed + applied (so
init.sqlexists)agent_memories.embedding - /
.pgpassconfigured (sopgpass.confcan write without prompting)psql -w - env vars for embedding API:
- (
EMBEDDING_PROVIDERorollama; defaultopenai)openai - (required for
EMBEDDING_API_KEY; optional foropenai)ollama - (default depends on provider)
EMBEDDING_API_URL - (default depends on provider)
EMBEDDING_MODEL - (optional; forwarded to the embeddings endpoint when supported)
EMBEDDING_DIMENSIONS
Windows example:
powershell
$env:EMBEDDING_PROVIDER = "ollama"
$env:EMBEDDING_MODEL = "nomic-embed-text"
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "scripts\ingest-embeddings.ps1" -Limit 25Linux/macOS example:
bash
export EMBEDDING_API_KEY=...
export EMBEDDING_MODEL=text-embedding-3-small
bash "scripts/ingest-embeddings.sh"Scheduling:
- run daily (or hourly) after you add new memories
- keep small until you trust it
Limit
Robustness note:
- On Windows, very long SQL strings can be fragile when passed via . The ingestion script writes per-row updates to a temporary
psql -cfile and runs.sqlto avoid command-line length/quoting edge cases.psql -f
Related Skills
systematic-debuggingpostgres-propostgresql-table-design