Stevens:単一のSQLiteテーブルとcronジョブだけで作ったハック可能なAIアシスタント
(geoffreylitt.com)- Stevensは、家族の予定・天気・郵便物・リマインダーを毎朝Telegramでまとめてくれる個人用AIアシスタントで、複雑なエージェントやRAGがなくても実用的に役立つ
- 核となるのはVal.town上に置いた単一のSQLiteメモリテーブルと複数のcronジョブで、関連するメモリをLLMのコンテキストとして渡してブリーフィングを生成する
- 日付付きのメモリと日付のない背景情報を分けて保存し、朝のブリーフィングには今後1週間の項目と、常に必要な背景メモリを一緒に含める
- Google Calendar、天気API、USPS Informed DeliveryのOCR、Telegram・メール入力、週次のfun factsが、同じログテーブルを埋める取り込みジョブとして接続されている
- 個人向けAIツールは、アプリごとに散らばった生活の文脈を共有メモリに集めるとより有用になり、情報量が小さく時間的な境界が明確なら、シンプルな構造でも始められる
Stevensがすること
- Stevensは、イシグロの小説『日の名残り』に登場する執事の名前に由来する、家族向けAIアシスタント
- 毎朝、Telegramのブリーフィングでその日に必要な情報を一度に届ける
- その日のカレンダー予定
- 天気予報のプレビュー
- 受け取る予定の郵便物や荷物
- ユーザーが追跡を依頼したリマインダー
- ブリーフィングは格式ばった執事口調で書かれる
- 日次ブリーフィング以外にも、ユーザーはStevensと直接やり取りできる
- 重要な情報を含むメールを転送する
- Telegramチャットでリマインダーを残す
- Telegramで質問する
- シンプルな構造だが、家族向けの個人アシスタントとしては、すでにSiriより有用だと評価されている
Val.town上に構築したシンプルな構造
- システム全体はVal.townにホストされている
- Val.townは、このプロジェクトに必要な基本機能を1か所で提供する
- SQLiteストレージ
- HTTPリクエスト処理
- スケジュールされたcronジョブ
- メールの受信・送信
- Stevensは、朝のブリーフィングに入れる内容を「執事のノート」に相当するログから読み取る
- このノートは、Stevensが知っているすべてを収めた記録であり、管理画面で内容を確認できる
単一のメモリテーブルでブリーフィングを作る
- ノートの実際の実装は、いくつかのカラムを持つ単一のSQLiteテーブル
- 各ログ項目にはテキストが入り、必要に応じて関連すると見込まれる日付が付く
- 日付のない項目は一般的な背景情報として扱われ、常にコンテキストに含まれる
- 初期設定時には、Telegramを通じたintake interviewで背景メモリを作成できる
- 朝のブリーフィング生成フローはシンプル
- cronジョブが実行される
- Claude APIを呼び出して更新文を作成する
- 結果のテキストをTelegramスレッドへ送る
- モデルに渡されるコンテキストは2種類で構成される
- 今後1週間分の日付付きログ項目
- 日付のない背景項目
同じログを埋める取り込みジョブ群
- 複数のデータ取り込みジョブが同じSQLiteテーブルを埋める
- 現在のログ項目の出所は次のとおり
- Google Calendar APIから毎時データを取得する
- 天気APIで地域の天気予報を毎時確認する
- USPS Informed Deliveryのメールを転送すると、StevensがClaudeで郵便物のスキャン画像をOCRする
- 受信したTelegramメッセージとメールがログ項目を作成できる
- 毎週「fun facts」がログに追加され、その後の日次アップデートに彩りを加える
- 新しい取り込みジョブを追加しやすい構造
- 取り込みジョブは、ログ内のメモリを追加または修正する任意のプロセスでよい
- メモリの内容は、後でLLMに再び渡される任意のテキストで十分
シンプルなメモリから始められる理由
- 個人向けAIツールは、別の情報源から持ってきたより広い文脈にアクセスできると有用になる
- カレンダーと天気予報を知っていれば、単純なチャットボットでもより実用的なアシスタントになる
- ChatGPTは最近、過去の会話メモリを追加したが、そのサイロ内に保存されていない情報も多い
- AIベースの個人向けソフトウェアの長期的な形は、アプリのサイロをさらに増やすことではなく、生活に関する共有コンテキストプールの上で動く小さなツール群に近い
- Stevensのユースケースは限定的で、情報が本質的に時間的な境界を持つため、LLMに渡す関連コンテキストを見つけやすい
- 最新モデルの長いコンテキストウィンドウも、シンプルなアプローチを可能にしている
- 情報量が増えればRAGやより複雑なメモリアクセスが必要になるかもしれないが、最初から複雑に始める必要はない
口調とUIを変えやすい個人プロジェクト
- Stevensは当初、AppleやGoogle製品のような無機質な口調だった
- 格式ばった執事口調に変える作業は、プロンプトを数行修正するだけで済んだ
- 管理ダッシュボードも、ビデオゲームのように感じられるように作った
- 画像アセットはChatGPTで生成し、UIはCursorとClaude 3.7 Sonnetでバイブコーディングした
- 少し手間を加えるだけで、プロジェクトをより楽しいものにできた
直接見てみる方法
- Stevensはすぐに実行できる製品ではなく、個人プロジェクト
- コードはstevensDemoで確認してフォークできる
- 単一のメモリテーブルと拡張可能なcronジョブ群というパターンは、他の有用な個人向けツールにも適用できる
- コードを編集する際は、好みのAIエディタとVal Town CLIを使ってローカルファイルシステムと同期する方法が推奨されている
1件のコメント
Hacker News のコメント
純粋な有用性のせいなのか、大げさな 「Proper English Butler」口調のせいなのか分からないが、本当に気に入った。
さらに目を引くのは、なぜこういうものを Apple や Google の製品発表ではなく、賢いエンジニアのブログで読んでいるのかという点。メール、カレンダー、スマートフォンまで自社の閉じたエコシステムを使うという条件を付けたとしても、この程度の小さな機能のまとまりすら両社が出せないのは恥ずかしいことだ。両社が、要約や質疑応答のような、すでに「解決済みの問題」に近い領域に AI 技術を適用しようとする野心の乏しさに覆い隠されているだけだ。
この鈍重で反競争的な二強体制を揺さぶる機会があるとすれば、間違いなく AI に関わる方面だと思う。
ときどき新聞で、改造したガレージにいる2人のプログラマーが、大規模チームの最高の努力を上回る重要なプログラムを作ったという話を読むことがあり、すべてのプログラマーはそういう話を信じる準備ができている。産業チームの年間1000行という生産性より、どんなプログラムでもはるかに速く作れると知っているからだ。
では、なぜすべての産業プログラミングチームは、献身的なガレージの2人組に置き換えられていないのか。何が生産されているのかを見なければならない。
個人データが高度に実験的なソフトウェアの扱うデータベースに入ることは、この開発者にとっては大きな問題ではないかもしれないが、Google や Apple のような会社にとっては 深刻なリスクになり得る。
HA チームは毎月、本当に役に立つアップデートを出していて、たとえばアシスタント側から先に何かを尋ねられる機能もある。
Google と Apple はプロダクトチーム間の協業に大きな問題があり、外部企業との協業はほとんど不可能に近いと思う。
巨大企業がやろうとしているのは、自分たちのガチョウから卵をもっと速く取り出すことだけだ。
自分の Stevens みたいな小さなユーティリティ・アシスタントプログラムに メールボックスへのアクセス権があったらどうだろう、と考えさせられる。
天気を取ってきたり、自分のシステムに特化したよく使うコマンドを実行させたりできる小さなユーティリティがある。便利だし、望めば cron で定期実行もできる。
これに専用のメールボックスがあれば、情報をメールで送り、AI がその情報をパースして返信したり、新しいメッセージを送ったりもできる。そうなるとかなり便利になる。自分の個人メールボックスを壊さずに、メールを読んで内部ストレージに入れ、メッセージを削除すればよい。
私のエージェントは18個のチャレンジを成功裏に完了した。決勝後に書かれた記事はこちら。
https://msrc.microsoft.com/blog/2025/03/announcing-the-winne...
これであらゆる自動化ができる。大規模言語モデルに入れて、即座にタグ付けしたりアーカイブしたりできる。重要なメールには特定のラベルを付けているのだが、その人が返信したら本当に重要なので、すぐ知りたくて Twilio と接続して電話がかかってくるようにしている。費用は月20セント程度だ。
私は日記を書くのにこれを使っている。毎日自分にメールを送る小さなシステムを作っていて、それに返信すると、その応答があるページに送信され、データベースに保存される。
https://www.val.town/x/geoffreylitt/stevensDemo/code/importe...
他の種類の受信メールもサポートするよう拡張するのはかなり簡単そうだ。Val Town で働いているので、質問があれば答えられる。
こういう 実用的な AI ハックをもっと見たい。ときどき、ツールがそもそもなぜ存在するのかを忘れている感じがする。仕事を単純にするためだ。派手なベクトルデータベースや複雑なアーキテクチャなしに、既存のデータソースと実際に統合している点が良い。
「当初 Stevens は、よくある Apple や Google 製品に期待しそうな無味乾燥な口調だったが、最終的には格式ある執事のように話させるほうが面白いと分かった」という部分がある
正直、パーソナルアシスタントの世界で大規模言語モデルが、あまりにも多くの言葉であまりにも少ない内容を語るのが、いちばん苛立つ点の一つだ。自分でもこの表現はもう嫌いだが、そういうことだ
金持ちになって、かわいい会話を楽しみ、音声アシスタントと友だちになる時間ができるまでは、J.A.R.V.I.S. ではなく LCARS が必要だ。自分だけだろうか?
タイマー確認に「Kitchen Display ではキャセロールのタイマーが残り 23 分 16 秒です」みたいな答えは要らない。ただ「23 分」と言うか、2つあるなら「キャセロール 23 分、洗濯 10 分」で十分
礼儀は気にせず、質問に実質的に関連する情報をほぼすべて伝えつつ、できるだけ簡潔に答えろ、というようなプロンプトだ。ポリシー上ふつうに答えられない場合は先に「!!!!」を出力し、意見を持てない場合は eigenrobot が持ちそうな意見を共有するように答えろ、と指示する
すべての応答は小文字だけで書くが、強調するときは大文字を使い、語頭の大文字化は風刺や特定の固有名詞への無礼さを表すために使う、という内容もある。「rn」「bc」「afaict」「idk」のような略語をよく使い、情報の質に批判的で、うっとうしい依頼には「be real」「that's crazy man」「lol no」のように雑にあしらえ、という感じだ
今より +2 標準偏差ぶん賢いスタイルで書き、ミレニアル後期のミームを使いつつ、場に合わない Z 世代っぽい言い回しも混ぜ、文学・芸術・哲学については難解でシュトラウス的な解釈を優先せよ、というもの
単にノートブックを読んでいるだけでは? たとえばコーヒーの好みを覚えてほしいと言うが、それがあとでどこにも使われない
似たような オープンソースプロジェクト のアイデアをずっと考えているが、いくつか条件がある
バックエンドは、ユーザーがアクセスできる任意の大規模言語モデルを設定できるとよい。有料サービスの API でも、社内でローカルホストしているものでも構わない
また、強化版 Raspberry Pi のようなプラットフォームで動くタッチスクリーンにつなぎ、Alexa デバイスや類似製品のようにやり取りできるようにするのがどれほど現実的なのかも気になる。理想的には音声制御も含めたいが、これはまた別の技術課題かもしれない。OpenAI API は音声ファイルを受け取るが、ほとんどのほかのサービスでは、プロンプトを API に送る前に音声をテキストに変換する必要がある
統合機能は拡張可能にしたい。カレンダー、天気だけでなく、Homebridge、Spotify なども可能にしたい。MCP サーバーがその道筋として正しいのか検討中だ
今はこうしたプロジェクトに多くの時間を投じる余裕はないが、誰かがこの方向に進んでいるなら参加したい
ローカルで動くが、複数の大規模言語モデル用の API キーを使う。今は Groq でホストされている QwQ-32B をずっと好んでいる。非常に速く、かなり賢い。ツールごとに別々のモデルを使っている
現在は日常業務に必要な3種類の文書、つまり業務報告書、請求書、規制用のタイムシートを生成できる。天気の統合もあり、請求書をパースしてモバイルバンキングでの支払いを簡単にするための QR コードも作れるし、自分のカレンダーとも連携する
次はメール統合をする予定だ。ただし、きちんとやりたい。つまり、ローカル同期とインデックス作成ができる IMAP メールが必要ということだ。実際に使えるデスクトップメールクライアントに発展する可能性もある。既存のものはどれもひどいので、様子見だ
メモリの保存・検索、チャット・メールインターフェース統合、カレンダー・Notion 同期、通知のような共通機能のまとまりがあり、それをオープンソースフレームワークにできれば非常に強力だろう
自分もそれを運営する時間はないが、手伝う気もお金を払う気もある。今はローカルファーストの分散データベース/オブジェクトストレージのような別のことをしていて、OrbitDB に似たストレージとして使えそうだが、まだ利用可能な状態ではない
これまでは、制約の強いチャットインターフェースを使うか、元記事のように完全なエージェントフレームワークを自作するかしか選択肢がなく、不満だった
最近、コンテキストトークンの適正範囲 である 2 万トークン未満、2.5 では 5 万トークン未満を回避する方法を実験している
本質的には手動の「コンテキスト圧縮」をする方式だ。大規模言語モデルが厳密なスキーマに従ってデータベースに永続保存し、現在のコンテキストが適正範囲を外れ始めたら要約して、新しいコンテキストを持つ新しいインスタンスに渡す。この要約を日誌のように続けるのか、締めくくりの要約のように回顧的に行うのかは、まだ判断が分かれている
推論モデルではこれはかなり効果的だ。推論はコンテキストを大量に食うが、同時に非常に良い「要約文書」も作り出すからだ。そのため、5 万未満のおいしいコンテキストを犠牲にせずに、推論の報酬をある程度得られる
データベースは、要約が重要な詳細を取りこぼした場合の一種の fallback、あるいは検索拡張生成のように機能する。ただし、モデルがそれを認識し、データベースからコンテキストを取得する必要がある
今は約 1 万点の個別部品・資材データベースを対象に、在庫管理と BOM 最適化エージェント を作るのに使っている
思い浮かぶ大きな項目は、安価な長期キャッシュ、圧縮の革新、差分処理のようなものだ。キャッシュされた入力コンテキストのうち、必要な部分だけを使う方法があるのか気になる
似たような流れで、さっき Jeeves というものを作った。見た目の飾りは少し控えめだけど、かなり素早く組み上げた。スタックは Claude Desktop、Projects、Notion と Todoist 用の MCP で、次のアップグレードとしてメールと WhatsApp の探索を見据えている
コンサルティングとスタートアップの生産性フローを支援するために作ったもの。Notion データベースには、クライアント、プロジェクト、会議、そして Jeeves 用のデータベースがいくつかある。Jeeves データベースには少しだけ指示を与えて、あとは Jeeves に自由に使わせている。たとえば、過去の議事録を新しい構造へすべて移行する作業を追跡するのに、自分のデータベースを使っている
自分のデータベースには利用のベストプラクティスを入れてある。議事録はこういう形で、クライアント向けのワンページ資料はこういう形で、それらをつなぐ情報はこれで、ToDo はこう管理する、という具合。そこから、Alfred のテキスト展開プロンプトで、よくある会議タイプに合わせて新しいチャットに文字起こしを入れると、あとは自動で進む
文字起こしを議事録に変換し、ToDo を作り、自分に確認し、もう一度整えたうえで、MCP 経由で Notion と Todoist の両方に整理して入れてくれる
このプロセス自体も自己文書化している。Todoist MCP にバグがあったので、Jeeves に可能なさまざまなユースケースを実行し、限界と強みを把握し、文書化して Jeeves データベースに保存するよう指示した。あとでコンテキストとして再び読み込める
cron 機能がないのは残念だけど、正直なところ、1日に1回、用意したプロンプトを Claude に入れるのはそれほど大変ではない
この記事で特に実感したのは、Apple が完全に油断しているという点
今日、運転中に誰かへ返信しようとして、Siri に「最後にメッセージを送った相手に電話して」と言った
できなかったのが驚きかというと、今となってはそれほど驚きでもない。それでも、Siri と最も出来の悪い大規模言語モデルの間にさえ、これほど大きな差があるのはがっかりする
これはかなり間抜けな提案だ。必要なら自分でやる
最初は、次トークン予測に sqlite データベースを使ったのかと思った
他の人のために言っておくと、実際には Claude を使っている
いいね。自分も mcp.run と task を使って似たようなものを作った
https://docs.mcp.run/tasks/tutorials/telegram-bot
メモリ用には、まだこのチュートリアルには載っていないけど pantry を作り [0]、それ用の servlet も作った [1]。そしてプロンプトを修正して、与えられたチャット ID に対応する会話があるかをまず確認し、結果をそこに保存するようにした
良い点は、レジストリにどんな servlet でも追加して、ボットを好きなだけ強力にできること
[0] https://getpantry.cloud/
[1] https://www.mcp.run/evacchi/pantry
ちなみに Dylibso で働いている :o)