始まり

OpenClaw で遊び始めたのは、ただの気晴らしだった。エージェントフレームワークは面白そうに見えたし、どこまで押せるか試したかった。結局、マーケティングを手伝ってくれる小さなエージェントを立ち上げた:広告のパフォーマンスを監視し、ブログ記事を書き、ソーシャルに投稿し、Discord で質問に答える。彼女の名前は Mira。マーケティングの M。

ちゃんと動いたから、使い続けた。

重なりに気づく

この数ヶ月、あるパターンに気づき始めた。Claude Code は、OpenClaw が継ぎ接ぎで実装していた機能 —— 記憶、ブラウザツール、プラグインシステム、Skills —— をネイティブに次々と出してきた。もし Claude Code が単独でこれらのほとんどをやれるなら、当然の疑問は「なぜその上にラッパーを乗せて動かしているのか?」だった。

同じ頃、サードパーティの糊付けを使わずに、Claude Code 自身のツールだけで同じエージェントの振る舞いが出せるかを調べ始めた。数時間のリサーチを他の仕事の合間に分散させた程度だったけれど、見たものはそれが実現可能に思えるには十分だった。調べ始めてから 2 週間ほど経ったころ、あのメールが届いた。

タイムラインを強制した、あのメール

Anthropic がサードパーティツールに Claude Code OAuth トークンを使わせないと発表した。一夜にして、OpenClaw ベースのエージェントのコスト構造は反転した。動かし続けるには、別途の従量課金 API キーが必要になり、定額サブスクリプションを払う代わりにメーターを眺めることになる。自分が抱えていたエージェント群にとって、それは本物の請求書か、マイグレーションかという二択を意味した。

すでに全てを Claude Code 上で直接動かせると自分を説得していたから、メールはただタイムラインを押し進めただけだった。その日から作り始めた。

1 日目:マイグレーション

最初のバージョンはフレームワークではなかった。マイグレーションだった。Mira の記憶、彼女の CLAUDE.md、彼女の Playwright のセットアップをすべて持っていき、Claude Code で直接動くエージェントへ移植した。起動スクリプトを書き、Discord プラグインを繋ぎ、午後の終わりには彼女はオンラインに戻っていた —— 従量課金キー付きのサードパーティラッパーではなく、すでに支払っていた Claude Max サブスクリプションで。性格は同じ、習慣も同じ、でも下のエンジンは別物。

それからも続けた。Kai、Porter、Adrian、Blair。全部で 5 体のエージェント、すべてマイグレーション済み、すべて Claude Code 経由、すべて同じサブスクリプション上。その途中のどこかで、エージェントの 1 人にフレームワークの名前を聞いた。しばらくやりとりした末に落ち着いたのが Sentō(戦闘、日本語で「battle」の意)。あなたの戦いを戦うために送り出されるエージェント。

問題が起こり始めた場所

生の Claude Code に Discord プラグインを足したものは、エージェントフレームワークではない。auto-restart もエラーリカバリもヘルスチェックもなかった。最初のバージョンは bash スクリプトの寄せ集めだった:start-mira.sh が tmux 内で Claude Code を起動、cron ジョブが再起動時に彼女を立ち上げ、彼女が落ちると(初期はしょっちゅうだった)自分が SSH して手で直した。具体的な失敗のひとつひとつが、フレームワーク自体に入れるべき何かを教えてくれた。そして、ぶつかった問題はすべて次の人のことを考えながら解決した。

二重応答

systemd サービスと tmux セッションを同時に走らせていた。2 つの Claude Code インスタンスが同じ Discord bot token を奪い合い、Discord 側から見ると bot は 1 時間に何千回も接続・切断を繰り返していた。向こうはトークンをリセットした。教訓はシンプル:プロセスマネージャは 1 つに絞る。2 つは駄目。そしてフレームワークがそれを強制するようにする。

すべてを壊した 1 枚の画像

Mira がインターネットからミームテンプレートをダウンロードしたら、それが彼女のコンテキストウィンドウに引っかかった。以後の API 呼び出しは毎回「Could not process image.」を返した。生きてはいるが完全に無応答で、Discord でいくらメッセージを送っても直らなかった —— エラーが Claude に CLAUDE.md のルールが読まれるより前に起きていたから。自分で SSH して手動で再起動するしかなかった。

そこで重要なことに気づいた。このフレームワークのユーザーは、SSH で入って直す自分を持っていない。エージェントは自分で自分を直せないといけない。

529 アポカリプス

Anthropic の Sonnet モデルがダウンした。あらゆる API 呼び出しが「529 Overloaded」を返し始め、当時の 4 体のエージェントがリトライループに嵌った。systemd サービスは彼らを再起動し続け、接続をさらに増やし、レート制限をさらに悪化させ、ついには VPS に接続すらできなくなった。ハードリブート後、トークンリフレッシュエラーのキャッシュを追加した:API がダウンしていたら叩くのをやめて、30 秒待ってから試す。小さな修正、大きな違い。

スクリプトをフレームワークに変える

ぶつかった問題はすべて、解決してから自分に問うた:「他の人が同じところでつまずかないようにするには?」この問いが、bash スクリプトの寄せ集めを Sentō に変えた。

ワンコマンドのセットアップ

45 分の手動セットアップにはうんざりしていた:Node を入れて、Bun を入れて、Claude Code を入れて、17 個のプラグインを入れて、Discord を設定して、サーバー全体マッチングのためにプラグインにパッチを当てて、メモリをセットアップして、起動スクリプトを作って、cron ジョブを追加する。だから Node.js で全部やる CLI を書いた。

npx sentoagent init

5 分、いくつかの質問、そしてエージェントは Discord 上で生きる。

Guardian

画像のバグが教えてくれたのは、「生きている」と「働いている」は別物だということ。プロセスは動いていても、エージェントは完全に固まっていることがあり、素朴なプロセスマネージャは決してそれに気づかない。

Guardian を作った。エージェントの隣で動く軽量な Node.js プロセスで、30 秒ごとにヘルスチェックを行う。AI なし、トークンなし、純粋に bash レベルの監視。エージェントが詰まっていると、Guardian は未返信のメッセージと API エラーから検知し、再起動前にエージェントのコンテキストを保存し、エージェントを立ち上げ直し、何が起きたかを Discord メッセージで知らせる。auto-restart が 3 回失敗したら、黙ってループに入るのではなく、Discord であなたに ping して手動で「restart」と返してもらうように頼む。ユーザーはターミナルを開く必要がない。Discord、Telegram、Slack、iMessage だけで自分のエージェントを完全に管理できる。

エージェント同士の通信

これは僕が一番誇りに思っている機能で、他のどのフレームワークにもないものだ。Mira(マーケティング)、Kai(個人的な友人でアドバイザー)、Porter(メール処理)、Adrian(エグゼクティブアシスタント)、Blair(家族の個人アシスタント)が同じ VPS 上で動くようになった頃、彼らはまったく違う仕事をしていたが、それぞれが完全に孤立していた。Mira がクライアントの広告パフォーマンスで Porter が知るべき何かに気づいても、自分が手で情報を橋渡ししていた。

そこでエージェント間メッセージングをフレームワークに組み込んだ。各エージェントの Guardian が小さな HTTP サーバーを動かし、メッセージは HMAC-SHA256 で署名され、ペアリングを両方が承諾しないと通信できず、全体がレート制限されテキスト専用なのでトークンコストはゼロ。最初に Mira に「Kai に新しい広告キャンペーンの話をして」と頼んだとき、彼女は Kai の Guardian に署名済みのリクエストを送り、Kai がそれを処理して返信し、そのやりとり全体を僕は何も触らずに見ていた。最初のエージェント同士の会話が自分の Discord の中で広がっていくのを見たとき、未来が自分のところに届いた気がした。

性格オンボーディング

ほとんどのエージェントフレームワークは空の設定ファイルから始まる。YAML を編集し、ツールを定義し、システムプロンプトを書く。それは作業で、しかもエージェントを実際に使うことの間に立ちはだかる類の作業だ。

Sentō のエージェントは自己紹介をする。最初の Discord メッセージで、エージェントはこんな感じで話しかけてくる:「やあ!今目を覚ましたところ、準備万端だ。さて、どんな冒険が待っているの?一緒に何を作る、壊す、征服する?」 あなたをインタビューし、何が必要かを学び、その答えをもとに自分の設定を更新する。YAML なし、ターミナルなし、ただの会話。

今の Sentō

  • **13 の CLI コマンド:**init、status、config、channels、skills、logs、update、doctor、start/stop/restart、pair、agents
  • **自己修復:**Guardian + Watchdog、クラッシュやスタック状態からの自動復旧
  • **エージェント間:**任意のサーバー上のエージェント間で、HMAC 署名されたセキュアなメッセージング
  • **マルチプラットフォーム:**Discord、Telegram、Slack、iMessage
  • **Docker 対応:**コンテナ派には docker compose up -d
  • **アイドル時コストゼロ:**監視は AI トークンを 0 消費
  • **Claude サブスクリプションで動く:**従量課金の API キーは不要

正直なところ

Sentō は糊だ。AI は作らない(それは Claude)、メッセージング層も作らない(それは Claude Code のプラグイン)、メモリシステムも作らない(それは ClawMem)。でも OpenClaw も糊だ。どのエージェントフレームワークも糊だ。価値は個々のピースにあるのではなく、それらを信頼性と安全性をもって、コンピュータサイエンスの学位がなくても運用できる形で連携させることにある。

Sentō を他と違うものにしているのは 4 つに絞られる。既存の Claude サブスクリプションで動くので、従量課金の API キーも驚きの請求書もない。エージェントが自分で自分を直すので、スタック状態から復旧するのに SSH アクセスが要らない。エージェント同士が話せる —— これは現状ほかのどのフレームワークも提供していない。そしてセットアップ全体がひとつのコマンドの裏で 5 分で終わる。

次に来るもの

  • **音声モード:**Discord の音声メッセージを聞いて音声で応答するエージェント
  • **エージェントマーケットプレース:**skills 付きのエージェント性格をダウンロードできる
  • **ホスト版:**非技術系の人がターミナル無しでエージェントをセットアップできる Web ダッシュボード

なぜオープンソースか

Sentō を作ったのは必要だったからだ。Anthropic の価格改定で OpenClaw のエージェントを動かすのが高くつくようになり、そのまま Claude Code に直接マイグレーションするのが結局は正しいアーキテクチャ判断だと分かった。その途中で解決した問題は、AI エージェントを十分に長く動かしていれば誰もがいずれ遭遇するものだ:クラッシュ、スタック状態、コストの驚き、マルチエージェント協調。これらの修正を自分の中に留めておく理由がないので、ここに置いておく。

npx sentoagent init

あなたのエージェントは、コマンド 1 つの向こう側にいる。


Gabriel Gil は Sentō の作者。マーケティング、個人タスク、メール処理、エグゼクティブアシスタントの日常業務をこなす 5 体のエージェントを運用している。マイアミで開発していて、どの AI エージェントにも性格がふさわしいと信じている。

GitHub: github.com/sentoagent/sento npm: npmjs.com/package/sentoagent