mcpField
G
GoodMemory

GoodMemory

ローカル
github.comメモリ・ナレッジ201 週間前に更新

GoodMemory について

GoodMemoryは、AI製品やコーディングエージェント向けの永続メモリ層です。ユーザーやプロジェクトの情報を検索・記録・監査・削除でき、既定ではローカルに保存します。

主な機能

  1. 01ユーザーとプロジェクトの永続メモリ
  2. 02メモリ検索とコンテキスト構築
  3. 03任意のメモリ書き戻し
  4. 04フィードバック、エクスポート、削除
  5. 05既定でローカルSQLiteに保存

活用シーン

  1. 01チャットセッション間で情報を引き継ぐ
  2. 02コーディングエージェントにスコープ付きメモリを追加
  3. 03誤った保存情報を確認または削除

MCP 対応

GoodMemoryは、CodexとClaude Codeの導入済み環境向けに読み取り専用のMCP確認経路を提供し、対応クライアント向けの独立したMCPサーバーも備えます。MCPツールからコンテキストを取得し、任意でメモリを書き込めます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"hjqcan-goodmemory": {
"command": "npx",
"args": [
"-y",
"goodmemory"
]
}
}
}
起動コマンドnpx -y goodmemory

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmgoodmemory0.7.5

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

GoodMemory

言語:英語 | 简体中文

GoodMemory は、AI プロダクトとコーディングエージェント向けのメモリレイヤーです。

リリースソース: このソースは安定版リリース 0.8.3 を対象としています。 レジストリコマンドを実行するには、[email protected] が公開されている必要があります。リリース ワークフローでは、ローカルで準備したマニフェストと、npm の latest およびすでに公開済みの GitHub アセットが 一致することを検証します。ビルドや公開は行いません。

チャットアプリ、コパイロット、エージェントホストに、永続的なユーザー/プロジェクトメモリのループを提供します。 選択した事実を書き込み、適切なコンテキストを取得して次のターンに挿入し、何が起きたかを監査し、誤りがあれば削除します。

GoodMemory は、LLM、エージェントフレームワーク、ベクトルデータベース、汎用 RAG システムではありません。 アプリまたはインストール済みエージェントホストとモデルのランタイムの間に位置する、プロダクト向けのメモリレイヤーです。

提供する機能

  • 永続的なメモリ API:remember、recall、buildContext、feedback、forget、 exportMemory、importMemory、deleteAllMemory。
  • Codex と Claude Code 向けのインストール済みエージェントメモリ。goodmemory setup、 管理対象フック、インストール済み Codex のアクション前処理、goodmemory status、読み取り専用 MCP、オプトイン方式の書き戻しを利用できます。
  • GoodMemoryConfig.remember、RememberProfile、rememberRules、 RememberInput.annotations、名前付きエクストラクター ID を使った、公開された書き込みカスタマイズ機能。
  • コンパイル済み dist アーティファクトと TypeScript 宣言を通じて利用できる、 goodmemory、goodmemory/ai-sdk、goodmemory/host、goodmemory/http のパッケージエクスポート。
  • ローカルファーストのストレージ:Bun ではデフォルトで永続的な SQLite を使用します。必要に応じて、 明示的な Postgres、注入可能なアダプター、埋め込みプロバイダーを追加できます。
  • 決定論的テスト、ライブ評価、プロバイダーを利用した評価、パッケージのスモークテスト、品質ゲートに対応する 評価およびリリースのエビデンスパス。

OpenAI Build Week 2026

開催前から存在した基盤。 GoodMemory は OpenAI Build Week より前から存在していました。 イベント前の基盤にはすでに、コアメモリ API、ローカルの SQLite/Postgres ストレージ、インストール済みホストとの統合、ローカルの Inspector が含まれていました。 ハッカソンへの応募対象は、2026 年 7 月 13 日に応募期間が始まった後に追加されたものであり、 リポジトリ全体ではありません。

Build Week 中に追加されたもの。 日付付きのコミットで v0.6.0 を完成させて公開し、 汎用的な検索と反復検索の検証を強化し、クレームの出典プロベナンスのカバレッジを追加し、 インストール済みホストのカナリアテストと漏洩監査を強化し、制御された Codex コーディング効果の評価パスを拡張しました。 正確な境界については、 開催前から Build Week までの差分 と、日付付きのコミット履歴を確認してください。

Codex と GPT-5.6 の使用方法。 GPT-5.6 を搭載した Codex を、主な実装・検証環境として使用しました。 リポジトリの調査、変更の実装とレビュー、回帰テストの作成、インストール済みホストの動作再現、 リリースおよびコーディング効果のエビデンスパスの実行に利用しました。 GPT-5.6 は、現在の評価プロファイルで、開示済みの審判以外のモデル呼び出しも担います。 公開クレームのパスでは決定論的なスコアリングを使用するか、審判モデルを回答モデルから独立させています。

実行と検証。 公開後、レジストリから 0.8.3 をインストールし、 ローカルのメモリ機能を確認してください。

npm install -g [email protected]
goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory inspector serve

bun install --frozen-lockfile、bun test、bun run typecheck を実行して、ソースからリポジトリを検証してください。 Devpost の応募ページと 公開デモ動画をご覧ください。

クレームの範囲: この応募では、セッションをまたぐ永続メモリ、制御された書き戻し、 検索エビデンス、検査・削除のための基盤を実証します。GoodMemory がすでに Codex のコーディング成果を 改善することを実証済みだとは主張していません。ペア比較による非公開テスト評価は、引き続き進行中の フェイルクローズ型エビデンストラックです。

まずはこちら:Codex または Claude Code

npm install -g [email protected]
goodmemory setup

アカウントやホステッドサービスは不要です。GoodMemory はデフォルトでメモリをローカルの SQLite に保存し、ライフサイクルフックと読み取り専用の MCP 検査機能を組み合わせ、永続的な書き戻しはオプトイン方式にしています。goodmemory status を実行して、インストールを確認してください。

別の MCP クライアントを使用している場合や、アプリケーションに統合する場合は、統合方法を選択してください。

ベンチマーク結果

GoodMemory では、現行の製品に関する主張、バージョン付きの過去のエビデンス、社内研究を区別しています。数値を現行の主張の表に掲載できるのは、gate:public-benchmark-claim --strict によって、現行パッケージバージョンに対するコミット済みの宣言が検証された場合に限ります。必要な条件は、網羅的なカバレッジ、executionFailures: 0、メモリなしのベースライン、決定論的なスコアリングまたは独立した評価者、データセットの出典とライセンスの検証、再現可能な実行(コミット+コマンド+パッケージバージョン)です。現在、許可リストに登録されているエンドツーエンドのベンチマークランナーはないため、現行と過去のどちらの行も昇格できません。保存済みの回答に対する再スコアリングや、レガシーな表示用プロジェクションでは、この境界を越えられず、README のスコアや開示情報の断片を自己証明として提示することもできません。

GoodMemory 0.8.3 には、現行またはバージョン付きの過去のベンチマークに関する主張はありません。保持されている v0.7.3 の LoCoMo プロジェクションはエンドツーエンドのランナーエビデンスではないため、社内診断として扱います。v0.6.0 の LoCoMo、BEAM、MemoryAgentBench の測定値と ImplicitMemBench も、同じフェイルクローズの境界の下で社内診断として扱います。 LongMemEval は、クリーンな再実行まで撤回されています。過去のルールのみを使った方式では回答アノテーションを使用しており、その後のラベルなし方式では、生の answer_* セッション ID が検索と回答生成に渡されていました。ImplicitMemBench の再試行分をマージした結果は、単一の新規実行に置き換わるものではないため、引き続き内部エビデンスとして扱います。HaluMem、MemGym、MINTEval は、公開ベンチマークの主張ではなく、引き続きリリースエビデンスとして扱います。

現在、0.8.3 で測定されたものとして提示されているベンチマーク結果はありません。

バージョン付きエビデンス

現在、バージョン付きエビデンスとして許可リストに登録されているエンドツーエンドのベンチマーク実行ツールはありません。

現在、バージョン付きの過去のエビデンスとして認められるベンチマーク結果はありません。

保持されている v0.7.3 LoCoMo の投影データは監査用にリポジトリ内で引き続き利用できますが、検証済みのパッケージ成果物として配布されておらず、公開またはバージョン付きの主張の根拠にはできません。古い成果物を後から適合させることはありません。今後、昇格を開始する前に、生成側と検証側を一体として実装する必要があります。

両方が利用可能な場合、各行には2つのトラックが示されます。厳格トラックは決定論的または判定者不要であり、LLM 判定者が水増しできない確実な下限です。2つ目のトラックでは、ベンチマークの出典または業界標準のプロンプトを使って、同じ保存済み回答(再生成した回答ではありません)を再判定します。数値の比較可能性を主張するのは、固定された評価モデルと残りのベンチマーク設定も一致する場合に限ります。プロトコルごとの詳細はすべて、リンク先の宣言に記録されています。

LongMemEval の宣言は、過去のエビデンスではなく paused_boundary になりました。古い数値成果物は監査証跡を保つためだけに残されています。不透明なセッション ID を使用し、ラベルを使わない完全な再実行で置き換えるまでは、GoodMemory の結果として引用してはなりません。詳しくは 撤回宣言を参照してください。 v0.6.0 の BEAM、MemoryAgentBench、LoCoMo の測定値は、引き続き内部診断データです。エンドツーエンド実行ツールの許可リストが空であるため、バージョン付きの過去のエビデンスには該当しません。

ImplicitMemBench Full-300 の保存済み回答の再スコアリングでは、まず正規の失敗ゼロの回答 run-phase61-full300-rerun-20260706-codex-current を使用し、次に同じ保存済み回答を gpt-5.4 で再スコアリングします(sourceAnswersUnchanged: true)。判定者はバージョンこそ異なりますが、回答モデルの gpt-5.5 と同じ GPT ファミリーであり、異なるファミリーの判定者ではありません。記録されたスコアは 0.691(207.35/300)で、上流チャットのベースライン 0.400(120/300)を上回ります。ベースラインと GoodMemory の両方で、判定者を必要とする行の判定は合計 530 件です。決定論的な structured_first_action の行は判定せず、そのまま引き継がれます。以前の同一モデルによる診断スコアは 0.708 でしたが、記録された結果ではありません。最近のコード変更後に行った最新の、クリーンな回答再生成によるドリフトチェックのスコアは 0.6895 で、executionFailures: 0 でした。これは現在のチェックアウトのドリフトを示すものであり、保存済み回答の比較可能性を示す成果物の代替ではありません。測定対象のソースからは、パッケージのバージョンとコミットの両方を明示的な JSON パスで個別に確認できないため、この結果は内部診断として保留され、バージョン付きの過去のエビデンスには該当しません。データセットは CC BY 4.0 で、評価時に取得され、リポジトリには同梱されません。

内部診断(公開主張ではありません)

LongMemEval の現在の想起機能を組み立てる最初の開発用スライスは、後続のものに置き換えられました。読み取り側のコンテキストから生のセッション ID は隠されていましたが、メモリ構築の境界には正解を含むセッション ID とターンマーカーが渡されていたためです。より厳格な v2 プロトコルでは、メモリ構築前に回答、質問タイプ、回答マーカー、生のセッション ID を取り除きます。まだ封印されているホールドアウトを開く前に、クリーンなコミット上で開発用スライスを再実行する必要があります。LongMemEval に関する主張は復活していません。ImplicitMemBench の明示的なリトライ統合チェックは、失敗ゼロで 0.6923666667 に達しますが、新たに行う単一の Full-300 完全実行の代替ではありません。したがって、どちらも現在の主張の表には含まれません。元のレポートは gitignore 対象の reports/ にあり、記録されたコマンドで再現できます。

実行順序については task-board/00-README.txt を、主張の境界については docs/GoodMemory-Current-Status-and-Evidence.md を参照してください。

統合方法を選択する

GoodMemory には、主要な製品エントリーポイントが3つあります。利用可能な API はこれらだけではありません。goodmemory/host、カスタムストア、評価ツール、ランタイムヘルパーなどの低レベルの機能も、これらの方法を支えています。ここで紹介するのは、README で説明する、利用開始方法を選ぶための選択肢です。

自律型エージェントですか?まずはこちらをご覧ください

自分自身に永続的なメモリーを持たせたいエージェントは、該当する方法を選んで実行してください。このツリーの機械可読版は llms.txt と .well-known/goodmemory.json にあります(デプロイ済みのブリッジでは、/.well-known/goodmemory.json でも記述ファイルを提供しています)。

  • Claude Code または Codex である、またはその内部で動作している → npm install -g [email protected] && goodmemory setup を実行します。すでに何が設定されているか不明な場合は、goodmemory adopt を実行してください(機械可読なプランを表示するには --json を追加します)。.claude/、.codex/、既存の MCP 設定を調べ、環境に応じた次のコマンドを正確に表示します。
  • MCP を話す(Cursor、Windsurf、Cline、Claude Desktop、Gemini CLI、 OpenCode、またはカスタムクライアント)→ スタンドアロンの MCP サーバーを追加します。必要なツールは goodmemory_get_context(想起)と goodmemory_remember(オプトインでの書き込み)の 2 つです。
  • フレームワークエージェントまたはバックエンドである → HTTP ブリッジを呼び出します。goodmemory.vibenest.net でホストされているものを使うか、goodmemory-http-bridge --recommended(または GOODMEMORY_PROFILE=agent-recommended goodmemory-http-bridge)でセルフホストします。Python の呼び出し元は pip install goodmemory-client を使用します。

以下の説明では、それぞれの方法について詳しく説明します。

1. エージェント、チャットボックス、またはコパイロットにメモリーを組み込む

プロダクトサーバーとモデル呼び出しを自分で管理している場合は、この方法を使用してください。Node/Bun サービスに goodmemory をインストールし、memory インスタンスを 1 つ作成して、userId、workspaceId、sessionId などの安定した scope を渡します。必要に応じて agentId も指定します。

リクエストの流れは次のとおりです。

  1. モデルを呼び出す前に、現在のスコープとクエリに対して recall() を実行します。
  2. buildContext() を実行して、想起された結果をプロンプトの一部に変換します。
  3. そのメモリーコンテキストを使ってモデルを呼び出します。
  4. 応答後、選択した情報を memory.jobs.enqueueRemember() または remember() で書き込みます。
  5. 修正、削除、ユーザーによる監査には、feedback()、対象を絞った reviseMemory()、forget()、exportMemory() を使用します。importMemory() はエクスポートを復元するか、Markdown ページのディレクトリを note メモリーとして取り込みます。

サーバーですでに Vercel AI SDK を使用している場合は、ループ全体を手作業で配線する代わりに、goodmemory/ai-sdk を使って generateText() または streamText() をラップしてください。アプリのクイックスタートから始め、AI SDK を使用している場合はAI SDK アダプターをお読みください。

2. Codex または Claude Code にメモリを追加する

インストール済みのコーディングエージェント自体は変更せずに、プロジェクトとユーザーのコンテキストを記憶させたい場合に使用します。グローバル CLI をインストールし、goodmemory setup を実行してください。

インストール済みホストでの処理の流れは次のとおりです。

  1. session-start でセッション概要を注入し、user-prompt-submit でプロンプトごとのコンテキストを注入します(新規インストールでは関連性に基づくゲート処理が行われ、重要度の低いプロンプトはクリーンな状態に保たれます)。
  2. Claude Code の Stop フックは、セッションのトランスクリプト(transcript_path)から各ターンを取得し、ガバナンス対象の書き戻し候補にします。候補は範囲が限定され、機密情報が削除され、生のトランスクリプトは保存されません。Codex では、goodmemory codex writeback --from-rollout により、最新のセッションのロールアウトを同じパイプラインに渡します。
  3. Codex の pre-tool-use は、同じインストール済み設定とストレージパスを使う goodmemory codex action を通じて、リスクのある Bash を拒否またはリダイレクトできます。
  4. MCP からトレース、コンテキスト、統計情報、アーティファクトの調査ができます。書き込みツール goodmemory_remember はオプトイン方式で、mcp.allowWrite(または goodmemory enable <host> --mcp-allow-write)で有効にできます。
  5. スクリプトによるインストールでは書き戻しは off のままです。対話型インストールと goodmemory setup --recommended(同意確認は1回)では、永続的な書き込みを selective に設定します。書き込みは writeback inspect で監査でき、writeback forget --event-id で取り消せます。
  6. 新規インストールでは、計測済みの BM25 ハイブリッド検索ティアが初期設定され、セッション概要は1024トークン、ゲート処理されたプロンプト注入は512トークンです。goodmemory status では、検索ティア、キャプチャの動作確認、注入のテレメトリが表示されます。オプションの sharedAgents 設定では、一方のホストからもう一方のホストの記録を読み取れます(書き込みの帰属先は維持されます)。

クイックスタート:Codex または Claude Code のメモリから始めてください。書き込みを確認または有効にする準備ができたら、インストール済みホストの書き戻しをご覧ください。

3. GoodMemory をバックエンドのメモリレイヤーサービスとしてデプロイする

別のバックエンドから GoodMemory をサービスとして呼び出す場合に使用します。特に、プロダクトのバックエンドが Python/FastAPI の場合や、OneLife などのプロダクトで GoodMemory をモバイルまたはブラウザーのクライアントにバンドルせず、サーバー側でメモリを管理したい場合に適しています。

パッケージ化された goodmemory-http-bridge を Node/Bun サイドカーにデプロイしてください。バックエンドから次のエンドポイントを呼び出します。

  • 独自のモデル呼び出しの前に /memory/recall-context
  • ユーザーが確認したシグナル、またはプロダクトが承認したシグナルの後に /memory/remember
  • 手続き的な修正には /memory/feedback
  • 監査と削除には /memory/export と /memory/forget
  • 明示的なメモリ ID を指定した対象を絞った修正には /memory/revise
  • エクスポートの復元、または Markdown ページの取り込みには /memory/import

認証、プロダクトポリシー、UI、モデルのオーケストレーションは、引き続きお客様のサービスが担当します。メモリの保存、検索、コンテキストの組み立て、書き込みガバナンス、監査/エクスポート/削除の処理は GoodMemory が担当します。Python/FastAPI HTTP ブリッジから始めてください。公式 Python クライアント(pip install goodmemory-client)とホスト型ブリッジインスタンス goodmemory.vibenest.net の詳細も、こちらに記載されています。続いて、SQLite と Postgres の選択肢についてランタイムとストレージをご確認ください。

モデルのターン中に、GoodMemory は次の4つの処理を行います。

  1. 現在の scope に対応するメモリを解決します。
  2. プロンプトにそのまま利用できるコンテキストの断片を構築します。
  3. アプリまたはホストが許可する場合、応答後に選択されたシグナルを記録します。
  4. ユーザーが管理できるよう、監査、修正、エクスポート、削除の手段を提供します。

認証、UI、モデル呼び出し、プロダクトポリシーは、引き続きお客様のアプリまたはインストール済みエージェントが担当します。メモリのループとストレージの境界は GoodMemory が担当します。

インストール

以下のコマンドは、公開後の GoodMemory 0.8.3 を対象としています。再現性のあるインストールには、以下のバージョン固定済みのレジストリコマンドを使用してください。

インストール済みのコーディングエージェント内でメモリー拡張を利用する場合は、グローバル CLI を使用してください。

npm install -g [email protected]
goodmemory setup
goodmemory status

アプリケーションを開発する場合は、パッケージ依存関係として追加してください。

npm install [email protected]

goodmemory と直接入力して実行する場合は、グローバル CLI をインストールしてください。 プロジェクトローカルで npm install [email protected] を実行しても、goodmemory はシェルの PATH に追加されません。 代わりに、そのプロジェクトで npx goodmemory、npm exec -- goodmemory、または ./node_modules/.bin/goodmemory を使用してください。

npx goodmemory -V

Bun を使用する場合は、直接インストールできます。

bun add [email protected]

このリリースのソースの tarball 検証:

npm install ./goodmemory-0.8.3.tgz

インストールされる CLI は、バージョン関連以外のコマンドで Bun を使用します。パッケージの実行ファイルは goodmemory -V と goodmemory --version で Node に対応しており、その他のコマンドは Bun に処理を委譲します。

クイックスタート:Codex または Claude Code のメモリー

多くのユーザーにとって、まず役立つのはインストール済みホストでメモリーを利用する方法です。

npm install -g [email protected]
goodmemory setup
goodmemory status

goodmemory setup は Codex と Claude Code を検出し、管理対象のホスト連携をインストールして、以下について確認します。

  • ホスト:codex、claude、または検出された両方のホスト
  • 有効化範囲:グローバル、現在のワークスペース、または手動オプトイン
  • GoodMemory のユーザー ID
  • オプションの Postgres ストレージ
  • オプションの埋め込みプロバイダー
  • オプションの LLM 抽出プロバイダー
  • 書き戻しモード:off、observe、review、または selective

対話形式のセットアップでは、デフォルトでワークスペースから導出した分離を伴うグローバル有効化が設定されます。また、新しいホスト設定には selective が推奨されます。これにより、監査と取り消しに対応しながら、重要度の高い書き込みをすぐに利用できます。永続的な書き込みの前に Inspector の承認を受けたい場合は、review を選択してください。既存のホスト設定では、対話型プロンプトのデフォルトを受け入れた場合も、現在の書き戻しモードが維持されます。スクリプトによるインストールでは、--json または --no-interactive を指定すると安全に実行できます。プロバイダーの設定をスキップしても問題ありません。GoodMemory はローカルの SQLite とルールのみの抽出で引き続き動作します。

便利なコマンド:

goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory enable codex --workspace-root . --writeback observe
goodmemory enable codex --workspace-root . --writeback selective
goodmemory disable codex --workspace-root .
goodmemory uninstall codex

インストール済みホストでの利用経路は、次の 4 つの要素で構成されます。

  • Codex 用の管理対象のアクション前処理:pre-tool-use はリスクのある Bash を拒否またはリダイレクトできます。また、goodmemory codex action は、想起と書き戻しに使用されるものと同じインストール済み設定、ストレージ、プロバイダー、スコープの経路で、審査済みの最初のステップを実行します。
  • 想起の挿入:session-start と user-prompt-submit のフックは recall() と buildContext() を呼び出し、設定、解析、またはストレージを利用できない場合は処理を続行します。
  • 詳細な調査:goodmemory mcp serve --host codex と goodmemory-mcp --host codex は、読み取り専用のコンテキスト、トレース、統計、アーティファクトの各ツールを公開します。
  • オプションの書き戻し:session-stop と明示的な書き戻しコマンドにより、選択した応答後のシグナルを永続的なメモリーに変換できます。

あらゆるクライアント向けスタンドアロン MCP

管理されたインストール経路がないホスト(Cursor、Windsurf、Cline、Claude Desktop、 Gemini CLI、OpenCode、または独自の MCP クライアント)でも、同じ MCP サーバーを スタンドアロンモードで実行できます。goodmemory setup も、ホストの設定ファイルも不要です。スコープと ストレージはフラグ/環境変数で指定し、提供される機能は同じ読み取り専用ツール 8 個と、 オプトインの管理された書き込みツールです。

{
  "mcpServers": {
    "goodmemory": {
      "command": "goodmemory-mcp",
      "args": ["--standalone", "--user-id", "YOUR_USER_ID"]
    }
  }
}

同等の起動方法:goodmemory-mcp --standalone --user-id <id>(PATH 上に Bun が必要です。GOODMEMORY_USER_ID はフラグの環境変数フォールバックとして機能します)。 --allow-write(または GOODMEMORY_MCP_ALLOW_WRITE=1)を指定すると、 通常の管理された記憶処理パイプラインを通じて書き込む goodmemory_remember と、 作成したページ(文章または Markdown、最大 8 KB)を note としてそのまま保存し、 書き換え時にはタイトルで以前のページを置き換える goodmemory_write_note が登録されます。 インストール済みホストが書き込んだエージェントタグ付きメモリは、そのエージェント専用のままです。 インストール済みホストのストアから読み取るには、共有の --storage-url とともに --agent-id codex を追加します。フラグ/環境変数の完全な一覧、スコープに関する注意事項、 ホストごとの手順については、以下を参照してください。 docs/GoodMemory-Standalone-MCP-Setup-Guide.md (Cursor · Gemini CLI · OpenCode)。

インストール済みホストからの書き戻し

インストール済みホストからの書き戻しはオプトインです。ユーザーが書き戻しモードを明示的に選択しない限り、 ランタイム設定のデフォルトと、新たにスクリプトで行うインストールでは off のままです。 明示的な上書きが指定されない場合、既存の設定では現在の書き戻しモードが維持されます。 新しい対話式インストールでは、監査と取り消し機能を備えた高シグナルの書き込みをすぐに 開始できるよう、selective を推奨します。永続的な書き込みの前に Inspector の承認を必要とする場合は、 review を選択してください。

selective の前に observe を使用します。

goodmemory enable codex --writeback observe
goodmemory codex writeback --json

goodmemory enable codex --writeback review
goodmemory inspector serve

goodmemory enable codex --writeback selective
goodmemory codex writeback --json

goodmemory inspector serve を実行すると、ユーザーとスコープ、カテゴリ別のメモリと置き換え履歴、 候補の判定、想起の根拠トレース、監査イベントを確認できる、組み込みのローカル React コンソールが開きます。 起動トークンは URL フラグメントとして渡され、ただちにセッションストレージへ移されて消去され、 Bearer ヘッダーとしてのみ送信されます。リビジョン操作と破壊的な操作には、確認、ETag、 冪等性キーが必要です。詳しくは Inspector And Admin API を参照してください。

書き戻しのルール:

  • off:応答後のメモリ抽出は行いません。
  • observe:生のトランスクリプトや永続的なメモリ書き込みを行わず、ローカルに上限付き/ レダクト済みの候補プレビューを保存して確認できるようにします。
  • review:上限付き/レダクト済みの候補を Inspector での承認待ちキューに追加します。オペレーターが 候補を承認するまで、永続的なメモリは書き込まれません。
  • selective:選択された候補を、公開されている remember インターフェイスを通じて書き込みます。
  • 生のトランスクリプトはメモリとして永続化されません。
  • ホストが確認または検証し、アクティブなプロファイルで許可されていない限り、アシスタントが生成した永続的な メモリの書き込みはブロックされます。
  • remember: "never" は、決定的抽出、カスタム抽出、支援抽出の前に、注釈付きコンテンツをマスクします。

監査と取り消し:

goodmemory codex writeback inspect --json
goodmemory codex writeback forget --event-id <event-id> --review-outcome false_write

監査台帳には、上限付き/レダクト済みの候補プレビュー、候補キー、型付きの関連レコード ID、 ステータス、理由、ホスト、モード、タイムスタンプ、スコープ/セッションのダイジェスト、 任意の手動レビュー用メタデータが保存されます。生のホストペイロードは保存されません。 forget --event-id は、永続的な監査イベントを忘却済みとしてマークする前に、公開されている forget() を通じて関連するメモリ/エビデンスレコードを削除します。observe のみのイベントでは、 forget() を呼び出さずに候補を却下済みとしてマークします。

Claude Code はフックおよび書き戻しコマンドについて、決定的な CLI 同等機能を備えています。 Codex は、ライブエビデンスを取得する標準的な経路です。

スクリプトによるホストのインストール

完全に非対話型のセットアップを行うには、goodmemory install <host> を使用します。

goodmemory install codex \
  --user-id <user-id> \
  --activation-mode global \
  --writeback observe \
  --storage-provider postgres \
  --storage-url "postgres://user:pass@host:5432/goodmemory" \
  --embedding-provider openai \
  --embedding-model text-embedding-3-small \
  --embedding-api-key <key> \
  --llm-provider openai \
  --llm-model gpt-4o-mini \
  --llm-api-key <key> \
  --no-interactive

管理対象の設定は ~/.goodmemory/<host>.json に保存されます。プロバイダーフラグを指定してインストールを再実行すると、同じ設定が更新され、MCP/フックの登録は冪等に保たれます。パッケージをアンインストールしても、~/.goodmemory、リポジトリ内の .goodmemory、ローカルの SQLite ファイル、リモートの Postgres データは削除されません。管理対象のホスト連携を削除するには goodmemory uninstall <host> を使用し、メモリデータを削除するには goodmemory forget ... またはストレージを明示的に削除してください。

アプリのクイックスタート

チャットボックス、コパイロット、またはプロダクトエージェントを構築する場合は、ルートパッケージを使用します。推奨される Node サービスの手順は、Express と Fastify のサンプルで使用されているものと同じシンプルなループです。詳しい手順については、docs/GoodMemory-15-Minute-App-Integration.md を参照してください。

import type { GoodMemoryTraceSpan } from "goodmemory";
import { createGoodMemory } from "goodmemory";

const traceSpans: GoodMemoryTraceSpan[] = [];

const memory = createGoodMemory({
  observability: {
    traceSink: {
      emit(span) {
        traceSpans.push(span);
      },
    },
  },
});

const scope = {
  userId: "u-1",
  workspaceId: "workspace-a",
  sessionId: "s-1",
};
const userMessage = "Remember that the migration rollout is blocked on QA signoff.";

// Call startSession once when the product opens a new session. For later turns
// with the same sessionId, append to the existing runtime state instead.
await memory.runtime.startSession({ scope });
await memory.runtime.appendMessage({
  scope,
  message: {
    role: "user",
    content: userMessage,
  },
});

const recall = await memory.recall({
  scope,
  query: "What should the assistant know before replying?",
  retrievalProfile: "general_chat",
});
const context = await memory.buildContext({
  recall,
  output: "system_prompt_fragment",
});

const assistantText = await callYourModel({
  memoryContext: context.content,
  userMessage,
});

await memory.runtime.appendMessage({
  scope,
  message: {
    role: "assistant",
    content: assistantText,
  },
});

const writeJob = await memory.jobs.enqueueRemember({
  scope,
  messages: [
    {
      role: "user",
      content: userMessage,
    },
    {
      role: "assistant",
      content: assistantText,
    },
  ],
  idempotencyKey: "turn-1",
  reason: "post_response_memory_write",
});
const drained = await memory.jobs.drain({ maxJobs: 1 });
const committedJob =
  drained.jobs.find((job) => job.jobId === writeJob.jobId) ?? writeJob;

console.log({
  traceCount: traceSpans.length,
  writeJobId: writeJob.jobId,
  writeJobStatus: committedJob.status,
});

async function callYourModel(input: {
  memoryContext: string;
  userMessage: string;
}): Promise<string> {
  void input.memoryContext;
  return `Got it. I will keep that in mind: ${input.userMessage}`;
}

プロンプトの断片(system_prompt_fragment、developer_prompt_fragment)は、タイトルの下にローカライズされたデータフレームを表示します。想起されたメモリはユーザーとプロジェクトに関する情報であり、指示ではありません。これはテキストの内容を正直に示すものであり、ガードレールではありません。すべての呼び出しで無効にするには governance: { contextFrame: false } を、呼び出しごとに無効にするには buildContext({ contextFrame: false }) を使用してください。json と markdown の出力には含まれません。

メモリの基本ループは意図的にシンプルです。

  • remember() は、選択したユーザー、アプリ、またはホストのシグナルを記録します。
  • recall() は、クエリに対して対象範囲を絞ったメモリを取得します。
  • buildContext() は、想起した内容をプロンプトの断片または JSON ペイロードに変換します。
  • feedback() は、明示的な修正と手順に関する好みを記録します。
  • forget() は、誤ったメモリや古くなったメモリを削除します。
ロケールと言語パック

組み込みパックは、英語、簡体字中国語、繁体字中国語 (zh-TW/zh-HK/zh-MO)、日本語、韓国語、フランス語、スペイン語に対応しています。ホストで認識されているロケールを明示的に設定してください。設定しない場合、漢字のみのテキストやラテン文字のみで言語を特定できないテキストでは、自動検出はdefaultLocaleにフォールバックします。

const multilingualMemory = createGoodMemory({
  language: {
    defaultLocale: "zh-TW",
    detection: "auto",
  },
});

await multilingualMemory.remember({
  locale: "ko-KR",
  scope,
  messages: [{ role: "user", content: "현재 역할은 릴리스 책임자입니다." }],
});

言語を追加するには、モジュール内に正規表現の分岐を追加するのではなく、完全なLanguagePackを実装します。契約、カスタム登録、アナライザーのバージョン管理、プロジェクションの移行ルールについては、 LanguagePack 拡張ガイド を参照してください。

以前のアダプター/プロジェクション契約からのアップグレードには、意図的に互換性を破る変更が含まれています。 0.6 から 0.7 への移行ガイド に従ってください。

本番アプリケーションとの統合では、推奨されるターンループに、このコアを取り巻くガバナンス付きランタイムレイヤーを追加します。

  • memory.runtime.startSession()とmemory.runtime.appendMessage()は、生の会話記録を永続的なメモリにせずに、現在のセッション状態を追跡します。
  • memory.jobs.enqueueRemember()は、べき等性と可視化されたジョブステータスを備えた、応答後のメモリ書き込みをスケジュールします。
  • memory.jobs.drain()は、このインメモリスケジューラーのキューに登録された書き込みを確定します。本番サービスでは、ワーカーまたはリクエストに隣接するジョブループでドレインを実行してください。
  • GoodMemoryConfig.observability.traceSinkは、remember、recall、context、revise、forget、export、jobの各イベントについて、機密情報の削除に安全に配慮したトレースを受け取ります。
  • memory.reviseMemory({ target: { memoryId } })は、あいまいなテキスト選択ではなく、明示的なIDを指定して既知のメモリを修正します。
  • exportMemory()は、ユーザーに監査/エクスポートの手段を提供します。pages/バンドルは、SHA-256マニフェストを含むmemoryfield互換のノートページディレクトリです。
  • memory.importMemory({ source })は、IDを指定してそのエクスポートを再インポートするか、ページをnoteメモリとして取り込みます。expectedSha256を指定すると、書き込み前に入力を固定できます。
  • governance.fileMirror: { root, scope }は、scope内で永続的な書き込みが行われるたびに、そのエクスポートバンドルの読み取り専用コピーをディスクに保持します(デバウンス処理とアトミックなディレクトリ置換を使用)。1つのルートは1つの永続スコープに対応します。このミラーはプロジェクションであり、読み戻されることはなく、書き込みが失敗する原因にもなりません。

ランタイムアーカイブの永続化は、デフォルトで無効になっています。memory.runtime.endSession({ scope, archive: "off" })を呼び出すと、アーカイブを書き込まずにセッション状態が消去されます。アーカイブの永続化を有効にする場合は、要約のみを保存し、生の会話記録をデフォルトのメモリソースとして扱わないでください。

サーバーとの統合では、まず次のシンプルなサンプルを参照してください。 examples/express-chat-server.tsまたは examples/fastify-chat-server.ts。 Python/FastAPIバックエンドでは、以下で説明するパッケージ済みのgoodmemory-http-bridgeパスを使用してください。

オプトインによるリコール調整:一般化された融合、マルチホップ、オプションの埋め込み、会話からの抽出

以下の設定項目はすべてオプションで、設計上、保守的な設定になっています。デフォルトのリコールは単一パスでルールのみを使用し、デフォルトの抽出動作も変更されません。オプトインしない限り、何も実行されません。推奨プリセットにはプロバイダーを必要としないローカルパスがあります。埋め込みプロバイダーと抽出プロバイダーはオプションのチャネルを追加しますが、必須ではありません。

1つのフラグで有効になる推奨リトリーバルプリセット

retrieval.preset: "recommended" を設定すると、汎用リトリーバルと条件付きの会話型抽出が1つのフラグで有効になります。

const memory = createGoodMemory({
  retrieval: { preset: "recommended" },
});

有効にすると、(a)メモリ、フィールド、文の粒度で想起ドキュメントをインデックス化し、(b)BM25、直接的なエンティティ隣接関係、利用可能なニューラル密ベクトル候補をRRFで統合し、(c)上限付きの動的な候補予算を適用し、(d)auto 想起ルーティングをハイブリッドに寄せます。strategy: "rules-only" を含む、呼び出し単位で明示された戦略は引き続き優先され、汎用的な統合はバイパスされます。ニューラル埋め込みが解決されると、topK: 16 の密ベクトルチャネルが追加されます。解決されない場合、リトリーバルはローカルで決定論的なまま、ネットワーク通信を一切行いません。このプリセットは、抽出モデルがすでに解決されていて、明示的なモードが設定されていない場合に限り、補助抽出を mode: "conversational" に切り替えます。プロバイダーを注入することはありません。preset を未設定にすると、既存のルールのみのデフォルトが維持されます。

要件と制約:

  • プロバイダーは必要ありません。ニューラル埋め込みエンドポイント(GOODMEMORY_EMBEDDING_*、providers.embedding、または adapters.embeddingAdapter)を使用すると、任意の密ベクトルチャネルが追加されます。ネットワーク通信を行わないニューラル処理の設定例は、以下のOllamaレシピをご覧ください。
  • createLocalEmbeddingAdapter() をこのプリセットと組み合わせることはできません。ハッシュ化された語彙ベクトルは、語彙的な証拠を重複させながら、密ベクトルの意味チャネルであるかのように見せてしまうためです。
  • inspectGoodMemoryRuntime(memory).retrievalPreset を確認してください。その extraction フィールドには、書き込み時の処理が有効になったか("conversational")、抽出器が利用できなかったか、または設定が変更されずに維持されたかが示されます。
  • このプリセットが対象とするのは、メモリのリトリーバルと条件付き抽出だけです。回答時のプロンプトと回答を差し控えるポリシーは、引き続きアプリケーション側で扱います。
  • 個別の従来型加算式BM25スロットを意図的に使用する場合を除き、bm25Ranking: true と併用しないでください。汎用の統合にはすでにBM25チャネルが含まれています。
  • 環境変数から解決される抽出を使っていて、このプリセットを採用した場合、書き込み時の出力は会話型のアトミックな主張になります。この動作を回避するには、mode: "default" を指定した providers.extraction オブジェクトを明示してください。
オプションのポイントワイズ再ランカー

統合後の候補セットは有用でも、最終的な順序が不安定な場合は、OpenAI互換のファーストパーティ製ポイントワイズ再ランカーを追加できます。

const memory = createGoodMemory({
  retrieval: { preset: "recommended" },
  providers: {
    reranking: {
      provider: "openai",
      model: process.env.RERANKING_MODEL!,
      apiKey: process.env.RERANKING_API_KEY!,
      baseURL: process.env.RERANKING_BASE_URL,
    },
  },
});

const result = await memory.recall({ scope, query });
console.log(result.metadata.retrievalTrace?.reranker);

選択された各事実は、それぞれ独立したクエリ・ドキュメント呼び出しでスコア付けされます。候補同士が同じ再ランカープロンプトに含められることはありません。再ランカーが並べ替えるのは、決定論的な想起によってすでに採用された事実だけです。そのため、候補の採用範囲を広げたり、根拠に基づく回答差し控えの基準を緩めたりすることはありません。プロバイダーのタイムアウト、スキーマ、またはゲートウェイのエラーが発生した場合は、元の決定論的な順序に戻り、retrievalTrace に status: "fallback" と安定した理由を記録します。1回の想起で再ランカーをスキップするには、rerank: false を設定してください。明示的な adapters.reranker は、引き続き providers.reranking より優先されます。プロバイダーを使う再ランカーのリクエストタイムアウトは、デフォルトで15秒です。選択したゲートウェイで異なるレイテンシ予算が必要な場合は、providers.reranking に任意の正の整数 requestTimeoutMs を設定してください。

トレースには、各チャネルとRRFの帰属情報、モデルの役割、サニタイズ済みのゲートウェイ、レイテンシ、スコア、変更前後の順位が、上限付きで含まれます。APIキー、クエリテキスト、メモリの内容は含まれません。この機能はオプトインであり、上限付きの再ランク対象範囲内では、事実ごとに1回のモデル呼び出しが追加されます。プロバイダー不要の推奨パスには変更ありません。

オプションのローカル埋め込みエンドポイント(Ollama)

推奨プリセットは、埋め込みなしで動作します。外部への通信が一切ないニューラルな高密度チャネルを追加するには、GOODMEMORY_EMBEDDING_BASE_URL に、ローカルの Ollama サーバーを含む、OpenAI 互換の /v1/embeddings エンドポイントを指定します。

ollama pull nomic-embed-text        # or bge-m3 for stronger multilingual recall

export GOODMEMORY_EMBEDDING_PROVIDER=openai
export GOODMEMORY_EMBEDDING_BASE_URL=http://localhost:11434/v1
export GOODMEMORY_EMBEDDING_MODEL=nomic-embed-text
export GOODMEMORY_EMBEDDING_API_KEY=ollama   # any placeholder; Ollama ignores it, the variable stays required

# smoke-check the endpoint before starting your app
curl http://localhost:11434/v1/embeddings \
  -H "Content-Type: application/json" \
  -d '{"model": "nomic-embed-text", "input": "hello"}'
  • provider は openai のままにします。これはベンダーではなく、OpenAI 互換の通信プロトコルを選択します。
  • ストアごとに使用する埋め込みモデルは1つにします。異なるモデルや次元のベクトルは比較できず、モデルを切り替える場合はコーパスを再度記憶させる(再埋め込みする)必要があります。
  • ローカル埋め込みの品質は text-embedding-3-small と異なります。公開されている LoCoMo の数値は OpenAI エンドポイントを使って測定されました。このレシピは、外部への通信なしでその仕組みを再現するものであり、同じ数値を再現するものではありません。
  • これは createLocalEmbeddingAdapter()(以下)ではありません。これはセマンティックではなくハッシュ化された語彙ベースのアダプターで、推奨プリセットでは拒否されます。
長いレコードの採用

デフォルトのリコールでは、ファクトのスコアは共通トークン数を大きい方のトークン集合で割って算出されます。そのため、インポートした長いファクトがクエリ全体をカバーしていても、スコアがほぼゼロになることがあります。retrieval.longRecordAdmission: true を設定すると、長いレコードのしきい値(重複トークン32個)を超えるレコードに対して、クエリ側のカバー率を示すシグナルが追加されます。クエリのトークンの60%以上、かつ2個以上に一致するレコードが採用されます。この処理は従来の選択を優先し、キャリブレーション済みのファクト選択で空いた容量だけを補充します。既存の選択済みレコードの順位は変更しません。トレースには fallback=long_record_coverage または below long-record coverage floor と表示されます。ノートは独自のリコールレーンを使用するため、このフラグには依存しません。最終的にレンダリングされるコンテキストは、引き続きトークン予算に従います。

v0.8 では、完全な LongMemEval/LoCoMo のペア保護ゲートに合格した後、新規の Codex および Claude インストールでこのフラグが有効になります。再インストール時には、キーが存在しない場合や明示的に false が設定されている場合も含め、既存の設定が保持されます。ライブラリでは引き続きオプトインであり、ファイルのミラーリングもデフォルトでは無効です。Phase 75 のエビデンスには適用範囲と制限事項が記録されていますが、公開ベンチマークの主張に変更はありません。

const memory = createGoodMemory({ retrieval: { longRecordAdmission: true } });
オプトインのマルチホップリコール

デフォルトでは、recall() は1回のパスで処理します。オプトインの2パス検索を行うには、multiHop: true を渡します。GoodMemory はクエリを実行し、1回目のパスのエビデンスに含まれるブリッジエンティティを抽出してクエリを拡張し、2回目のパスを実行します。

const recall = await memory.recall({
  scope,
  query: "Who manages the project Alice started?",
  multiHop: true,
});

答えに、最初のホップでのみ名前が示されるエンティティが必要な場合に使用します(ホップ1で「Alice が Project Atlas を開始した」を見つけ、ホップ2で「Project Atlas を管理しているのは誰か」を調べる場合)。

  • オプトイン機能です。デフォルトのリコールは引き続き1回のパスで処理され、multiHop を設定しなくても何も変わりません。
  • 汎用的なセマンティック検索ではありません。 名前付きエンティティを語彙的に橋渡しするものであり、意味に基づいて順位付けするものではありません。
  • 最初のパスのリコールが弱い場合、ノイズが増えることがあります。 ホップ1で誤ったエビデンスが見つかると、抽出されるブリッジエンティティも誤りになり、拡張クエリによってリコールが薄まります。ベース検索の性能が非常に低い LoCoMo で測定したところ、multiHop はリコールを悪化させました。そのため、会話や言い回しのずれによる検索の問題を解決するために使わないでください。必要なのはマルチホップの橋渡しではなく、実際のセマンティック検索です。
オフラインのローカル埋め込みアダプター

createLocalEmbeddingAdapter() は、決定論的でオフライン動作し、依存関係のない埋め込みアダプターです(文字 n グラムのハッシュ化ベクトルを使用)。埋め込みプロバイダーを設定せずに、語彙的・形態的な同点判定に使用するには、これを注入します。

import { createGoodMemory, createLocalEmbeddingAdapter } from "goodmemory";

const memory = createGoodMemory({
  adapters: { embeddingAdapter: createLocalEmbeddingAdapter() },
});
  • ニューラルなセマンティック検索ではありません。ベクトルは語彙特徴をハッシュ化したものなので、語彙的に似た候補間の同点を判定できますが、意味は理解しません。
  • セマンティック検索のベンチマーク改善を主張するために使用しないでください。表層的な語彙の重複ではすでに捉えられない、質問とテキストの言い回しのずれを橋渡しすることはできません。
  • 実際のセマンティックな順位付けには、代わりに GOODMEMORY_EMBEDDING_* を使ってニューラル埋め込みプロバイダーを設定してください。
オプトイン方式の会話ファクト抽出

デフォルトでは、補助抽出(providers.extraction モデルが設定されている場合)は、永続的なプロダクトメモリ(プロフィール、好み、参照情報、ファクト)を抽出します。代わりに書き込み時に、対話を自己完結型で、照応解決済み、エンティティと日付を正規化した原子的な主張へ分解するには、providers.extraction.mode: "conversational" を設定します。これにより、後で検索する際、会話の生のターンではなく正規化されたファクトに一致するようになります。

const memory = createGoodMemory({
  providers: {
    extraction: {
      provider: "openai",
      model: "gpt-5.6-terra",
      apiKey: process.env.GOODMEMORY_ASSISTED_EXTRACTOR_API_KEY!,
      baseURL: process.env.GOODMEMORY_ASSISTED_EXTRACTOR_BASE_URL,
      mode: "conversational",
    },
  },
});

複数ターンの会話からメモリを作成し、発言された内容とは異なる言い回しで質問されるチャット/エージェント製品(「ユーザーのマネージャーは誰ですか?」と「そうそう、上司のDanaが承認しました」のようなケース)に適しています。

  • オプトイン方式です。mode を未設定にする(または providers.extraction を省略する)と、デフォルトの抽出動作が維持されます。想起のランキング経路にも変更はありません。
  • 書き込み時の LLM 処理です。設定済みのチャットモデルを使用するため、抽出のレイテンシとトークンコストが増加します。また、他の LLM 処理と同様に、主張が抜け落ちたり、不適切な言い回しになったりする可能性があります。生のターンが正となる情報源です。
  • セマンティック検索ではありません。保存されたテキストを正規化し、字句検索で照合しやすくしますが、意味に基づいてランキングするわけではありません。会話特有の言い回しの違いに対処する、埋め込みを使わない手段であり、ニューラル埋め込みプロバイダーの代替ではありません。
  • 保留データによる検証なしに、この機能のベンチマーク数値を引用しないでください。また、特定のベンチマークの言い回しに合わせて抽出プロンプトを調整しないでください。

ランタイムとストレージ

createGoodMemory({}) は、ローカルファーストの自動ストレージ契約に従います。

  • storage.provider が明示的に指定されている場合は、それが優先されます。
  • ストレージが明示されていない場合、設定されたターゲットで GoodMemory バックエンドを初期化できるときに限り、GoodMemory は Postgres を使用します。
  • Bun では、設定不要の永続ストレージとして ./.goodmemory/memory.sqlite にローカル SQLite を使用します。
  • 組み込みのローカル SQLite アダプターがない Node ランタイムでは、設定不要のストレージはインメモリにフォールバックします。
  • サポートされていない組み込みの sqlite または postgres が明示的に選択された場合、永続ストレージとして誤表示されず、利用不可として報告されます。
  • 注入された documentStore、sessionStore、または vectorStore アダプターは、アダプター定義のストレージとして報告されます。
  • 検索プリセットがない場合、埋め込みの設定に関係なく、ランタイムの動作は rules-only のままです。recommended プリセットでは、auto がプロバイダー不要のハイブリッドフュージョン経路に振り分けられ、設定されている場合は密なエビデンスが追加されます。
  • サポート対象のローカルランタイムでは、SQLite のセマンティックインデックスに sqlite-vss を使用できます。サポート対象外のランタイムでは、永続性を維持しつつ、アクセラレーションなしでフォールバックします。

カスタム DocumentStore アダプターは、従来の set/get/update/query/delete 契約を維持します。recommended の汎用フュージョンプリセットや、オプトイン方式の行動結果レコーダーなどのアトミック機能には、追加で ProjectionCapableDocumentStore が必要です。その projectionBatchSemantics は、エクスポートされる PROJECTION_BATCH_SEMANTICS のバージョンと一致し、writeBatchIfUnchanged() は expected/unchanged 行をアトミックに検証したうえで、バッチ内のすべての set と delete を適用しなければなりません。既存のアダプターは引き続きプロジェクションなしで動作できます。同名のレガシーメソッドは、意図的に現行のアトミック契約として扱われません。完全なセマンティクスを実装した後にのみ、バージョンマーカーを追加してください。組み込みの memory、SQLite、Postgres ストアは、すでにこの契約を実装しています。

推測せずに、解決済みのランタイムを確認してください。

import { createGoodMemory, inspectGoodMemoryRuntime } from "goodmemory";

const memory = createGoodMemory({});
const runtime = inspectGoodMemoryRuntime(memory);

console.log(runtime.storage);

SQLite ベクター制御項目:

  • GOODMEMORY_SQLITE_VECTOR_MODE=off|prefer|require
  • GOODMEMORY_SQLITE_CUSTOM_LIBRARY_PATH
  • GOODMEMORY_SQLITE_VECTOR_EXTENSION_PATH
  • GOODMEMORY_SQLITE_VECTOR_EXTENSION_ENTRYPOINT
  • GOODMEMORY_SQLITE_VECTOR_SEARCH_FUNCTION

パブリックな記憶のカスタマイズ

製品のインテグレーションでは、パブリックな remember サーフェスを通じて書き込みをカスタマイズしてください。製品の動作に、テスト専用の抽出器用シームを使用しないでください。

import { createGoodMemory, rememberRules } from "goodmemory";

const memory = createGoodMemory({
  remember: {
    preset: "default",
    profiles: [
      {
        id: "life-coach",
        when: { agentId: "life-coach" },
        rules: [
          rememberRules.fact(/my top priority this quarter is (.+)/i, {
            id: "life-goal-priority",
            category: "goal",
            tags: ["life_coach", "long_term_goal"],
            attributes: { horizon: "quarter" },
            content: ({ match }) => match[1] ?? "",
          }),
          rememberRules.preference(/please coach me with (.+)/i, {
            id: "life-coaching-style",
            category: "coaching_style",
            value: ({ match }) => match[1] ?? "",
          }),
        ],
        assistantOutputs: { mode: "confirmed_or_verified_only" },
      },
    ],
  },
});

await memory.remember({
  scope: { userId: "u-1", agentId: "life-coach" },
  messages: [
    {
      role: "user",
      content: "My top priority this quarter is rebuilding my sleep routine.",
    },
  ],
  annotations: [
    {
      messageIndex: 0,
      remember: "always",
      metadataPatch: { tags: ["confirmed_by_host"] },
    },
  ],
});

プロフィールの extractors には、生の MemoryExtractor オブジェクト、または名前付きの { id, extractor } エントリーを指定できます。実際のインテグレーションでは名前付き抽出器を使用してください。これにより、プロフィールの構成が変わっても、記憶イベントと評価レポートで安定した extractorIds が保持されます。記憶イベントには、解決済みの profileId と presetId のメタデータも含まれます。

作成したノート(原文のままのページ)

会話には抽出が適していますが、ページ(ハウツー、ランブック、苦労して得た知見)を残したいエージェントが、その内容を文単位の事実に分解されることを望むとは限りません。note 種別ではメッセージ本文を一字一句そのまま保存し、文単位には分割しません。埋め込みアダプターがある場合は、本文全体を埋め込みます。デフォルト設定では、独立した上限付きレーンとして想起します(タイトルと本文に対する BM25 を使うため、クエリを網羅する長いページも対象になります)。本文は UTF-8 で 8,192 バイトまでです。それより長いページは分割してください。同じタイトルで再度書き込むと、系譜を保ったまま前のページに置き換わります。同一のページは統合されます。

await memory.remember({
  scope,
  messages: [{ role: "assistant", content: pageMarkdown }],
  annotations: [
    {
      messageIndex: 0,
      remember: "always",
      confirmed: true,
      kindHint: "note",
      metadataPatch: { noteTitle: "Reading MediaWiki sites as an agent" },
    },
  ],
});

同じ形式は、MCP ツール goodmemory_write_note、POST /memory/remember の HTTP kindHint: "note" アノテーション、および goodmemory remember --kind note --title "..." --message "..." からも利用できます。想起されたノートは Notes セクションとして表示され、プロンプトの断片を含むすべての出力モードで、本文の Markdown 構造が維持されます。ノートはほかのすべての種別と同様に管理されます。スコープが設定され、編集・忘却が可能で、durable.notes にエクスポートされ、MEMORY.md ではタイトルでインデックス化されます。

AI SDK アダプター

GoodMemory の Node 互換 AI SDK パスは、createGoodMemory() と createGoodMemoryAISDK() から構築される、シンプルな Request -> Response サーバーハンドラーです。

import { createGoodMemory } from "goodmemory";
import type { GoodMemoryStreamTextInput } from "goodmemory/ai-sdk";
import { createGoodMemoryAISDK } from "goodmemory/ai-sdk";

const memory = createGoodMemory({});

const aiSDK = createGoodMemoryAISDK({
  memory,
});

type MemoryChatRequest = Pick<
  GoodMemoryStreamTextInput,
  "messages" | "query" | "scope" | "system"
>;

function isMemoryChatRequest(value: unknown): value is MemoryChatRequest {
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    return false;
  }

  const candidate = value as Record<string, unknown>;
  const scope = candidate.scope;
  return Array.isArray(candidate.messages)
    && !!scope
    && typeof scope === "object"
    && !Array.isArray(scope)
    && typeof (scope as { userId?: unknown }).userId === "string"
    && (scope as { userId: string }).userId.trim().length > 0;
}

export async function handleMemoryChat(request: Request): Promise<Response> {
  const body: unknown = await request.json();
  if (!isMemoryChatRequest(body)) {
    return new Response(
      JSON.stringify({
        error: "Expected a request body with a messages array and scope.userId.",
      }),
      {
        headers: { "content-type": "application/json; charset=utf-8" },
        status: 400,
      },
    );
  }

  const result = aiSDK.streamText({
    messages: body.messages,
    query: body.query,
    scope: body.scope,
    system: body.system,
    model: {} as never,
  });

  return result.toTextStreamResponse();
}

注記:

  • 正式なサーバーの例は examples/plain-ai-sdk-server.ts です。
  • Express と Fastify の簡易的な例は、 examples/express-chat-server.ts と examples/fastify-chat-server.ts です。
  • examples/vercel-ai-chat.ts は、引き続き低レベルのラッパー/API の例です。
  • Next.js App Router では、export async function POST(request: Request) を同じハンドラー本体に割り当てられます。
  • 最初のパブリックなサーバーパスは、ModelMessage を優先します。
  • ラッパーは recall() と buildContext() を通じて system を拡張し、メモリーレイヤーでエラーが発生した場合もソフトに失敗します。

Python/FastAPI HTTP ブリッジ

Python バックエンドから GoodMemory をサーバー側のメモリサービスとして呼び出す場合は、同梱の HTTP ブリッジを使用します。

GOODMEMORY_HTTP_BRIDGE_TOKEN="replace-with-service-token" \
GOODMEMORY_STORAGE_PROVIDER=postgres \
GOODMEMORY_STORAGE_URL="postgres://user:pass@host:5432/goodmemory" \
./node_modules/.bin/goodmemory-http-bridge --profile life-coach

Python の呼び出し元は、Authorization: Bearer <token> と x-goodmemory-* スコープヘッダーを付けて、POST /memory/recall-context、/memory/remember、 /memory/feedback、/memory/export、/memory/import、/memory/forget、 および対象を指定する /memory/revise にリクエストを送信します。TypeScript ブリッジ API は goodmemory/http から利用できます。

推奨の検索プリセット(マルチグラニュラー BM25 + エンティティ + RRF、 任意の高密度チャネル付き)をブリッジ経由で提供するには、スイッチ --recommended(または GOODMEMORY_PROFILE=agent-recommended、 GOODMEMORY_HTTP_BRIDGE_RECOMMENDED=1)を指定して起動します。埋め込みエンドポイントは不要です。 GOODMEMORY_EMBEDDING_* を設定すると、高密度チャネルが追加されます。GET /healthz は retrievalTier と embeddingEnabled を返します。また、想起リクエストはデフォルトで strategy: "auto" になり、プリセットによって hybrid に振り分けられます。明示的に strategy: "rules-only" を指定したリクエストでは、引き続き厳格な最低ラインが選択されます。

または、Docker で 1 つのコマンドを使ってデプロイできます(SQLite ボリュームを含みます。pgvector を使う場合は compose の postgres プロファイルを追加してください)。

GOODMEMORY_HTTP_BRIDGE_TOKEN="replace-with-service-token" docker compose up -d
curl -fsS http://127.0.0.1:8739/healthz

GET /healthz は、コンテナ、ロードバランサー、クライアントの準備完了待機に使う、認証不要の稼働確認エンドポイントです。Python バックエンドでは、公式クライアント — pip install goodmemory-client(PyPI)— を使用してください。このクライアントは、1 つの Scope オブジェクトから呼び出し元のヘッダーを生成し、エンドポイントごとの冪等性ルールを反映し、想起時の routing を表示するため(戦略が意図せずダウングレードされた場合に確認できます)、詳細は docs/GoodMemory-Python-HTTP-Integration-Bridge.md をご覧ください。

ホスト型インスタンス。 稼働中の GoodMemory ブリッジは https://goodmemory.vibenest.net で利用できます(稼働確認: /healthz)。ローカル URL の代わりに GOODMEMORY_BRIDGE_HOST / --goodmemory-host(または GoodMemoryClient のホスト引数)を指定して、任意のクライアントから接続できます。このブリッジではベアラートークン認証が必要なため、ご自身のサービス用トークンをご用意ください。これは単一プロセスの書き込み可能な API です。公開する場合は、事前にレート制限と破棄可能なスコープのデータを追加し、共有の書き込みトークンを決して公開しないでください。

ホストアダプター API

外部ホストが内部実装をインポートせずに成果物やホスト固有の契約を必要とする場合は、goodmemory/host を使用します。

import { createGoodMemory } from "goodmemory";
import { createHostAdapter } from "goodmemory/host";

const memory = createGoodMemory({});

const adapter = createHostAdapter({
  id: "codex-handoff",
  hostKind: "codex",
  memory,
  readableArtifactTypes: ["session_memory"],
});

const result = await adapter.readArtifacts({
  scope: {
    userId: "u-1",
    workspaceId: "workspace-a",
    sessionId: "s-1",
  },
  includeRuntime: true,
});

モード:

  • file-assisted:MEMORY.md、user.md、session-memory/<sessionId>.md、playbooks/*.md などのコンパイル済み成果物を読み取ります。ファイルを正規のストレージとして扱うことはありません。
  • file-authoritative:最小限の書き込み可能なサブセットで利用できます。現在のサブセットは正規の playbooks/*.md ファイル形式であり、構造化された差分を、有効なアクティブなパターンのフィードバックレコードに書き戻します。

書き込み時のガードレール:

  • プロンプトファイルとスキルスニペットファイルは、引き続き派生した読み取り専用の出力です。
  • リスクの高いガイダンスの編集には、明示的な verifyWrite による承認が必要です。
  • appliesTo や Why などの低リスクなメタデータ編集は、追加の承認手順なしで書き戻せます。
  • 書き込み可能な操作に失敗した場合は、ロールバックのガイダンスを含む診断情報が返されます。

現在の Claude/Codex の例は、デフォルトで file-assisted モードのままです。

CLI リファレンス

シェルの PATH 上にある goodmemory コマンドは、npm install -g [email protected] でインストールされたグローバル CLI です。ローカルに依存関係をインストールした場合は、npx goodmemory、npm exec -- goodmemory、または ./node_modules/.bin/goodmemory としてパッケージの bin を実行してください。リポジトリ内の bun run goodmemory スクリプトは開発専用です。

メモリ優先コマンド:

./node_modules/.bin/goodmemory inspect --user-id <user-id> --workspace-id <workspace-id>
./node_modules/.bin/goodmemory trace --user-id <user-id> --workspace-id <workspace-id> --query "Which runbook is the source of truth?"
./node_modules/.bin/goodmemory export-memory --user-id <user-id> --workspace-id <workspace-id> --output ./tmp/export
./node_modules/.bin/goodmemory import-memory --user-id <user-id> --workspace-id <workspace-id> --input ./tmp/export --dry-run
./node_modules/.bin/goodmemory stats --user-id <user-id> --workspace-id <workspace-id>
./node_modules/.bin/goodmemory remember --user-id <user-id> --workspace-id <workspace-id> --session-id <session-id> --message "Remember that the deploy is blocked on smoke verification."
./node_modules/.bin/goodmemory remember --user-id <user-id> --kind note --title "Reading MediaWiki sites as an agent" --message "$(cat page.md)"
./node_modules/.bin/goodmemory feedback --host codex --workspace-root . --session-id <session-id> --signal "Keep coding summaries short and list explicit next steps."
./node_modules/.bin/goodmemory forget --host codex --workspace-root . --session-id <session-id> --memory-id <memory-id>

インストール済みホストのコマンド:

goodmemory -V
goodmemory --version
goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory install codex --activation-mode global --writeback observe --user-id <user-id>
goodmemory enable codex --workspace-root . --writeback selective
goodmemory mcp serve --host codex
goodmemory-mcp --host codex
goodmemory codex bootstrap --user-id <user-id> --workspace-id <workspace-id>
goodmemory claude bootstrap --user-id <user-id> --workspace-id <workspace-id>

フックと書き戻しの例:

printf '%s' '{"cwd":".","session_id":"s-1","hook_event_name":"SessionStart","source":"startup"}' \
  | goodmemory codex hook session-start

printf '%s' '{"cwd":".","session_id":"s-1","tool_name":"Bash","tool_input":{"command":"./tools/DeepAnalyzer --detailed"}}' \
  | goodmemory codex hook pre-tool-use

goodmemory codex action -- ./tools/DeepAnalyzer --detailed

printf '%s' '{"cwd":".","session_id":"s-1","messages":[{"role":"user","content":"Next step is to finish the release smoke."}]}' \
  | goodmemory codex writeback --json

printf '%s' '{"cwd":".","session_id":"s-1","event_id":"stop-1","summary":"Keep coding summaries short."}' \
  | goodmemory codex hook session-stop

評価アーティファクトの確認:

./node_modules/.bin/goodmemory eval inspect --run-dir reports/eval/live/<run-id> --case-id <case-id>
./node_modules/.bin/goodmemory eval trace --run-dir reports/eval/live/<run-id> --case-id <case-id>
./node_modules/.bin/goodmemory eval export-case --run-dir reports/eval/live/<run-id> --case-id <case-id> --output /tmp/case.json

CLI の一覧:

  • goodmemory -V
  • goodmemory --version
  • goodmemory setup
  • goodmemory status
  • goodmemory install
  • goodmemory uninstall
  • goodmemory enable
  • goodmemory disable
  • goodmemory inspect
  • goodmemory trace
  • goodmemory export-memory
  • goodmemory import-memory
  • goodmemory stats
  • goodmemory --schema(エージェントやツール向けに CLI 全体を JSON 形式で出力します。goodmemory <command> --help は人間向けの形式です)

インストール済みホストでは、エクスポートバンドルをディスク上に保持することもできます。goodmemory setup --file-mirror(または install <host> --file-mirror)を実行すると、永続化される書き込みのたびに <workspace>/.goodmemory/memory/ に書き込みます。これにより、CLI を実行しなくても MEMORY.md、topics/*.md、pages/*.md を検索できます。

  • goodmemory remember
  • goodmemory feedback
  • goodmemory forget
  • goodmemory mcp serve
  • goodmemory-mcp
  • goodmemory codex hook
  • goodmemory codex writeback
  • goodmemory claude hook
  • goodmemory claude writeback
  • goodmemory codex bootstrap
  • goodmemory claude bootstrap
  • goodmemory eval inspect
  • goodmemory eval trace
  • goodmemory eval export-case

例

インストール済みパッケージのガイド:

リポジトリ内の例:

このリポジトリから例を実行するには:

bun run example:chat
bun run example:coding-agent
bun run example:ai-sdk-server
bun run example:express-chat
bun run example:fastify-chat
bun run example:vercel-ai
bun run example:life-coach-profile
bun run example:host-claude
bun run example:host-codex

テストと評価

デフォルトのローカルゲート:

bun test
bun run typecheck
bun run test:coverage

パッケージ、カバレッジ、ランタイム利用者、サイズ、来歴の準備をすべて行うには、明示的な出力ディレクトリを1つ指定します:

bun run release:prepare -- --output-dir <dir>

このコマンドはソースの識別情報を固定し、必須チェックを実行し、tarballを1つだけパッケージ化し、同じtarballをNodeとBunで検証して、正式なrelease-manifest.jsonと決定論的なエビデンスアーカイブを書き込みます。 summary.mdは人間が読みやすい形式にしたものです。準備処理では昇格も公開も行いません。このソースツリーには汎用の昇格コマンドはありません。安定版の公開では、メンテナーの承認のもと、これらのローカル成果物をそのまま使用します。読み取り専用のリリースワークフローでは、2回目のパッケージ化やレジストリの認証情報を使わずに、公開済みアセットとnpmの整合性を検証します。

リポジトリの調査プロトコルは、静的レジストリから選択します:

bun run research:list
bun run research:run -- <id> --root <path>
bun run research:verify -- <id> --root <path>

過去のフェーズ検証ツールとリリース検証ツールは、紐付けられたタグまたはコミットからスクリプトを直接実行して引き続き再現できます。以前のパッケージエイリアスは、現在のコマンド一覧には意図的に含まれていません。

ベンダー提供またはサードパーティのテストツリーも含めた、より広範な一括実行を意図的に行う場合に限り、bun run test:allを使用してください。

評価コマンド:

bun run eval:smoke
bun run eval:fallback
bun run eval:live
bun run eval:live-memory
bun run eval:live-auto-memory
bun run eval:live-provider-memory
bun run eval:summary

各コマンドの意味:

  • eval:smoke:ハーネスの自己チェックです。
  • eval:fallback:ライブモデル呼び出しを行わない、決定論的な検証です。
  • eval:live:インメモリバックエンドを使用した、ライブジェネレーターとライブジャッジです。
  • eval:live-memory:自動ストレージのセマンティクスを使用する、ライブジェネレーターとライブジャッジです。プロバイダーストレージが解決されない場合、デフォルトのストレージはローカルのSQLiteです。
  • eval:live-auto-memory:スクリプトで自動ストレージを明示する必要がある場合に使用する、eval:live-memoryのエイリアスです。
  • eval:live-provider-memory:Postgres、埋め込み、支援付き抽出を必要とする、プロバイダーを利用したエビデンスパスです。SQLiteへの暗黙のフォールバックは行いません。
  • eval:summary:既存の評価出力ディレクトリを要約します。

ライブ評価の環境変数:

  • GOODMEMORY_EVAL_PROVIDER
  • OpenAI互換ゲートウェイ用のGOODMEMORY_EVAL_BASE_URL
  • GOODMEMORY_EVAL_MODEL
  • GOODMEMORY_EVAL_API_KEY
  • 任意の並列処理上限GOODMEMORY_EVAL_MAX_CONCURRENCY
  • GOODMEMORY_JUDGE_PROVIDER
  • OpenAI互換ゲートウェイ用のGOODMEMORY_JUDGE_BASE_URL
  • GOODMEMORY_JUDGE_MODEL
  • GOODMEMORY_JUDGE_API_KEY

eval:live-memoryとeval:live-auto-memoryには、埋め込みと支援付き抽出の設定も必要です:

  • GOODMEMORY_EMBEDDING_PROVIDER
  • OpenAI互換ゲートウェイ用のGOODMEMORY_EMBEDDING_BASE_URL
  • GOODMEMORY_EMBEDDING_MODEL
  • GOODMEMORY_EMBEDDING_API_KEY
  • GOODMEMORY_ASSISTED_EXTRACTOR_PROVIDER
  • OpenAI互換ゲートウェイ用のGOODMEMORY_ASSISTED_EXTRACTOR_BASE_URL
  • GOODMEMORY_ASSISTED_EXTRACTOR_MODEL
  • GOODMEMORY_ASSISTED_EXTRACTOR_API_KEY

eval:live-provider-memoryには、さらに次の環境変数が必要です:

  • GOODMEMORY_TEST_POSTGRES_URL

出力ディレクトリ:

  • ライブ実行:reports/eval/live/run-*
  • 自動ストレージを使用するライブメモリ実行:reports/eval/live-memory/run-*
  • プロバイダーを利用するライブメモリ実行:reports/eval/live-provider-memory/run-*
  • フォールバック実行:reports/eval/fallback/run-*

戦略の段階的導入

GoodMemoryでは、サポート対象のベースラインとしてrules-onlyを維持しています。新しい検索動作はobserve -> assist -> promoteの段階を経て導入します。

運用ガイダンス:

  • observe:実行経路を変更せず、分離されたシャドウエビデンスを収集します。
  • assist:制御された評価実行で、候補の実行を許可します。
  • promote:strategy-promotion-gate.json、問題のないregression-dashboard.json、およびstrategy-promotion-authorization.jsonを必須とします。
  • 評価エビデンスが不完全な場合、プロバイダーを利用する依存関係が利用できない場合、またはロールバック条件に該当する場合は、rules-onlyを維持してください。

現在のステータス

現在の安定版で公開されている機能:

  • goodmemory を通じたルートメモリ API
  • goodmemory/ai-sdk を通じた AI SDK アダプター
  • goodmemory/host を通じたホストアダプターとホストコントラクト
  • goodmemory/http を通じた HTTP ブリッジ API と、パッケージ化された goodmemory-http-bridge
  • インストール済み CLI と、goodmemory setup を通じた管理対象ホストのセットアップ
  • 想起用の Codex と Claude Code のフック
  • 検査とデバッグ用の読み取り専用 MCP
  • 監査と取り消し機能を備えた、オプトイン方式のインストール済みホストへの書き戻し
  • Bun でのローカル SQLite 永続フォールバック
  • 設定時の Postgres、埋め込み、支援付き抽出、プロバイダー連携評価

内部 API、記憶、想起、CLI のオーケストレーションは、ADR-009 の責務境界に沿って分割されています。これは動作を維持したまま行う保守上の変更です。公開 API/CLI の出力、デフォルト、永続化の順序、フォールバック、トレース、シリアライズの各コントラクトに変更はありません。HTTP ブリッジ、インストール済みホストへの書き戻し、ベンチマークに関する主張の方針は、このリファクタリングの対象外です。

現在、公開機能として認められていないもの:

  • デフォルトで有効な自動書き戻し
  • 生のトランスクリプトのアーカイブ
  • ダッシュボードまたは管理対象クラウド
  • エクスポートされたアーティファクトファイルを正規のストレージとして扱うこと
  • 内部の提案または昇格に関する実装をルートのエクスポートに追加すること

現在の状態と根拠の詳細な一覧については、 docs/GoodMemory-Current-Status-and-Evidence.md を参照してください。

ドキュメント

実行順序、未完了のフォローアップ作業、フェーズ固有の受け入れ範囲については、task-board/00-README.txt を参照してください。アーカイブされた設計資料は現在の正しい情報ではなく、docs/README.md から案内されています。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。