メモリとコンテキスト
エージェントは重要なことを記憶します。すべての会話が分析され、事実・出来事・約束が抽出されて自動的に保存・呼び出されます。
メモリカテゴリ
メモリは4つのカテゴリに保存されます。
- ファクト(Facts): 永続的な知識——ユーザーの好み、個人情報、背景。例:「ユーザーはタイ料理が好きなソフトウェアエンジニア」
- イベント(Events): 共有体験のエピソード記憶。例:「先週、彼らの日本旅行について話した」
- コミットメント(Commitments): エージェントが交わした約束や計画。例:「次回は就職面接について聞くと約束した」
- サマリー(Summaries): 統合された会話サマリー。セッション間で自動生成されます。
メモリの仕組み
メモリは完全に自動です——管理する必要はありません。プラットフォームは各会話を分析し、事実・出来事・コミットメントを抽出します。各応答の前に、最も関連性の高いメモリが自動的に組み立てられてコンテキストに含まれます。
オーケストレーション不要
chatを呼び出すだけで、プラットフォームがメモリの抽出・保存・取得をすべてのインタラクションで処理します。
自己改善するメモリ
メモリは静的なストアではありません。すべてのchat呼び出しの背後で、メモリの正確性、組織化、関連性を時間とともに保つために、いくつかの閉じたフィードバックループが自動的に実行されます。これらはあなた側のコードを必要としません。
- 重要度フィードバック — エージェントが応答で実際に使う事実は強化され、ロードされても無視される事実は徐々に薄れます。
- 信頼度の強化 — 事実が呼び出されて会話で確認されると、その信頼度は確実性に向かって着実に上昇します。
- 自然な忘却 — 事実は時間とともに緩やかに減衰しますが、フロアを下回ることはありません。感情的に重要な事実やアイデンティティを定義する事実は、中立的なものよりもはるかにゆっくり減衰します。
- ユーザー別の検索ポリシー — プラットフォームはセッションフィードバックから各エージェント–ユーザーペアの検索の好みを学習します。数週間後、検索はそのユーザーのパターンに合わせて調整されます。
- メモリの関連付け — 一緒にアクセスされるメモリは、それらの間のリンクを強化します。メモリグラフ内で頻繁にトラバースされるパスは、時間とともに高速化します。
- 適応型検索バジェット — 検索は自己調整型の時間バジェットの下で実行されます。品質は一貫しており、ユーザーは常にレスポンシブと感じます。
- 次セッション予測 — セッション終了時に、プラットフォームはユーザーが次回取り上げそうなトピックを予測し、それらのコンテキストを事前に温めます。
統合、クラスタリング、重複排除、トピック転換検出、ナラティブアーク、ブレイクスルー、ロールアウト安全システムを含むすべてのメカニズムの完全なウォークスルーについては、エージェントが時間とともに賢くなる仕組みを参照してください。
自動統合・重複排除・クリーンアップ
プラットフォームは、メモリが成長してもコンパクトでナビゲートしやすい状態を保つために、バックグラウンドで積極的にメモリを再構築します。これらは呼び出す必要はありません——デフォルトで適切な周期で実行されます。
テーマ別クラスタリング
新しい事実は自動的に意味的なクラスタにグループ化されます。クラスタは多様すぎるようになると分割され、互いに近づくと統合され、空になると廃止されます——調整なしでクラスタセットをバランスよく保ちます。
可逆的な重複排除
2つの事実が同じものであると判明した場合、プラットフォームはそれらを統合し、完全な監査証跡とともに統合を記録します。後の信号がそれと矛盾する場合、すべての統合は逆転できます。メモリは決して破壊されません——再編成されますが、すべての再編成が追跡されます。
競合解決
新しい情報が既存のメモリと矛盾する場合(「先月ベルリンに引っ越した」が「パリに住んでいる」を上書きする場合)、プラットフォームは競合について推論し、適切なアクションを選択します——両方を新しい情報として保持する、組み合わせる、古い事実を置き換える、または厳密な重複を破棄する。矛盾がまだ明確に解決できない場合、両方のバージョンが保存されるため、何も時期尚早に失われることはありません。
出典に紐づいた事実
会話の実際の引用にトレースできない事実は、ストレージに入る前に拒否されます。エージェントはメモリを幻覚することはできません——保存されるすべての事実は、実際の話者からの実際のメッセージにアンカーされていることが検証されています。
プルーニング
信頼度、重要度、最新性の組み合わせが低いブランチはプルーニングされます。プラットフォームは決して高価値のメモリを削除しませんが、何も貢献しないブランチを表面化することをやめます。
ツリーの自己組織化
階層的なメモリツリーは時間とともに自身を再構築します。頻繁にアクセスされるブランチは、検索を高速化するために徐々にルートに近づきます。過密ノードはバランスのとれたサブツリーに分割されます。メモリの形は、実際にどう使われているかを反映するようになります。
ナラティブアーク圧縮
複数のセッションにわたって繰り返される実体やテーマは、名前付きのナラティブアークに圧縮されます。長期にわたるスレッド(例:「ユーザーのスタートアップ立ち上げ」)は、20個の個別の事実ではなく1つのアークになります——長期的な会話は、コンテキストウィンドウを爆発させることなくコヒーレントな状態を保ちます。
トピック転換の検出とエピソード
会話には整然とした区切りがありません——ユーザーが「とにかく、まったく別の話題で...」と言うこともあれば、段落の途中で方向転換することもあります。プラットフォームはこれらの転換を自動的に検出し、メモリをコヒーレントなエピソードに整理するために使用します。
二段階チェックは、最初に軽量な信号を実行し、それらの信号が曖昧な場合のみ、より深い意味的チェックにエスカレートします。信号の重みは、セッション終了時の監査からエージェント–ユーザーペアごとにキャリブレーションされるため、エピソード検出は使用とともに改善されます。
エージェントがメモリを取り出すとき、キーワードマッチした断片だけでなく「このエピソードからのすべてのメモリ」を取得できます——返答にナラティブの連続性を与えます。
メモリのシード
memory.seed() を使用して、最初の会話の前にエージェントがユーザーについて知っている内容を事前ロードします。
import { Sonzai } from "@sonzai-labs/agents";
const client = new Sonzai({ apiKey: "sk-..." });
await client.agents.memory.seed("agent-id", {
userId: "user-123",
memories: [
{ text: "User's name is Jane Smith", factType: "fact" },
{ text: "Jane is a senior product manager at Acme Corp", factType: "fact" },
{ text: "Jane lives in San Francisco and enjoys hiking", factType: "fact" },
],
});メモリの検索
キーワードまたはセマンティッククエリで、ユーザーとエージェントのペアのメモリを検索します。
const results = await client.agents.memory.search("agent-id", {
userId: "user-123",
query: "hiking trip",
limit: 10,
});
for (const mem of results.memories) {
console.log(mem.content, mem.type, mem.createdAt);
}一覧表示とブラウズ
すべてのメモリを一覧表示するか、カテゴリ別にブラウズします。
// すべてのメモリを一覧表示(ページネーション付き)
const memories = await client.agents.memory.list("agent-id", {
userId: "user-123",
type: "fact", // "fact" | "event" | "commitment" | "summary"
limit: 20,
offset: 0,
});
// カテゴリ別ブラウズ
const facts = await client.agents.memory.listFacts("agent-id", {
userId: "user-123",
});メモリタイムライン
ユーザーのメモリ履歴を時系列で取得します。
const timeline = await client.agents.memory.timeline("agent-id", {
userId: "user-123",
from: "2026-01-01",
to: "2026-03-31",
});
for (const entry of timeline.entries) {
console.log(entry.date, entry.summary);
}メモリツリーのブラウズ
ユーザーの階層的なメモリ構造をナビゲートします。
// 指定パスでメモリツリーをブラウズ
const nodes = await client.agents.memory.browse("agent-id", {
userId: "user-123",
path: "/facts", // オプション:パスでフィルタ
});メモリのリセット
ユーザーとエージェントのペアのすべてのメモリをクリアします——テスト時や、ユーザーが新たなスタートを望む場合に便利です。
await client.agents.memory.reset("agent-id", {
userId: "user-123",
});実践ガイド
メモリはすべてのユースケースにおいて中心的な役割を果たしますが、活用方法は構築するものによって異なります。あなたのトラックをお選びください。
メモリは関係性のアークです。 コンパニオンは共有の歴史を積み重ねていきます——「天文学について初めて話した日」「期末試験でストレスを抱えていた週」——エージェントはそれを自然に参照してつながりを深めます。
シードは控えめに。 ユーザーについて知っていることをすべて事前ロードしないでください。ほとんどのメモリは会話を通じて自然に形成させましょう。シードするのは、永続的なアイデンティティに関わる事実(名前・主要な興味・参加した経緯)のみにします。
タイムラインをUI駆動に活用。 タイムラインエンドポイントは日付付きのエピソード記憶を表示します——これをアプリの「共有の思い出」ビューとしてレンダリングし、ユーザーが関係の歴史を見られるようにしましょう。
const timeline = await client.agents.memory.timeline("agent-id", {
userId: "user-123",
limit: 30,
});
for (const entry of timeline.entries) {
// コンパニオンUIでエピソードを1つのモーメントとしてレンダリング
render(entry.date, entry.summary, entry.moodBefore, entry.moodAfter);
}コンパニオンアプリにはリセットボタンを設けないでください——「自分のことを忘れてほしい」という意味でない限り、それは関係を壊します。