あなたがAIと一時間、頭を突き合わせてブレストしているところを想像してみてください。そこへ無料枠のレート制限がヒットします。すると今度は別のAIに切り替えて、最初から全部を言い直さないといけません。状況(コンテキスト)、問題、これまでに試したこと、どこで詰まっているか。すべて。
あなたが自分の作業内容を唯一理解しているからこそ、どのAIアシスタントに問い合わせるにも、その知識を毎回、あなた一人で抱え込まなければなりません。
そこで2週間前、オフラインのハッカソンの最中に――自分のアイデアの小さなバージョン、Meniscus を作りました。これはツールの外側にあるレイヤーで、その知識をあなたの代わりに保持します。いまの作業状態の共有された1枚の図――何を試したか、何があなたをブロックしているか、何が決まったか。切り替えたどのAIも、そこから読み込むので、ゼロから始める必要はありません。
中核となる考え方:
コンテキストは個々のツールの中に置かれるべきではありません。別の外部レイヤーとして外に置くべきで、AIツールはそこから読み取るべきです。
今この瞬間、あなたが自分の作業内容を唯一知っていて、どのAIアシスタントに問い合わせるにも、その知識を一人で全部抱え込まないといけません。Meniscus は、その知識をようやくあなたのために保持してくれるレイヤーです。
Meniscus は、ツール横断でユーザーのアクティビティをキャプチャし、それをスレッドに構造化します。スレッドは、ユーザーが現在アクティブに行っていることを表すコアな作業単位です。そして、生の履歴の代わりにサブグラフとして関連コンテキストを取り出せるようにします。
アーキテクチャは 3 つのプリミティブで構成されています:
Event(イベント) は原子的な単位です。変更不能で、タイムスタンプ付きで「あなたが行った1つのこと」を記録したもの。ChatGPT に何かを聞いた、YouTube の動画を見た、GitHub にコミットした、Notion のページを更新した――それぞれがキャプチャされ、正規化され、保存されます。
entity(エンティティ) は、イベントから抽出される意味のある概念です。テキスト全文ではなく、信号だけ。たとえば「JWT」「middleware」「refresh token」「auth」などです。つまり、そのイベントが何についてのものかを実際に教えてくれるキーワードです。
thread(スレッド) は、関連するイベントのクラスターです。文章的に似ているからではなく、共有される作業コンテキストによって結びついています。「私は JWT の認証バグをデバッグしている」はスレッドです。GitHub のコミット、ChatGPT の会話、Notion のアーキテクチャドキュメント、トークンの期限切れに関する YouTube 動画にまたがります。個別のイベントは互いに無関係に見えても、それらが一緒になると「1 本の作業の流れ」になります。
パイプラインは次の通りです:
→ アクティビティが入力される
→ エンティティが抽出される
→ 新しい各イベントは、エンティティの重なりと時間的な近さによって既存のスレッドと比較される
→ 適切なスレッドに割り当てられる、または新しいスレッドが作成される
→ すべてが、イベント、エンティティ、スレッド間の明示的なエッジを持つグラフとして保存される
エージェントが Meniscus をクエリするとき、あなたの履歴の生データをそのまま渡されるわけではありません。渡されるのはサブグラフです――関連するスレッド、そのイベント、そのエンティティ。すべてを一度にではなく、コンテキストの「上限つきで構造化された切り出し」を渡します。エージェントはそれをプロンプトに注入し、あなたの実際の作業に根ざした回答を返します。
...
このプロジェクトのデモでは、私は次のことをしました:
- ChatGPT、YouTube、GitHub からイベントをシミュレートしました――リアルな1日の作業から 4 つのスレッド、合計 12 イベントです。
- クエリシステムは3つのモードでルーティングします: Retrieve(エンティティを辿る) --> Overview(スレッド横断の、あなたがやってきたことの要約) --> General(会話形式。関連するものが何も見つからない場合は「i don't know」と言います)。
プロジェクトを始めるとき、私は SHOULD(〜であるべき)という観点で考えるのが好きです。何かはどうやって行うべきかを考え、十分に良いと判断できるアーキテクチャに辿り着くまで、あらゆるステップで自分の判断に攻撃的にツッコミを入れます。
デモで見せたものは、私が計画していた実装全体のほんの一部にすぎません。ハッカソンが終わった後、2日経ってからもう一度プロジェクトに向き合い、残りの実装を仕上げることにしました。しかし、いくつか大きな穴があることに気づき、「自分がやっていることは結局、すでに存在しているものと大差ない」――Zep、Mem0、Supermemory、Rewind などと同じだと理解しました。
私が作ったもののほとんどは、すでに存在しており、私が出荷できたよりもずっと良い状態です。
外部メモリレイヤー、グラフストレージ、エピソード的リトリーバル、エージェントAPI――これらは、資金の潤沢なチームが解決しているか、現在まさに積極的に解決しているところです。だから、同じことをやり直す意味はありません。
ただし、唯一の差別化要因になっている特定のアーキテクチャ要素が1つあります。そしてそれについて、解決され続けている疑問があり、結論を出す前に徹底的に調査する必要があります。
既存のあらゆるシステムは類似度によって取得します――コサイン距離、セマンティック検索、ランキングされたチャンク。質問すると、履歴の中で最も文章的に似ている断片を見つけて返してくれます。
しかし「いま自分が取り組んでいるのは何か」は類似度の問題ではありません。それは作業状態(ワーキングステート)の問題です。エージェントは、最も似ているチャンクを必要としているわけではありません。必要なのは、進行中のタスクの現在の状態です。目標は何か、これまでに何を試したか、何が進捗を妨げているか、何が決まっているか。これは別の問いであり、類似度検索ではそれらにきれいに答えられません。
そこで当然の疑問が出ます――それなら、すべてを長いコンテキストウィンドウに丸ごと突っ込むだけではどうでしょうか?Gemini や Claude のようなフロンティアモデルには巨大なコンテキストウィンドウがあります。だったら、全履歴を渡して、作業状態を自分たちで見つけさせればいいのでは?
正直、たぶんそれなりに上手くやるでしょう。Claude にあなたのアクティビティを十分に与えれば、「今あなたが取り組んでいること」をかなり妥当な形で合成できます。
ただし、問題が3つあります:
1つ目、コスト。毎回、何十万トークンも送るのは、スケールすると無料では済みません。
2つ目、「真ん中に埋もれる」問題――経験的に記録されている通り、長いコンテキストの奥深くに埋もれた情報は、モデルの性能が悪化します。トークンが増えることが、これらのトークンに対するより良い推論を意味するわけではありません。
3つ目。たとえモデルが生の履歴から正しく作業状態を合成できるとしても、クエリを投げるたびに毎回、その作業を新しくやっています。Meniscus は一度だけ行い、継続的に維持します。 合成は、エージェントが必要とするときにはすでに完了しています。
仮説は2つです――
Thread-state packet retrieval(スレッド状態パケット取得)は、ハイブリッド検索よりも、アクティブな作業状態に対するクエリでエージェントの回答を改善する。
Thread-state packet retrieval は、同じクエリに対してより少ないトークンで済む。構造化された状態オブジェクトが、エージェントが取得するためにそこに最初から存在するため。
私は答えを予想できたかもしれませんが、確信を持つ必要があります。そして率直に言うと、正しいことはベンチマークを作り、thread-state packet retrieval を、アクティブな作業状態クエリにおける最先端のリトリーバル手法と比較し、トークン数と回答の質を測定し、見つかったことを書き残すことです。
読んでくれてありがとうございます :)
GitHub リポジトリ: https://github.com/magic-bubblez/meniscus-






