Files
pegas-memory/EXAMPLES.md
T

7.7 KiB

Pegas Memory — Usage Examples

Concrete examples of how the agent should interact with the knowledge base. All calls go through the MCP tools mcp__pegas-memory__*.

On the values. Tool names, argument names, response shapes and behaviour are exact — verified against the running service on 2026-10-15. Concrete numbers (atom/doc/gap counts, ids, similarity scores, doc_id) are a snapshot taken at that moment and change as the base grows; every example that captures real output is marked actual, and every example that mutates data shows an illustrative id (marked accordingly). The shape is stable, the values are not — always call the tool instead of quoting a remembered number.


Example 1 — "What do you know?" (the most common mistake)

User: "What's in your knowledge base?"

✗ Wrong (a real observed failure)

memory_search("knowledge base")       → []      (semantic search finds nothing useful)
read("/home/neo/workspace")           → ERROR   (it is a directory, not a file)
web_search("memory")                  → ❌ searching the INTERNET for your OWN base
web_search("knowledge base")          → ❌
web_search("atoms")                   → ❌
web_search("logical_rule")            → ❌

That is 2 wrong calls + 4 wasted web searches.

✓ Correct

memory_stats()

Result (actual, 2026-10-15):

{"atoms": 89, "documents": 6, "open_gaps": 3}

Answer: "My knowledge base holds 89 atoms across 6 documents; 3 open research gaps."

Counts grow as the base grows — always call the tool, never quote a remembered number.


Example 2 — "What do you know about X?"

User: "What do you know about Memgraph?"

✓ Correct

memory_search("Memgraph", top_k = 5)

Result (actual, abridged):

{"query": "Memgraph",
 "hits": [
   {"id": 171, "score": 0.854, "type": "text",
    "claim": "Memgraph Lab provides graph visualization and execution of ad hoc queries for data understanding.",
    "status": "candidate", "confidence": 0.9, "doc_id": 13},
   {"id": 168, "score": 0.843, "type": "fact",
    "claim": "Memgraph documentation is available at memgraph.com/docs.",
    "status": "candidate", "confidence": 0.95, "doc_id": 13},
   {"id": 128, "score": 0.835, "type": "definition",
    "claim": "Memgraph serves as the graph engine for GraphRAG pipelines, AI memory systems...",
    "status": "candidate", "confidence": 0.9, "doc_id": 10}
 ]}

Answer: "The base holds several Memgraph atoms (Lab visualization, docs location, role as a GraphRAG engine). All are still candidate — cross-confirm before treating them as verified."

IDs, scores and doc_id change with every ingest. The shape is stable; the values are not.

If nothing is found → say "not in the knowledge base" and offer to research it.


Example 3 — Filling a knowledge gap (full loop)

User: "Research how HNSW indexing works in vector databases."

1. memory_search("HNSW")            → []                        # not known yet
2. memory_add_gap("How does HNSW work?",
                  reason = "low_coverage", priority = 0.8)
3. memory_research("How does HNSW indexing work?")
                                    → searches the web, ingests sources,
                                      distills atoms, saves them
4. memory_verify()                  → cross-confirm the new atoms
5. memory_search("HNSW")            → now returns verified hits

Note: step 1 (CHECK) is mandatory — it prevents re-researching what is already known.


Example 4 — Storing one fact

User: "Remember that Memgraph keeps the whole graph in RAM."

✓ Correct — one atomic claim + type

memory_store(
  type       = "fact",
  claim      = "Memgraph keeps the entire graph in RAM",
  content    = "Memgraph stores the graph in memory, which is why it is faster than a disk-based graph DB on analytical workloads.",
  confidence = 0.9
)

Result (illustrative — the id is assigned by the database):

{"atom_id": 172, "created": true}

If the same claim already exists, the deduplicator returns the existing id instead:

{"atom_id": 168, "created": false, "duplicate_of": 168}

✗ Wrong

memory_store(type = "text", content = "<entire article pasted here>")

Raw articles are not atoms. Use memory_ingest to distill a document, or write one claim.


Example 5 — Ingesting a document

User: "Add this article to the base: https://example.com/graph-dbs"

memory_ingest(url = "https://example.com/graph-dbs")

Result (illustrative shape — values depend on the source):

{"doc_id": 14, "chunks": 5, "atoms_created": 14,
 "atoms_skipped": 3, "duplicates": 2}
  • duplicates — near-duplicates filtered by the semantic deduplicator (cosine ≥ 0.90).
  • atoms_skipped — low-confidence atoms dropped by the distillation threshold.
  • If the site is geo-blocked and PROXY_URL is set, the fetch goes through the proxy; otherwise a research-level snippet fallback is used.

Example 6 — Verifying a fact

User: "Is it true that Memgraph is faster than Neo4j?"

memory_verify(atom_id = 113, self_critique = true)

Result (illustrative — depends on the atom and the current base):

{"atom_id": 8, "verdict": "duplicate", "corroborations": 1,
 "new_status": "stale", "new_confidence": 1.0,
 "reason": "Repeats an already known fact about Qdrant from another source."}

Verdicts: new · duplicate (→ stale) · corroborates (→ verified) · contradicts (→ contested).


Example 7 — Code analysis

User: "What functions does this module call, and who depends on it?"

memory_code_graph(language = "python", source = "<file contents>",
                  repo = "pegas-memory", path = "db.py")

Result:

{"symbols_stored": 7, "dependencies_stored": 27}

Then:

memory_search_code("upsert")

Result (actual, abridged):

{"query": "upsert",
 "symbols": [
  {"id": 11, "repo": "pegas-memory",
   "path": "/home/neo/workspace/pegas-memory/pegas_memory/memgraph_store.py",
   "symbol_name": "upsert_link", "kind": "function", "line_start": 26},
  {"id": 83, "repo": "pegas-memory", "path": "memgraph_store.py",
   "symbol_name": "upsert_link", "kind": "function"}
]}

Inference (edges imports → depends_on, transitive):

memory_infer(if = "imports", then = "depends_on")
memory_infer(if = ["depends_on", "depends_on"], then = "depends_on")

Example 8 — Inspecting the graph

memory_query_graph(kind = "depends_on", top_k = 10)

Result (actual, abridged):

{"kind": "depends_on",
 "edges": [
   {"src": "code_symbols", "dst": "hashlib",  "kind": "depends_on", "inferred": true},
   {"src": "code_symbols", "dst": "tree_sitter","kind": "depends_on", "inferred": true},
   {"src": "db",           "dst": "psycopg",   "kind": "depends_on", "inferred": true}
 ],
 "nodes": 89, "code_symbols": 162}

"inferred": true marks an edge produced by logical inference, not extracted from source. Empty-ish targets like "." come from relative imports (from . import x) — harmless.


Anti-patterns (do not do this)

Anti-pattern Why it is wrong Do instead
web_search to learn what your base contains it searches the internet, not memory memory_stats / memory_search
read on a directory read expects a file bash ls or the fs-search tool
memory_store of a whole article violates the atomic-atom rule memory_ingest
Skipping memory_search before research re-researches known facts check first
Reporting unverified atoms as facts they are candidate run memory_verify
Estimating counts memory_stats gives exact numbers call it