Cara Self-host Mem0 pada VPS: Panduan Lengkap
Ketahui cara sebenar menjalankan pelayan memori Mem0 pada VPS anda. Dapatkan konfigurasi Docker Compose, keperluan RAM minimum 1GB, serta cara mengintegrasikan Ollama dengan selamat.
Kos sebenar RAM untuk self-hosting mem0 pada VPS
Self-hosting mem0 bermaksud menjalankan tiga kontena: pelayan memori FastAPI, Postgres dengan sambungan pgvector, dan papan pemuka Next.js. mem0 ialah lapisan memori untuk ejen. Anda menghantar perbualan kepadanya, model bahasa akan mengekstrak fakta kekal daripada perbualan tersebut, dan fakta itu disimpan sebagai vektor supaya pertanyaan seterusnya boleh mendapatkan semula maklumat yang relevan.
Peruntukkan kira-kira 1 GB memori residen untuk ketiga-tiga kontena tersebut, dan 3 hingga 4 GB ruang cakera setelah imej dibina. VPS 2 GB boleh menjalankan ini dengan selesa apabila model bahasa ditempatkan di tempat lain. Apabila model dijalankan pada mesin yang sama melalui Ollama, model tersebut akan menggunakan sumber yang paling banyak: model 8B yang dikuantisasi kepada 4 bit memerlukan sekitar 6 GB secara sendirian, jadi binaan yang sepenuhnya tempatan bermula pada 8 GB.
Jangan ambil angka tersebut daripada catatan blog, termasuk catatan ini. Ukur tindanan (stack) yang anda bina sendiri.
docker compose ps
docker stats --no-stream
docker system df -vdocker stats mencetak memori residen bagi setiap kontena. docker system df -v mencetak ruang cakera yang digunakan oleh setiap imej dan setiap volum.
Keadaan stabil bukanlah kemuncak penggunaan. docker compose up -d --build menyusun (compile) papan pemuka Next.js, dan binaan Node tersebut merupakan saat yang paling banyak menggunakan sumber sepanjang pemasangan. Pada VPS 1 GB, pembunuh kehabisan memori (OOM killer) kernel akan menghentikannya dan binaan berakhir dengan exit code 137. Sahkan puncanya sebelum anda mencari pepijat Docker:
dmesg -T | grep -i "killed process"Jika pelayan dirasakan terlalu berat untuk keperluan anda, pilihan yang lebih kecil adalah realistik. storan memori ejen tempatan tanpa pelayan dan memori yang berada di dalam Claude Code itu sendiri kedua-duanya tidak memerlukan pangkalan data. Kembali ke sini apabila beberapa ejen, atau beberapa mesin, perlu membaca memori yang sama.
Adakah saya perlukan Neo4j untuk memori graf mem0?
Tidak. Jika panduan yang anda rujuk meminta anda menambah kontena Neo4j, panduan tersebut sudah lapuk berbanding kod semasa.
Memori graf dalam mem0 dahulu merujuk kepada pangkalan data graf luaran yang dikonfigurasikan di bawah kunci graph_store dengan enable_graph ditetapkan kepada true. Algoritma memori baharu yang dikeluarkan pada April 2026 telah membuang kedua-dua kunci tersebut daripada SDK sumber terbuka. Pengekstrakan entiti kini berjalan di dalam laluan add biasa, dan entiti tersebut ditulis ke dalam koleksi pgvector kedua yang dinamakan sempena koleksi utama anda dengan tambahan _entities. Tiada migrasi yang perlu dijalankan. Pemautan entiti terbina dalam akan mula berfungsi pada panggilan add seterusnya.
Membuang stor graf menjimatkan kontena JVM, heap-nya, serta beberapa ratus megabait imej. Pada VPS 2 GB, ini adalah perbezaan antara sistem yang berjalan lancar dan sistem yang mengalami swapping.
Berikut adalah perkara yang anda lepaskan, dinyatakan dengan jelas. Hasil carian dahulu membawa medan relations yang menyenaraikan hubungan (edges) antara entiti. Medan tersebut sudah tiada. Padanan entiti kini meningkatkan kedudukan memori dalam skor gabungan, dan tiada struktur yang boleh anda teroka (traverse). Jika aplikasi anda sebelum ini menelusuri hubungan tersebut, mem0 tidak lagi menyimpannya, dan anda perlu mengekalkan pangkalan data graf anda sendiri di luar mem0, yang diisi oleh kod anda sendiri.
Fail compose dalam repo tersebut adalah compose pembangunan
server/docker-compose.yaml mengisytiharkan name: mem0-dev, dan ia bermaksud sedemikian. Baca fail tersebut sebelum anda menjalankannya, kerana terdapat lima perkara di dalamnya yang tidak sesuai untuk pelayan.
- Ia membina daripada
server/dev.Dockerfiledan melakukan mount pada direktori checkout anda ke atas imej dengan.:/app, jadi kontena akan menjalankan apa sahaja yang ada dalam direktori tersebut dan bukannya apa yang telah anda bina. - Perintahnya ialah
rm -rf /app/packages && pip install -q --force-reinstall --no-deps mem0ai && alembic upgrade head && uvicorn main:app --reload. Ini memasang semulamem0aidaripada PyPI pada setiap permulaan, jadi versi yang dijalankan oleh pelayan anda boleh berubah semasa but semula yang anda tidak sangka sebagai naik taraf. - Langkah pip yang sama bermakna but semula tanpa rangkaian keluar akan gagal sebelum uvicorn sempat berjalan. Pelayan memori anda kemudiannya akan terhenti kerana PyPI tidak dapat dicapai.
--reloadmemulakan pemerhati fail uvicorn. Ia wujud untuk memulakan semula proses apabila anda mengedit kod, dan ia memakan memori serta proses tambahan yang tidak berguna dalam pengeluaran.Dockerfilepengeluaran juga membawa--reloaddalamCMD-nya, jadi anda akan mengatasi perintah tersebut walau apa pun caranya.- Port yang diterbitkan ialah
"8888:8000","8432:5432"dan"3000:3000". Port yang diterbitkan tanpa alamat di hadapannya akan mengikat0.0.0.0, jadi Postgres akan menjawab permintaan daripada internet awam pada port 8432 sebaik sahaja stack bermula.
Perkara terakhir itu memerlukan amaran tersendiri. Docker menerbitkan port dengan menulis peraturannya sendiri mendahului rantaian yang diuruskan oleh ufw, jadi ufw deny 8432 tidak akan menutup port kontena yang diterbitkan. Docker menerbitkan port terus melepasi ufw menghuraikan peraturan yang terlibat.
Fail compose untuk pelayan sebenar
Bekerja di dalam server/, kekalkan init-db.sh di tempatnya, dan gantikan docker-compose.yaml dengan ini.
name: mem0
services:
mem0:
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
env_file: .env
ports:
- "127.0.0.1:8888:8000"
networks: [mem0_network]
volumes:
- mem0_history:/app/history
depends_on:
postgres:
condition: service_healthy
command: >
sh -c "alembic upgrade head &&
uvicorn main:app --host 0.0.0.0 --port 8000"
environment:
- PYTHONUNBUFFERED=1
- DASHBOARD_URL=https://mem0.example.com
- APP_DB_NAME=mem0_app
- AUTH_DISABLED=false
- MEM0_TELEMETRY=false
postgres:
image: pgvector/pgvector:pg17
restart: unless-stopped
shm_size: "128mb"
networks: [mem0_network]
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
healthcheck:
test: ["CMD-SHELL", "pg_isready -q -U ${POSTGRES_USER:-postgres}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- postgres_db:/var/lib/postgresql/data
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
mem0-dashboard:
build: ./dashboard
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
networks: [mem0_network]
environment:
- NEXT_PUBLIC_API_URL=https://mem0.example.com
- API_INTERNAL_URL=http://mem0:8000
depends_on:
mem0:
condition: service_started
volumes:
postgres_db:
mem0_history:
networks:
mem0_network:
driver: bridgeLima perubahan penting di sini, dan setiap satunya mempunyai sebab.
Setiap entri ports bermula dengan 127.0.0.1, supaya kernel hanya menerima sambungan tersebut daripada pelayan itu sendiri. Segala trafik dari luar tiba melalui reverse proxy, yang merupakan satu-satunya komponen yang memegang sijil.
Postgres tidak mempunyai blok ports langsung. Kontena mem0 mencapainya melalui mem0_network menggunakan nama servis, jadi menerbitkan 8432 tidak memberikan sebarang manfaat dan hanya membuka port yang tidak perlu. Gunakan docker compose exec postgres psql -U postgres apabila anda memerlukan shell.
Sejarah dipindahkan daripada bind mount ./history kepada named volume. Bind mount mengikat data kepada satu path dan satu uid pada hos ini, manakala named volume ialah objek yang boleh disnaphot dan dipindahkan oleh Docker. Named volumes berbanding bind mounts membincangkan bila setiap satunya sesuai digunakan.
Arahan tersebut menggugurkan --reload dan mengekalkan alembic upgrade head. Kekalkan langkah migrasi tersebut. Tanpanya, aplikasi akan bermula dengan pangkalan data yang tiada jadual, dan setiap permintaan akan gagal pada query pertama.
NEXT_PUBLIC_API_URL ialah URL yang dipanggil oleh pelayar anda, jadi ia mestilah alamat HTTPS awam dan bukan http://mem0:8000. Next.js memasukkan setiap nilai NEXT_PUBLIC_ semasa proses binaan (build time), jadi menukarnya memerlukan docker compose up -d --build mem0-dashboard. Restart biasa akan mengekalkan nilai lama yang telah terbenam di dalam JavaScript dan papan pemuka akan memanggil hos yang salah.
Rahsia disimpan dalam .env, dan .env tidak boleh diakses dari internet
cd server
cp .env.example .env
openssl rand -hex 32 # paste into JWT_SECRET
openssl rand -hex 32 # paste into ADMIN_API_KEY
chmod 600 .envTetapkan POSTGRES_PASSWORD, JWT_SECRET dan ADMIN_API_KEY. Biarkan AUTH_DISABLED=false. Nama flag tersebut menerangkan fungsinya dengan jelas: apabila diaktifkan, pelayan akan memberikan semua memori yang dipegangnya kepada sesiapa sahaja yang boleh mencapai port tersebut. Tetapkan MEM0_TELEMETRY=false jika anda tidak mahu acara onboarding dihantar ke upstream.
ADMIN_API_KEY dibandingkan dengan header X-API-Key menggunakan secrets.compare_digest, dan padanan yang berjaya akan melangkau setiap carian pangkalan data. Ia merupakan kelayakan root untuk keseluruhan API. Kendalikannya seperti kelayakan root: jangan simpan dalam shell history, jangan masukkan ke dalam git, dan jangan tampal ke dalam prompt. Menyusun fail env dan punca kebocoran rahsia daripadanya dan menjauhkan kunci API daripada konteks ejen kedua-duanya terpakai secara langsung, kerana pemanggil pelayan ini adalah ejen.
Nilai yang dimuatkan daripada env_file berada dalam persekitaran kontena, dan docker inspect mencetaknya secara penuh. Sesiapa sahaja dalam kumpulan docker boleh membacanya, dan sesiapa sahaja dalam kumpulan docker secara efektifnya adalah root pada hos.
Letakkan TLS di hadapan API dan bukannya membuka port 8888
API menjawab pada 127.0.0.1:8888 dan papan pemuka pada 127.0.0.1:3000. nginx menamatkan TLS (transport layer security) pada port 443 dan menghalakan trafik kepada kedua-duanya.
server {
listen 443 ssl;
server_name mem0.example.com;
ssl_certificate /etc/letsencrypt/live/mem0.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mem0.example.com/privkey.pem;
location ~ ^/(memories|search|configure|auth|api-keys|docs|openapi.json) {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 180s;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}proxy_read_timeout adalah lebih penting daripada yang kelihatan. Panggilan tambah (add call) akan menyekat sementara model bahasa membaca perbualan dan mengekstrak fakta. Model 8B tempatan pada CPU biasanya mengambil masa lebih lama daripada nilai lalai 60 saat nginx, dan kemudian pemanggil akan melihat 504 Gateway Time-out semasa model masih berfungsi dan memori masih ditulis. Anda akan berakhir dengan memori yang diberitahu sebagai gagal.
Tutup port lain dengan polisi ufw default deny, dan biarkan port 22 dan 443 terbuka. Terbitkan sijil dengan certbot pada Ubuntu 24.04 di belakang nginx. Jika pelayan sudah mengendalikan aplikasi lain dengan Traefik yang menghalakan beberapa aplikasi Compose, tambahkan mem0 pada router tersebut dan bukannya memasang proksi kedua.
Ujian asap: tambah satu memori dan baca semula
export MEM0_KEY='<the ADMIN_API_KEY from .env>'
curl -sS -X POST http://127.0.0.1:8888/memories \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d '{"messages":[{"role":"user","content":"I deploy with Docker Compose and I run Postgres 17."}],"user_id":"smoke"}'Respons yang sihat ialah objek JSON dengan senarai results, dan setiap entri mengandungi id, teks memory yang diekstrak, dan "event": "ADD". Algoritma semasa hanya mengembalikan peristiwa ADD. Peristiwa UPDATE dan DELETE telah dibuang, jadi ketiadaannya bukanlah satu pepijat.
curl -sS -X POST http://127.0.0.1:8888/search \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d '{"query":"which database do I run?","filters":{"user_id":"smoke"},"top_k":5}'Fakta tentang Postgres 17 sepatutnya kembali dengan skor. Hantar pengecam di dalam filters, seperti yang ditunjukkan. user_id peringkat atas masih berfungsi, dan pelayan mencatat Top-level user_id in /search is deprecated. Use filters={...} instead. setiap kali anda menggunakannya.
Bersihkan data anda supaya data ujian tidak mencemarkan carian sebenar:
curl -sS -X DELETE "http://127.0.0.1:8888/memories?user_id=smoke" \
-H "X-API-Key: $MEM0_KEY"Jika carian mengembalikan baris yang lebih sedikit daripada yang anda jangkakan, semak tetapan lalai sebelum menyalahkan proses perolehan data. Dalam keluaran semasa, top_k ditetapkan secara lalai kepada 20, turun daripada 100, dan threshold ditetapkan secara lalai kepada 0.1 dan bukannya tiada, jadi padanan yang lemah kini ditapis untuk anda. Sebaik sahaja ini berfungsi melalui curl, titik akhir yang sama adalah apa yang anda sambungkan ke ejen, sama ada secara terus atau melalui pelayan MCP yang berjalan pada VPS yang sama.
Jalankan mem0 tanpa sebarang kunci OpenAI
Mulakan dengan penyekat, kerana anda akan menemuinya dalam lima minit pertama. Imej pelayan menghantar set pustaka penyedia yang tetap, dan /configure menolak sebarang perkara di luar set tersebut:
LLM provider 'ollama' is not bundled in this image. Bundled providers: openai, anthropic, gemini. To use another provider, install its Python package, rebuild the container, and extend BUNDLED_LLM_PROVIDERS in server/main.py.Anda tidak perlu membina semula apa-apa. Ollama menyediakan API yang serasi dengan OpenAI pada /v1, meliputi /v1/chat/completions dan /v1/embeddings, dan penyedia openai mem0 menerima openai_base_url. Halakan kunci tersebut ke Ollama dan semakan yang dibundel akan lulus, kerana penyedianya sememangnya openai. Hanya alamatnya yang berubah.
Tambah Ollama ke dalam projek Compose yang sama:
ollama:
image: ollama/ollama
restart: unless-stopped
networks: [mem0_network]
ports:
- "127.0.0.1:11434:11434"
volumes:
- ollama_models:/root/.ollamaTambah ollama_models: di bawah kunci peringkat atas volumes:, kemudian tarik satu model sembang dan satu model embedding:
docker compose up -d ollama
docker compose exec ollama ollama pull llama3.1:8b
docker compose exec ollama ollama pull nomic-embed-textJika Ollama sudah berjalan pada hos sebagai unit systemd, seperti dalam menjalankan Ollama secara terus pada VPS, jangan halakan kontena ke 127.0.0.1:11434. Di dalam kontena mem0, 127.0.0.1 ialah kontena mem0 itu sendiri. Berikan perkhidmatan mem0 extra_hosts: ["host.docker.internal:host-gateway"], tetapkan Environment="OLLAMA_HOST=0.0.0.0:11434" dalam drop-in systemd supaya Ollama mendengar pada alamat yang boleh dicapai oleh bridge, dan pastikan port 11434 ditutup pada firewall.
Tanya model tentang dimensi embeddingnya sebelum anda mengkonfigurasi apa-apa
Langkah ini menentukan sama ada fungsi perolehan (retrieval) akan berfungsi atau tidak.
Storan pgvector mem0 mencipta jadualnya dengan lebar vektor tetap, vector vector(1536), kerana embedding_model_dims secara lalai menggunakan 1536, iaitu lebar bagi text-embedding-3-small OpenAI. nomic-embed-text mengembalikan 768 nilai. Tiada apa-apa di dalam mem0 yang membandingkan kedua-dua nombor tersebut, jadi ketidakpadanan itu akan timbul daripada Postgres pada sisipan pertama:
expected 1536 dimensions, not 768Jangan percaya nombor dalam perenggan ini juga. Tanya model tersebut:
curl -sS http://127.0.0.1:11434/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"model":"nomic-embed-text","input":"dimension check"}' \
| python3 -c "import json,sys; print(len(json.load(sys.stdin)['data'][0]['embedding']))"Ini akan mencetak lebar yang perlu digunakan oleh koleksi anda. Tulis konfigurasi ke dalam fail, kerana menampal kata laluan Postgres melalui shell quoting adalah punca kesilapan taip masuk ke dalam pengeluaran.
{
"vector_store": {
"provider": "pgvector",
"config": {
"host": "postgres",
"port": 5432,
"dbname": "postgres",
"user": "postgres",
"password": "<POSTGRES_PASSWORD from .env>",
"collection_name": "memories_local_768",
"embedding_model_dims": 768
}
},
"llm": {
"provider": "openai",
"config": {
"model": "llama3.1:8b",
"api_key": "ollama",
"openai_base_url": "http://ollama:11434/v1",
"temperature": 0.2
}
},
"embedder": {
"provider": "openai",
"config": {
"model": "nomic-embed-text",
"api_key": "ollama",
"openai_base_url": "http://ollama:11434/v1"
}
}
}curl -sS -X POST http://127.0.0.1:8888/configure \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d @config.json
curl -sS http://127.0.0.1:8888/configure -H "X-API-Key: $MEM0_KEY"Panggilan kedua membaca semula konfigurasi, yang merupakan semakan bahawa penulisan telah berjaya. Kemudian ulangi ujian asap di atas.
Empat butiran dalam JSON tersebut tidak jelas, dan setiap satu akan menyebabkan kegagalan jika anda tersilap.
api_key ialah rentetan ollama, dan Ollama mengabaikan nilainya. Ia tidak boleh kosong, kerana pustaka klien OpenAI akan melenting sebelum sebarang permintaan meninggalkan proses apabila tiada kunci ditetapkan. Sebarang rentetan yang tidak kosong akan berfungsi.
embedding_model_dims diletakkan pada storan vektor, dan sengaja tiada embedding_dims pada embedder. mem0 menghantar parameter dimensions OpenAI hanya apabila anda menetapkan embedding_dims, dan backend yang tidak melaksanakan pemotongan Matryoshka akan menolak parameter tersebut secara terus. Tetapkan lebar di tempat jadual dicipta, dan biarkan embedder seperti sedia ada.
collection_name adalah baharu. mem0 mencipta jadualnya dengan CREATE TABLE IF NOT EXISTS, jadi menghalakan lebar yang berbeza ke koleksi sedia ada tidak akan memberi kesan: lajur vector(1536) yang lama kekal, dan setiap sisipan akan gagal. Perubahan lebar memerlukan nama koleksi yang baharu, atau anda perlu membuang jadual lama secara manual.
Hos dalam openai_base_url ialah nama perkhidmatan Compose ollama, bukan localhost. Kontena menyelesaikan antara satu sama lain melalui nama perkhidmatan pada rangkaian kongsi mereka.
Kos laluan tempatan sepenuhnya
Jujurlah dengan diri sendiri mengenai kualiti. Skor penanda aras mem0 yang diterbitkan diukur dengan model sempadan (frontier models) yang melakukan pengekstrakan, jadi anggap ia sebagai siling dan bukannya ramalan untuk model 8B pada VPS anda. Model kecil menulis fakta yang lebih samar, dan kadangkala mengembalikan prosa apabila JSON diminta, yang ditunjukkan sebagai panggilan tambah yang mengembalikan senarai results kosong tanpa ralat.
Kelajuan adalah kos yang lain. Pengekstrakan berasaskan CPU sahaja mengambil masa beberapa saat bagi setiap panggilan tambah, dan setiap mesej yang anda simpan akan menanggung kos tersebut. Jika kependaman (latency) itu penting, VPS dengan GPU terpasang adalah penyelesaian yang jujur. Menambah lebih banyak teras CPU pada model 8B kurang membantu berbanding jangkaan orang ramai.
Satu peraturan kekal tidak kira apa yang anda pilih: jangan sesekali mencampurkan model embedding di dalam satu koleksi. Dua model berbeza yang kebetulan berkongsi lebar yang sama akan menghasilkan vektor yang tidak boleh dibandingkan. Sisipan berjaya, carian mengembalikan baris, dan baris tersebut adalah salah, tanpa sebarang laporan ralat di mana-mana.
Sandaran: terdapat dua pangkalan data, bukan satu
Kesilapan sandaran mem0 yang paling biasa ialah melakukan dump pada satu pangkalan data sahaja. init-db.sh mencipta mem0_app di samping pangkalan data lalai postgres, dan kedua-duanya menyimpan data yang berbeza. Pangkalan data postgres menyimpan koleksi pgvector, iaitu memori. mem0_app pula menyimpan pengguna, sesi, kunci API dan log permintaan.
Jika anda memulihkan postgres sahaja, memori akan kembali tetapi semua akaun dan kunci API akan hilang, menyebabkan tiada apa-apa yang boleh disahkan untuk membacanya. Lakukan dump kedua-duanya, berserta peranan (roles), dalam satu arahan:
docker compose exec -T postgres pg_dumpall -U postgres --clean \
| gzip > "mem0-$(date +%F).sql.gz"Volum sejarah adalah berasingan daripada Postgres dan memerlukan salinannya sendiri:
docker run --rm -v mem0_mem0_history:/data -v "$PWD:/backup" \
alpine tar czf /backup/mem0-history.tgz -C /data .Docker meletakkan awalan nama projek pada nama volum, jadi sahkan nama volum anda dengan docker volume ls sebelum menganggap ia adalah mem0_mem0_history.
Pulihkan ke dalam kontena baharu (scratch container) dan semak kiraan baris sebelum anda mempercayai data tersebut:
gunzip -c mem0-2026-08-03.sql.gz \
| docker compose exec -T postgres psql -U postgres -d postgresSandaran yang tidak pernah anda pulihkan hanyalah satu andaian. Apabila dump sudah betul, pindahkan ia keluar dari pelayan dengan syot kilas restic ke storan luar tapak, kerana sandaran yang disimpan pada pelayan yang sama tidak memberikan sebarang perlindungan.
Mod kegagalan dan rentetan tepat yang akan anda lihat
{"detail":"Authentication required. Provide a Bearer token or X-API-Key header."} bermaksud pengepala hilang atau tersalah eja. Namanya ialah X-API-Key, dan curl menghantar nama pengepala secara literal.
{"detail":"At least one identifier (user_id, agent_id, run_id) is required."} pada penambahan bermaksud permintaan tersebut tidak mempunyai sebarang pengepala. Memori perlu diletakkan dalam skop sesuatu, kerana penapis carian berfungsi tepat pada medan tersebut.
LLM provider 'ollama' is not bundled in this image dengan HTTP 400 bermaksud anda menghantar "provider": "ollama". Gunakan "provider": "openai" dengan openai_base_url dihalakan ke Ollama.
expected 1536 dimensions, not 768 daripada Postgres bermaksud koleksi dicipta pada satu lebar dan penyemat (embedder) mengembalikan lebar yang lain. Tetapkan embedding_model_dims pada stor vektor dan gunakan collection_name yang baharu.
Carian mengembalikan baris yang tidak masuk akal selepas perubahan model, tanpa sebarang ralat. Lebar masih sepadan, jadi pangkalan data berfungsi dengan baik, tetapi dua model meletakkan ayat yang sama pada kedudukan yang berbeza. Mulakan koleksi baharu dan tambah semula.
Connection refused dalam log mem0 semasa mencapai Ollama biasanya bermaksud 127.0.0.1 dalam openai_base_url. Di dalam kontena, alamat tersebut ialah kontena itu sendiri. Gunakan nama servis, atau host gateway apabila Ollama berjalan pada hos.
504 Gateway Time-out daripada nginx pada penambahan bermaksud model mengambil masa lebih lama daripada proxy_read_timeout. Tingkatkan nilainya, dan semak sama ada memori telah ditulis sebelum anda mencuba semula permintaan tersebut.
exit code 137 semasa docker compose up --build ialah pembunuh kehabisan memori (out-of-memory killer) yang menghentikan binaan papan pemuka. Tambah swap, atau bina imej pada mesin yang lebih besar dan tolak (push) ke registri.
error: port 3000 is already in use datang daripada sasaran make up dalam repo, yang enggan bermula apabila port 3000 atau 8888 sedang digunakan. Cari pemiliknya dengan lsof -iTCP:3000 -sTCP:LISTEN.
FAQ
Adakah saya masih memerlukan Neo4j untuk menjalankan mem0 dengan memori graf?
Tidak. Algoritma memori baharu, yang dikeluarkan pada April 2026, telah membuang kunci konfigurasi graph_store dan enable_graph daripada SDK sumber terbuka. Pengekstrakan entiti kini berjalan semasa proses penambahan biasa dan menulis ke koleksi pgvector kedua yang dinamakan <collection_name>_entities, jadi tiada pangkalan data graf luaran, tiada kontena tambahan dan tiada langkah migrasi diperlukan. Kesannya, medan relations pada hasil carian tidak lagi wujud. Entiti kini meningkatkan kedudukan memori dan bukannya memberikan anda hubungan (edges) untuk dilalui, jadi aplikasi yang sebelum ini melayari hubungan tersebut memerlukan storan grafnya sendiri di luar mem0.
Apakah saiz VPS terkecil yang boleh menjalankan pelayan mem0 yang dihoskan sendiri?
Dengan model bahasa dihoskan di tempat lain, 2 GB RAM dan kira-kira 4 GB ruang cakera kosong sudah memadai untuk kontena API, Postgres dan papan pemuka. Saat yang kritikal ialah binaan pertama, kerana menyusun (compiling) papan pemuka Next.js menggunakan lebih banyak memori berbanding menjalankannya, dan pelayan 1 GB akan menyebabkan proses binaan dimatikan dengan exit code 137. Jika Ollama dijalankan pada pelayan yang sama, sediakan ruang untuk model tersebut: model 8B pada kuantisasi 4-bit memerlukan kira-kira 6 GB secara sendirian, jadi rancang untuk menggunakan 8 GB.
Bolehkah saya menjalankan mem0 tanpa kunci API OpenAI?
Boleh, melalui endpoint Ollama yang serasi dengan OpenAI. Menetapkan "provider": "ollama" akan gagal, kerana imej pelayan hanya menyertakan pustaka openai, anthropic dan gemini serta akan mengembalikan HTTP 400. Sebaliknya, kekalkan "provider": "openai" dan tetapkan "openai_base_url": "http://ollama:11434/v1" dengan sebarang api_key yang tidak kosong, untuk kedua-dua llm dan embedder. Ollama akan mengabaikan kunci tersebut, dan semakan pembekal yang disertakan akan lulus kerana pembekalnya memang openai.
Mengapa mem0 tidak mengembalikan sebarang hasil selepas saya bertukar kepada model embedding tempatan?
Ini kerana jadual pgvector dicipta dengan lebar tetap. embedding_model_dims ditetapkan secara lalai kepada 1536, nomic-embed-text mengembalikan 768, dan Postgres akan menolak sisipan tersebut dengan expected 1536 dimensions, not 768. mem0 mencipta jadual dengan CREATE TABLE IF NOT EXISTS, jadi menukar nombor tersebut sahaja tidak akan memberi kesan kepada koleksi yang sedia ada. Tetapkan embedding_model_dims kepada lebar sebenar model anda, sahkan lebar tersebut dengan memanggil /v1/embeddings dan mengira nilai yang dikembalikannya, serta berikan storan vektor tersebut collection_name yang baharu pada masa yang sama.