Synap の使用方法
Synap は AI エージェント向けのローカルファーストメモリエンジンです。すべてのデータはユーザーのマシンの ~/.synap/ 配下に保存されます — クラウドもアカウントも API キーも不要です。操作は mcp__synap__* ツールファミリを通じて行います。
このスキルでは、どのツールを、いつ、どのような引数で使うかという意思決定ツリーを解説します。正確なパラメータ構文についてはツールのスキーマを参照してください。このドキュメントは、適切なツールを選択し、効果的に使用する方法を説明します。
基本概念
Synap はデータを アプリ 単位で整理します。アプリはスキーマを持つ名前空間(tasks、accounting、recipes、…)です。スキーマは内部的には EAV 形式であるため、後からマイグレーションなしでフィールドを追加できます。各アプリは エンティティ(行)を保持し、エンティティは 属性(フィールド)を持ちます。
組み込みのアプリが 2 つあり、これらは Synap 自身が所有します。
synap.memories— ユーザーに関する長期記憶。書き込みはremember/forgetを通じて行います(writeは使用禁止)。読み取りはquery/searchを通じて行います。synap.sessions— 会話履歴(ターン、要約)。読み取り専用です。書き込まないでください。
ユーザー(またはユーザーの代わりにあなた)が作成するアプリは、他の名前で配置します(synap. プレフィックスは予約済みのため使用不可)。
意思決定ツリー
「私について X を覚えておいて」
synap.memories に対して remember を使用します。2 つの形式があります。
- プロファイル属性(
type: "attr")— ユーザーに関する永続的な事実(preferred_language、city、allergies)。上書きするにはop: "set"、リストに追加するにはop: "append"を使用します。 - イベント(
type: "event")— タイムスタンプ付きの観測結果(「ユーザーが v0.1.0 をリリースした」「ユーザーが圧倒されていると言及した」)。追記専用で、description、subject、オプションのwhenを含みます。
永続的な状態を示す事実には attr を、後でコンテキストとして重要な一瞬の出来事には event を選択してください。
「あなたは私について何を知っていますか?」
synap.memories に対して、filters=[{field:"subject", op:"eq", value:"user"}] を指定して query を実行します。ユーザーがあいまいな検索を求めた場合(「旅行の計画について何か知ってる?」など)にのみ search を使用します。その場合は rank: "time_decay" を指定した search で、最近の関連イベントを表示します。
「X を忘れて」
forget を使用します。正確にキーを指定します。「query して null を書き込む」ようなことはしないでください。forget は属性のクリアとイベントの削除をアトミックに処理します。
「タスク / レシピ / 費用 / … を追跡したい」(新しい種類のデータ)
list_apps— 既存のアプリがないか確認します。- 存在しない場合: 適切なスキーマを指定して
init_appを実行します。 writeでエンティティを追加します。opsは配列です: op が 1 つ = 単一書き込み、N 個 = アトミックバッチ(すべて成功するか、すべて失敗するかのいずれか)。
スキーマ設計のヒント:
- 長いテキストフィールド(説明、メモ)には
vectorized: trueを設定すると、セマンティック検索が可能になります。 - 1 つのアプリで異なる形状を保持する場合(例: 1 つの
workspaceアプリに「タスク」と「ノート」)はentity_typeを使用します。 - v1 を過度に設計しないでください — EAV なら後からフィールドを追加できます。
「ToDo を見せて / 先週のノートを見せて / …」
フィルターとソートを指定して query を実行します。TSV 出力は高密度です — パースしてからユーザーに表示してください(生のまま表示しない)。
「X に関するものを何か見つけて」
search を使用します。3 つのランキングモードがあります。
relevance(デフォルト)— 純粋なセマンティックマッチ + キーワードマッチ。recency— 類似性を無視して最新順。最新のノートを探す場合に適しています。time_decay— 両方の要素を混合。新鮮さと関連性の両方が重要な、進化するコンテキスト(イベント、日記)に適しています。
app_id を指定してスコープを絞るか、省略してアプリ横断検索を行います。
「このファイルを読んで」
read_file — file://、synap:// URI、およびローカルパスを処理します。チャンク化されたページを返します(デフォルト約 4K 文字)。page パラメータでページ送りができます。
「前に言ってたあれは何だっけ?」(コンテキストが圧縮された場合)
会話中に <compressed_segment turn_ids="..."> ブロックを探します。その turn_ids を指定して expand を実行すると、元の逐語的な内容に戻ります。<stale_tool_result turn_id="..."> も同様のパターンで、折りたたまれたツール出力に対して使用します。
アンチパターン
synap.*アプリにwriteしないでください。 Synap は拒否します。メモリにはremember/forgetを使用してください。- カスタムアプリでメモリを再発明しないでください。
synap.memoriesにはプロファイル+イベントのセマンティクス、時間減衰ランキング、および毎ターン自動インジェクションが組み込まれています。 - 手動で過度にチャンク化しないでください。 長いテキスト(1024 トークン超)は自動的にオーバーラップ付きでチャンク化されます。全体をそのまま書き込んでください。
- subject フィールドを無視しないでください。 メモリは
subjectによってスコープが設定されます(デフォルトは"user")。ユーザーが他の誰かを追跡している場合(「アリスは紅茶が好きだということを覚えておいて」など)は、subject: "alice"を渡してください。
よくあるパターン
ユーザーの生活の新しい領域を設定する
ユーザー: 「読書のトラッキングを始めたい。」
1. list_apps — 「reading」アプリが存在しないことを確認します
2. init_app name="reading" (フィールド指定):
- title (テキスト, 必須)
- author (テキスト)
- status (列挙: to_read | reading | done)
- started_at, finished_at (日付)
- notes (テキスト, vectorized: true)
- rating (数値, 1-5)
3. 「準備できました — 何を読んでいるか教えてください。追加します。」
会話開始時にコンテキストを表示する
[memory: profile] および [memory: events] ブロックは毎ターン自動的にインジェクションされます。それらを表示するために query を呼び出す必要はありません。ただし、ユーザーがより広範な記憶を必要とする質問をした場合(「最近何に取り組んでいる?」など)は、synap.memories に対して rank: "time_decay" を指定した search を使用するのが適切です。
データの移行 / 再構成
Synap には正式なマイグレーション機能はありません。フィールドを追加するには: 単に書き込みを開始するだけです。既存の行にはその属性が単に存在しません。名前を変更するには: query ですべての entity_id を取得し、古いフィールド→新しいフィールドへのマッピング(および古いフィールドのクリア)を含む書き込みのバッチを実行します。EAV のコストは最小限です。
ツール早見表
| 目的 | ツール | 備考 |
|---|---|---|
| ユーザーの事実を記憶 | remember type=attr | op: set または append |
| タイムスタンプ付きイベントを記録 | remember type=event | 追記専用 |
| 記憶を消去 | forget | 正確なキーを指定、推測しない |
| データアプリを作成 | init_app | べき等、進化に対応 |
| アプリ一覧を表示 | list_apps | include_internal: true で synap.* も表示 |
| エンティティを追加/更新 | write | ops 配列、N = アトミックバッチ |
| エンティティをフィルタ | query | TSV 出力、フィールド投影 |
| セマンティック検索 | search | rank: relevance | recency | time_decay |
| ファイルを読む | read_file | 自動ページ送り |
| 圧縮されたターンを復元 | expand | 圧縮ブロックから turn_ids を渡す |
| エンティティ間のリンクを検出 | detect_links | オプトイン、知識グラフ用 |