用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/MarchLiu/hypatia --skill hypatia-memory命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Interact with the Hypatia AI memory system using natural language. Translate user requests into hypatia CLI commands for knowledge CRUD, statement (RDF triple) management, JSE queries, full-text search, and shelf management. Trigger when: user mentions memories, knowledge bases, knowledge graphs, triples, statements, relationships, shelves, or asks to store, recall, remember, record, save, find, or search information in hypatia. Also trigger when user wants to create or explore relationships between concepts, query existing knowledge, or manage shelves. Examples: 'remember that Rust is a systems language', 'find everything about Alice', 'record that Alice knows Bob', 'search for programming', 'show all knowledge', 'list shelves'.
Automatic memory extraction and management for hypatia knowledge graph
正在显示 SKILL.md
| name | hypatia-memory |
| description | Automatic memory extraction and management for hypatia knowledge graph |
| user-invocable | false |
| allowed-tools | Bash, Read, Grep, Glob |
You are an automatic memory management system built on hypatia. Your job is to:
All layers run in the same hook invocations; conversation logging always runs first.
This skill is activated via hooks in ~/.claude/settings.json (or Cursor equivalent):
| Hook Event | When | Output Signal | AI Response |
|---|---|---|---|
UserPromptSubmit | Every user message | TRIGGER:log | Record user message + check summary cascade + optional semantic extract |
UserPromptSubmit | Every user message (if remember/forget) | TRIGGER:immediate | Explicit remember/forget (semantic layer) |
UserPromptSubmit | Every 5 turns | TRIGGER:extract | Scan for completed work units (semantic layer) |
Stop / assistant turn hook | Session end or each assistant reply | TRIGGER:log | Record assistant message + check summary cascade |
Stop | Session ending | TRIGGER:session-end | Record session summary if available + final semantic extract pass |
On every TRIGGER:log: always execute Conversation Logging Protocol first.
If the hook outputs nothing (no trigger), no action is needed.
The same protocol runs natively in Codex via ~/.codex/hooks.json (see
codex-integration/ in the Hypatia repo). The bundled scripts translate
Codex lifecycle events into the exact trigger signals above:
| Codex event | Hook script | What it does |
|---|---|---|
SessionStart | hypatia_session_start.sh | Loads project/global rules + taboos and injects them as additionalContext |
UserPromptSubmit | hypatia_user_prompt_submit.sh | Logs the user message, recalls relevant memories, emits TRIGGER:log + optional TRIGGER:immediate / TRIGGER:extract (every 5 turns) / TRIGGER:summary (≥16 unsummarized) |
Stop | hypatia_stop.sh | Logs the assistant message (side-effect only; Codex Stop hooks cannot inject context) |
Installation: ./codex-integration/install.sh, restart Codex, then review and
trust the hooks (CLI: /hooks; desktop app: Settings → Hooks).
The hook scripts are thin, deterministic shells: they write message entries
(msg-<session_id>-<turn_id>, tag message) and retrieval context, and emit
trigger signals. The AI-heavy steps in this document (summary synthesis,
work-unit extraction) are still performed by the agent following this skill —
the hooks never make model calls.
When a new session begins, load relevant rules and taboos:
basename of the git root or CWD)# Load project-specific and global rules
hypatia query '["$knowledge", ["$contains", "tags", "rule"], ["$or", ["$contains", "scopes", "<PROJECT>"], ["$contains", "scopes", ""]]]'
# Load project-specific and global taboos
hypatia query '["$knowledge", ["$contains", "tags", "taboo"], ["$or", ["$contains", "scopes", "<PROJECT>"], ["$contains", "scopes", ""]]]'
This protocol runs on every user and assistant message (TRIGGER:log). It is independent of semantic work-unit extraction.
Resolve from hook context when available; otherwise derive:
| Field | Source |
|---|---|
<PROJECT> | basename of git root or CWD |
<SESSION_ID> | Hook session_id, Cursor conversation_id, or stable hash of transcript path |
<TURN> | Monotonic turn counter within session (increment per logged message) |
<ROLE> | user or assistant |
Every conversational turn becomes one knowledge entry.
hypatia knowledge-create "msg-<SESSION_ID>-<TURN>" \
-d "## Role
<ROLE>
## Timestamp
<ISO-8601>
## Content
<full message text>" \
--tags "message" \
--scopes "<PROJECT>"
Rules:
message (no role tag; use content to determine role).msg-<SESSION_ID>-<TURN>.If the hook or environment provides a session-level summary (e.g. compaction summary, session title, or end-of-session digest):
hypatia knowledge-create "session-<SESSION_ID>" \
-d "<session summary text>" \
--tags "session" \
--scopes "<PROJECT>"
session-<SESSION_ID> when new summary text arrives (prefer knowledge-update if entry exists).When both msg-<SESSION_ID>-<TURN> and session-<SESSION_ID> exist:
hypatia statement-create "msg-<SESSION_ID>-<TURN>" "belongTo" "session-<SESSION_ID>" \
--scopes "<PROJECT>"
Predicate is exactly belongTo (message → session).
After writing each new message, run the cascade from level 1 upward.
Constants: BATCH_SIZE = 16 (for L2+)
Relation: All summary triples use relation summary.
| Triple | Meaning |
|---|---|
<summary-name> summary <item-name> | Summary condenses the item |
| Level | Tag | Triggers when | Summarizes |
|---|---|---|---|
| 1 | ["summary", "summary 1"] | Token count ≥ max_tokens × 0.9 | message entries |
| 2 | ["summary", "summary 2"] | Count ≥ 16 unlinked L1 | summary 1 entries |
| N | ["summary", "summary N"] | Count ≥ 16 unlinked L(N-1) | summary (N-1) entries |
Token-based L1 threshold:
max_tokens depends on the model in use (e.g. GLM-5.1: 200k, DeepSeek V4 Pro: 1M).Context compression trigger:
settings.max_token × 0.9, also trigger summary generation and start a new session. This is independent of the L1 count/trigger — it's an emergency compression.Use $not-summaried (native JSE operator with LEFT JOIN):
hypatia query '["$not-summaried", "<TAG>", ["$contains", "scopes", "<PROJECT>"]]'
Or use the shorthand:
hypatia session-current --scope <PROJECT>
| Level | <TAG> |
|---|---|
| 1 | message |
| 2 | summary 1 |
| N | summary (N-1) |
Results are sorted oldest first (ASC). For L1: count tokens (estimate chars/4). For L2+: take first 16 if count ≥ 16.
When a batch is ready at level L:
hypatia knowledge-create "<extracted-summary-name>" \
-d "<synthesized summary markdown>" \
--tags "summary,summary <L>" \
--scopes "<PROJECT>"
summary,summary <L> where L is the level number.hypatia statement-create "<summary-name>" "summary" "<item-name>" \
--scopes "<PROJECT>"
Run one statement-create per item in the batch.
After creating a level-L summary, re-run step 4a for level L+1 (the new summary may complete another batch at the next tier).
Stop when a level has fewer than the required threshold — do not partially summarize.
When submitting a conversation to the AI API, construct the messages list as:
[system_prompt, uncompressed_messages..., reference_info, latest_user_input]
System prompt: Constructed using the existing logic (rules, taboos, project context).
Uncompressed messages: The current set of messages that have not been summarized. Query with:
hypatia query '["$not-summaried", "message", ["$contains", "scopes", "<PROJECT>"]]'
Reference info: Analyze the user's latest input — do NOT use it verbatim as a search query. Instead:
["$not-summaried", "message", ["$contains", "scopes", "<PROJECT>"]] + filter in reasoning["$knowledge", ["$search", "<derived keywords>"]]["$knowledge", ["$similar", "<conceptual query>"]]["$statement", ["$triple", "<entity>", "$*", "$*"]]## Reference Information
The following relevant context was retrieved from the knowledge base:
1. <entry-name>: <summary or key content>
2. <entry-name>: <summary or key content>
...
Latest user input: Always the most recent user message, placed last.
After receiving the response: Save the assistant's response as a new message in the conversation history.
This layer extracts insights (rules, taboos, work units). It does not replace conversation logging.
When receiving TRIGGER:extract:
[hypatia-memory] Work unit still in progress, nothing extracted. and stop (logging still completed in Step 1)For TRIGGER:session-end:
When a completed work unit is detected:
Skip short or insubstantial segments (greetings, single-line acknowledgments like "thanks" or "ok").
| Pattern | Signature | Extraction Strategy |
|---|---|---|
| One-shot correct | Question → correct answer, no back-and-forth | Extract Q+A directly |
| Correction chain | Question → answer → user correction → fix → ... | Synthesize: initial Q + each correction + final answer |
| Exploration | Open-ended discussion without single "correct" answer | Extract key findings, decisions, rationale |
| Bug fix | Bug report → investigation → root cause → fix | Extract: symptoms, root cause, fix approach |
| Design decision | Tradeoff discussion → decision → rationale | Extract: options considered, decision, why |
| Trivial | Greeting, chitchat, simple factual lookup | Skip — not worth remembering |
For one-shot correct:
Title: <topic-slug>
Content:
## Context
<1 line summary>
## Solution
<the answer or approach>
## Key Detail
<non-obvious detail>
For correction chains:
Title: <topic-slug>
Content:
## Context
## Initial Attempt
## Why It Was Wrong
## Correct Approach
## Lesson
Synthesis rules:
Arc<Mutex<T>>" is good. "Use proper synchronization" is useless.2026-08-29, "下周一" → 2026-08-31, "三小时后" → the concrete clock time. Never store "明天/下周/稍后" verbatim — the memory will be read at a different time than it was written.What to include: technical decisions, non-obvious solutions, error patterns, design patterns, user preferences, project conventions.
What to discard: full debug logs, temporary paths, verbose tool outputs, repetitive retries, "thank you"/"ok" exchanges.
hypatia knowledge-create "wu-<date>-<slug>" \
-d "<synthesized content>" \
--tags "memory,work-unit,<topic-tags>" \
--scopes "<PROJECT>"
hypatia statement-create "wu-<date>-<slug>" "is_a" "work-unit" \
--scopes "<PROJECT>"
Optionally link to conversation graph:
hypatia statement-create "wu-<date>-<slug>" "derivedFrom" "msg-<SESSION_ID>-<TURN>"
Before storing, check for similar knowledge:
hypatia search "<keywords>" --limit 5 -c knowledge
supersedes statementextends statementWhen the user explicitly asks to remember or forget:
rule, taboo, or general memoryhypatia knowledge-create "<name>" \
-d "<content>" \
--tags "memory,<type>" \
--scopes "<PROJECT>,<optional-global>"
is_a statement and relationship statementshypatia search "<topic>" --limit 10message / summary entries if full erasure)For conversation logging:
[hypatia-memory] Logged msg-abc-042. Cascade: +1 summary 1 (token threshold).
For work unit extraction:
[hypatia-memory] Extracted 2 work units (1 one-shot, 1 correction-chain), skipped 1 trivial.
wu-2026-05-10-sort-function → memory,work-unit,rust
For immediate operations:
[hypatia-memory] Stored: "rule:prefer-immutable-patterns" (rule, scoped to my-project).
For forget operations:
[hypatia-memory] Removed 1 entry and 2 relationships.
When nothing to extract (semantic only):
[hypatia-memory] Work unit still in progress, nothing extracted.
message, session, summary <N>, memory, work-unit, rule, taboo--scopes "<PROJECT>"; global rules use ""session-<SESSION_ID> (tags: session)
↑ belongTo
msg-<SESSION_ID>-<TURN> (tags: message)
<summary-name> (tags: summary, summary 1)
↓ summary (×batch)
msg-...
<summary-name> (tags: summary, summary 2)
↓ summary (×16)
<summary-name>... (tags: summary, summary 1)
wu-<date>-<slug> (tags: memory, work-unit) ← semantic layer, optional derivedFrom → msg-*