* feat(docs): mirror every docs/ page in all 65 locales Extends the documentation mirrors from the 22-page core set (#13940) to every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors (6,208 new), language bars rewritten for the full locale list, state adopted so the blocking drift gate now covers all 152 pages. run-translation.mjs: an oversized block made only of table rows or list items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is cut at item boundaries and rejoined without a blank line — the single 16-40 KB request outlived the backend socket for verbose scripts. 48 older mirrors whose tables had lost rows were retranslated with --force. * docs(i18n): refresh mirrors for the sources the base changed since the branch cut Section-level retranslation of the 29 docs (and README.md) whose source or mirrors moved on release/v3.8.51 during the run, then state adoption; the drift gate is green again on the merged tree.
85 KiB
Memory System (አማርኛ)
🌐 Languages: 🇺🇸 English · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
የእውነት ምንጭ፦
src/lib/memory/እናsrc/app/api/memory/ለመጨረሻ ጊዜ የዘመነው፦ 2026-06-28 — v3.8.40 (በነባሪ የተሰናከለ + የ int8 quantization ማሟያ)
OmniRoute በAPI ቁልፍ (እና እንደ አማራጭ በክፍለ-ጊዜ መታወቂያ) የሚለይ ቋሚ የውይይት ማህደረ ትውስታ ያቀርባል። ትውስታዎች ቀላል የregex ስርዓተ-ጥለት ማዛመድን በመጠቀም ከLLM ምላሾች በራስ-ሰር ይወጣሉ፣ ከዚያም የመጀመሪያ የስርዓት መልዕክት ሆነው ወደ ቀጣይ ጥያቄዎች ይካተታሉ (ወይም የስርዓት ሚናን ለማይቀበሉ አቅራቢዎች እንደ መጀመሪያው የተጠቃሚ መልዕክት ይካተታሉ)።
ማህደረ ትውስታ በነባሪ ተሰናክሏል (v3.8.30+)።
DEFAULT_MEMORY_SETTINGS.enabledአሁንfalseነው (src/lib/memory/settings.ts)። ማህደረ ትውስታን ማንቃት እስከmaxTokens(~2k) የተመለሰ ዐውድ በእያንዳንዱ የውይይት ጥያቄ ውስጥ ያካትታል፣ ለዚህም ክፍያ ይከፈላል — ይህ ለአዲስ ጭነቶች እና የራሳቸውን ዐውድ ለሚያስተዳድሩ ደንበኞች ያልተጠበቀ ወጪ ነው። በSettings → Memory ስር በግልጽ ያንቁት (MemorySkillsTabማህደረ ትውስታ ሲነቃ የቶከን ወጪ ማስጠንቀቂያ ጥሪ ያሳያል)። አንድ ደንበኛ የx-omniroute-no-memoryየጥያቄ ራስጌን (true/1/yes) በመጠቀም አንድን ጥያቄ ከዚህ ማስወጣት ይችላል — በAPI_REFERENCE.md ውስጥ ያለውን የጥያቄ-ራስጌ ሰንጠረዥ ይመልከቱ። ማህደረ ትውስታ የሌለው ጥያቄmemoryOwnerId = nullያዘጋጃል፣ ይህም ለዚያ ጥያቄ ሁለቱንም የማህደረ ትውስታ እና የክህሎት ማካተትን ያሰናክላል (open-sse/handlers/chatCore/headers.ts::isNoMemoryRequested)።
ማህደረ ትውስታው በእያንዳንዱ API ቁልፍ የተወሰነ እንጂ በተጠቃሚ የተወሰነ አይደለም — በተመሳሳይ
API ቁልፍ የተረጋገጠ እያንዳንዱ ጥያቄ ተመሳሳይ የማህደረ ትውስታ ስብስብን ይጋራል፣
እንደ አማራጭም በsessionId የበለጠ ሊወሰን ይችላል።
አርክቴክቸር
ደንበኛ → /v1/chat/completions (apiKeyInfo በቅድሚያ ተፈቷል)
→ handleChatCore() [open-sse/handlers/chatCore.ts]
→ resolveMemoryOwnerId(apiKeyInfo) # መታወቂያውን ያወጣል
→ getMemorySettings() # የተሸጎጡ ቅንብሮች
→ shouldInjectMemory(body, {enabled}) # መቆጣጠሪያ
→ retrieveMemories(apiKeyId, config) # SQL + FTS5 + እንደ አማራጭ vector
→ injectMemory(body, memories, provider) # የስርዓት ወይም የተጠቃሚ መልዕክት
→ ወደ ውጫዊ አቅራቢ ጥሪ
→ በምላሹ ጊዜ፦ extractFacts(text, apiKeyId, sessionId) # የማያግድ
→ setImmediate → createMemory(fact) ለእያንዳንዱ ማዛመድ
→ embed(content) + upsertVector(id, vec)
የማካተት እና የማውጣት ጥሪ ቦታዎች በ
open-sse/handlers/chatCore.ts ውስጥ ተገናኝተዋል (retrieveMemories፣ injectMemory
እና extractFactsን ይፈልጉ)።
የሞተር አርክቴክቸር (ባለ3-ደረጃ መፍትሔ)
የማህደረ ትውስታ ሞተሩ በሚገኙ መሠረተ ልማቶች እና ቅንብሮች መሠረት በስራ ላይ ባለበት ጊዜ የሰርስሮ ማውጣት መንገዱን ይወስናል። በቅድሚያ ቅደም ተከተል የሚተገበሩ ሦስት ደረጃዎች አሉ፦
┌─────────────────────────────────────────────────────────────┐
│ ደረጃ 0 — ቁልፍ ቃል (FTS5) │
│ በፍተሻ የሚወሰን ተገኝነት፦ የSQLite ግንባታው │
│ ሲደግፈው FTS5 (better-sqlite3 / node:sqlite / bun:sqlite)፤│
│ FTS5 በሌላቸው ግንባታዎች (ለምሳሌ sql.js/WASM — │
│ "no such module: fts5") ላይ አይገኝም። strategy = "exact" │
│ ሲሆን ወይም እንደ አማራጭ መመለሻ ይጠቀማል፤ የengine-status │
│ keyword ፍተሻውን ያንጸባርቃል። │
└──────────────────────────────────┬──────────────────────────┘
│ strategy = semantic|hybrid?
▼
┌─────────────────────────────────────────────────────────────┐
│ ደረጃ 1 — የተካተተ Vector (sqlite-vec) │
│ sqlite-vec v0.1.9 በdb.loadExtension() ይጫናል። │
│ በFloat32 vectors ላይ KNN brute-force። ንቁ የሚሆነው፦ │
│ • sqlite-vec loadExtension ሲሳካ │
│ • Float32Array ማምረት የሚችል የembedding ምንጭ │
│ (remote | static | transformers) ሲገኝ │
│ • vec_memories ሰንጠረዥ ሲኖር (በመጀመሪያው ready() ይፈጠራል)│
└──────────────────────────────────┬──────────────────────────┘
│ qdrant.enabled?
▼
┌─────────────────────────────────────────────────────────────┐
│ ደረጃ 2 — Qdrant (በምርጫ የሚነቃ ውጫዊ vector database) │
│ ሲነቃ ለsemantic/hybrid sqlite-vecን ይተካል። │
│ እየሰራ ያለ Qdrant instance + የተዋቀረ host/port ይፈልጋል። │
└─────────────────────────────────────────────────────────────┘
ወደ ዝቅተኛ ደረጃ መመለስ ራስ-ሰር እና ግልጽ ነው፦
- sqlite-vec መጫን ካልቻለ፣ ደረጃ 1 አይገኝም → ወደ ደረጃ 0 ይመለሳል።
- የembedding ምንጩ ስህተት ከመለሰ፣ ደረጃ 1 ወደ ደረጃ 0 ይመለሳል።
- Qdrant ጤናማ ካልሆነ፣ ደረጃ 2 ወደ ደረጃ 1 ይመለሳል (ወይም ደረጃ 1ም የማይገኝ ከሆነ ወደ ደረጃ 0 ይመለሳል)።
የEmbedding ምንጮች
የembedding ንብርብሩ (src/lib/memory/embedding/) በMemorySettingsExtended.embeddingSource ላይ ተመስርቶ የትኛውን ምንጭ መጠቀም እንዳለበት ይወስናል፦
| ምንጭ | መግለጫ | ቁልፍ ያስፈልጋል | የመጀመሪያ ማስነሻ |
|---|---|---|---|
remote |
የተዋቀረ አቅራቢ embedding APIን ይጠቀማል (OpenAI፣ Cohere፣ ወዘተ) | አዎ | የለም |
static |
በpotion-base-8M በኩል የሚከናወን አካባቢያዊ የፍለጋ-ሰንጠረዥ embedding (WordPiece + አማካይ pooling) |
አይ | ~200ms |
transformers |
በ@huggingface/transformers v4፣ all-MiniLM-L6-v2 በኩል የሚከናወን አካባቢያዊ ONNX inference |
አይ | ~3s + ~400MB RAM |
auto |
በruntime ጊዜ መወሰን፦ remote (ቁልፍ ካለ) → static → transformers → null | እንደሁኔታው | እንደሁኔታው |
የauto መወሰኛ ቅደም ተከተል፦
- በ
listEmbeddingProviders()ውስጥhasKey === trueየሆነውን የመጀመሪያ አቅራቢ ያግኙ →remote። settings.staticEnabled === trueከሆነ →static።settings.transformersEnabled === trueከሆነ →transformers።- ካልሆነ →
null(ወደ FTS5 ቁልፍ-ቃል ፍለጋ ዝቅ ይላል)።
የembedding cache (src/lib/memory/embedding/cache.ts) በ${source}:${model}:${dim}:${sha256(text)} ቁልፍ የሚሰጠውን በማህደረ ትውስታ ውስጥ ያለ LRU map ይጠቀማል፤ በMEMORY_EMBEDDING_CACHE_MAX ግቤቶች (ነባሪው 1000) የተገደበ ሲሆን TTL ደግሞ MEMORY_EMBEDDING_CACHE_TTL_MS (ነባሪው 5 ደቂቃ) ነው። በአንድ process lifecycle ውስጥ በሁሉም ጠሪዎች መካከል ይጋራል።
ድብልቅ RRF (k=60)
strategy = "hybrid" ሲሆን እና vector store ሲገኝ፣ retrieval የFTS5 እና vector ውጤቶችን ለማዋሃድ Reciprocal Rank Fusionን ይጠቀማል፦
RRF(d) = Σ 1 / (k + rank_i(d)) k = 60 ሲሆን (በMEMORY_RRF_K ሊዋቀር ይችላል)
i
በተግባር፦
- የFTS5 ፍለጋን ያስኪዱ → ደረጃ የተሰጠው ዝርዝር
R_fts(ቦታ 1..N)። - የKNN vector ፍለጋን ያስኪዱ → ደረጃ የተሰጠው ዝርዝር
R_vec(ቦታ 1..M)። - ለእያንዳንዱ ልዩ
memoryId፦
rrf_score = 1/(60 + fts_rank)+1/(60 + vec_rank)(በዝርዝሩ ውስጥ ከሌለ 0)። - በ
rrf_scoreDESC ደርድሩ፣ የtoken budget ቅኝቱን ይተግብሩ።
RRF በልዩ ልዩ retrieval systems መካከል የውጤት መደበኛነት ሳያስፈልገው ውጤታማ እንደሆነ በሰፊው ይታወቃል። ነባሪው k=60 ከመጀመሪያው የCormack et al. ጥናታዊ ጽሑፍ የተወሰደ ሲሆን ለአነስተኛ corpora (<10k ትውስታዎች) ጥሩ ይሰራል።
Backfill (lazy + reindex)
የembedding model ሲቀየር (በembedding_signature በኩል ይገኛል)፣ vector store እንደገና ይገነባል እና ሁሉም ነባር ትውስታዎች በmemories ሰንጠረዥ ውስጥ needs_reindex = 1 ተብለው ምልክት ይደረግባቸዋል።
Lazy backfill፦ በሚቀጥለው retrieval ጊዜ፣ vector ግቤት የሌለው ማንኛውም ትውስታ ፍለጋው ከመከናወኑ በፊት embed ተደርጎ ወደ vec_memories ይገባል። ይህ ማስነሻውን ሳያግድ የbackfill ወጪውን በእውነተኛ ጥያቄዎች ላይ ያከፋፍላል።
ግልጽ reindex፦ በ/dashboard/memory ውስጥ ያለው Engine tab POST /api/memory/reindexን የሚጠራ "አሁን Reindex አድርግ" የሚል አዝራር ያቀርባል። handlerው src/lib/memory/reindex.ts ውስጥ ያለውን runReindexBatch() ይጠራል፤ ይህም በእያንዳንዱ ጥያቄ እስከ limit የሚደርሱ በመጠባበቅ ላይ ያሉ ግቤቶችን ያስኬዳል። ሂደቱ በGET /api/memory/engine-status (vectorStore.needsReindex) በኩል በተደጋጋሚ ሊፈተሽ ይችላል።
የmemory_vec_meta ሰንጠረዥ (migration 083_memory_vec.sql) የሚከተሉትን ያከማቻል፦
active_dim— የአሁኑ vector dimension (null = ገና አልተስተካከለም)።embedding_signature— ለውጦችን ለማግኘት የሚያገለግል${source}:${model}:${dim}።last_reset_at— የመጨረሻው ሙሉ reset timestamp።vec_loaded— sqlite-vec በተሳካ ሁኔታ መጫኑን የሚያሳይ 0/1 flag።
የቅንብሮች ቅጥያ
ዘጠኝ የembedding እና vector መስኮች በMemorySettingsExtended ውስጥ፣
በsrc/shared/schemas/memory.ts ይገኛሉ፤ በsrc/lib/db/settings.ts በኩል ዘላቂ ሆነው ይቀመጣሉ፦
| መስክ | ዓይነት | ነባሪ | መግለጫ |
|---|---|---|---|
embeddingSource |
"remote" | "static" | "transformers" | "auto" |
"auto" |
የትኛውን የembedding ምንጭ መጠቀም እንዳለበት |
embeddingProviderModel |
string | null |
null |
አቅራቢ/ሞዴል በprovider/model ቅርጸት |
customBaseUrl |
string | null |
null |
ለማህደረ ትውስታ ብቻ የሚያገለግል OpenAI-ተኳኋኝ endpoint መሠረታዊ URL |
customModelId |
string | null |
null |
ወደብጁ endpoint የሚላክ የሞዴል ID |
transformersEnabled |
boolean |
false |
ለTransformers.js በፈቃደኝነት ማንቃት (MiniLM፣ ~400MB) |
staticEnabled |
boolean |
false |
ለአካባቢያዊው ቋሚ potion-base-8M ሞዴል በፈቃደኝነት ማንቃት |
rerankEnabled |
boolean |
false |
እንደገና የደረጃ አሰጣጥ ደረጃን ማንቃት (+200-500ms/req ይጨምራል) |
rerankProviderModel |
string | null |
null |
የእንደገና ደረጃ አሰጣጥ አቅራቢ/ሞዴል በprovider/model ቅርጸት |
vectorStore |
"sqlite-vec" | "qdrant" | "auto" |
"auto" |
የትኛውን የvector backend መጠቀም እንዳለበት |
እነዚህ በGET /PUT /api/settings/memory (schema MemorySettingsExtendedSchema) በኩል ተደራሽ ተደርገዋል።
ለremote ምንጭ፣ Memory አማራጭ የሆኑትን customBaseUrl እና
customModelId ቅንብሮችም ይቀበላል። እነዚህ በአንድነት ዓለም አቀፉን የembedding registry
ሳይቀይሩ OpenAI-ተኳኋኝ የ/embeddings endpoint እና ሞዴል ይመርጣሉ። endpoint ጥቅም ላይ
ከመዋሉ በፊት መደበኛ ቅርጽ ይሰጠዋል፣ እና በአቅራቢው የወጪ URL ፖሊሲ ይፈተሻል፦ HTTP(S)
ያስፈልጋል፣ የተካተቱ የመግቢያ ማረጋገጫዎች እና query strings ውድቅ ይደረጋሉ፣ እንዲሁም
የcloud-metadata አድራሻዎች እንደታገዱ ይቆያሉ። ባዶ እሴቶች የተመረጠውን የregistry አቅራቢ
እንዳለ ያቆዩታል። ወደ dashboard የሚመለሱ ስህተቶች ሚስጥራዊ መረጃ እንዳያካትቱ
ይጣራሉ፣ እና የendpoint የመግቢያ ማረጋገጫዎች ፈጽሞ አይመዘገቡም።
TODO (D20): የ
globalscope (በሁሉም API keys መካከል ማህደረ ትውስታዎችን መጋራት) በዚህ ልቀት ውስጥ አልተተገበረም። የschema ለውጦችን እና ዓለም አቀፍ የretrieval መንገድን ይፈልጋል። ለብቻው ይከታተሉት።
የማከማቻ ንብርብሮች
ዋና፦ SQLite (memories table)
በmigration 015_create_memories.sql የተፈጠረ፦
| ዓምድ | ዓይነት | ማስታወሻዎች |
|---|---|---|
id |
TEXT PRIMARY KEY |
በcrypto.randomUUID() የሚፈጠር UUID |
api_key_id |
TEXT NOT NULL |
ባለቤት የሆነው API key |
session_id |
TEXT |
አማራጭ የውይይት-ተኮር scope |
type |
TEXT NOT NULL |
ከfactual፣ episodic፣ procedural፣ semantic አንዱ |
key |
TEXT |
የተረጋጋ upsert key፣ ለምሳሌ preference:i_prefer_python |
content |
TEXT NOT NULL |
ትክክለኛው የእውነታ ጽሑፍ |
metadata |
TEXT |
JSON blob (category, extractedAt, source, ...) |
created_at / updated_at |
TEXT |
ISO 8601 strings |
expires_at |
TEXT |
አማራጭ የማብቂያ ጊዜ፤ NULL ቋሚ ማለት ነው |
memory_id |
INTEGER UNIQUE |
UUIDs ↔ FTS5 rowids ለማገናኘት በ023_fix_memory_fts_uuid.sql የታከለ |
Indexes፦ api_key_id፣ session_id፣ type፣ expires_at፣ እንዲሁም ልዩ
የmemory_id index።
የUpsert ባህሪ፦ createMemory() ተመሳሳይ (api_key_id, key) ያለውን ነባር row
ይፈልጋል፣ ሲያገኘውም በቦታው ላይ ያዘምነዋል (metadataን በshallow spread
በማዋሃድ)። ይህ ተደጋጋሚ የምርጫ መግለጫዎች ሲኖሩ table ያለገደብ እንዳያድግ
ያደርጋል።
የሙሉ ጽሑፍ ፍለጋ (memory_fts virtual table)
022_add_memory_fts5.sql በcontent እና key ላይ FTS5 virtual table ይፈጥራል።
023_fix_memory_fts_uuid.sql የUUID primary key ከFTS5 integer rowid ጋር የማይገናኝበትን
በተግባር የታየ ስህተት ያስተካክላል — migration የmemory_id ዓምድን ይጨምራል፣
የFTS tableን እንደገና ይፈጥራል፣ እና INSERT፣ DELETE እና UPDATE ሲደረጉ FTSን
የተመሳሰለ እንዲያቆዩ የሚያደርጉ triggers
(memory_fts_ai, memory_fts_ad, memory_fts_au) ያገናኛል።
በretrieval.ts ውስጥ ለsemantic እና hybrid strategies ጥቅም ላይ ይውላል
(ከታች ይመልከቱ)። የretrieval code በhasTable("memory_fts") ማረጋገጫ ያደርጋል፣
እና የFTS table ከሌለ ወይም የFTS query ስህተት ካስነሳ ወደ ቅደም ተከተላዊ የጊዜ
አደራደር ይመለሳል።
አማራጭ፦ Qdrant (vector store tier 2)
src/lib/memory/qdrant.ts እንደ tier 2 vector store አማራጭ የQdrant ውህደትን
ይተገብራል። Retrieval ወደ Qdrant የሚመራው የengine selector
memoryVectorStore === "qdrant" ሲሆን ብቻ ነው — ነባሪው "auto" (እና
"sqlite-vec") Qdrantን ፈጽሞ አይመርጥም። የEngine-tab toggle ሁለቱንም
qdrantEnabled እና memoryVectorStore በአንድነት ያቀናብራል፦ ማንቃት Qdrantን
ዋና store ያደርገዋል፣ ማሰናከል ደግሞ ወደ "auto" ይመልሰዋል (#5597 — ከዚያ
ማስተካከያ በፊት ምንም ነገር የengine selectorን ስለማይጽፍ ማንቃቱ ውጤት አልነበረውም)።
Qdrant የማይደረስ ከሆነ ወይም ምንም ውጤት ካልመለሰ፣ retrieval ወደ
sqlite-vec → FTS5 ይመለሳል።
upsertSemanticMemoryPoint()— በተዋቀረው embedding modelkey + content-ን embed ያደርጋል፣ collection-ው መኖሩን ያረጋግጣል (በመጀመሪያ አጠቃቀም cosine-distance vectors ይፈጥራል)፣ እና payload{memoryId, apiKeyId, sessionId, key, content, metadata, createdAtUnix, expiresAtUnix}ያለውን point upsert ያደርጋል።searchSemanticMemory(query, topK, scope)— query-ውን embed ያደርጋል፣ በkind = "omniroute_memory"እና እንደ አማራጭ በapiKeyId/sessionIdየተጣራውን collection ይፈልጋል።topK-ን በ[1, 20]ውስጥ ይገድባል።deleteSemanticMemoryPoint(id)— አንድ point ይሰርዛል። የSQLite row ከተወገደ በኋላ በdeleteMemory()ይጠራል (D15)።cleanupSemanticMemoryPoints({retentionDays})—expiresAtUnixጊዜው ያለፈ ወይምcreatedAtUnixከretention cutoff በላይ ያረጀባቸውን points በጅምላ ይሰርዛል። dashboard-ው ትክክለኛዎቹን ቁጥሮች ማሳየት እንዲችል መጀመሪያ ይቆጥራል።checkQdrantHealth()— latencyን ያካተተGET /readyzየጤንነት ምርመራ።
የsettings UI የQdrant config፣ የጤንነት ምርመራ፣ የsemantic search ሙከራ እና cleanupን በ/dashboard/memory Engine tab ውስጥ ያቀርባል። በsrc/app/api/settings/qdrant/ ስር ያሉት ተጓዳኝ routes ከv3.8.6 ጀምሮ ሁሉም ተገናኝተዋል፦
| Route | ዘዴ | መግለጫ |
|---|---|---|
/api/settings/qdrant |
GET / PUT |
የQdrant settingsን ማንበብ / ማዘመን |
/api/settings/qdrant/health |
GET |
የLiveness ምርመራ + latency |
/api/settings/qdrant/search |
POST |
የSemantic search ሙከራ |
/api/settings/qdrant/cleanup |
POST |
ጊዜያቸው ያለፈ / ያረጁ pointsን ማስወገድ |
/api/settings/qdrant/embedding-models |
GET |
ያሉትን embedding models መዘርዘር |
የባህሪ ማስታወሻዎች (ምን እንደሚጠበቅ)፦
- Engine selection — በEngine tab ውስጥ Qdrantን ማንቃት ዋናው store ያደርገዋል (
memoryVectorStore="qdrant"ያዘጋጃል)፤ ማሰናከል ወደ"auto"ይመልሰዋል (#5597)። - No back-fill — Qdrant ከነቃ በኋላ የተፈጠሩ/የተዘመኑ memories ብቻ ወደ እሱ ይጻፋሉ (fire-and-forget dual-write)። ቀድሞ የነበሩ SQLite memories አይዛወሩም፤ "Reindex Now" የsqlite-vec indexን ብቻ ነው እንደገና የሚገነባው፣ Qdrantን አይደለም።
- Vector dimension በራስ-ሰር ይለያል፤ ይህም በመጀመሪያ አጠቃቀም ከትክክለኛው embedding ይወሰዳል — የሚሞላ dimension field የለም። collection ከተፈጠረ በኋላ embedding modelን መቀየር በራስ-ሰር አይስተናገድም፦ ያለው collection ሳይነካ ይቀራል፣ dimension የማይዛመድባቸው writes/searches ይሳናሉ እና ወደ sqlite-vec fallback ያደርጋሉ። embeddersን ለመቀየር collection-ውን እንደገና ይፍጠሩ (አዲስ ስም ይጠቀሙ ወይም በQdrant ውስጥ ይሰርዙት)።
- Distance metric — ሁልጊዜ Cosine ነው (collection ሲፈጠር hardcoded ነው፤ ሊዋቀር አይችልም)።
- Auth — API key ብቻ (እንደ
api-keyheader ይላካል፤ authentication ለማይጠቀም local Docker አማራጭ ነው)። JWT/RBAC ጥቅም ላይ አይውሉም። - Config fields — UI-ው
host፣port፣collection፣embeddingModel፣apiKeyን ያቀርባል።vectorSize/hnswEfConstructበenv/DB ብቻ ይገኛሉ፣ እናvectorSizecollectionን ለመፍጠር ጥቅም ላይ አይውልም (dimension-ው ከembedding ይመጣል)።
Vector quantization (int8 — በምርጫ የሚነቃ፣ ለሁለቱም backends)
ሁለቱም vector backends የተከማቹ vectors የmemory footprintን ለመቀነስ (~ከFloat32 4× ያነሰ) በትንሽ የrecall ኪሳራ በምርጫ የሚነቃ int8 quantization ይደግፋሉ። በሁለቱም ላይ default-ው off ነው — በግልጽ ካልነቃ vectors ሙሉ precision ይዘው ይቆያሉ።
| Backend | Setting | ዓይነት | Default | የሚነበብበት ቦታ |
|---|---|---|---|---|
| Qdrant | qdrantQuantization (DB key) |
"none" | "int8" | "binary" |
"none" |
src/lib/memory/qdrant.ts::normalizeQdrantConfig() |
| sqlite-vec | MEMORY_VEC_QUANTIZATION (env) |
"none" | "int8" |
"none" |
src/lib/memory/vectorStore.ts::requestedVecQuantization() |
- Qdrant በ
qdrantQuantizationsetting key በኩል ለእያንዳንዱ instance ይዋቀራል (በPUT /api/settings/qdrantላይ እንደquantizationfield ይቀርባል)።"int8"ሲሆን፣buildQuantizationConfig()scalar quantization (always_ram፣ quantile0.99) ይጠይቃል፣ እና ሙሉ-precision vectors የint8 candidate setን እንዲያጣሩ searchesrescore: trueን ያነቃሉ። - sqlite-vec quantization በenvironment ብቻ ነው (የDB setting አይደለም)፦ local vectorsን በ
vec_quantize_int8(?, 'unit')በኩል እንደint8[dim]column ለማከማቸትMEMORY_VEC_QUANTIZATION=int8ን ያዘጋጁ። የተመረጠው mode በembedding_signatureውስጥ (:int8suffix) ይካተታል፤ ስለዚህ modesን መቀየር የvec_memoriestable ሙሉ reindexን ያስነሳል — embedding model ሲቀየር ጥቅም ላይ ከሚውለው lazy-backfill path ጋር ተመሳሳይ ነው።
የማህደረ ትውስታ ዓይነቶች
MemoryType (src/lib/memory/types.ts):
| ዓይነት | ጥቅም ላይ የሚውለው |
|---|---|
factual |
ምርጫዎች፣ የማይለዋወጡ የተጠቃሚ መረጃዎች፣ የባህሪ ቅጦች |
episodic |
ከተወሰነ ጊዜ ጋር የተያያዙ ውሳኔዎች ("I chose Postgres") |
procedural |
የሥራ ሂደት / እንዴት-እንደሚደረግ ማህደረ ትውስታ (የተያዘ፤ በአሁኑ ጊዜ ራስ-ሰር አውጪ የለም) |
semantic |
ለ vector-store ግቤቶች የተያዘ |
የMemoryConfig ማምጫ ስልት ከexact፣ semantic፣ ወይም hybrid አንዱ ሲሆን፣
ወሰኑም ከsession፣ apiKey፣ ወይም global አንዱ ነው። ከ
getMemorySettings() የሚመጣው ነባሪ ወሰን apiKey ነው።
የእውነታ ማውጣት (extraction.ts)
ማውጣቱ በregex ላይ የተመሠረተ እንጂ በLLM ላይ የተመሠረተ አይደለም — በሂደቱ ውስጥ
በsetImmediate() ይሠራል፣ ስለዚህ የምላሽ ዥረቱን ፈጽሞ አያግድም፦
- የምርጫ ቅጦች →
MemoryType.FACTUAL(ለምሳሌI prefer …፣I really like …፣my favorite is …፣I hate …) - የውሳኔ ቅጦች →
MemoryType.EPISODIC(ለምሳሌI'll use …፣I chose …፣I went with …፣I'm going to adopt …) - የልማድ ቅጦች →
MemoryType.FACTUAL(ለምሳሌI usually …፣I always …፣I tend to …)
እያንዳንዱ ተዛማጅ ይጸዳል (trim፣ የነጭ ቦታ ማጣበቅ፣ እስከ 500 ቁምፊዎች
መገደብ)፣ በቋሚ factKey(category, content) አማካኝነት በቡድኑ ውስጥ
የተደጋገሙት ይወገዳሉ፣ እና በcreateMemory() በኩል ከ
{category, extractedAt, source: "llm_response"} ሜታዳታ ጋር ይከማቻሉ። የግቤት ጽሑፉ
በ64 KiB (MAX_EXTRACTION_TEXT_LENGTH) ይገደባል — ከዚህ በላይ ሲሆን፣
በቅርብ ጊዜ የተፈጠረው የረዳት ይዘት ሁልጊዜ እንዲካተት የጽሑፉ መጨረሻ ጥቅም ላይ ይውላል።
extractFactsFromText(text) ለሙከራዎች ወደ ውጭ ይላካል፣ እና ሳያከማቻቸው
የተዋቀሩትን እውነታዎች ይመልሳል።
ማምጣት (retrieval.ts)
retrieveMemories(apiKeyId, config) ዋናው የመግቢያ ነጥብ ነው። ይህ፦
- ውቅሩን በ
MemoryConfigSchemaበኩል መደበኛ ያደርገዋል እና ያረጋግጠዋል። enabledfalse ሲሆን ወይምmaxTokens <= 0ሲሆን ወዲያውኑ[]ይመልሳል።maxTokensን በ[1, 8000]ክልል ውስጥ ይገድባል።- የቆዩ የውሂብ ጎታዎች እንደቀድሞው መሥራታቸውን እንዲቀጥሉ፣ ዘመናዊው
memoriesሰንጠረዥ መኖሩን (ከቀድሞውmemoryሰንጠረዥ ጋር በማነጻጸር) ይለያል። - የማብቂያ ጊዜ ጥበቃ
(
expires_at IS NULL OR datetime(expires_at) > datetime('now'))፣ አማራጭ የክፍለ-ጊዜ ወሰን፣ እና አማራጭ የretentionDaysመቁረጫ ያለውን መሠረታዊ ጥያቄ ይገነባል። - በስልቱ መሠረት ቅርንጫፍ ይመርጣል፦
exact(ነባሪ)፦ በጊዜ ቅደም ተከተልORDER BY created_at DESC LIMIT 100።semantic፦config.queryካለ እናmemory_ftsካለ፣memory_fts MATCH ?ን JOIN አድርጎ በFTS ደረጃ ያዛል፤ FTS 0 ረድፎችን ሲመልስ ወደ ጊዜ ቅደም ተከተል ይመለሳል።hybrid፦ የFTS ውጤቶችን (ከፍተኛ ተዛማጅነት ያላቸውን) እና በጊዜ ቅደም ተከተል የተዘጋጀውን ስብስብ ያዋህዳል፣ በid የተደጋገሙትንም ያስወግዳል።
- ጥያቄ ሲቀርብ በ
content፣key፣ እናmetadataJSON ላይ የቁልፍ ቃል ተዛማጅነት ውጤት (getRelevanceScore) ያሰላል። ውጤታቸው ዜሮ የሆኑ ረድፎች ይጣራሉ። - በውጤት ከከፍተኛ ወደ ዝቅተኛ፣ ከዚያም በ
createdAtከአዲስ ወደ አሮጌ ይደረድራል። - በደረጃ የተደረደረውን ዝርዝር በተከታታይ በማለፍ፣ እየተደመረ የሚሄደው
estimateTokens(content)(≈length / 4) ከበጀቱ በታች እስከቆየ ድረስ ግቤቶችን ይቀበላል። ማንኛውም ተዛማጅ ሲኖር ሁልጊዜ ቢያንስ አንድ ግቤት ይመልሳል።
estimateTokens ወደ ውጭ ይላካል፣ እና በማምጣት፣ በማጠቃለል፣ እና በMCP
omniroute_memory_search መሣሪያ ጥቅም ላይ ይውላል።
ማስገባት (injection.ts)
injectMemory(request, memories, provider):
- ሁሉንም የማህደረ ትውስታ ይዘቶች ወደ አንድ
Memory context: …ሕብረቁምፊ ያጣምራል። - በአቅራቢው ስም መሠረት ስልት ይመርጣል፦
- የስርዓት መልዕክት (ለOpenAI፣ Anthropic፣ Gemini፣ … ነባሪ) — የተጠቃሚው የስርዓት መጠየቂያዎች አሁንም ቅድሚያ እንዲኖራቸው፣
{role: "system", content: memoryText}ን ከማናቸውም ነባር የስርዓት መልዕክቶች በፊት ያስገባል። - የተጠቃሚ መልዕክት (የመጠባበቂያ አማራጭ) — በ
PROVIDERS_WITHOUT_SYSTEM_MESSAGEውስጥ ላሉ አቅራቢዎች፦o1፣o1-mini፣o1-preview፣glm፣glmt፣glm-cn፣zai፣qianfan። እነዚህ የስርዓት ሚናውን ውድቅ ያደርጋሉ፤ አለበለዚያ 400 ስህተት ይመልሳሉ (ለGLM/Zhipu issue #1701ን ይመልከቱ)።
- የስርዓት መልዕክት (ለOpenAI፣ Anthropic፣ Gemini፣ … ነባሪ) — የተጠቃሚው የስርዓት መጠየቂያዎች አሁንም ቅድሚያ እንዲኖራቸው፣
- ብዛቱን፣ ስልቱን እና ሞዴሉን በ
memory.injection.injectedስር ይመዘግባል።
providerSupportsSystemMessage(provider) የራሳቸውን የማዘዋወር ውሳኔዎች ማድረግ ለሚያስፈልጋቸው
ጠሪዎች ወደ ውጭ ይላካል። ያልታወቁ አቅራቢዎች ለደህንነት ሲባል በነባሪ true
(የስርዓት ሚና የተፈቀደ) ይጠቀማሉ።
ቅንብሮች (settings.ts)
የማህደረ ትውስታ ውቅር በenv vars ውስጥ ሳይሆን በDB ቅንብሮች ሰንጠረዥ ውስጥ ይከማቻል።
getMemorySettings() ከgetSettings() ያነባል እና ውጤቱን
በሂደቱ ውስጥ በመሸጎጫ ያስቀምጣል፤ ከመጻፍ በኋላ በቅንብሮች PUT
መስመር invalidateMemorySettingsCache() ይጠራል።
የቆዩ መስኮች (ሁሉም ስሪቶች)
| DB ቁልፍ | ዓይነት | ነባሪ | የUI መቆጣጠሪያ |
|---|---|---|---|
memoryEnabled |
boolean | false (ከv3.8.30 ጀምሮ በነባሪ ጠፍቷል) |
ማህደረ ትውስታ ማብራት/ማጥፋት |
memoryMaxTokens |
integer | 2000 (ክልል 0–16000) |
ለማስገባት የቶከን በጀት |
memoryRetentionDays |
integer | 30 (ክልል 1–365) |
የማቆያ ጊዜ መስኮት |
memoryStrategy |
enum | "hybrid" (ከrecent፣ semantic፣ hybrid አንዱ) |
የሰርስሮ ማውጣት ስልት |
skillsEnabled |
boolean | false |
በቁልፍ የሚደረግ የክህሎት ማስገባትን ያበራል/ያጠፋል (SKILLS.mdን ይመልከቱ) |
ማስታወሻ፦ የUI ስልት "recent" በtoMemoryRetrievalConfig() በኩል ወደ ውስጣዊው "exact" የሰርስሮ ማውጣት
ስልት ይዛመዳል (በጊዜ ቅደም ተከተል)።
አዲስ መስኮች (v3.8.6፣ plan 21 D9)
ለመስኮች መግለጫዎች ከላይ ያለውን "የቅንብሮች ቅጥያ" ክፍልም ይመልከቱ።
| DB ቁልፍ | የAPI መስክ | ነባሪ |
|---|---|---|
memoryEmbeddingSource |
embeddingSource |
"auto" |
memoryEmbeddingModel |
embeddingProviderModel |
null |
memoryTransformersEnabled |
transformersEnabled |
false |
memoryStaticEnabled |
staticEnabled |
false |
memoryRerankEnabled |
rerankEnabled |
false |
memoryRerankModel |
rerankProviderModel |
null |
memoryVectorStore |
vectorStore |
"auto" |
ከQdrant ጋር የተያያዙ DB ቁልፎች (qdrantEnabled፣ qdrantHost፣ qdrantPort፣
qdrantApiKey፣ qdrantCollection ነባሪ "omniroute_memory"፣
qdrantEmbeddingModel ነባሪ "openai/text-embedding-3-small") በ
qdrant.ts ውስጥ ባለው normalizeQdrantConfig() ይነበባሉ።
የአካባቢ ተለዋዋጮች (v3.8.6)
ስድስት አማራጭ env vars የኤንጂኑን የአሂድ ጊዜ ባህሪ ያስተካክላሉ (በ.env.example ውስጥ ተመዝግበዋል)፦
| ተለዋዋጭ | ነባሪ | መግለጫ |
|---|---|---|
MEMORY_EMBEDDING_CACHE_TTL_MS |
300000 |
የembedding መሸጎጫ TTL (5 ደቂቃ) |
MEMORY_EMBEDDING_CACHE_MAX |
1000 |
በembedding LRU መሸጎጫ ውስጥ ከፍተኛው የግቤቶች ብዛት |
MEMORY_TRANSFORMERS_MODEL |
Xenova/all-MiniLM-L6-v2 |
ለTransformers.js ሞዴል የHF ማከማቻ |
MEMORY_STATIC_MODEL |
minishlab/potion-base-8M |
ለስታቲክ potion ሞዴል የHF ማከማቻ |
MEMORY_STATIC_CACHE_DIR |
<DATA_DIR>/embeddings |
የወረዱ ሞዴሎች የሚከማቹበት |
MEMORY_VEC_TOP_K |
20 |
ለvector ፍለጋ ነባሪ top-K |
MEMORY_RRF_K |
60 |
ለhybrid ፍለጋ የRRF k ቋሚ |
MEMORY_VEC_QUANTIZATION |
none |
የአካባቢያዊ sqlite-vec vectorsን በquantized መልክ ለማከማቸት ወደ int8 ያቀናብሩ (~4× ያነሰ፤ በምርጫ የሚነቃ)። ሁነታውን መቀየር ዳግም መጠቆምን ያስገድዳል። |
ማጠቃለያ (summarization.ts)
summarizeMemories(apiKeyId, sessionId?, maxTokens = 4000) በአንድ ቁልፍ ትውስታዎች ውስጥ ያለው አጠቃላይ የቶከን ብዛት ከተመደበው ገደብ ሲያልፍ የቆየውን
ይዘት ያመቃል። ረድፎቹን በcreated_at መሠረት DESC ቅደም ተከተል ይዞ ይደጋገማል፣ ከገደቡ ጋር የሚጣጣሙትን ረድፎች ያቆያል፣ ለቀሩት ደግሞ
contentን በቦታው በዋናው ይዘት የመጀመሪያ ሦስት ዓረፍተ ነገሮች ይተካል። tokensSaved በድሮው እና
በአዲሱ ይዘት መካከል ያለው የestimateTokens ልዩነት ነው።
ይህ ሂደት ይገኛል፣ ነገር ግን አሁን ባለው የውይይት ፓይፕላይን ውስጥ በራስ-ሰር አይጠራም — ቀጣይነት ያለው ማመቅ ካስፈለገዎት ከcron፣ ከአስተዳዳሪ ድርጊት ወይም
ከMemoryConfig.autoSummarize ማገናኛ ይጥሩት። የውሂብ
መጥፋቱ የአንድ አቅጣጫ ነው፤ ዋናው ጽሑፍ ተደርቦ ይጻፋል።
REST API
ሁሉም መዳረሻዎች የአስተዳደር ማረጋገጫ (requireManagementAuth) ይፈልጋሉ።
ዋና የትውስታ መዳረሻዎች (ነባር + የተዘመኑ)
| ዘዴ | ዱካ | መግለጫ |
|---|---|---|
GET |
/api/memory |
ገጽ የተከፋፈለ ዝርዝር ከማጣሪያዎች ጋር፦ apiKeyId፣ type፣ sessionId፣ q፣ limit፣ page፣ offset። ምላሹ stats.total፣ stats.tokensUsed፣ stats.hitRate፣ cacheStatsን ያካትታል |
POST |
/api/memory |
ግቤት ይፍጠሩ (በZod የተረጋገጠ፦ content፣ key፣ አማራጭ type፣ sessionId፣ apiKeyId፣ metadata፣ expiresAt)። በ(apiKeyId, key) ላይ upsert የሚያደርገውን createMemory() ይጠራል |
GET |
/api/memory/[id] |
በUUID አንድ ግቤት ያምጡ |
PUT |
/api/memory/[id] |
የግቤቱን መስኮች (type፣ key፣ content፣ metadata) ያዘምኑ። አካል፦ MemoryUpdatePutSchema። የembedding ምንጭ ካለ ቬክተሩንም ያመሳስላል። |
DELETE |
/api/memory/[id] |
ግቤትን ይሰርዙ፤ ከvec_memories (D15) እና ከQdrantም በሚቻለው መጠን ይሰርዛል። ካልተገኘ 404 ይመልሳል። |
GET |
/api/memory/health |
verifyExtractionPipeline("health-check")ን ያስኬዳል — ሙሉ ዑደት ፍጠር→ዘርዝር→ሰርዝ። {working, latencyMs, error?}ን ይመልሳል |
አዲስ የትውስታ ሞተር መዳረሻዎች (ዕቅድ 21)
| ዘዴ | ዱካ | መግለጫ |
|---|---|---|
POST |
/api/memory/retrieve-preview |
የretrieveMemories የሙከራ ሂደት — በውጤት ነጥብ፣ ደረጃ እና ቶከኖች የተሰናዱ ውጤቶችን ይመልሳል። አካል፦ RetrievePreviewSchema። ትውስታዎችን አያስገባም ወይም አያሻሽልም። |
GET |
/api/memory/embedding-providers |
የትኞቹ የተዋቀረ API ቁልፍ እንዳላቸው በማመልከት፣ አቅራቢዎችን ከembedding ሞዴሎች ጋር ይዘረዝራል። |
GET |
/api/memory/engine-status |
ሙሉ የሞተሩን ሁኔታ ይመልሳል፦ የቁልፍ ቃል ደረጃ፣ የembedding ውሳኔ፣ የቬክተር ማከማቻ ስታቲስቲክስ፣ የQdrant ጤና፣ የrerank ውቅር። ቅርጽ፦ MemoryEngineStatusSchema። |
POST |
/api/memory/summarize |
የትውስታ ማመቅን በእጅ ያስጀምሩ። አካል፦ MemorySummarizeSchema (olderThanDays፣ apiKeyId?፣ dryRun)። {candidates, tokensSaved}ን ይመልሳል። |
POST |
/api/memory/reindex |
needs_reindex=1 ላላቸው ትውስታዎች የቬክተር ዳግም መረጃ ጠቋሚ ማዘጋጀትን ያስጀምሩ። አካል፦ MemoryReindexSchema (force)። {started, pending}ን ይመልሳል። |
የቅንብሮች መዳረሻዎች
| ዘዴ | ዱካ | መግለጫ |
|---|---|---|
GET |
/api/settings/memory |
የአሁኑ ደረጃውን የጠበቀ MemorySettingsExtended (7 አዲስ መስኮች + የቆየ) |
PUT |
/api/settings/memory |
ከMemorySettingsExtendedSchema ውስጥ ማንኛውንም መስክ ያዘምኑ (በድምሩ 12 መስኮች) |
GET |
/api/settings/qdrant |
የአሁኑ የQdrant ቅንብሮች (QdrantSettingsSchema) |
PUT |
/api/settings/qdrant |
የQdrant ቅንብሮችን ያዘምኑ። አካል፦ QdrantSettingsUpdateSchema። apiKey = ባዶ ሕብረቁምፊ ቁልፉን ያስወግዳል። |
GET |
/api/settings/qdrant/health |
በተዋቀረው የQdrant አብነት ላይ የህያውነት ምርመራ ያካሂዳል። QdrantHealthResultSchemaን ይመልሳል። |
POST |
/api/settings/qdrant/search |
በQdrant ላይ የትርጉም ፍለጋ ሙከራ ያካሂዳል። አካል፦ QdrantSearchSchema (query፣ topK)። |
POST |
/api/settings/qdrant/cleanup |
ጊዜያቸው ላለፈ / ለቆዩ ትውስታዎች የQdrant ነጥቦችን ያስወግዱ። |
GET |
/api/settings/qdrant/embedding-models |
ለQdrant የሚገኙትን embedding ሞዴሎች ይዘርዝሩ። |
የ/api/memory ዝርዝር መጠይቅ በpage ላይ የተመሠረተ ገጽ ክፍፍልን
(parsePaginationParams) ወይም ጥሬ offsetን ይደግፋል — offset ካለ
ቅድሚያ ይወስዳል፣ እና ለምላሹ ቅርጽ የተሰላ page ይፈጠራል።
MCP መሣሪያዎች (open-sse/mcp-server/tools/memoryTools.ts)
MCP አገልጋዩ ሲነቃ፣ ሦስት የማህደረ ትውስታ መሣሪያዎች ይመዘገባሉ፦
omniroute_memory_search—{apiKeyId, query?, type?, maxTokens?, limit?}→retrieveMemories()ን ይጠቀልላል። ከv3.8.6 (D16) ጀምሮ፣strategyበቋሚነት ወደ"exact"ከመቀመጥ ይልቅ ከgetMemorySettings()ይነበባል።queryከቀረበ እናstrategysemanticወይምhybridከሆነ፣ ቬክተር ማከማቻው ሲኖር ጥቅም ላይ ይውላል።omniroute_memory_add—{apiKeyId, sessionId?, type, key, content, metadata?}→createMemory()ን ይጠቀልላል። 4ቱን መደበኛ ዓይነቶች ብቻ ይቀበላል፦factual፣episodic፣procedural፣semantic(D17)።omniroute_memory_clear—{apiKeyId, type?, olderThan?}→ የሚዛመዱ ግቤቶችን ይዘረዝራል፣ እንደ አማራጭ ከተወሰነ ጊዜ በፊት በተፈጠሩበት የጊዜ ማህተም ያጣራል፣ ከዚያም እያንዳንዱን በdeleteMemory()ይሰርዛል (ይህም ቬክተሮችን ከsqlite-vec + Qdrant ያስወግዳል)።
ስለ ማጓጓዣ እና ወሰን ዝርዝሮች MCP-SERVER.mdን ይመልከቱ።
ዳሽቦርድ (የማህደረ ትውስታ ስቱዲዮ)
src/app/(dashboard)/dashboard/memory/page.tsx አሁን ባለ3-ትር ስቱዲዮ ነው፦
ትር፦ ማህደረ ትውስታዎች
- የፅንሰ-ሐሳብ ካርድ (ሊታጠፍ የሚችል «እንዴት እንደሚሠራ» ማብራሪያ)።
- ቅጽበታዊ ዝርዝር፣ ፍለጋ እና ገጽ ክፍፍል (በ300 ms የዘገየ)።
- የዓይነት ማጣሪያ (
factual/episodic/procedural/semantic/ ሁሉም)። - የማህደረ ትውስታ ማከያ ሞዳል (ቁልፍ፣ ይዘት፣ ዓይነት)።
- በቦታው ላይ ማርትዕ (የእርሳስ አዝራር →
PUT /api/memory/[id])። - በየረድፉ መሰረዝ (ከማረጋገጫ መገናኛ ሳጥን ጋር)።
- የአሁኑን ገጽ ወደ JSON መላክ፤ በፋይል መራጭ በኩል JSON ማስገባት።
- የስታቲስቲክስ ካርዶች፦
totalEntries፣tokensUsed፣hitRate። - «የቆዩትን አጠቃልል» አዝራር →
POST /api/memory/summarize(በመጀመሪያ dry-run የዕጩዎችን ብዛት ያሳያል፣ ከዚያም ማረጋገጫ ይጠይቃል)። - በ
GET /api/memory/healthየሚመራ አረንጓዴ/ቀይ የጤና ነጥብ።
ትር፦ የሙከራ መድረክ
- የመጠይቅ ግቤት + የስልት መራጭ (ትክክለኛ / ትርጉማዊ / ድብልቅ) + የቶከን በጀት።
- «አስመስል» →
POST /api/memory/retrieve-preview— በደረጃ የተደረደሩ ውጤቶችን ከscore፣tier፣tokens፣vecScore፣ftsScoreጋር ያሳያል። - የትኛው የመክተቻ ምንጭ / ቬክተር ማከማቻ ጥቅም ላይ እንደዋለ እና የአማራጭ መመለሻ መከሰቱን የሚያሳይ የመፍትሔ ፓነል።
ትር፦ ሞተር
- የሞተር ሁኔታ ፓነል (የቁልፍ ቃል FTS5 ቺፕ፣ የመክተቻ ቺፕ፣ የቬክተር ማከማቻ ቺፕ፣ የQdrant ጤና ቺፕ፣ የድጋሚ ደረጃ አሰጣጥ ቺፕ)።
- «አሁን ዳግም አውጫ» አዝራር →
POST /api/memory/reindex። - የመክተቻ ምንጭ መራጭ (ራስ-ሰር / ሩቅ / የማይለወጥ / transformers + መቀያየሪያዎች)።
- የQdrant ውቅር ካርድ (የማንቃት መቀያየሪያ፣ አስተናጋጅ/ወደብ/ስብስብ/ቁልፍ፣ ግንኙነትን መሞከር፣ የትርጉማዊ ፍለጋ ሙከራ፣ ማጽዳት)።
- የድጋሚ ደረጃ አሰጣጥ ውቅር ካርድ (የማንቃት መቀያየሪያ፣ የአቅራቢ/ሞዴል መራጭ)።
የማህደረ ትውስታ እና Qdrant ቅንብሮች ለቀድሞው/ዓለም አቀፍ የቅንብሮች በይነገጽ
በ/dashboard/settings → Memory & Skills (MemorySkillsTab.tsx) ሥርም ይገኛሉ።
መሸጎጫ
src/lib/memory/store.ts ለgetMemory(id) ንባቦች በሂደት ውስጥ ያለ LRU-መሰል
መሸጎጫ (MEMORY_CACHE_TTL = 1 min፣ MEMORY_MAX_CACHE_SIZE = 500፣ 20 %
ከቆዩት መጀመሪያ በማስወጣት) ይይዛል፤ በተጨማሪም የራሳቸውን ወሰን ያለው መሸጎጫ
መጠቀም በሚፈልጉ ጠሪዎች የሚጠቀሙበት get/set/invalidate ሜተዶች ያሉት
አጠቃላይ የቁልፍ/እሴት memoryCache ንብርብር (src/lib/memory/cache.ts) አለው
(1 000-ግቤት LRU፣ ነባሪ TTL 5 min)።
ግላዊነት እና የሕይወት ዑደት
- የማህደረ ትውስታ ባለቤትነት የAPI ቁልፍ መለያ ነው (
resolveMemoryOwnerIdበchatCore.tsውስጥ)።apiKeyInfo.idከሌለ ሰርስሮ ማውጣትም፣ ማስገባትም ሆነ ማውጣጣት አይከናወንም። - ወደፊት የሚያልቅ
expires_atያላቸው ግቤቶች ከሰርስሮ ማውጣት ይጣራሉ፤ ከretentionDaysበላይ ያረጁ ግቤቶች በretrieveMemoriesውስጥ ባለውcreated_at >= cutoffአንቀጽ አይካተቱም። - ለቋሚ ስረዛ፣
DELETE /api/memory/[id]ወይምomniroute_memory_clearይጠቀሙ። - ማውጣጣት በ
setImmediateበኩል ውጤቱን ሳይጠብቅ ይከናወናል፤ አለመሳካቶች በmemory.extraction.background.failedስር ይመዘገባሉ እና ለጠሪው ፈጽሞ አይታዩም። - የማረጋገጫ ዙር-ጉዞዎች (
verifyExtractionPipeline) የራሳቸውን የሙከራ ግቤቶች በfinallyብሎክ ውስጥ ያጸዳሉ።
በተጨማሪ ይመልከቱ
- SKILLS.md — የ
skillsEnabledቅንብር ከማህደረ ትውስታ ጎን ለጎን የመሣሪያ ትርጓሜዎችን ያስገባል። - MCP-SERVER.md — የMCP ማጓጓዣ / ወሰኖች።
- API_REFERENCE.md — የበለጠ ሰፊ የAPI ወሰን።
- የምንጭ ሞጁሎች፦
src/lib/memory/types.ts,schemas.tssrc/lib/memory/store.ts,retrieval.ts,injection.ts,reindex.tssrc/lib/memory/extraction.ts,summarization.ts,verify.tssrc/lib/memory/settings.ts,qdrant.ts,cache.tssrc/lib/memory/vectorStore.ts— sqlite-vec + ዲቃላ RRFsrc/lib/memory/embedding/index.ts— ባለብዙ-ምንጭ የኢምቤዲንግ ንብርብርsrc/lib/memory/embedding/types.ts,remote.ts,staticPotion.ts,transformersLocal.ts,cache.tssrc/shared/schemas/memory.ts— ለሁሉም የማህደረ ትውስታ API አካሎች የZod ንድፎችsrc/shared/schemas/qdrant.ts— ለQdrant ቅንብሮች/ክዋኔዎች የZod ንድፎችsrc/lib/db/memoryVec.ts— ለmemory_vec_metaCRUDsrc/lib/db/migrations/015_create_memories.sql,022_add_memory_fts5.sql,023_fix_memory_fts_uuid.sql,083_memory_vec.sqlsrc/app/api/memory/route.ts,[id]/route.ts,health/route.tssrc/app/api/memory/retrieve-preview/route.tssrc/app/api/memory/engine-status/route.tssrc/app/api/memory/embedding-providers/route.tssrc/app/api/memory/summarize/route.tssrc/app/api/memory/reindex/route.tssrc/app/api/settings/memory/route.tssrc/app/api/settings/qdrant/route.ts+ ንዑስ-መስመሮችsrc/app/(dashboard)/dashboard/memory/— የStudio UI (ገጽ + ክፍሎች + ትሮች + hooks)open-sse/handlers/chatCore.ts(የማስገባት / የማውጣጣት ሽቦ አያያዝ)open-sse/mcp-server/tools/memoryTools.ts
የኢምቤዲንግ አቅራቢን መምረጥ (v3.8.16+)
የOmniRoute ማህደረ ትውስታ ሞተር አራት የኢምቤዲንግ ምንጮችን (src/lib/memory/embedding/) ይደግፋል። እያንዳንዳቸው በመዘግየት፣ ወጪ፣ የሞዴል ጥራት እና የማዋቀር ውስብስብነት ረገድ የተለያዩ ሚዛናዊ ምርጫዎች አሏቸው።
የኢምቤዲንግ ምንጮች
| አቅራቢ | ምንጭ | መዘግየት | ወጪ | ጥራት | ማዋቀር |
|---|---|---|---|---|---|
transformers |
አካባቢያዊ ONNX ሞዴል (Xenova/all-MiniLM-L6-v2) | ~50-150ms (CPU) | ነጻ | ጥሩ | npm install ብቻ |
static |
አስቀድሞ የተሰሉ ቬክተሮች (የተሸጎጡ) | <1ms | ነጻ | አይመለከተውም (በመሸጎጫ መገኘት ይወሰናል) | ምንም |
remote |
OpenAI / Cohere / Voyage API | ~100-300ms | $0.02-0.10/1M ቶከኖች | እጅግ በጣም ጥሩ | API ቁልፍ |
auto |
በአሂድ ጊዜ የሚገኘውን ምርጥ ምንጭ ይመርጣል | ከተመረጠው ምንጭ ጋር ተመሳሳይ | ነጻ | ከተመረጠው ምንጭ ጋር ተመሳሳይ | ምንም |
| (cache) | በማንኛውም ምንጭ ላይ ያለ የማህደረ ትውስታ ውስጥ LRU ንብርብር | <1ms (ሲገኝ)፣ ሙሉ መዘግየት (ሳይገኝ) | ነጻ | ከመሠረታዊው ጋር ተመሳሳይ | ሁልጊዜ ክፍት (ሊመረጥ የሚችል ምንጭ አይደለም) |
የውሳኔ ዛፍ
የማሰማሪያ አውድዎ ምንድን ነው?
│
┌───────────┼───────────┬──────────────┐
│ │ │ │
ልማት/ሙከራ አነስተኛ ፕሮድ ትልቅ ፕሮድ ጠርዝ / ከመስመር ውጭ
│ │ │ │
▼ ▼ ▼ ▼
transformers transformers remote (Qdrant) transformers
(ነጻ፣ API የለም) (ምርጥ ጥራት) (በይነመረብ የለም)
│ │ │ │
└────────┬──┴───────────┴──────────────┘
│
▼
ሁልጊዜ `cache` ንብርብርን ከላይ ያክሉ
(LruCache ማንኛውንም አቅራቢ ይጠቀልላል)
የውሂብ ጎታ እና API ውቅር
የማህደረ ትውስታ ኢምቤዲንግ አማራጮች የሚዋቀሩት በSettings API/UI በኩል እንጂ በአካባቢ ተለዋዋጮች አይደለም። በSettings ስር ያሉት አግባብነት ያላቸው የቅንብር ውሂብ ጎታ ቁልፎች (normalizeMemorySettings በsrc/lib/memory/settings.ts ውስጥ) እነዚህ ናቸው፦
memoryEmbeddingSource:"transformers"(አካባቢያዊ)፣"remote"(በAPI ላይ የተመሠረተ፣ ለምሳሌ OpenAI)፣"static"(ውጫዊ ማከማቻ)፣ ወይም"auto"memoryEmbeddingProviderModel: ለremote/static ምንጮች የሞዴል መለያ (ለምሳሌ፣"text-embedding-3-small")memoryTransformersEnabled:true|falsememoryStaticEnabled:true|falsememoryVectorStore:"sqlite-vec","qdrant", ወይም"auto"
አካባቢያዊ ሞዴል (transformers)
አካባቢያዊ ሞዴሎችን ለማስኬድ transformers.jsን በውስጥ ይጠቀማል፦
# በኮዱ ውስጥ የሚነበቡ የአካባቢ ተለዋዋጮች (src/lib/memory/embedding/index.ts):
MEMORY_TRANSFORMERS_MODEL=Xenova/all-MiniLM-L6-v2 # የHF ሞዴል ማከማቻ
MEMORY_STATIC_MODEL=minishlab/potion-base-8M # የHF static potion ሞዴል
MEMORY_STATIC_CACHE_DIR=<DATA_DIR>/embeddings # የመሸጎጫ ማውጫ
የLRU ኢምቤዲንግ መሸጎጫ
መሸጎጫው በነባሪነት ሁልጊዜ ክፍት ሲሆን በአካባቢ ተለዋዋጮች በኩል ይዋቀራል፦
MEMORY_EMBEDDING_CACHE_MAX=1000 # ከፍተኛው የተሸጎጡ ንጥሎች ብዛት
MEMORY_EMBEDDING_CACHE_TTL_MS=300000 # TTL (5 ደቂቃ)
የአፈጻጸም ቁጥሮች
በተለመደ ባለ 4-ኮር x86 ሰርቨር ላይ የተደረገ የአፈጻጸም መለኪያ (እያንዳንዱ ጽሑፍ ~100 ቶከኖች)፦
| አቅራቢ | p50 | p95 | p99 | የ1M embeddings ወጪ |
|---|---|---|---|---|
transformers (CPU) |
80ms | 180ms | 350ms | ነጻ |
remote (OpenAI) |
120ms | 220ms | 400ms | ~$0.02 (ada-002) / $0.13 (3-large) |
static (Qdrant) |
15ms | 30ms | 60ms | በQdrant ማስተናገጃ ላይ ይወሰናል |
cache (የተገኘ) |
<1ms | <1ms | 2ms | ነጻ |
የእውነታ ማውጣት ንድፎች (v3.8.16+)
የextraction.ts ሞጁል (src/lib/memory/extraction.ts) ከውይይት መልዕክቶች የተዋቀሩ እውነታዎችን ለማውጣት የregex ንድፍ ማዛመድን ይጠቀማል። እነዚህን ንድፎች መረዳት ለአጠቃቀም ሁኔታዎ የማውጣት ጥራትን እንዲያስተካክሉ ይረዳዎታል።
ነባሪ የንድፍ ምድቦች
| ምድብ | የንድፍ ምሳሌ | የሚይዘው |
|---|---|---|
| PREFERENCE_PATTERNS | "I prefer <X>", "I like <X>", "I hate <X>" |
የተጠቃሚ ምርጫዎች |
| DECISION_PATTERNS | "I'll use <X>", "I decided to <X>", "I went with <X>" |
የተጠቃሚ ውሳኔዎች (ክስተታዊ) |
| PATTERN_PATTERNS | "I usually <X>", "I always <X>", "I never <X>" |
ቀጣይነት ያላቸው የባህሪ ንድፎች |
የንድፍ ምሳሌዎች (ቀለል የተደረጉ)
// ከ src/lib/memory/extraction.ts
const PREFERENCE_PATTERNS = [
/\bI\s+(?:really\s+)?prefer\s+([^.,\n]+)/gi,
/\bI\s+(?:really\s+)?like\s+([^.,\n]+)/gi,
/\bI\s+(?:hate|dislike|avoid)\s+([^.,\n]+)/gi,
];
const DECISION_PATTERNS = [
/\bI'?(?:ll|will)\s+use\s+([^.,\n]+)/gi,
/\bI\s+(?:have\s+)?decided\s+(?:to\s+)?([^.,\n]+)/gi,
];
const PATTERN_PATTERNS = [/\bI\s+usually\s+([^.,\n]+)/gi, /\bI\s+always\s+([^.,\n]+)/gi];
ምን ይወጣል
አንድ ተጠቃሚ እንዲህ ሲል፦
"TypeScriptን እመርጣለሁ። ለዚህ ፕሮጀክት Postgresን እጠቀማለሁ። ከመግፋቴ በፊት ሁልጊዜ commit አደርጋለሁ። Pythonን አልወድም።" ማውጣቱ 4 ትውስታዎችን ያመነጫል፦
ቁልፍ ምድብ ዓይነት ይዘት preference:typescriptምርጫ እውነታዊ "TypeScript" decision:postgres_for_this_projectውሳኔ ክስተታዊ "Postgres ለዚህ ፕሮጀክት" pattern:commit_before_pushingንድፍ እውነታዊ "ከመግፋት በፊት commit ማድረግ" preference:pythonምርጫ እውነታዊ "Python"
የማውጣት ገደቦች
ከቁጥጥር ውጪ የሆነ ማውጣትን ለመከላከል፣ የሚከተሉት ገደቦች ተፈጻሚ ይሆናሉ፦
| ዝቅተኛው የይዘት ርዝመት | 3 ቁምፊዎች | | ከፍተኛው የይዘት ርዝመት | 500 ቁምፊዎች |
ማውጣትን መቼ ማሰናከል እንዳለብዎት
ትውስታ በነቃ ቁጥር ማውጣቱ በራስ-ሰር ይሠራል፤ የተለየ
ማውጣት-ብቻ መቀያየሪያ የለም። ለማጥፋት፣ ትውስታን ሙሉ በሙሉ ያሰናክሉ (enabled: false
በPUT /api/settings/memory በኩል)። በሚከተሉት ሁኔታዎች ይህን ማድረግ ያስቡበት፦
- ከፍተኛ የመልዕክት መጠን ሲኖርዎት እና የማውጣቱ ወጪ ቀላል የማይባል ሲሆን
- ውይይቶችዎ አብዛኛውን ጊዜ ጊዜያዊ (ውይይት፣ ማረም) እና የረጅም ጊዜ ዋጋ የሌላቸው ሲሆኑ
- አውድን አስቀድመው በብጁ ተሰኪዎች እየመዘገቡ ከሆነ
የድብልቅ RRF ማስተካከያ (v3.8.16+)
የReciprocal Rank Fusion (RRF) ስልተ ቀመር የFTS5 (ቁልፍ ቃል) እና የvector (ትርጉማዊ) ውጤቶችን ያጣምራል። የk መለኪያ ዝቅተኛ ደረጃ ላላቸው ውጤቶች ምን ያህል ክብደት እንደሚሰጥ ይቆጣጠራል።
ቀመሩ
ለእያንዳንዱ እጩ ትውስታ፣ የRRF ነጥብ፦
RRF(d) = Σ 1 / (k + rank_i(d))
ይህም፦
kቋሚው ነው (ነባሪ 60)rank_i(d)በiኛው የመልሶ ማግኛ ሥርዓት (FTS፣ vector) ውስጥ የሰነድdደረጃ ነው- ድምሩ በሁሉም የመልሶ ማግኛ ሥርዓቶች ላይ ይከናወናል
k ውጤቶችን እንዴት እንደሚነካ
የk ዋጋ |
ተጽዕኖ | ተስማሚ የሆነው |
|---|---|---|
k=0 |
ንጹሕ የደረጃ ውህደት (ማለስለስ የለም) | የንድፈ ሐሳብ መነሻ |
k=10-30 |
ከፍተኛ ውጤቶችን በከፍተኛ ሁኔታ ይመዝናል፣ ዝቅተኛ ደረጃ ያለው የሚያበረክተው በጣም ትንሽ ነው | ከፍተኛዎቹ 3 ውጤቶች ብዙውን ጊዜ ትክክል ሲሆኑ |
k=60 (ነባሪ) |
ሚዛናዊ — ከፍተኛዎቹ 10 ውጤቶች ሁሉ ትርጉም ባለው ሁኔታ ያበረክታሉ | ለአጠቃላይ ዓላማ መልሶ ማግኘት |
k=100+ |
ይበልጥ ጠፍጣፋ — ዝቅተኛ ደረጃ ያላቸው ውጤቶች እንኳ በብዙ ሥርዓቶች ውስጥ ከታዩ የበላይ ሊሆኑ ይችላሉ | recall > precision ወሳኝ በሚሆንበት ጊዜ |
kን በተግባር ማስተካከል
# ነባሪ
MEMORY_RRF_K=60
# ከፍተኛ precision (አነስተኛ ትውስታ፣ ጥቂት ሰነዶች)
MEMORY_RRF_K=20
# ከፍተኛው recall (ትልቅ ትውስታ፣ የተለያዩ ጥያቄዎች)
MEMORY_RRF_K=120
k=20 ያለው ምሳሌ፦
- FTS ደረጃ 1 → አስተዋጽኦ
1/21 = 0.048 - FTS ደረጃ 10 → አስተዋጽኦ
1/30 = 0.033 - Vector ደረጃ 1 → አስተዋጽኦ
0.048 - ከፍተኛው ጥምር፦
0.096
k=60 ያለው ምሳሌ፦
- FTS ደረጃ 1 → አስተዋጽኦ
1/61 = 0.016 - FTS ደረጃ 10 → አስተዋጽኦ
1/70 = 0.014 - Vector ደረጃ 1 → አስተዋጽኦ
0.016 - ከፍተኛው ጥምር፦
0.033
ከፍ ያለ k ሲኖር፣ በከፍተኛ-1 እና በደረጃ-10 መካከል ያለው አንጻራዊ ልዩነት አነስተኛ ይሆናል፤ ስለዚህ ስልተ ቀመሩ ከከፍተኛ ደረጃ እምነት ይልቅ በመልሶ ማግኛ ሥርዓቶች መካከል ባለ ስምምነት ላይ የበለጠ ይመረኮዛል።
kን መቼ መቀየር እንዳለብዎት
| ምልክት | ይህን ይሞክሩ |
|---|---|
| ከፍተኛው ውጤት ሁልጊዜ ያሸንፋል፣ ግን የተሳሳተ ነው | kን ዝቅ ያድርጉ (ለምሳሌ፣ 20) — የከፍተኛ ደረጃ እምነት የበለጠ አስፈላጊ ነው |
| ትክክለኛው መልስ ከከፍተኛዎቹ 5 ውስጥ ነው፣ ግን ከፍተኛ-1 አይደለም | kን ከፍ ያድርጉ (ለምሳሌ፣ 100) — ጠፍጣፋ የነጥብ አሰጣጥ ስምምነትን ይሸልማል |
| Recall ከፍተኛ ነው፣ ግን precision ዝቅተኛ ነው | kን ዝቅ ያድርጉ — ደረጃ አሰጣጡን ያጥሩ |
| Recall ዝቅተኛ ነው (ተዛማጅ ሰነዶች ጠፍተዋል) | kን ከፍ ያድርጉ — ዝቅተኛ ደረጃ ላላቸው ሰነዶች ዕድል ይስጡ |
የRRF ክብደት አሰጣጥ
Reciprocal rank fusion ለትርጉማዊ vector ደረጃ እና ለሙሉ-ጽሑፍ ፍለጋ ደረጃ እኩል ክብደቶችን ይጠቀማል፦
RRF(d) = 1/(k + rank_vector) + 1/(k + rank_fts)
የእያንዳንዱን ክብደት ለማስተካከል የሚያስችሉ የአካባቢ ተለዋዋጮች የሉም (MEMORY_RRF_VECTOR_WEIGHT/MEMORY_RRF_FTS_WEIGHT አይኖሩም)።
የማጠቃለያ ስልት (v3.8.16+)
የsummarization.ts ሞጁል (src/lib/memory/summarization.ts) የንቁ ስብስቡን መጠን አነስተኛ ለማድረግ፣ የማስታወስ ችሎታን እንደጠበቀ የቆዩ ትውስታዎችን ይጨምቃል።
ማጠቃለያ የሚጀመርበት ጊዜ
| አስጀማሪ | ገደብ (ነባሪ) |
|---|---|
| በAPI በኩል በእጅ ማስጀመር | አይመለከተውም |
ምን ይጠቃለላል
ከsummarization.ts ሁለት መግቢያ ነጥቦች ይላካሉ፦
summarizeMemories(apiKeyId, sessionId?, maxTokens = 4000)— የአንድን ክፍለ ጊዜ ትውስታዎች በቶከን በጀት የተገደበ አንድ የማጠቃለያ ጽሑፍ አድርጎ ያጠቃልላል።summarizeMemoriesOlderThan(apiKeyId, days, dryRun)— በAPI የሚጠቀምበት በዕድሜ ላይ የተመሠረተ ማጨቅ፦ ከdaysበላይ የቆየን እያንዳንዱን ትውስታ ይመርጣል፣ ከእነሱ አንድ የታመቀ የማጠቃለያ ትውስታ ይፈጥራል፣ እና (dryRunfalseሲሆን) የመጀመሪያዎቹን ይሰርዛል። ምንም ነገር ሳይለወጥ የዕጩዎችን ስብስብና አጠቃላይ የቶከን ብዛት ለማየትdryRun: trueያስተላልፉ።
የመለያ/ቁልፍ ማሰባሰቢያ ዙር ወይም ለእያንዳንዱ ትውስታ "ዋና ከማጠቃለል ከሚችል" የሚል የውጤት አሰጣጥ የለም — ምርጫው ሙሉ በሙሉ በዕድሜ ገደቡ ላይ የተመሠረተ ሲሆን፣ የማጠቃለያው ጽሑፍም ለእያንዳንዱ ዕጩ ዓይነት-ቅድመ ቅጥያ ያለው የታመቀ መስመር ነው።
ማጠቃለያን ማስጀመር
ማጠቃለያ በእጅ / በምርጫ የሚነቃ ነው — የautoSummarize ቅንብር በነባሪ
false ነው፣ ስለዚህ ምንም ነገር በራስ-ሰር አይጨመቅም። በAPI በኩል ያስጀምሩት፦
curl -X POST http://localhost:20128/api/memory/summarize \
-H "Authorization: Bearer $OMNIROUTE_KEY"
እንዳይነቃ ለማድረግ፣ autoSummarizeን በነባሪ እሴቱ (false) ላይ ብቻ ያቆዩት።
የማጠቃለያ ጥራት ምክሮች
- መጀመሪያ በ
dryRunቅድመ ዕይታ ያድርጉ —summarizeMemoriesOlderThan(..., true)የመጀመሪያዎቹን ከመሰረዝዎ በፊት ምን እንደሚዋሃድ ማረጋገጥ እንዲችሉ የዕጩዎችን ዝርዝርና አጠቃላይ የቶከን ብዛት ይመልሳል። - ብዙ የትውስታ ስብስብ ካለዎት ማጠቃለያውን ትራፊክ በሚቀንስባቸው ሰዓታት ያስኪዱ — የLLM ጥሪው ዘገምተኛው ክፍል ነው
# የCron አይነት፦ በየቀኑ ከጠዋቱ 3 ሰዓት ላይ አጠቃልል
0 3 * * * curl -X POST http://localhost:20128/api/memory/summarize \
-H "Authorization: Bearer $OMNIROUTE_KEY"
የMemoryBackend አቅራቢ ንድፍ
ትክክለኛው የመረጃ ምንጭ፦
src/lib/memory/backend.ts,src/lib/memory/genericBackend.ts,src/lib/memory/manager.tsሙከራዎች፦src/lib/memory/__tests__/generic-backend.test.ts
የMemoryBackend አቅራቢ ንድፍ በነባሩ የትውስታ ሞተር ላይ ሊሰካ የሚችል የጀርባ-ክፍል ረቂቅ ንብርብር ያስተዋውቃል። ከአንድ የማከማቻ ትግበራ ጋር ብቻ ከመታሰር ይልቅ፣ የትውስታ ሥርዓቱ አሁን ሊዋቀር የሚችል ዋና/ተተኪ ማዞሪያ ያላቸውን በርካታ የጀርባ ክፍሎች (SQLite፣ Obsidian፣ Notion፣ ብጁ HTTP የጀርባ ክፍሎች) ይደግፋል።
አርክቴክቸር
┌──────────────────────────────────────────────────────────┐
│ የAPI መንገዶች │
│ (src/app/api/memory/route.ts) │
└──────────────────────┬───────────────────────────────────┘
│
┌──────────────────────▼───────────────────────────────────┐
│ MemoryManager │
│ ነጠላ አስተባባሪ (manager.ts) │
│ │
│ ዋና ──────► የጀርባ ክፍል A (ለምሳሌ SQLite) │
│ ተተኪ ─────► የጀርባ ክፍል B (ለምሳሌ Obsidian) │
│ የጀርባ ክፍል C (ለምሳሌ Notion በGenericBackend)│
└──────────────────────┬───────────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌──────────────────┐
│ SQLite │ │ Obsidian │ │ GenericMemory │
│ የጀርባ ክፍል │ │ የጀርባ ክፍል │ │ የጀርባ ክፍል (HTTP) │
└────────────┘ └────────────┘ └──────────────────┘
ዋና በይነገጽ (backend.ts)
እያንዳንዱ የጀርባ ክፍል የMemoryBackend በይነገጽን መተግበር አለበት፦
interface MemoryBackend {
readonly id: string;
readonly displayName: string;
// CRUD
create(input: CreateMemoryInput): Promise<Memory>;
get(id: string): Promise<Memory | null>;
update(id: string, updates: Partial<...>): Promise<boolean>;
delete(id: string): Promise<boolean>;
list(filter: MemoryFilter): Promise<{ data: Memory[]; total: number; byType: Record<string, number> }>;
// ፍለጋ
search(config: SearchConfig): Promise<Memory[]>;
// ጤንነት
health(): Promise<HealthCheckResult>;
// የሕይወት ዑደት (አማራጭ)
initialize?(): Promise<void>;
shutdown?(): Promise<void>;
}
MemoryManager (manager.ts)
የሚከተሉትን የሚያከናውን ነጠላ አስተባባሪ፦
- የጀርባ ክፍሎችን በ
register(backend)ይመዘግባል — ሲነሳ ከindex.tsይጠራል - ዋናውን + ተተኪዎችን በ
configure(primary, fallbacks)ያዋቅራል - CRUD/ፍለጋን ወደ ዋናው ያዞራል፣ ሲከሽፍም የተተኪ ሰንሰለትን ይጠቀማል
- ሁሉንም የጀርባ ክፍሎች በየጊዜው የጤንነት ፍተሻ ያደርግባቸዋል
የተተኪ ባህሪ፦
| ክወና | ዋና | ተተኪዎች |
|---|---|---|
create |
✅ ዋናው ብቻ | ❌ |
get |
✅ መጀመሪያ ዋናውን ይሞክራል | ✅ null ከሆነ ተተኪን ይጠቀማል |
update |
✅ ዋናው ብቻ | ✅ ጀምሮ-ሳይጠብቅ ማመሳሰል |
delete |
✅ ዋናው ብቻ | ✅ ጀምሮ-ሳይጠብቅ ማመሳሰል |
list |
✅ ዋናው ብቻ | ❌ |
search |
✅ መጀመሪያ ዋናው | ✅ ስህተት ሲኖር ተተኪን ይጠቀማል |
GenericMemoryBackend (genericBackend.ts)
ማንኛውንም REST API ወደ MemoryBackend የሚያስማማ አጠቃላይ HTTP አገናኝ። ለሚከተሉት ጠቃሚ ነው፦
- Notion — በNotion API በኩል ያገናኙ
- Obsidian — በObsidian Local REST API በኩል ያገናኙ
- ብጁ የጀርባ ክፍሎች — RESTful የትውስታ API የሚያቀርብ ማንኛውም አገልግሎት
ውቅር፦
interface GenericBackendConfig {
baseUrl: string; // የጀርባ API መሠረታዊ URL
apiKey?: string; // ለማረጋገጫ የBearer ቶከን
headers?: Record<string, string>; // ብጁ HTTP ራስጌዎች
timeout?: number; // የጥያቄ ጊዜ ገደብ (ነባሪ፦ 30000ms)
backendType?: string; // ለምዝግብ ማስቀመጥ
// የመዳረሻ ነጥብ ሽረቶች (ነባሪዎች የREST ልማዶችን ይጠቀማሉ)
endpoints?: {
search?: string; // ነባሪ፦ "/memories/search"
create?: string; // ነባሪ፦ "/memories"
list?: string; // ነባሪ፦ "/memories"
get?: string; // ነባሪ፦ "/memories/{id}"
update?: string; // ነባሪ፦ "/memories/{id}"
delete?: string; // ነባሪ፦ "/memories/{id}"
health?: string; // ነባሪ፦ "/health"
};
// የጥያቄ መለኪያ ስም ማዛመጃዎች
queryParams?: {
query?/apiKeyId?/limit?/offset?/strategy?/maxTokens?/type?/sessionId?/orderBy?/orderDir?/options?
};
// የዱካ መለኪያ ስም ማዛመጃዎች
pathParams?: {
id?/memoryId?
};
}
የታወቁ ጀርባዎች በKNOWN_BACKENDS ውስጥ አስቀድመው ተዋቅረዋል፦
createKnownBackend("obsidian"); // → ወደ localhost:27123 የሚያመለክት GenericMemoryBackend
createKnownBackend("notion"); // → ወደ api.notion.com/v1 የሚያመለክት GenericMemoryBackend
አብሮገነብ ጀርባዎች
SQLiteBackend (sqliteBackend.ts)
ነባሪው ዋና ጀርባ። src/lib/memory/store.tsን በመጠቀም ነባሩን SQLite-ተኮር የማህደረ ትውስታ ማከማቻ ይጠቀልላል። ሲነሳ በራስ-ሰር ይመዘገባል።
import { sqliteBackend } from "./sqliteBackend";
memoryManager.register(sqliteBackend);
ObsidianBackend (obsidianBackend.ts)
ነባሩን የObsidian ውህደት (src/lib/memory/obsidianBackend.ts) ይጠቀልላል። በObsidian Local REST API በኩል ከObsidian ማከማቻ ጋር ይገናኛል።
ቅንብሮች
የማህደረ ትውስታ ጀርባ ቅንብሮች በመተግበሪያው የቅንብሮች ሰንጠረዥ ውስጥ ይከማቻሉ፣ እንዲሁም በsrc/lib/memory/settings.ts በኩል ይተዳደራሉ፦
| ቅንብር | የአካባቢ/ውቅር ቁልፍ | ነባሪ | መግለጫ |
|---|---|---|---|
| ዋና ጀርባ | memoryPrimaryBackend |
"sqlite" |
የዋናው ጀርባ ID |
| ተጠባባቂ ጀርባዎች | memoryFallbackBackends |
[] |
በቅደም ተከተል የተደረደሩ ተጠባባቂ ጀርባ IDዎች |
| የጀርባ ውቅሮች | memoryBackendConfigs |
{} |
ለእያንዳንዱ ጀርባ የሚደረጉ የውቅር ሽረቶች |
ቅንብሮች በnormalizeMemorySettings() በኩል መደበኛ ቅርጽ ይይዛሉ፣ እና በgetMemorySettings() ላይ ይሸጎጣሉ።
የማስጀመር ፍሰት
የመተግበሪያ ማስነሻ
→ index.ts ማስመጣቶች (እንደ ጎንዮሽ ውጤት)፦ SQLiteBackendን ይመዘግባሉ
→ initMemoryBackends() ከመተግበሪያው የሕይወት ዑደት ይጠራል፦
1. ቅንብሮችን ጫን (getMemorySettings)
2. ዋናውን + ተጠባባቂዎቹን አዋቅር
3. ሁሉንም ጀርባዎች አስጀምር (የጤና ምርመራ)
4. ለጥያቄዎች ዝግጁ
አዲስ ጀርባ ማከል
- በ
src/lib/memory/<name>Backend.tsውስጥ የ**MemoryBackendን በይነገጽ ይተግብሩ** - ከ
src/lib/memory/index.tsወደ ውጭ ይላኩ - ሲነሳ በ
memoryManager.register(yourBackend)ይመዝግቡ - በቅንብሮች በኩል ያዋቅሩ፦
memoryPrimaryBackendን ወደ ጀርባዎ ID ያቀናብሩ src/lib/memory/__tests__/generic-backend.test.tsን እንደ ማጣቀሻ በመጠቀም ይፈትሹ
ምሳሌ፦ Brain ጀርባ
import { createGenericMemoryBackend } from "./genericBackend";
const brainBackend = createGenericMemoryBackend("brain", "BK-Brain", {
baseUrl: process.env.BRAIN_API_URL || "http://localhost:9099",
apiKey: process.env.BRAIN_API_KEY,
endpoints: {
search: "/api/memory/search",
create: "/api/memory",
health: "/api/health",
},
});
memoryManager.register(brainBackend);
ማረጋገጫ
የክፍል ፈተናዎች
npx vitest run src/lib/memory/__tests__/generic-backend.test.ts --reporter=verbose
የሚጠበቀው ውጤት፦ 35 ፈተናዎች፣ ሁሉም ያለፉ፣ የሚከተሉትን ይሸፍናሉ፦
- ገንቢ (2)
- የጤና ምርመራ (4) — ስኬት፣ ውድቀት 500፣ የአውታረ መረብ ስህተት፣ መዘግየት
- ማስጀመር (2) — ስኬት፣ ውድቀት
- መፍጠር (2) — ነባሪ መዳረሻ ነጥብ፣ ብጁ መዳረሻ ነጥብ
- ማግኘት (4) — ስኬት፣ 404 → null፣ 404 ያልሆነ ስህተት መጣል፣ ብጁ የዱካ መለኪያዎች
- ማዘመን (2) — ስኬት፣ 404 → false
- መሰረዝ (2) — ስኬት፣ 404 → false
- መዘርዘር (2) — የጥያቄ መለኪያዎች፣ ብጁ የመለኪያ ስሞች
- መፈለግ (3) — የጥያቄ መለኪያዎች፣ ብጁ መዳረሻ ነጥብ፣ የአማራጮች ተከታታይ ማድረግ
- የማረጋገጫ ራስጌዎች (2) — Bearer ቶከን፣ ብጁ ራስጌዎች
- ፋብሪካ (1)
የዓይነት ምርመራ
npm run typecheck:core
የሚጠበቀው፦ 0 ስህተቶች።