Ajan bellek türleri ve depolama maliyetleri
Anlamsal, epizodik ve yordamsal bellek türlerinin teknik farklarını ve VPS üzerinde her birinin depolama ile yeniden vektörleştirme maliyetlerini detaylı bir tabloda inceleyin.
Üç ajan bellek türü nedir
Ajan bellek türleri üç şekilde ayrılır ve her biri ödediğiniz donanım üzerinde farklı bir etki yaratır: anlamsal bellek olguları, epizodik bellek yaşanan olayları, yordamsal bellek ise bir işin nasıl yapılacağını tutar. Aşağıdaki tablo, her birini bir sunucu örneğiyle tanımlar. Tablodan sonra gelen kısım genellikle yazılmayan, yani her türün depolama ve yeniden oluşturma maliyetini açıklayan bölümdür.
The data behind this chart
[
{
"label": "Semantic",
"what_it_holds": "Facts the agent should treat as currently true",
"server_example": "The database listens on 10.8.0.4:5432 and the nightly dump runs at 03:15 UTC"
},
{
"label": "Episodic",
"what_it_holds": "A record of one past event or session",
"server_example": "On 2026-08-11 the deploy failed because the disk was full, and rotating logs fixed it"
},
{
"label": "Procedural",
"what_it_holds": "How to carry out a task, as steps the agent can run",
"server_example": "The restore runbook: stop the service, load the dump, run migrations, start the service"
}
]Bu isimler insan psikolojisinden ödünç alınmıştır ve bu kullanım oldukça esnektir. Bu ayrım pratik bir nedenden dolayı yerini korur: üç türün boyutları ve onarım yolları farklıdır, bu nedenle hepsini tek bir vektör deposuna koymak her birinin performansını düşürür.
Anlamsal bellek küçüktür ve onu elle düzenlemek isteyeceksiniz
Kendi sunucularınız hakkındaki birkaç yüz gerçek, birkaç on kilobaytlık metne tekabül eder. Burada sorun depolama alanı değil, düzeltme işlemidir. Anlamsal bellekteki yanlış bir bilgi, temsilcinin (agent) bundan sonra vereceği her yanıtta yanlış olacaktır; bu nedenle depolama alanı, bir bilgiyi adına göre bulmanıza, değiştirmenize ve eski değerin silindiğinden emin olmanıza olanak tanımalıdır.
Bu durum anahtarlı bir depolama birimine işaret eder: birincil anahtara sahip bir Postgres tablosu veya git içindeki küçük markdown dosyalarından oluşan bir dizin. Her ikisi de tek bir sorgu çalıştırmanıza, değeri görmenize ve yerinde düzenlemenize olanak tanır. Benzerlik araması (similarity search) size bunu sağlamaz, çünkü anahtar yerine benzerliğe göre geri alırsınız. "Veritabanı portunu değiştir" komutu, "veritabanı portundan bahseden her parçayı bul" işlemine dönüşür ve hepsini bulduğunuzu kanıtlayamazsınız. Gerçekleri anahtarlı tutun. Gevşek geri çağırma (loose recall) da istiyorsanız bunları ayrıca gömün (embed), ancak anahtarlı kopyayı gerçek kabul edin.
Eski bilgiler kendilerini belli etmez. Port değişir ancak satır aynı kalır, bu nedenle temsilci Haziran ayında doğru olan bir sayıyla yanıt vermeye devam eder. Temsilci belleği için eskime ve budama politikası bu sayfanın diğer yarısıdır ve tablo henüz küçükken tasarlanması çok daha az maliyetlidir.
Epizodik bellek neden sınırsız büyür
Epizodik bellek bir log dosyasıdır ve loglar büyür. Her oturum, her araç çağrısı ve her başarısız komut birer bölüm adayıdır. Her adımda bir satır yazan bir aracı, bir ay içinde kimsenin okuyamayacağı kadar çok satır yazar. Üstelik tek maliyet disk alanı değildir; gömülü (embedded) her bölüm, arama motorunun taraması gereken dizine de eklenir.
Saklama kuralına, tabloyu oluşturduğunuz gün, silme işlemi henüz maliyetsizken karar verin. İki soru bu konunun çoğunu netleştirir. Birincisi, neyin yazılmaya değer olduğu: Bir oturumun özeti genellikle değerlidir, ancak bir ls -la komutunun tüm çıktısı genellikle değildir. İkincisi, her bölüm sınıfının ne kadar süre saklanacağıdır: Örneğin ham bölümler 30 gün, oturum özetleri ise bir yıl saklanabilir.
Her bölüm satırına bir created_at zaman damgası ve bir source sütunu ekleyin. created_at olmadan verileri yaşa göre silemezsiniz. source olmadan, hatalı bir kaynaktan gelen her şeyi silemezsiniz; oysa bir web sayfasının veya destek biletinin belleğe komutlar yazdığı ortaya çıktığında tam olarak buna ihtiyaç duyarsınız.
DELETE FROM episodes WHERE created_at < now() - interval '30 days';Bunu bir systemd zamanlayıcısı üzerinden çalıştırın, ardından satır sayısının ve tablo boyutunun gerçekten azaldığını gözlemleyin. Kimsenin uygulamadığı bir saklama politikası, sadece bir yorum satırından ibarettir.
psql -d agentmem -c "SELECT count(*) FROM episodes;"
psql -d agentmem -c "SELECT pg_size_pretty(pg_total_relation_size('episodes'));"Prosedürel bellek bir depoda tutulmalıdır
Prosedürel bellek, bir ajanın işi nasıl yapacağını belirler: bir shell script, bir yetenek dosyası veya numaralandırılmış adımlardan oluşan bir runbook. Bu bir koddur ve kod, kodun ait olduğu yerde, yani gözden geçirme, sürümleme ve okunabilir diff çıktıları sunan bir git deposunda bulunmalıdır.
Bir runbook'u gömülü parçalar (embedded chunks) halinde saklarsanız, elinize yaklaşık bir kopya geçer. Geri getirme işlemi en yüksek puanı alan parçaları döndürür; bu nedenle ajan 2. ve 5. adımları uygularken 3. adım hiç ortaya çıkmayabilir ve prosedürün hangi sürümünün çalıştığına dair hiçbir kayıt tutulmaz. Git üzerinde ise git log her iki soruyu da yanıtlar. Depolama maliyeti neredeyse sıfırdır; bu da prosedürel veriler için vektör veritabanı ücretleri ödememeniz için diğer bir nedendir.
Bir embedding'in disk üzerindeki gerçek maliyeti
The data behind this chart
[
{
"label": "bge-small-en-v1.5 (384 dims)",
"bytes_per_vector": 1544,
"mib_per_100k_rows": 147.2
},
{
"label": "bge-base-en-v1.5 (768 dims)",
"bytes_per_vector": 3080,
"mib_per_100k_rows": 293.7
},
{
"label": "bge-large-en-v1.5 (1024 dims)",
"bytes_per_vector": 4104,
"mib_per_100k_rows": 391.4
},
{
"label": "text-embedding-3-small (1536 dims)",
"bytes_per_vector": 6152,
"mib_per_100k_rows": 586.7
},
{
"label": "text-embedding-3-large (3072 dims)",
"bytes_per_vector": 12296,
"mib_per_100k_rows": 1172.6
}
]pgvector, bir vector verisini boyut başına 4 bayt ve 8 baytlık bir başlık (header) olarak saklar; bu aritmetik sabittir ve herhangi bir veri yüklemeden önce planlama yapmanıza olanak tanır. 384 boyutlu bir vektör 1544 bayttır, bu da 100.000 parçanın 147.2 MiB vektör alanı kaplaması demektir. Aynı külliyat 3.072 boyutta embedding edildiğinde, satır başına 12296 bayt ile 1172.6 MiB yer kaplar. Aynı metin, yaklaşık sekiz katı depolama alanı demektir.
Bu sadece vektör sütunudur. Parça metni, birincil anahtar, satır ek yükü ve indeks de bunun üzerine eklenir; insanların unuttuğu kısım ise indekstir. HNSW (pgvector tarafından oluşturulan grafik indeksi olan hierarchical navigable small world), bağladığı vektörlerin kendi kopyasını tutar; bu nedenle indekslenmiş bir depo, yukarıdaki rakamların iki katından fazlasını rahatlıkla kaplar. Tahmin etmek yerine kendi verilerinizi ölçün.
SELECT pg_size_pretty(pg_total_relation_size('memories')) AS total,
pg_size_pretty(pg_relation_size('memories_embedding_idx')) AS idx;Arama işleminin hızlı hissedilip hissedilmeyeceğine RAM karar verir, çünkü grafik ancak bellekte olduğu sürece hızlı taranabilir. İndeks, Postgres'in bellekte tutabileceğinden daha büyük olduğunda, aramalar diskten okumaya başlar ve gecikme artar. Derleme işleminin kendi sınırı olan maintenance_work_mem değeri vardır; grafik bu sınırı aştığında derleme işlemi bunu bildirir ve yavaşlar:
NOTICE: hnsw graph no longer fits into maintenance_work_mem after 61440 tuples
HINT: Increase maintenance_work_mem to speed up builds.Aynı külliyatı küçültmek için iki yöntem vardır. Daha küçük bir model seçin; 384 boyut, 1.536 boyutun dörtte biri maliyetindedir ve kendi notlarınızı tekrar bulmak için doğruluk farkı genellikle kabul edilebilir düzeydedir. Alternatif olarak yarım hassasiyetle (half precision) saklayın: halfvec türü, boyut başına 2 bayt ve aynı 8 baytlık başlığı kullanır; bu da sütun ve indeks boyutunu neredeyse yarı yarıya azaltır.
Model seçmeden önce bilinmesi gereken bir sınır vardır. Ağustos 2026 itibarıyla, bir vector sütunu 2.000 boyuta kadar indekslenebilir; bu nedenle 3.072 boyutlu bir embedding sütun tarafından kabul edilir ancak indeks tarafından reddedilir:
ERROR: column cannot have more than 2000 dimensions for hnsw indexhalfvec, 4.000 boyuta kadar indeksleme yapabilir; bu nedenle yaygın çözüm, cast edilmiş veriyi indekslemektir:
CREATE INDEX ON memories USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops);pgvector ne zaman ayrı bir bellek servisinden daha avantajlıdır
Sunucuda halihazırda Postgres çalışıyorsa, vektörler tek bir paket ve tek bir ifade ile yönetilebilir.
psql -V
sudo apt install postgresql-16-pgvectorCREATE EXTENSION vector;Paket adındaki sayı Postgres ana sürümünüzü belirtir; Ubuntu 24.04 üzerinde bu 16'dır, bu nedenle yazmadan önce psql -V kısmını okuyun.
Belleği veritabanı içinde tutmak, hem belleği hem de uygulama verilerini aynı anda kapsayan tek bir yedekleme, tek bir bağlantı havuzu ve işlem (transaction) garantisi sağlar: bir veri ve onu tanımlayan satır birlikte commit edilir veya birlikte başarısız olur. Ayrı bir servis bu garantiyi veremez.
Aşağıdaki durumlardan biri geçerli olduğunda özel bir bellek servisine geçiş yapın. Arama yükü uygulamanızla çakışıyorsa ve kendi makinesine ihtiyaç duyuyorsa. Birden fazla ana makinedeki birden fazla aracı tek bir belleği paylaşıyorsa. Veya hazır bir ürünün sunduğu ayıklama ve tekilleştirme mantığını istiyorsanız; bu, kendi kendine barındırılan bir Mem0 bellek sunucusu kullanmak için temel argümandır. Tek bir aracı ve milyonlarca parçadan oluşan bir veri kümesi için, halihazırda kullandığınız sunucudaki pgvector'ü yönetmek daha kolaydır ve hata payı daha düşüktür. Motor seçimi ve her motorun RAM üzerinde ihtiyaç duyduğu kaynaklar bir VPS üzerinde vektör veritabanı çalıştırma bölümünde ele alınmıştır.
Model değişikliğinde yeniden vektörleştirme maliyetleri
İki farklı modele ait vektörler birbiriyle kıyaslanamaz; bu nedenle yeni bir modelle yeni bellekleri vektörleştirip eski satırları olduğu gibi bırakamazsınız. Karma bir tablo anlamsız sonuçlar döndürür, çünkü iki farklı koordinat sistemi arasında hesaplanan mesafe hiçbir anlam ifade etmeyen bir sayıdır. Model değişikliği, tüm veri kümesinin yeniden vektörleştirilmesi anlamına gelir.
Bu maliyet dört bölümden oluşur: tokenlar (bir API ücreti veya kendi sunucunuzdaki CPU ve GPU süresi), işlem süresi boyunca geçen duvar saati süresi, arka plan doldurma (backfill) sırasında her iki sütunun aynı anda kapladığı disk alanı ve sonunda yapılacak dizin (index) yeniden oluşturma işlemi. Güvenli yöntem şudur: yeni bir sütun ekleyin, bu sütunu gruplar halinde doldurun, sorguyu yeni sütuna yönlendirin ve ardından eski sütun ile dizinini silin.
Yayınlanan rakamlara güvenmek yerine hızı kendi donanımınızda ölçün; çünkü küçük bir VPS üzerinde sadece CPU ile yapılan vektörleştirme, aynı modelin GPU üzerinde çalışmasından çok daha yavaştır. Temsili bir parçanın süresini ölçün ve ardından bu değeri toplam veri kümesi boyutuyla çarpın.
ollama pull nomic-embed-text
time curl -s http://localhost:11434/api/embed \
-d '{"model": "nomic-embed-text", "input": "one representative chunk of your corpus"}' > /dev/nullYerel bir vektörleştirme modeli, ağırlıklarını bellek deposuyla aynı diske yazar; Ollama'nın indirilen modelleri nereye kaydettiği bu alanın nereye gittiğini açıklar.
Tüm bunları mümkün kılan tek bir gereksinim vardır: kaynak metni her vektörün yanında tutun. Sadece vektörleri barındıran bir depo hiçbir şekilde yeniden vektörleştirilemez, çünkü yeni modele beslenecek bir veri kalmamıştır. "Bu satırı hangi metin üretti" sorusuna yanıt veremiyorsanız, geçiş yolunuz metnin ilk geldiği kaynaktan tam bir yeniden oluşturma olacaktır.
Bellek dolduğunda izlenmesi gerekenler
Depolama alanı doldukça değişen tek şey maliyet değildir. Eski olgular güncelliğini yitirir ve eski bölümler faydalı sonuçları bastırır; bu durum tekrar budama sorununu ortaya çıkarır. Bir bellek deposu, aynı zamanda ajanın gelecekteki davranışları için yazılabilir bir girdi niteliğindedir; bu nedenle içine yazılmasına izin verilen her şey, ajanı daha sonra yönlendirebilir. Web sayfalarından veya destek taleplerinden gelen metinler belleğe ulaşıyorsa, yazma yetkisi verilen kaynakları genişletmeden önce ajan belleği zehirlenmesinin nasıl çalıştığını okuyun. Geri getirme boyutu, her bir istekteki token harcamasını da belirler; bir ajanın işletim maliyetini öngörülebilir tutmak işte buradan başlar.
FAQ
Ajan belleği için vektör veritabanına ihtiyacım var mı?
Olgusal veriler için hayır. Anlamsal bellek küçüktür ve isim bazlı düzeltme gerektirir; bu nedenle anahtarlı bir tablo veya git içindeki markdown dosyalarından oluşan bir dizin daha kullanışlıdır, çünkü tek bir değeri görüp düzenleyebilirsiniz. Gömme (embedding) vektörleri, listelenemeyecek kadar büyük bir külliyat içinde anlamsal arama yapmanız gerektiğinde maliyetini karşılar; bu genellikle epizodik bellek ve belgeler için geçerlidir. Zaten Postgres kullanıyorsanız, CREATE EXTENSION vector bunu yönetilecek başka bir servis eklemeden karşılar.
Bir ajan bellek deposu ne kadar disk alanı kullanır?
Vektörler öngörülebilirdir; pgvector içinde boyut başına 4 bayt ve 8 baytlık bir başlık kullanılır. 768 boyutta bu, 100.000 satır için 293.7 MiB, 384 boyutta ise 147.2 MiB eder. Buna parça metinlerini, satır ek yükünü ve vektörlerin kendi kopyasını tutan HNSW indeksini ekleyin; bu nedenle vektör boyutunun en az iki katını bütçenize dahil edin ve gerçek değeri pg_total_relation_size ile ölçün.
Prosedürel bellek nerede tutulmalıdır?
Ajanın doğrudan çalıştırdığı betikler veya yetenek dosyaları olarak bir git deposunda tutulmalıdır. Bir prosedür kesin geri çağırma ve sürüm geçmişi gerektirir; benzerlik araması bunların hiçbirini sağlamaz. Parçalara ayrılmış bir operasyonel el kitabı (runbook), en yüksek puanlı parçaları getirir; bu da 2. ve 5. adımların gelip 3. adımın eksik kalması anlamına gelebilir ve hangi sürümün çalıştığına dair hiçbir kayıt tutulmaz.
Gömme modelini değiştirmenin maliyeti nedir?
Külliyatın tamamen yeniden gömülmesi gerekir, çünkü farklı modellerden gelen vektörler birbiriyle kıyaslanamaz. Token ücretini veya GPU süresini, aynı anda hem eski hem de yeni sütunlar için gereken disk alanını ve indeksin yeniden oluşturulma maliyetini bütçenize ekleyin. Yeni sütunu ekleyin, toplu işlemlerle verileri doldurun, sorguyu değiştirin ve ardından eski sütunu silin. Tüm bunlar, kaynak metni her vektörün yanında saklamış olmanıza bağlıdır.