lociとは?
lociは、AIエージェント向けの型付き長期記憶レイヤーです。会話から長期的に役立つ事実を抽出し、SQLiteに保存して後で想起するために順位付けし、不要になった情報を削除します。
このプロジェクトは、記憶には場所と構造の両方が必要だという考えに基づいています。保存されたすべての発言を同じように扱うのではなく、lociは好み、期限、目標、関係などの情報の種類を区別し、それぞれに適したライフサイクルで管理します。
lociは、Limaの本番環境で使われている記憶システムから移植され、特定のホストアプリケーションに依存しない形に書き直されています。
記憶システムの仕組み
型付き記憶
すべての記憶は、次の8カテゴリのいずれかに属します。
- routine
- study
- preferences
- finance
- goals
- relationships
- constraints
- ephemeral
記憶には、4段階の重要度とステータスのライフサイクルもあります。この構造により、システムは長く続く好みを、一時的な期限や短期間だけ有効な事実とは異なる方法で扱えます。
2つの抽出経路
抽出には2つの仕組みを組み合わせます。モデルベースの抽出器は会話の意味を読み取り、正規表現ヒューリスティクスは明示的に対応している表現を検出します。結果は統合され、モデルの出力が優先されます。
モデルプロバイダーが利用できない場合も、正規表現による経路は実行を継続できます。モデル呼び出し、プロバイダーSDK、APIキーは意図的にホストアプリケーション側に任せており、ホスト側からModelExtractorを注入できます。
フィルタリング、順位付け、減衰
書き込みフィルターは、一時的な気分や同様の短期間だけ有効な発言が、恒久的なプロフィールデータになるのを防ぎます。たとえば、「今日は疲れた」という発言は数時間は正しくても、数か月後には誤解を招く可能性があります。
記憶をモデルのコンテキストに追加するとき、lociは結果を12件の事実に制限します。重要度で順位付けした後、期限までの近さと新しさも考慮します。この上限により、プロンプトが際限なく増大するのを防ぎます。
毎日の統合と減衰によって、保存内容を有用な状態に保ちます。
- 完全な重複は統合されます。
- 未確認の推測は、最終的に期限切れになります。
- 一時的な事実の有効期間は24時間です。
- 完了した目標は90日後に期限切れになります。
統合方法を選ぶ
lociは、1つの共有コアと2つのアダプターを提供します。
MCPサーバー
MCPアダプターは、互換性のある任意のMCPクライアントで動作します。remember、recall、forgetの3つのツールを公開します。
MCPはリクエストとレスポンスに基づくため、ターン終了時の自動フックはありません。エージェントは意図的にrememberを呼び出す必要があります。リクエストに応じて記憶を想起し、コンテキストに注入できます。
Hermesプラグイン
Hermesアダプターは同じ3つのツールを提供しますが、自動抽出にも対応し、すべての呼び出しの前にコンテキストを注入します。これは、Hermesがモデルの応答後に会話を調べられるpost_llm_callフックを提供しているため可能です。
Pythonから直接統合
エージェントのループを自分で管理し、抽出、永続化、想起、コンテキスト注入を実行するタイミングを決めたい場合は、コアライブラリを直接使用します。
インストールとセットアップ
コアパッケージをインストールする
pip install mowave-lociMCPサポートをインストールする
pip install mowave-loci[mcp]MCP追加機能をインストールしたら、MCPクライアントの設定にlociを追加します。
{
"mcpServers": {
"loci": {
"command": "python",
"args": ["-m", "loci.adapters.mcp_server.server"]
}
}
}クライアントを再起動または再読み込みして、remember、recall、forgetのツールを検出できるようにします。
Hermesプラグインをインストールする
hermes plugins install <you>/loci
hermes plugins enable loci<you>/lociは、使用する環境に適したプラグインリポジトリまたはソースに置き換えてください。
ストレージを設定する
デフォルトでは、lociはSQLiteデータベースの~/.loci/memory.dbに記憶を保存します。別のファイルを使用するには、LOCI_DB環境変数を設定します。
export LOCI_DB=/path/to/memory.db別途データベースサーバーを用意する必要はありません。
Pythonでの基本的な使い方
基本的なワークフローは、ストアを作成し、候補となる記憶を抽出し、フィルタリングして、受け入れた記憶を保存し、アクティブな記憶をシステムプロンプトに追加することです。
from loci import Store, extract, should_persist, context_block
store = Store()
for memory in extract(
"eu prefiro respostas curtas",
assistant_text=reply,
):
if should_persist(memory):
store.upsert(memory)
system_prompt += "\n\n" + context_block(store.active())この例では、replyは会話に対応するアシスタントのテキストを表します。ポルトガル語のユーザーメッセージは、ユーザーが短い回答を好むという意味です。
Store()は、設定されたSQLite記憶ストアを開きます。extract(...)は、会話から候補となる記憶を生成します。should_persist(memory)は、書き込みフィルターを適用します。store.upsert(memory)は、受け入れた記憶を挿入または更新します。store.active()は、アクティブな記憶を取得します。context_block(...)は、それらの記憶をプロンプト注入用に整形します。
MCPツールを使う
MCPサーバーを設定すると、接続されたエージェントは次の3つの操作を利用できます。
- remember: 保持すべき事実を意図的に保存します。
- recall: 関連する保存済み情報を取得します。
- forget: 保持する必要がなくなった情報を削除します。
MCPアダプターはメモリを自動的に抽出しないため、エージェントの指示では、エージェントがいつrememberを呼び出すべきかを明確にする必要があります。完了したすべての会話ターンが検査され、保存されるとは限りません。
高度な統合のヒント
プロバイダーのロジックをコアの外部に置く
lociのコアはPython標準ライブラリのみを使用します。モデル呼び出し、APIキー、プロバイダーSDKはアプリケーション側で管理します。意味抽出にモデルが必要な場合は、プロバイダーの依存関係をコアに追加するのではなく、ホストからModelExtractorを注入してください。
ホストからライフサイクルジョブを実行する
lociはメモリの形状、統合、減衰の動作を定義しますが、日次処理のスケジュールは行いません。ホストのcron、s6、systemd、または同等のスケジューラーを使って、日次ジョブを起動してください。
コンテキスト上限を維持する
データベース全体をすべてのプロンプトに追加して、ランク付けされたコンテキストブロックを迂回しないでください。12件の事実という上限は、重要で適時性があり、かつ新しい情報を優先しながら、コンテキストの増大を抑えるために存在します。
適切なアダプターを使用する
- 複数のMCPクライアント間での移植性が重要で、明示的なメモリ操作を許容できる場合は、MCPを選択します。
- モデル呼び出し後の自動抽出と、すべての呼び出し前のメモリ注入が必要な場合は、Hermesを選択します。
- アプリケーションがエージェントループを管理し、永続化とプロンプト構築を正確に制御する必要がある場合は、直接Python APIを選択します。
トランスポートとセッションはホストに任せる
エージェントループ、ツールディスパッチ、セッション、トランスポート、認証はコアの責任範囲外です。Hermes、OpenClaw、Claude Codeなどのホストが周辺のランタイムを管理し、アダプターがホスト固有のトランスポートと認証を処理します。
テストスイートを実行する
pytest -qこのプロジェクトには、テンポラリファイル内の実際のSQLiteストアに対して実行される92件のテストが含まれています。ストア自体はモックされていないため、実際のデプロイで使用されるものと同じストレージ技術に対する動作を検証できます。
まとめ
lociは、別個のサーバーを必要とせずに、AIエージェントへコンパクトで型付きの永続的なメモリレイヤーを提供します。共有コアがメモリの構造とライフサイクルを処理し、MCP、Hermes、または独自のPythonエージェントが周辺のランタイムを担います。ホストに合ったアダプターから始め、抽出とスケジューリングの責任を明確にし、ランク付けしたコンテキスト注入を使って、メモリがプロンプトを圧迫しないようにしてください。
