docs: add openspec proposals for memory v2 and orchestrator flow patterns
This commit is contained in:
60
openspec/changes/memory-v2-hybrid-search/design.md
Normal file
60
openspec/changes/memory-v2-hybrid-search/design.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Memory v2 — Design
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────┐
|
||||
│ system-prompt.ts │
|
||||
│ (inject memory block) │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
┌─────────▼──────────┐
|
||||
│ memory/recall.ts │
|
||||
│ (renamed to query) │
|
||||
└─────────┬──────────┘
|
||||
│
|
||||
┌───────────────┼───────────────┐
|
||||
│ │ │
|
||||
┌────────▼──────┐ ┌─────▼──────┐ ┌──────▼───────┐
|
||||
│ BM25Ranker │ │ EmbedCache │ │ CosineRanker │
|
||||
│ (stateless) │ │ (LRU map) │ │ (ONNX) │
|
||||
└───────────────┘ └────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
## Module Changes
|
||||
|
||||
### `apps/server/src/services/memory/` — new/changed files
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `recall.ts` | Replace `rankByRelevance` with hybrid `rankByHybrid(query, entries)` |
|
||||
| `embeddings.ts` | **New** — ONNX model loader + `embed(texts: string[]): number[][]` |
|
||||
| `bm25.ts` | **New** — BM25 scorer with `score(query, doc): number` |
|
||||
| `ranker.ts` | **New** — weighted merge of BM25 + cosine scores |
|
||||
| `entries.ts` | Add `serializeForEmbedding(entry): string` helper |
|
||||
|
||||
### Embedding Model
|
||||
|
||||
- Model: `all-MiniLM-L6-v2` (384-dim, ~23MB ONNX)
|
||||
- Runtime: `onnxruntime-node` npm package or subprocess via `node:child_process`
|
||||
- Cache: `Map<string, { embedding: number[], mtime: number }>` in-memory, cleared on process restart
|
||||
- Fallback: BM25-only when model file is missing
|
||||
|
||||
### Agent Tools (new)
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `extract_memory(topic, title, content, tags?)` | Persists a memory entry. Topic must be one of project/user/reference |
|
||||
| `search_memory(query)` | Returns up to 10 ranked memory entries matching the query. Replaces blind injection |
|
||||
|
||||
### Scoring Formula
|
||||
|
||||
```
|
||||
score = (BM25_score * 0.3) + (cosine_similarity * 0.7)
|
||||
```
|
||||
|
||||
Both normalized to [0,1] before merging. Entries below threshold (0.15) are excluded.
|
||||
|
||||
## Rollback
|
||||
|
||||
Set `MEMORY_SEARCH=keyword` env var to fall back to the v1 keyword-only path. Default is `hybrid`.
|
||||
Reference in New Issue
Block a user