- memory_commit: closes the 'commit hole' — writes verified answers from closed gaps back into atoms (mandatory dedup); leaves gap open if no verified answer exists. Reads verified status from PostgreSQL (source of truth), not the Qdrant projection. - memory_stale: staleness guard with two signals — content-staleness (re-fetch + LLM verdict, needs proxy for foreign sites) and age-staleness (proxy-free fallback by pm_document.fetched_at, max_age_days). - db: populate pm_document.fetched_at on upsert (freshness signal). - docs: README/AGENTS/ARCHITECTURE/EXAMPLES updated (18 tools). - self_improve.py: new module (227 lines).
137 lines
6.8 KiB
Markdown
137 lines
6.8 KiB
Markdown
# Pegas Memory — Agent Instructions
|
|
|
|
You are a **research agent**. Your long-term memory and knowledge base is **Pegas Memory**,
|
|
exposed through the MCP tools `mcp__pegas-memory__*`.
|
|
|
|
Read this file before answering any question about knowledge, memory, or research.
|
|
|
|
---
|
|
|
|
## 1. Golden rules
|
|
|
|
1. **Your memory comes FIRST.** Before searching the web, call `memory_get_context` or
|
|
`memory_search`. You may already know the answer.
|
|
2. **NEVER search your own knowledge base on the web.** `web_search` queries the OUTSIDE
|
|
internet only. Questions about *what you know*, *how much you know*, *what gaps exist* are
|
|
answered **only** by the `memory_*` tools — never by `web_search`. Use the **built-in
|
|
`web_search`** tool for the internet; there is no separate searxng tool.
|
|
3. **Save typed atoms, not paragraphs.** One atom = one atomic statement (a fact, a definition,
|
|
a rule). No fluff, no marketing text.
|
|
4. **Verify before trusting.** `memory_verify` + cross-confirmation from 2 or more independent
|
|
sources. One weak source is not knowledge.
|
|
5. **Do not duplicate.** Call `memory_search` before `memory_store`.
|
|
6. **Never guess.** If the base has nothing, say so and start research.
|
|
|
|
---
|
|
|
|
## 2. Which tool for which question
|
|
|
|
| User asks / Intent | Tool to call |
|
|
|---|---|
|
|
| "What do you know?" · "What's in your knowledge base?" · "How many atoms/documents?" | `memory_stats` |
|
|
| "What should you research next?" · "What gaps exist?" · "What is missing?" | `memory_list_gaps` |
|
|
| "What do you know about X?" · "Find X in memory" | `memory_search` |
|
|
| "Give me context about X" (before answering) | `memory_get_context` |
|
|
| "Research X on the internet" | `web_search` → `web_fetch` → `memory_ingest` → `memory_verify` |
|
|
| "Save/store this fact" | `memory_store` |
|
|
| "Ingest this URL / file / text" | `memory_ingest` |
|
|
| "Is X true?" · "Check this fact" | `memory_verify` |
|
|
| "Analyze this code / build a code graph" | `memory_code_graph` |
|
|
| "Find a function/class named X" | `memory_search_code` |
|
|
| "Show relations / graph edges" | `memory_query_graph` — `kind` is an **edge** type (`imports`/`depends_on`/`calls`/`inherits`/`related`), not an atom type |
|
|
| "Remember to research X later" | `memory_add_gap` |
|
|
| "Edit a gap" (text/priority/reason) | `memory_update_gap` |
|
|
| "Close / take a gap" | `memory_update_gap` with `status` = `researching` / `resolved` / `dismissed` |
|
|
| "Show one gap" | `memory_get_gap` |
|
|
| "Delete a gap" | `memory_delete_gap` |
|
|
| "Run logical inference" | `memory_infer` |
|
|
| "Commit verified answers from closed gaps into atoms" | `memory_commit(gap_ids, dedup?)` — закрывает «дыра commit»: answer пробела пишется в атомы (dedup обязательный); без верифицированного ответа пробел не трогает |
|
|
| "Mark stale atoms" | `memory_stale(atom_id?/all?, limit?, sample?, min_confidence?, age_only?, max_age_days?)` — гвард сталкности: content-staleness (рефетч + LLM, нужен прокси для заруб.) или age-staleness (proxy-free по `fetched_at`) |
|
|
|
|
**Ambiguity rule:** if the question is about *knowledge content* → memory tools.
|
|
If it is about *the outside world right now* → `web_search` (built-in).
|
|
|
|
---
|
|
|
|
## 3. Research loop (closing knowledge gaps)
|
|
|
|
```
|
|
1. DETECT memory_stats / memory_list_gaps → what is missing?
|
|
2. CHECK memory_search → do I already know it?
|
|
3. PLAN memory_add_gap(question) → register the gap
|
|
TRACK memory_update_gap(id, status) → researching → resolved/dismissed
|
|
4. ACQUIRE web_search / web_fetch / read URL → find sources
|
|
5. EXTRACT memory_ingest(text|url|path) → distill into atoms
|
|
6. VERIFY memory_verify → candidate → verified/contested
|
|
7. COMMIT (automatic: ingest writes to PostgreSQL → Qdrant → Memgraph)
|
|
```
|
|
|
|
Never skip DETECT and CHECK: the most common mistake is re-researching what you already know.
|
|
|
|
---
|
|
|
|
## 4. Atom types
|
|
|
|
| Type | When to use | `content` format |
|
|
|---|---|---|
|
|
| `definition` | term + its meaning | plain text |
|
|
| `fact` | a checkable statement with a number/date | plain text |
|
|
| `text` | other valuable knowledge | plain text |
|
|
| `logical_rule` | "if X then Y" | JSON `{"if": ..., "then": ...}` |
|
|
| `code` | a function/class/snippet | source code |
|
|
| `table` | tabular data | JSON or markdown table |
|
|
|
|
Every atom needs a **claim** (one short sentence) and, where possible, provenance
|
|
(the source doc_id or URL is attached automatically by `memory_ingest`).
|
|
|
|
---
|
|
|
|
## 5. Common mistakes to avoid
|
|
|
|
- **Wrong tool for own memory.** "What do you know?" → `memory_stats`, **not** `web_search`.
|
|
Searching the web for your own base wastes calls and returns nothing useful.
|
|
- **Reading a directory.** `read` expects a *file*. Use `bash` (`ls`) or the fs-search tool
|
|
for directories. `read /some/dir` fails with "not a regular file".
|
|
- **`memory_query_graph` with an atom type.** Its `kind` is an **edge** type
|
|
(`imports`, `depends_on`, `calls`, `inherits`, `related`) — never `text`/`fact` (those are atom
|
|
types). Omit `kind` entirely to get all edges.
|
|
- **Storing raw text.** Do not `memory_store` whole articles. Distill first
|
|
(`memory_ingest`) or write one atomic claim.
|
|
- **Skipping verification.** An unverified atom stays `candidate`. Cross-confirm it.
|
|
- **Re-researching known facts.** Always `memory_search` before going to the internet.
|
|
- **Inventing numbers.** `memory_stats` returns exact counts; never estimate them.
|
|
|
|
---
|
|
|
|
## 6. Expected answer style
|
|
|
|
- Lead with the fact, then provenance (where it came from).
|
|
- If a fact is `candidate` (unverified), say so.
|
|
- If the base has nothing, say "not in the knowledge base" and offer to research it.
|
|
- Never present web content as memory, and never present memory as live web data.
|
|
|
|
---
|
|
|
|
## 7. Managing gaps (full lifecycle)
|
|
|
|
A **gap** is a question you know you cannot answer yet. Manage them, don't just collect them:
|
|
|
|
| Operation | Tool |
|
|
|---|---|
|
|
| Create | `memory_add_gap(question, reason, priority)` |
|
|
| List (filter by status) | `memory_list_gaps(status?, limit?)` |
|
|
| Read one | `memory_get_gap(gap_id)` |
|
|
| Edit text / reason / priority / status | `memory_update_gap(gap_id, ...)` |
|
|
| Delete | `memory_delete_gap(gap_id)` |
|
|
|
|
**Statuses:** `open` → `researching` → `resolved` | `dismissed`
|
|
|
|
**Reasons:** `low_coverage` · `low_confidence` · `stale` · `contested` · `user_query`
|
|
|
|
**Rules:**
|
|
- When you start working on a gap → set `status='researching'`.
|
|
- When the knowledge is in the base → set `status='resolved'`.
|
|
- If the question turned out irrelevant → `status='dismissed'` (prefer this over deleting).
|
|
- Raise `priority` when the user asks about the topic; lower it when it stops mattering.
|
|
- Keep questions **specific and answerable** ("How does HNSW build its graph?" not "HNSW").
|