Bellek
OpenClaw belleği ajan çalışma alanındaki düz Markdown dosyalarından oluşur. Dosyalar tek gerçek kaynaktır; model yalnızca diske yazılanları “hatırlar”. Bellek arama araçları, etkin bellek eklentisi tarafından sağlanır (varsayılan:memory-core). Bellek eklentilerini plugins.slots.memory = "none" ile devre dışı bırakın.
Bellek dosyaları (Markdown)
Varsayılan çalışma alanı düzeni iki bellek katmanı kullanır:memory/YYYY-MM-DD.md- Günlük kayıt (yalnızca ekleme).
- Oturum başlangıcında bugün + dün okunur.
MEMORY.md(isteğe bağlı)- Küratörlü uzun vadeli bellek.
- Yalnızca ana, özel oturumda yüklenir (grup bağlamlarında asla).
agents.defaults.workspace, varsayılan
~/.openclaw/workspace). Tam düzen için Agent workspace bölümüne bakın.
When to write memory
- Kararlar, tercihler ve kalıcı gerçekler
MEMORY.mddosyasına gider. - Günlük notlar ve akan bağlam
memory/YYYY-MM-DD.mddosyasına gider. - Birisi “bunu hatırla” derse, yazın (RAM’de tutmayın).
- Bu alan hâlâ gelişiyor. Modele anıları kaydetmesini hatırlatmak yardımcı olur; ne yapacağını bilir.
- Bir şeyin kalıcı olmasını istiyorsanız, botun belleğe yazmasını isteyin.
Otomatik bellek boşaltma (ön-sıkıştırma ping’i)
Bir oturum otomatik sıkıştırmaya yaklaştığında, OpenClaw bağlam sıkıştırılmadan önce kalıcı belleğin yazılmasını hatırlatan sessiz, ajanik bir tur tetikler. Varsayılan istemler modelin yanıt verebileceğini açıkça söyler; ancak genellikle kullanıcı bu turu hiç görmesin diye doğru yanıtNO_REPLY olur.
Bu davranış agents.defaults.compaction.memoryFlush ile denetlenir:
- Yumuşak eşik: oturum belirteç tahmini
contextWindow - reserveTokensFloor - softThresholdTokensdeğerini geçtiğinde boşaltma tetiklenir. - Varsayılan olarak sessiz: istemler, hiçbir şeyin iletilmemesi için
NO_REPLYiçerir. - İki istem: bir kullanıcı istemi ve bir sistem istemi hatırlatmayı ekler.
- Sıkıştırma döngüsü başına tek boşaltma (
sessions.jsoniçinde izlenir). - Çalışma alanı yazılabilir olmalıdır: oturum
workspaceAccess: "ro"veya"none"ile sandbox içinde çalışıyorsa boşaltma atlanır.
Vektör bellek araması
OpenClaw,MEMORY.md ve memory/*.md üzerinde küçük bir vektör dizini
oluşturabilir; böylece anlamsal sorgular, ifade farklı olsa bile ilgili notları
bulabilir.
Varsayılanlar:
- Varsayılan olarak etkindir.
- Bellek dosyalarındaki değişiklikleri izler (debounce’lu).
- Bellek aramasını
agents.defaults.memorySearchaltında yapılandırın (üst seviyememorySearchdeğil). - Varsayılan olarak uzak embedding’ler kullanır.
memorySearch.providerayarlı değilse OpenClaw otomatik olarak seçer:local(birmemorySearch.local.modelPathyapılandırılmışsa ve dosya varsa).- Bir OpenAI anahtarı çözümlenebiliyorsa
openai. - Bir Gemini anahtarı çözümlenebiliyorsa
gemini. - Bir Voyage anahtarı çözümlenebiliyorsa
voyage. - Aksi hâlde yapılandırılana kadar bellek araması devre dışı kalır.
- Yerel mod node-llama-cpp kullanır ve
pnpm approve-buildsgerektirebilir. - SQLite içinde vektör aramasını hızlandırmak için (mevcutsa) sqlite-vec kullanır.
models.providers.*.apiKey’den veya
ortam değişkenlerinden çözümler. Codex OAuth yalnızca sohbet/completion’ları
kapsar ve bellek araması için embedding’leri karşılamaz. Gemini için
GEMINI_API_KEY veya models.providers.google.apiKey kullanın. Voyage için VOYAGE_API_KEY veya
models.providers.voyage.apiKey kullanın. Özel bir OpenAI-uyumlu uç nokta kullanırken
memorySearch.remote.apiKey’yi (isteğe bağlı memorySearch.remote.headers ile) ayarlayın.
QMD arka ucu (deneysel)
Yerleşik SQLite dizinleyiciyi QMD ile değiştirmek içinmemory.backend = "qmd"’ü ayarlayın: BM25 + vektörler + yeniden sıralamayı birleştiren,
yerel-öncelikli bir arama yan hizmeti. Markdown tek gerçek kaynak olmaya devam
eder; OpenClaw getirim için QMD’yi çağırır. Öne çıkan noktalar:
Ön koşullar
- Varsayılan olarak kapalıdır. Yapılandırma bazında etkinleştirin (
memory.backend = "qmd"). - QMD CLI’yi ayrı olarak kurun (
bun install -g https://github.com/tobi/qmdveya bir sürüm indirin) veqmdikilisinin gateway’inPATH’inde olduğundan emin olun. - QMD, uzantılara izin veren bir SQLite derlemesine ihtiyaç duyar (macOS’ta
brew install sqlite). - QMD, Bun +
node-llama-cppüzerinden tamamen yerel çalışır ve ilk kullanımda HuggingFace’ten GGUF modellerini otomatik indirir (ayrı bir Ollama daemon’u gerekmez). - Gateway,
XDG_CONFIG_HOMEveXDG_CACHE_HOMEayarlayarak QMD’yi~/.openclaw/agents/<agentId>/qmd/altında kendi kendine yeten bir XDG evinde çalıştırır. - OS desteği: macOS ve Linux, Bun + SQLite kurulduktan sonra kutudan çıktığı gibi çalışır. Windows için WSL2 önerilir.
- Gateway,
~/.openclaw/agents/<agentId>/qmd/altında kendi kendine yeten bir QMD evi yazar (yapılandırma + önbellek + sqlite DB). - Koleksiyonlar,
memory.qmd.paths’dan (qmd collection addile) oluşturulur (varsayılan çalışma alanı bellek dosyaları dâhil); ardındanqmd update+qmd embedaçılışta ve yapılandırılabilir bir aralıkta (memory.qmd.update.interval, varsayılan 5 dk) çalışır. - Gateway artık QMD yöneticisini başlangıçta başlatır, böylece ilk
memory_searchçağrısından önce bile periyodik güncelleme zamanlayıcıları etkinleştirilmiş olur. - Açılış yenilemesi artık varsayılan olarak arka planda çalışır; sohbet başlatma
engellenmez. Önceki engelleyici davranışı korumak için
memory.qmd.update.waitForBootSync = true’ı ayarlayın. - Aramalar
qmd query --jsonüzerinden çalışır. Seçilen mod QMD derlemenizde bayrakları reddederse, OpenClawqmd queryile yeniden dener. QMD başarısız olursa veya ikili yoksa, OpenClaw otomatik olarak yerleşik SQLite yöneticisine geri döner; böylece bellek araçları çalışmaya devam eder. - OpenClaw bugün QMD embed batch-size ayarını sunmaz; batch davranışı QMD’nin kendisi tarafından denetlenir.
- İlk arama yavaş olabilir: QMD, ilk
qmd queryçalıştırmada yerel GGUF modellerini (yeniden sıralayıcı/sorgu genişletme) indirebilir.-
OpenClaw, QMD’yi çalıştırırken
XDG_CONFIG_HOME/XDG_CACHE_HOME’ü otomatik ayarlar. -
Modelleri manuel olarak önceden indirmek (ve OpenClaw’ın kullandığı aynı dizini
ısıtmak) isterseniz, ajan XDG dizinleriyle tek seferlik bir sorgu çalıştırın.
OpenClaw’ın QMD durumu durum dizininiz altında bulunur (varsayılan
~/.openclaw). OpenClaw’ın kullandığı XDG değişkenlerinin aynısını dışa aktararakqmd’yı tam olarak aynı dizine yönlendirebilirsiniz:
-
OpenClaw, QMD’yi çalıştırırken
memory.qmd.*)
command(varsayılanqmd): çalıştırılabilir dosya yolunu geçersiz kılar.searchMode(varsayılansearch):memory_searchiçin hangi QMD komutunun kullanılacağını seçin (search,vsearch,query).includeDefaultMemory(varsayılantrue):MEMORY.md+memory/**/*.md’ü otomatik indeksler.paths[]: ek dizin/dosyalar ekler (path, isteğe bağlıpattern, isteğe bağlı kararlıname).sessions: oturum JSONL indekslemesine katılım (enabled,retentionDays,exportDir).update: yenileme sıklığını ve bakım yürütümünü denetler: (interval,debounceMs,onBoot,waitForBootSync,embedInterval,commandTimeoutMs,updateTimeoutMs,embedTimeoutMs).limits: geri çağırma yükünü sınırlar (maxResults,maxSnippetChars,maxInjectedChars,timeoutMs).scope:session.sendPolicyile aynı şema. Varsayılan DM-only’dir (denytümü,allowdoğrudan sohbetler); grup/kanallarda QMD sonuçlarını göstermek için gevşetin.match.keyPrefix, normalize edilmiş oturum anahtarıyla eşleşir (küçük harfe dönüştürülmüş ve baştakiagent:<id>:kaldırılmış). Örnek:discord:channel:.match.rawKeyPrefix,agent:<id>:dahil olmak üzere ham oturum anahtarıyla (küçük harfe dönüştürülmüş) eşleşir. Örnek:agent:main:discord:.- Eski kullanım:
match.keyPrefix: "agent:..."hâlâ ham anahtar öneki olarak değerlendirilir, ancak açıklık içinrawKeyPrefixtercih edilmelidir.
scopebir aramayı reddettiğinde, OpenClaw türetilmişchannel/chatTypeile bir uyarı kaydeder; böylece boş sonuçların hata ayıklaması kolaylaşır.- Çalışma alanı dışından kaynaklanan parçalar,
memory_searchsonuçlarındaqmd/<collection>/<relative-path>olarak görünür;memory_getbu öneki anlar ve yapılandırılmış QMD koleksiyon kökünden okur. memory.qmd.sessions.enabled = trueolduğunda OpenClaw, temizlenmiş oturum dökümlerini (Kullanıcı/Yardımcı turları)~/.openclaw/agents/<id>/qmd/sessions/altında özel bir QMD koleksiyonuna dışa aktarır; böylecememory_search, yerleşik SQLite dizinine dokunmadan yakın konuşmaları geri çağırabilir.memory_searchparçaları,memory.citationsauto/onolduğunda artık birSource: <path#line>altbilgisi içerir; yol meta verisini dahili tutmak içinmemory.citations = "off"’i ayarlayın (ajan yinememory_getiçin yolu alır, ancak parça metni altbilgiyi içermez ve sistem istemi ajana bunu alıntılamamasını söyler).
memory.citations, arka uçtan bağımsız olarak geçerlidir (auto/on/off).qmdçalıştığında, tanılamalarda hangi motorun sonuçları sunduğunu göstermek içinstatus().backend = "qmd"etiketleriz. QMD alt süreci çıkarsa veya JSON çıktısı ayrıştırılamazsa, arama yöneticisi bir uyarı kaydeder ve QMD toparlanana kadar yerleşik sağlayıcıyı (mevcut Markdown embedding’leri) döndürür.
Ek bellek yolları
Varsayılan çalışma alanı düzeni dışındaki Markdown dosyalarını indekslemek istiyorsanız, açık yollar ekleyin:- Yollar mutlak veya çalışma alanına göreli olabilir.
- Dizinler
.mddosyaları için özyinelemeli taranır. - Yalnızca Markdown dosyaları indekslenir.
- Symlink’ler yok sayılır (dosya veya dizin).
Gemini embedding’leri (yerel)
Gemini embedding’leri API’sini doğrudan kullanmak için sağlayıcıyıgemini olarak ayarlayın:
remote.baseUrlisteğe bağlıdır (varsayılan Gemini API taban URL’sidir).remote.headers, gerekirse ek başlıklar eklemenizi sağlar.- Varsayılan model:
gemini-embedding-001.
remote yapılandırmasını
kullanabilirsiniz:
memorySearch.provider = "local"’i kullanın veya
memorySearch.fallback = "none"’yı ayarlayın.
Geri dönüşler:
memorySearch.fallback,openai,gemini,localveyanoneolabilir.- Geri dönüş sağlayıcısı yalnızca birincil embedding sağlayıcısı başarısız olduğunda kullanılır.
- OpenAI ve Gemini embedding’leri için varsayılan olarak etkindir. Devre dışı
bırakmak için
agents.defaults.memorySearch.remote.batch.enabled = false’yi ayarlayın. - Varsayılan davranış batch tamamlanmasını bekler; gerekirse
remote.batch.wait,remote.batch.pollIntervalMsveremote.batch.timeoutMinutes’i ayarlayın. - Paralel gönderilecek batch iş sayısını denetlemek için
remote.batch.concurrency’yı ayarlayın (varsayılan: 2). - Batch modu,
memorySearch.provider = "openai"veya"gemini"olduğunda uygulanır ve ilgili API anahtarını kullanır. - Gemini batch işleri, async embeddings batch uç noktasını kullanır ve Gemini Batch API erişimi gerektirir.
- Büyük geri doldurmalar için OpenAI, tek bir batch işinde çok sayıda embedding isteği gönderebildiğimiz ve OpenAI’nin bunları asenkron işlemesine izin verdiği için genellikle desteklediğimiz en hızlı seçenektir.
- OpenAI, Batch API iş yükleri için indirimli fiyatlandırma sunar; bu nedenle büyük indeksleme çalışmaları çoğu zaman aynı istekleri eşzamanlı göndermekten daha ucuzdur.
- Ayrıntılar için OpenAI Batch API belgeleri ve fiyatlandırmasına bakın:
memory_search— dosya + satır aralıklarıyla parçalar döndürür.memory_get— yola göre bellek dosyası içeriğini okur.
agents.defaults.memorySearch.provider = "local"’i ayarlayın.agents.defaults.memorySearch.local.modelPathsağlayın (GGUF veyahf:URI).- İsteğe bağlı: uzak geri dönüşü önlemek için
agents.defaults.memorySearch.fallback = "none"’ü ayarlayın.
Bellek araçları nasıl çalışır
memory_search,MEMORY.md+memory/**/*.mdiçindeki Markdown parçalarını anlamsal olarak arar (~400 belirteç hedefi, 80 belirteç örtüşme). Parça metnini (~700 karakter sınırı), dosya yolunu, satır aralığını, skoru, sağlayıcı/modeli ve yerel → uzak embedding’lere geri düşülüp düşülmediğini döndürür. Tam dosya içeriği döndürülmez.memory_get, belirli bir bellek Markdown dosyasını (çalışma alanına göreli), isteğe bağlı olarak bir başlangıç satırından ve N satır boyunca okur.MEMORY.md/memory/dışındaki yollar reddedilir.- Her iki araç da yalnızca ajan için
memorySearch.enabledtrue çözümlendiğinde etkindir.
Neler indekslenir (ve ne zaman)
- Dosya türü: yalnızca Markdown (
MEMORY.md,memory/**/*.md). - Dizin depolama: ajan başına SQLite,
~/.openclaw/memory/<agentId>.sqlite’te (agents.defaults.memorySearch.store.pathile yapılandırılabilir,{agentId}belirteci desteklenir). - Tazelik:
MEMORY.md+memory/üzerinde izleyici dizini kirli işaretler (debounce 1,5 sn). Eşitleme oturum başlangıcında, aramada veya bir aralıkta zamanlanır ve asenkron çalışır. Oturum dökümleri, arka plan eşitlemeyi tetiklemek için delta eşiklerini kullanır. - Yeniden indeksleme tetikleyicileri: dizin, embedding sağlayıcı/model + uç nokta parmak izi + parçalara ayırma parametrelerini saklar. Bunlardan biri değişirse OpenClaw tüm depoyu otomatik olarak sıfırlar ve yeniden indeksler.
Hibrit arama (BM25 + vektör)
Etkinleştirildiğinde OpenClaw şunları birleştirir:- Vektör benzerliği (anlamsal eşleşme, ifade farklı olabilir)
- BM25 anahtar kelime uygunluğu (ID’ler, env değişkenleri, kod sembolleri gibi tam belirteçler)
Neden hibrit?
Vektör arama “aynı anlama geliyor” durumlarında harikadır:- “Mac Studio gateway ana makinesi” vs “gateway’i çalıştıran makine”
- “dosya güncellemelerini debounce et” vs “her yazmada indekslemeyi önle”
- ID’ler (
a828e60,b3b9895a…) - kod sembolleri (
memorySearch.query.hybrid) - hata dizeleri (“sqlite-vec unavailable”)
Sonuçları nasıl birleştiriyoruz (mevcut tasarım)
Uygulama taslağı:- Her iki taraftan aday havuzu alın:
- Vektör: kosinüs benzerliğine göre en iyi
maxResults * candidateMultiplier. - BM25: FTS5 BM25 sıralamasına göre en iyi
maxResults * candidateMultiplier(daha düşük daha iyidir).
- BM25 sıralamasını 0..1 benzeri bir skora dönüştürün:
textScore = 1 / (1 + max(0, bm25Rank))
- Union candidates by chunk id and compute a weighted score:
finalScore = vectorWeight * vectorScore + textWeight * textScore
vectorWeight+textWeight, yapılandırma çözümlemesinde 1,0’a normalize edilir; böylece ağırlıklar yüzde gibi davranır.- Embedding’ler kullanılamıyorsa (veya sağlayıcı sıfır vektör döndürürse), BM25 yine çalıştırılır ve anahtar kelime eşleşmeleri döndürülür.
- FTS5 oluşturulamıyorsa, yalnızca vektör aramayı koruruz (sert hata yok).
Embedding cache
OpenClaw, parça embedding’lerini SQLite’ta önbelleğe alabilir; böylece yeniden indeksleme ve sık güncellemeler (özellikle oturum dökümleri) değişmeyen metni yeniden embed etmez. Yapılandırma:Oturum belleği araması (deneysel)
İsteğe bağlı olarak oturum dökümlerini indeksleyebilir ve bunlarımemory_search üzerinden sunabilirsiniz.
Bu özellik deneysel bir bayrakla
korunur.
- Oturum indeksleme isteğe bağlıdır (varsayılan olarak kapalı).
- Oturum güncellemeleri debounce edilir ve delta eşiklerini aştıktan sonra asenkron olarak indekslenir (en iyi çaba).
memory_searchindekslemeyi asla beklemez; arka plan eşitlemesi bitene kadar sonuçlar biraz eski olabilir.- Sonuçlar yine yalnızca parçaları içerir;
memory_getbellek dosyalarıyla sınırlı kalır. - Oturum indeksleme ajan başına yalıtılmıştır (yalnızca o ajanın oturum günlükleri indekslenir).
- Oturum günlükleri diskte yaşar (
~/.openclaw/agents/<agentId>/sessions/*.jsonl). Dosya sistemi erişimi olan herhangi bir süreç/kullanıcı okuyabilir; bu nedenle disk erişimini güven sınırı olarak değerlendirin. Daha sıkı yalıtım için ajanları ayrı OS kullanıcıları veya ana makineler altında çalıştırın.
SQLite vektör hızlandırma (sqlite-vec)
sqlite-vec uzantısı mevcut olduğunda OpenClaw embedding’leri bir SQLite sanal tablosunda (vec0) saklar ve vektör mesafe sorgularını veritabanında
yürütür. Bu, her embedding’i JS’e yüklemeden aramayı hızlı tutar.
Yapılandırma (isteğe bağlı):
enabledvarsayılan olarak true’dur; devre dışı bırakıldığında arama, saklanan embedding’ler üzerinde süreç içi kosinüs benzerliğine geri döner.- sqlite-vec uzantısı yoksa veya yüklenemezse OpenClaw hatayı kaydeder ve JS geri dönüşüyle devam eder (vektör tablo yok).
extensionPath, paketlenmiş sqlite-vec yolunu geçersiz kılar (özel derlemeler veya standart dışı kurulumlar için yararlı).
Yerel embedding otomatik indirme
- Varsayılan yerel embedding modeli:
hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf(~0,6 GB). memorySearch.provider = "local"olduğundanode-llama-cpp,modelPath’i çözümler; GGUF eksikse önbelleğe (veya ayarlıysalocal.modelCacheDir) otomatik indirir, sonra yükler. İndirmeler yeniden denemede devam eder.- Yerel derleme gereksinimi:
pnpm approve-buildsçalıştırın,node-llama-cpp’i seçin, ardındanpnpm rebuild node-llama-cpp. - Geri dönüş: yerel kurulum başarısız olursa ve
memorySearch.fallback = "openai"ise, otomatik olarak uzak embedding’lere geçeriz (openai/text-embedding-3-smallvarsayılan, aksi belirtilmedikçe) ve nedeni kaydederiz.
Özel OpenAI-uyumlu uç nokta örneği
remote.*,models.providers.openai.*’ya göre önceliklidir.remote.headers, OpenAI başlıklarıyla birleştirilir; anahtar çakışmalarında uzak taraf kazanır. OpenAI varsayılanlarını kullanmak içinremote.headers’i atlayın.