SSD Nodes Learn 8GB 記憶體 — 每年 $66
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-01

Memmy:在 VPS 上建立 AI 代理共用記憶體

Memmy 將 AI 代理的記憶集中在本機 SQLite 資料庫。本文說明如何在 Ubuntu 從原始碼建置,啟動 port 18960 的服務,並讓 Claude Code、Codex 與 Cursor 共用。

Memmy 的用途與儲存內容

Memmy 是在您自己的 VPS (virtual private server) 上執行的 AI 代理程式本機記憶體中樞。它會將代理程式學到的內容儲存在單一 SQLite 資料庫中,該主機上的每個代理程式都會讀取及寫入同一個儲存區。此專案由 MemTensor memmy-agent,採用 MIT 授權;截至 2026 年 7 月,版本為 1.0.4。

在伺服器上,只有其中一部分功能相關。Memmy 提供在 http://127.0.0.1:18960 上接聽的記憶體服務、與該服務通訊的 memmy-memory 命令列介面 (CLI),以及桌面工作台。工作台僅提供 macOS 和 Windows 套件,因此在 Linux VPS 上,您只需執行服務和 CLI。這樣即可讓 Claude Code、Codex 和 Cursor 共用記憶體。

Memmy 將儲存內容分為四個層級。L1 Trace 是原始回合,包括請求、回應和工具呼叫。L2 Policy 是從已證實有用的追蹤記錄中歸納出的程序。L3 World Model 是關於專案或環境的穩定知識。Skill 是從原則具體化而成的可呼叫程序。服務在擷取回合時會指派層級,因此您不必手動建立這些層級。

共用記憶中樞與各工具個別記憶的差異

目前每個代理程式都有自己的記憶體。Claude Code 會將指示檔案儲存在存放庫中。Cursor 會將規則儲存在其工作區資料庫中。Codex 會將工作階段記錄儲存在 ~/.codex 下。每個儲存區都隸屬於單一工具,因此您週一在某個工具中教導的資訊,週二在另一個工具中仍然無法取得。這會產生兩種成本:一是重複說明同一個專案所耗用的權杖,二是代理程式根據您已在其他位置修正的假設執行錯誤工作。

中樞會將儲存區移出工具。Memmy 也會讀取現有的儲存區,因此您不必從空白資料庫開始。其掃描器支援 6 個來源:位於 ~/.claude/projects/**/*.jsonl 的 Claude Code、位於 ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl 的 Codex、位於 ~/.local/share/opencode/opencode.db 的 OpenCode、Cursor 的 state.vscdb 檔案、位於 ~/.openclaw 下的 OpenClaw SQLite 資料庫,以及位於 ~/.hermes 的 Hermes。您可以手動新增來源,指定名稱和本機路徑。

匯入計數不會一致,這是預期行為。掃描器會依來源和對話將訊息分組,然後為每個完整回合寫入一筆 L1 記憶。當回合包含非空白的使用者內容,且以非空白的代理程式訊息結束時,才算完整。因此,中斷的工作階段不會產生任何內容。訊息會透過對話檢查點和穩定的回合 ID 去除重複。同一次執行中,掃描數、匯入訊息數和新增記憶數都會不同。

這是與Claude Code 如何在單一工作階段內管理內容相互配合的部分。內容管理決定單一視窗能容納哪些內容。記憶中樞則決定視窗關閉後哪些內容仍會保留。

VPS 所需環境

  • Node.js 22 或更新版本。Memmy 文件要求此版本,而 Ubuntu 24.04 內建 Node 18。
  • git 和建置工具鏈,因為 better-sqlite3 是原生模組,安裝期間可能需要編譯。
  • 約 2 GB RAM。root 安裝會載入大型工作區和前端建置工具鏈。
  • 數 GB 可用磁碟空間,用於 node_modules 和資料庫。
sudo apt update
sudo apt install -y git build-essential python3 curl ca-certificates sqlite3
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node --version

node --version 應輸出 v22 或更高版本。若此處顯示 v18,表示 NodeSource 步驟未成功,之後安裝會在專案的引擎檢查階段失敗。

在 Ubuntu 24.04 上從原始碼安裝 Memmy

git clone https://github.com/MemTensor/memmy-agent.git
cd memmy-agent
cp .env.example .env
npm install
npm run memory:build

npm run memory:build 會將 @memmy/memory 工作區編譯為 Memory/dist。無頭伺服器不需要建置樹狀目錄中的其他內容。確認原生模組已載入:

node -e "require('better-sqlite3'); console.log('better-sqlite3 loads')"

如果該行擲回錯誤而不是輸出內容,表示原生模組與您的 Node 版本不相容。請執行 npm rebuild better-sqlite3。這正是專案自己的啟動指令碼在啟動任何內容前執行的命令。

README 將 bash scripts/dev-start.sh 記載為單一命令的啟動方式。請勿在無頭 VPS 上執行。它會啟動 Electron 桌面 shell,以及在 port 19000 上執行的 Vite 開發伺服器,並與記憶體服務並行。Electron 需要顯示器,因此在沒有圖形工作階段的伺服器上,該指令碼會停滯或結束。

啟動記憶體服務並確認其回應

npm run memory:serve:dev

這是從原始碼執行記憶體服務的文件指定方式。它會繫結至 127.0.0.1:18960,將資料庫保留在 ~/.memmy/memory-service/memory.sqlite,並從 ~/.memmy/config.yaml 讀取設定。若要明確指定這些值,README 也列出了相同內容:

npm run memory:serve:dev -- \
  --host 127.0.0.1 --port 18960 \
  --db ~/.memmy/memory-service/memory.sqlite \
  --config ~/.memmy/config.yaml

在第二個 shell 中,詢問服務是否正常運作:

curl -sS http://127.0.0.1:18960/api/v1/health

Health 是唯一不會要求 token 的端點,因此適合作為探測端點。如果 curl 以代碼 7 結束,並顯示 Failed to connect to 127.0.0.1 port 18960 訊息,表示沒有任何程序正在監聽。查看執行服務的終端機,因為服務啟動時發生當機會在該處輸出,最常見的原因是原生 SQLite 模組載入失敗。服務啟動後,ss -lntp | grep 18960 會確認 socket。

其餘 HTTP API(應用程式介面)位於 /api/v1 底下。

  • POST /api/v1/memory/add 會寫入記憶,POST /api/v1/memory/search 會執行查詢。
  • GET /api/v1/memory/:idDELETE /api/v1/memory/:id 會讀取及移除單一項目。
  • POST /api/v1/sessions/openPOST /api/v1/sessions/:sessionId/close 會標示代理程式工作階段的開始與結束。
  • POST /api/v1/turns/startPOST /api/v1/turns/:turnId/complete 會記錄一個回合。
  • GET /api/v1/panel/overview/api/v1/panel/analysis/api/v1/panel/items 會將資料提供給儀表板。

Memmy 會保留一組連續的連接埠;在無頭模式下只會使用其中第一個:18960 用於記憶體服務、18970 用於 gateway health、18980 用於 Web UI 和管理 HTTP、18990 用於由 memmy serve 啟動的 OpenAI 相容 API,接著是 19000 和 19010,供桌面前端的開發伺服器使用。如果您的電腦上已有其他程式占用其中一個連接埠,請從這份清單開始檢查。

memmy-memory 命令實際來源

這通常是首次安裝出錯的地方,因此請直接從套件讀取,不要猜測。命令名稱與儲存庫名稱無關。它來自定義該命令之工作區的 bin 欄位:

node -p "JSON.stringify(require('./Memory/package.json').bin)"

這會輸出 {"memmy-memory":"./dist/src/cli/index.js"}。因此,建置後的進入點是 Memory/dist/src/cli/index.js。它只有在執行 npm run memory:build 後才會存在,因為建置程序會建立 dist 並將檔案設為可執行。直接執行:

node Memory/dist/src/cli/index.js health

如果要讓短名稱位於 PATH 中,請建立同一檔案的連結:

sudo ln -s "$PWD/Memory/dist/src/cli/index.js" /usr/local/bin/memmy-memory
memmy-memory health

CLI 預設為 http://127.0.0.1:18960,並接受 --url--token--config--source--user-id。其子命令包括 inithealthsearchaddgetdelete,此外還有由代理程式使用、而非由人員使用的工作階段與回合呼叫。memmy-memory search "deploy steps"memmy-memory add "staging migrates on deploy" 是代理程式最常執行的兩個命令。

如何將 Claude Code 連線至 Memmy?

Claude Code 沒有記憶體外掛程式介面,因此 Memmy 不會掛接至其中。這項整合其實更簡單。Claude Code 會將 memmy-memory 當作一般 shell 命令執行,並由指示檔案告知它何時執行。Memmy 的文件化安裝程式會替你寫入該檔案:memmy-memory init --agent 會將記憶體指示檔案放入目標代理程式的規則目錄。

請先手動撰寫一次指示內容,這樣才能確切知道代理程式收到的指示。Claude Code 會在每個工作階段開始時,從專案根目錄讀取 CLAUDE.md,因此以下這類區段就是完整的整合方式:

## Memory

Before starting a task, run `memmy-memory search "<topic>"` and read what comes back.
When a task is done, run `memmy-memory add "<what you learned>"` for anything that will matter next session.

請清楚了解這項功能的限制。這是指示層級的整合,因此只有在模型決定執行命令時才會運作。沒有任何機制強制執行該呼叫。如果工作階段結束時沒有執行 add,就不會儲存任何內容;下次搜尋時,唯一的訊號就是空白結果。這與 Claude Code 自身的記憶檔案有相同的取捨,但有一項差異:儲存區是共用的,因此同一部機器上的 Codex 和 Cursor 也能取得該筆記錄。

反向整合完全不需要設定。Memmy 的掃描器已經會讀取 ~/.claude/projects/**/*.jsonl,Claude Code 會將其工作階段逐字稿寫入此處。在執行 tmux 工作階段中的 Claude Code 的同一部伺服器上執行 Memmy,昨天的工作就會自動成為記憶,不需要進行任何設定。

Memmy 是否可作為 Claude Code 的 MCP 伺服器?

不可以。了解這個方向可節省一下午的時間。MCP(model context protocol)包含用戶端和伺服器。Memmy 是用戶端。它會連出至 MCP 伺服器,並將這些伺服器提供的工具提供給自己的代理程式執行環境。它不會發布可供 claude mcp add 連接的 MCP 端點。儲存庫中唯一的 MCP 橋接屬於桌面本機 API 內的 Composio 整合,而該 API 會在 127.0.0.1 上繫結隨機連接埠,並受其自有的 x-memmy-mcp-token 標頭保護。

用戶端端的設定位於 ~/.memmy/config.yaml,也就是 MEMMY_CONFIG 所指向的檔案,在 tools.mcpServers 下:

tools:
  mcpServers:
    example:
      type: stdio
      command: npx
      args:
        - "-y"
        - "your-mcp-server"
      toolTimeout: 30
      enabledTools:
        - "*"

type 接受 stdiossestreamableHttpstdio 伺服器會作為 Memmy 的子程序執行,因此其命令必須存在於同一台主機上,並以相同的使用者身分執行。如果您已在 VPS 上執行 MCP 伺服器,請將這些伺服器列於此處。

保持記憶儲存區為私有

Memmy 擁有的所有內容都位於 ~/.memmy 下:config.yaml、工作區、memory-service/memory.sqlite 和執行階段檔案。掃描與擷取作業都在本機執行,記憶也會寫入本機 SQLite 檔案,因此預設狀態確實是本機運作。

有兩條路徑會連線至網路。MEMMY_CLOUD_SERVICE 預設為 https://memmy-api.memtensor.cn,並以試用權杖支援帳戶模式,因此 API 金鑰模式不會呼叫它。記憶改善計畫是隱私設定中的獨立切換選項,除非你手動開啟,否則會維持關閉。

第三條路徑較容易被忽略。如果你設定代管的嵌入提供者,每則記憶的文字都會傳送至該提供者,以轉換為向量。本機儲存無法避免這種傳送。只有自行代管嵌入端點,才能完全阻止資料離開本機。

請讓連接埠 18960 綁定至迴路位址。這不需要防火牆規則,因為綁定至 127.0.0.1 的服務完全無法從本機以外連線。請改用 SSH 從筆記型電腦連線:

ssh -N -L 18960:127.0.0.1:18960 you@your-vps

如果你需要將服務綁定至更廣泛的位址,請先設定權杖。在設定中設定 storage.token,或設定 MEMMY_MEMORY_TOKENMEMORY_SERVICE_TOKEN 環境變數後,除了 health 端點外,所有端點都會要求 bearer token。設定值支援 ${ENV_NAME} 參照,因此權杖和模型 API 金鑰不會直接存放在檔案中。這與在其他地方避免讓 AI 代理程式接觸密碼的做法相同;如果未來版本變更預設綁定位址,預設拒絕的 ufw 原則則可作為最後一道防線。

信任前先備份 ~/.memmy

memory.sqlite 是完整的資料庫。向量透過 sqlite-vec 擴充功能儲存在同一個檔案中,因此備份一個檔案即可。服務寫入期間使用 cp 複製檔案,可能會產生損毀的資料庫。請使用 SQLite 內建的備份命令:

mkdir -p ~/memmy-backup
sqlite3 ~/.memmy/memory-service/memory.sqlite ".backup '$HOME/memmy-backup/memory.sqlite'"

這會在服務持續執行時建立一致的副本。請依排程將副本傳送到伺服器外部;restic 備份至異地儲存 就是用於此目的。遺失 config.yaml 時,只需重新輸入提供者設定。遺失 memory.sqlite 時,所有記憶都會遺失,而機器上的其他位置沒有第二份副本。

在 systemd 下執行記憶體服務

Shell 中的 npm run memory:serve:dev 會隨 Shell 結束。Unit file 可讓服務在重新啟動後持續執行。

[Unit]
Description=Memmy memory service
After=network-online.target

[Service]
Type=simple
User=memmy
WorkingDirectory=/opt/memmy/memmy-agent
EnvironmentFile=/etc/memmy/memory.env
ExecStart=/usr/bin/npm run memory:serve:dev
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

請勿將權杖放在 unit 中。將其放入 /etc/memmy/memory.env,由 root 擁有,權限設為 600:

MEMMY_CONFIG=/home/memmy/.memmy/config.yaml
MEMMY_MEMORY_TOKEN=replace-this-with-a-long-random-string
sudo systemctl daemon-reload
sudo systemctl enable --now memmy-memory
systemctl status memmy-memory --no-pager
curl -sS http://127.0.0.1:18960/api/v1/health

狀態輸出中的 status=203/EXEC 表示 systemd 完全無法執行 ExecStart,因此請檢查 which npm:在 NodeSource 安裝中,它位於 /usr/bin/npm;在 nvm 中,則位於使用者主目錄下的某個位置,而 systemd 找不到該位置。若 unit 啟動後立即結束,表示 npm 內部發生錯誤;journalctl -u memmy-memory -n 50 會列出原因。其運作方式與 VPS 上的其他 systemd 服務 相同。

Memmy 目前尚未支援的功能

  • 目前沒有 Linux 桌面版本。封裝指令碼涵蓋 macOS 和 Windows,因此 workbench、初始設定精靈與記憶體儀表板無法直接在伺服器上使用。
  • memory:serve:dev 會透過 tsx 執行 TypeScript 進入點,這是開發用途的執行路徑。儲存庫也提供 memory:serve,用於編譯後的輸出。執行不帶引數的 npm run,即可查看目前 checkout 實際包含哪些指令碼。
  • 擷取功能會從最新的 2,000 筆向量資料列建立搜尋範圍,然後在該範圍內套用 Top-K 選取。在非常大的儲存區中,較舊的記憶可能位於搜尋範圍之外。
  • 擷取完成後才會建立嵌入向量。若建立失敗,系統會將工作放入重試佇列,而不會阻塞代理程式回合。剛加入的記憶可能尚未能透過向量搜尋找到。
  • 一個 SQLite 檔案只能對應一個節點。目前沒有叢集功能,因此第二部伺服器會使用另一份獨立的記憶。

截至 2026 年 7 月,版本 1.0.4 約有 329 顆星,顯示這仍是早期專案。不同版本之間可能會變更旗標、路徑與指令碼名稱。請查看自己 checkout 中的 bin 欄位,以及 npm run 的輸出,不要直接信任從任何地方複製的指令,包括本文中的指令。

FAQ

為什麼健康檢查會回傳連線遭拒?

連接埠 18960 上沒有任何服務正在監聽。curl 結束代碼 7 與 Failed to connect to 127.0.0.1 port 18960 表示記憶體服務未執行,或在啟動時終止,因此請查看服務啟動時所在的終端機輸出或 journal。最常見的兩個原因是與 Node 版本不相容的 better-sqlite3 原生模組,可使用 npm rebuild better-sqlite3 修正;另一個原因是 Node 版本低於 22。服務啟動後,使用 ss -lntp | grep 18960 確認 socket。

從原始碼建置後,memmy-memory 命令來自哪裡?

它來自 @memmy/memory 工作區套件的 bin 欄位,而不是儲存庫名稱。在 checkout 目錄中執行 node -p "JSON.stringify(require('./Memory/package.json').bin)",即可看到 {"memmy-memory":"./dist/src/cli/index.js"}。只有執行 npm run memory:build 後該檔案才會存在,因為建置程序會建立 dist,並將該檔案標記為可執行。請以 node Memory/dist/src/cli/index.js health 執行,或將它建立符號連結至 /usr/local/bin,以使用簡短名稱。

我可以使用 claude mcp add 將 Memmy 加入 Claude Code 嗎?

不可以。Memmy 是 MCP 用戶端,不是 MCP 伺服器。它會連線至 ~/.memmy/config.yamltools.mcpServers 下列出的伺服器,並將這些伺服器的工具提供給自身的執行環境。Claude Code 則透過另一種方式存取 Memmy:將 memmy-memory CLI 當作 shell 命令執行,並依據 memmy-memory init --agent 寫入代理程式規則目錄的指示檔操作。

執行 Memmy 會將我的記憶傳送至雲端服務嗎?

掃描與擷取程序都在本機執行,記憶會寫入您自己磁碟上的 ~/.memmy/memory-service/memory.sqliteMEMMY_CLOUD_SERVICE 會在帳戶模式與試用權杖中指向 https://memmy-api.memtensor.cn,而記憶改善計畫在您啟用前都維持關閉。需要監控的項目是嵌入提供者:託管的嵌入模型會接收每筆記憶的文字,並將其轉換為向量;如果這點很重要,請使用您自行執行的端點。