Skip to main content

Persistent Vector Memory — upgrade embeddings from retrieval keys to evolvable memory primitives. Zero GPU, zero API keys, zero vector database.

Project description

English · 中文

🧠 PVM — Persistent Vector Memory

AI memory that learns. Zero API keys. Zero GPU. Zero cloud.

Python 3.10+ Tests Zero Deps License SLOC


What PVM Is

PVM is a memory engine — turning one-shot vector queries into evolvable, persistent memories.

Every AI system today suffers from amnesia. Traditional RAG: encode your question into a vector → search a vector database → return the top-K most similar → then throw everything away. Query vectors are discarded. Document vectors never change. An article that helped 10,000 users and one untouched for 3 years — identical retrieval priority. Guess wrong once, guess wrong again, forever.

PVM solves this at the data structure level. Each memory record carries evolving weights, decaying timestamps, and edges that connect related memories. The result: retrieval quality improves with use — rather than peaking at deployment.

      User Query
          │
          ▼
    ┌───────────┐
    │ PVM Engine │
    └─────┬─────┘
     ┌────┴────┐
     ▼         ▼
 Semantic     Exact
 Channel      Channel
(cosine)    (inverted)
     └────┬────┘
          ▼
        Union
          │
     BFS Co-activate
          │
   Composite Rank
   (w × τ × bonus)
          │
        Top-K
          │
    User Feedback
          │
     Delta Rule
    w += α(s - w)
          │
          └──── loops back to PVM Engine

What PVM Can Do

1. AI Long-Term Memory (replaces mem0 / Zep / Letta)

PVM sits between your application and the LLM. Before each LLM call: recall relevant historical context. After each LLM reply: calibrate memory weights based on user feedback. Five lines of code to integrate.

emb  = embed(user_message)
mems = pvm.query(user_message, emb, keywords)
prompt = build_prompt(mems, user_message)
reply = llm.chat(prompt)
pvm.calibrate(mems[0].fingerprint, signal=1.0)

→ Run: python examples/integration_ai_middleware.py

2. Enterprise Document Retrieval (replaces Elasticsearch / Pinecone)

50,000 documents. 100 queries per day. 30 consecutive days. PVM's dual-channel retrieval ensures zero blind spots — what the semantic channel misses, the keyword channel catches. Frequently accessed documents gain weight automatically. Cold data settles naturally.

→ Run: python examples/demo_document_recall.py

3. Honest AI (Fuzzy Attribution)

When multiple memories are equally likely, PVM does not guess. It tells you: "I've noticed a pattern — you've been startled at the beach twice, and in an escape room once. You seem particularly sensitive to sudden threats." Builds trust. Doesn't break it.

→ Run: streamlit run examples/dashboard.py — click the three-act button.


PVM vs The Competition

 Traditional RAG       mem0 / Letta / Zep            PVM (us)
 ═══════════════      ════════════════════      ═══════════════
 Query → Encode       Query → API Key Auth      Query → Dual-Channel
   │                     │                         │
 Cosine Similarity     Cloud Embedding           Edge BFS
   │                     │                         │
  Top-K                Cloud Vector DB           Composite Rank
   │                     │                         │
 Inject to LLM         LLM extracts facts        Return
   │                     │                         │
 ❌ Discard vector     ❌ Never evolves           ✅ Calibrate weights
   │                     │                         │
 Dead loop              Dead loop                 Gets smarter ↩

Comparison Table

Capability Traditional RAG mem0 Letta Zep PVM
API Key Required 1 (OpenAI) 2 (OpenAI + mem0) 1 (Letta) 1 (Zep) 0
GPU Required Yes Yes Yes Cloud No
External Vector DB Pinecone/Milvus Managed cloud pgvector Managed cloud Local JSONL
Learns from feedback ❌ No ❌ No ❌ No ❌ No ✅ Every interaction
Honest when uncertain ❌ Must guess ❌ Must guess ❌ Must guess ❌ Must guess ✅ Fuzzy attribution
Data stays local ❌ Cloud ❌ Cloud ❌ Cloud ✅ 100%
Annual cost (100K queries/day) $3,600–13,000 ~$600–3,600/yr ~$x/mo (archived) ~$600–6,000/yr $0 (server only)
Auditable code N/A 10K+ lines 10K+ lines Closed source ~800 lines
pip install ❌ (archived)
License N/A Apache 2.0 Apache 2.0 Apache 2.0 BSL→MIT 2030

The Essential Difference

mem0:    You give us your API key. We store your data on our cloud.
         We charge per call. Your vectors never evolve.

PVM:     You clone the repo. It runs on your machine.
         Your data never leaves your device. Your vectors evolve with every interaction.
         Zero additional cost beyond your own server.

How PVM Achieves This

Mechanism 1: Delta Rule Weight Calibration

Each time a user confirms or corrects a retrieved memory, PVM updates its weight using the Widrow-Hoff Delta Rule (1960):

$$w \gets w + \alpha \cdot (s - w)$$

  • $w$: memory weight $\in [0,1]$
  • $s$: feedback signal ($1.0$ = confirm, $0.0$ = correct)
  • $\alpha$: learning rate (default $0.05$)

One subtraction. One multiplication. One addition. One clamp. O(1). No GPU. No batch training.

5 confirmations: weight rises from $0.500$ to $0.613$. 5 corrections: drops from $0.500$ to $0.387$.

Mechanism 2: Temporal Decay

Memories settle gracefully over time — never deleted, just quieter:

$$\tau(\Delta t) = e^{-\lambda \cdot \Delta t}$$

  • $\lambda = 0.01$ gives a half-life of 69 days
  • 1 day: $\tau = 0.990$ (nearly fresh)
  • 69 days: $\tau = 0.502$ (weight halved)
  • 365 days: $\tau = 0.026$ (nearly dormant)

Composite ranking unifies weight and freshness:

$$S = w \cdot \tau(\Delta t) \cdot (1 + \text{edge bonus})$$

Mechanism 3: Dual-Channel Retrieval

Semantic channel (cosine similarity)
    │
    ├── "seaside" ≈ "beach"   (semantic match, different words)
    ├── "startled" ≈ "scared"  (meaning preserved)
    └── Handles synonyms, paraphrasing, multilingual

Exact channel (keyword inverted index)
    │
    ├── "Python" → exact hit in content
    ├── "Docker" → found in inverted index
    └── Deterministic, zero floating-point ops, O(1) lookup

        ↓
      U N I O N
        ↓
  What one channel misses, the other catches.
  Every memory has three recovery paths.

Mechanism 4: Fuzzy Attribution (PVM Exclusive)

This is something traditional RAG and mem0/Letta/Zep architecturally cannot do.

When a query hits multiple memories with close similarity scores — e.g., "startled at the beach" hits Huizhou jellyfish (0.72), escape room NPC (0.62), Qingdao moray eel (0.77) — traditional systems can only pick one. Guess.

PVM keeps all candidates. When score differences < 0.2, it triggers fuzzy attribution. Instead of picking one, it reports the common pattern:

"I've noticed a pattern. You've been startled at the beach and in an escape room. It's not that you're timid — you seem particularly sensitive to sudden threats."

After user correction, Delta Rule calibrates the weights. Next similar query, the system automatically converges toward the precise match. Fuzzy attribution is not "giving up on precision" — it's staying honest when data is insufficient, while accumulating data to achieve precision.


Test Results

Baseline Validation: Temporal Continuity = Relevance

python experiments/baseline_temporal.py
Metric Traditional RAG (Top-K=3) PVM Baseline
Results returned 3 6
Context integrity Broken Fully preserved
Topic switch coverage 0/2 2/2
Coreference resolution Failed Native resolution
Embedding calls per query 1 0
GPU required Yes No
Information loss Top-K truncation Zero

Experiment proves: In cross-topic conversations (Python → hot pot → weather → back to Python), traditional RAG breaks the context chain by discarding intermediate messages. PVM preserves the full timeline. The LLM natively resolves "go back to what we were saying" — no special algorithm needed.

Unit Tests

74 tests all pass (0.12s)
├── test_engine.py      · 25 tests  ✅
├── test_calibration.py · 12 tests  ✅
├── test_ranking.py     · 14 tests  ✅
├── test_edges.py       ·  8 tests  ✅
└── test_persistence.py · 10 tests  ✅

Reproduce: python -m unittest discover tests -v


Architecture

PVM Record (6 fields)
┌────────────┬─────────┬───────────┬────────┬───────┬──────────────────┐
│fingerprint │ content │ embedding │ weight │ edges │ created/last_act │
│SHA-256 128b│lossless │dense vec  │ 0-1 ev │directed│   timestamps     │
└────────────┴─────────┴───────────┴────────┴───────┴──────────────────┘

Write:  Text ──▶ [SHA-256 → fingerprint] ──┐
        Text ──▶ [Embedding → vector]    ──┤
                                           ▼
                                       PVMRecord ──▶ JSONL on disk

Read:   Query ──▶ Semantic (cosine) ──┐
        Query ──▶ Exact (inverted)  ──┤
                                      ▼
                         Union → BFS → Composite Rank → Top-K + Fuzzy Attrib

Evolve: User Feedback → Delta Rule → Update weight → Update last_activated
                                                        │
                                           Next query ranking auto-adjusts

Real-World Performance

Run demo_vector_storage.py (Full Pipeline)

$ python examples/demo_vector_storage.py

========================================================================
  🔬 PVM Digital Vector Storage — Full Pipeline Demo
========================================================================

📥 Stage 1: Ingest — raw text enters PVM
  Input: "Python list comprehensions are a concise syntax for creating lists..."
  Length: 51 characters, size: 91 bytes

🔑 Stage 2: Fingerprint — SHA-256 content addressing
  SHA-256: bcfb8e9772e0e8e813010e59df0deca6...
  Fingerprint: bcfb8e9772e0e8e813010e59df0deca6 (16 bytes = 128 bits)

🧬 Stage 3: Encode — text → dense vector
  Embedding: [0.82, 0.15, 0.08, 0.03, 0.01] (5-dim example; real: 768-4096 dims)

💾 Stage 4: Store — generate PVMRecord
  fingerprint · content · embedding · weight: 0.500 · edges: 0 · timestamps
  Format: JSONL · Before: 0 records → After: 1 record

🔍 Stage 5: Interpret — retrieval + ranking
  Query: "How to write Python list comprehensions"
  #1  w=0.500  List comprehension vs for loop: performance comparison    [semantic+keyword]
  #2  w=0.500  Python decorators @decorator                               [semantic+keyword]
  #3  w=0.500  Python list comprehensions are a concise syntax for...     [semantic+keyword]

⚖️  Stage 6: Evolution — Delta Rule
  Round 1  0.5000 + 0.05×(1.0 - 0.5000) = 0.5250
  Round 2  0.5250 + 0.05×(1.0 - 0.5250) = 0.5488
  ...
  Round 5  0.5927 + 0.05×(1.0 - 0.5927) = 0.6131
  Final weight: 0.6131  (+0.1131)  ·  5 calibrations @ O(1)

⏳ Stage 7: Temporal Decay
  Δt=0 days    τ=1.000   effective=0.800   freshly activated
  Δt=7 days    τ=0.932   effective=0.746   last week
  Δt=69 days   τ=0.502   effective=0.401   half-life
  Δt=365 days  τ=0.026   effective=0.021   near zero

Run demo_document_recall.py (Document Retrieval)

$ python examples/demo_document_recall.py

========================================================================
  📂 PVM Document Retrieval Recall Demo · 50 enterprise knowledge base docs
========================================================================

📡 Semantic channel (cosine similarity): 50 hits
🔑 Keyword channel (inverted index): 15 hits

📊 Channel Analysis:
   Semantic-only: 35 docs (semantically similar, no keyword match)
   Keyword-only: 0 docs (keyword match, low semantic similarity)
   Both channels: 15 docs
   Union total: 50 docs

⚖️  Weight changes after 30 days of high-frequency queries:
   Python docs:    w=0.500 → 0.736  (+0.236)  ★ High-frequency
   Database docs:  w=0.500 → 0.299  (-0.201)  ↓ Settling

🎯 Final query (post-evolution):
  #1 w=0.736  Doc #046 | PostgreSQL Indexing...     ★
  #2 w=0.736  Doc #039 | XSS Defense...             ★
  #3 w=0.736  Doc #016 | TCP Three-Way Handshake...  ★

Quick Start

# Clone
git clone https://github.com/rocky007cn/vector-as-memory.git
cd vector-as-memory

# Dashboard (requires: pip install streamlit)
streamlit run examples/dashboard.py

# Demos (Python 3.10+ only, zero extra deps)
python examples/integration_ai_middleware.py
python examples/demo_document_recall.py
python examples/demo_vector_storage.py

# Tests
python -m unittest discover tests -v

# Paper baseline experiment
python experiments/baseline_temporal.py

Repository Structure

vector-as-memory/
├── pvm/                          Core engine (~800 lines, zero deps)
│   ├── engine.py                 PVMEngine: store, query, calibrate
│   ├── record.py                 PVMRecord + Edge data structures
│   ├── calibration.py            Delta Rule (Widrow-Hoff 1960)
│   ├── ranking.py                Temporal decay + composite ranking
│   ├── edges.py                  BFS edge co-activation
│   └── persistence.py            JSONL storage
├── examples/                     5 runnable demos
│   ├── dashboard.py              Memory evolution dashboard
│   ├── integration_ai_middleware.py  Pluggable memory layer for any LLM
│   ├── demo_document_recall.py   Enterprise document retrieval
│   ├── demo_vector_storage.py    Full-pipeline demo
│   └── basic_usage.py / _zh.py   Getting started
├── experiments/
│   └── baseline_temporal.py      Paper §3.6 validation
├── tests/                        74 unit tests
├── paper/                        Full paper (EN + ZH)
├── pyproject.toml                pip install pvm-memory
├── CONTRIBUTING.md
└── LICENSE                       BSL 1.1 → MIT July 2030

Paper

Persistent Vector Memory: Upgrading Embeddings from Retrieval Keys to Evolvable Memory Primitives — Wenhui Tian, 2026. SSRN


License

BSL 1.1, automatically converts to MIT in July 2030.

Free for non-commercial use. Commercial use: contact rocky007cn@outlook.com.

Full license text


PVM v1.1 · Wenhui Tian · github.com/rocky007cn/vector-as-memory

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pvm_memory-1.1.0.tar.gz (28.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pvm_memory-1.1.0-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file pvm_memory-1.1.0.tar.gz.

File metadata

  • Download URL: pvm_memory-1.1.0.tar.gz
  • Upload date:
  • Size: 28.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.14

File hashes

Hashes for pvm_memory-1.1.0.tar.gz
Algorithm Hash digest
SHA256 d61949756876ac943b698bb04b1975cf3d65aabc984941ba23bcdac7745bf99e
MD5 4eae2c0d8275e47b1b36a8c3195b3945
BLAKE2b-256 8f910c2dd0a903fa2374f0ded2749fd9d0cc130001f5f4a2d9e754a48d9a12c9

See more details on using hashes here.

File details

Details for the file pvm_memory-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: pvm_memory-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.14

File hashes

Hashes for pvm_memory-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 155dcd0ca61a02e4db5f589fbef3503df88a17d80553869c59695521a2becc3c
MD5 f53922591452c058defa303321d55811
BLAKE2b-256 21fc0ec2a937a738ebb7421863089dd2596b8073410d8290c07403786db1cc2d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page