Metadata-Version: 2.4
Name: pvm-memory
Version: 1.1.0
Summary: Persistent Vector Memory — upgrade embeddings from retrieval keys to evolvable memory primitives. Zero GPU, zero API keys, zero vector database.
Author-email: "Wenhui Tian (Muchuan)" <rocky007cn@outlook.com>
License: BSL-1.1
Project-URL: Homepage, https://github.com/rocky007cn/vector-as-memory
Project-URL: Documentation, https://github.com/rocky007cn/vector-as-memory#readme
Project-URL: Repository, https://github.com/rocky007cn/vector-as-memory
Project-URL: Issues, https://github.com/rocky007cn/vector-as-memory/issues
Project-URL: Paper, https://ssrn.com/
Keywords: vector-memory,rag,embedding,memory,ai-memory,llm,retrieval,persistent-memory
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Database :: Database Engines/Servers
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

﻿<p align="center">  <a href="README.md">English</a> ·  <a href="README-zh.md">中文</a></p>

# 🧠 PVM — Persistent Vector Memory

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

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue)](https://www.python.org/)
[![Tests](https://github.com/rocky007cn/vector-as-memory/actions/workflows/tests.yml/badge.svg)](https://github.com/rocky007cn/vector-as-memory/actions)
[![Zero Deps](https://img.shields.io/badge/dependencies-zero-success)](pyproject.toml)
[![License](https://img.shields.io/badge/license-BSL%201.1%E2%86%92MIT%202030-green)](LICENSE)
[![SLOC](https://img.shields.io/badge/SLOC-~800-lightgrey)](pvm/)

---

## 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.**

```python
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

```bash
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)

```text
$ 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)

```text
$ 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

```bash
# 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](https://ssrn.com/)

- [`paper/paper-en.md`](paper/paper-en.md) — Full English (7 chapters + appendix)
- [`paper/paper-zh.md`](paper/paper-zh.md) — Full Chinese (7 chapters + appendix)

---

## 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](LICENSE)

---

<p align="center"><b>PVM v1.1</b> · Wenhui Tian · <a href="https://github.com/rocky007cn/vector-as-memory">github.com/rocky007cn/vector-as-memory</a></p>
