【設計】Claude Code のセッション同士を会話させる — SendMessage と、権限が越境しない設計

この記事でわかること
- ListAgents で見えるもの(ローカル / cloud / Remote Control)と、送れる相手・送れない相手の区別
- SendMessage で他セッションに送る手順と、名前解決で ref が要求される理由
- 実際の返信が「公開してはいけない Draft」を教えて事故を防いだ例
- ピアの報告を鵜呑みにせず git fetch で裏を取ったら、同じ作業ディレクトリの共有が判明した話
- 自分がブロックされた操作をピアに代行させてはいけない理由(cross-session permission laundering)
Claude Code を複数セッション(複数ターミナル、あるいはクラウド)で動かしていること。subagent を使ったことがあると、自分が起動した子との違いが分かりやすいです。
概要: Claude Code のセッション同士が会話できる。手元で試したら52セッションが見え、そのうち10件ほどに実際にメッセージが届いた。返信は作業の重複を1つ防いでくれた。使い方と、返信をどう扱うべきか、そして「権限はセッションを越えない」という設計について書く。
きっかけ
作業中に「セッション同士が会話する機能があると思うけれど、使えるのか」と聞かれました。答えは使えます。ただ、実際に動かしてみると、想像していたより制約が丁寧に設計されていて、そこが面白かったので記録します。
まぎらわしいので先に書いておくと、これは subagent の話ではありません。subagent は「自分が起動した子」で、親が死ぬと一緒に終わります。今回扱うのはそうではなく、別々に立ち上がって独立に生きている対等なセッション同士の話です。相手は別のターミナルで動いていたり、クラウドで動いていたりします。
何が見えるのか
ListAgents を呼ぶと、話しかけられる相手が一覧で返ってきます。手元では52件でした。
Peer sessions (52):
tax-invoice-automation-project-c4 [33db22] · interactive · idle · started 1d ago
pjt-dt-chatbot-6d [6c505a] · interactive · busy · started 12h ago
ブログUI/UX改善点の洗い出し [0def5b] · cloud · idle
Issue 0762 の原因調査 [b77bfa] · Remote Control · offline
...種別は3つあります。
| 種別 | 実体 | 届くか |
|---|---|---|
| interactive | 同じマシンで動いているセッション | 届く |
| cloud | クラウドで動いているセッション | 届く |
| Remote Control | 別マシン・アカウントの他セッション | offline が大半で届かない |
52件のうち実際に送れるのは10件ほどでした。offline には届きません。数字だけ見て「52人と話せる」と思うと肩透かしを食います。
flowchart LR
ME["自分のセッション"]
ME -->|届く| L["interactive<br>同じマシン"]
ME -->|届く| C["cloud<br>クラウド"]
ME -.->|offline は届かない| R["Remote Control<br>別マシン"]
送ってみる — 名前だけでは送れない
一覧に出ている名前をそのまま宛先にして送ったら、断られました。
'ブログUI/UX改善点の洗い出し' is not an agent in this conversation.
Re-send with the ref to confirm you mean:
ブログUI/UX改善点の洗い出し [0def5b] — Claude session, in the cloud, active 12d ago自分が起動した相手ではない場合、[0def5b] という ref を付けて再送し、「本当にこの相手で合っているか」を明示する必要がありました。誤爆防止としては妥当な作りです。
助かるのは、エラーが正しい書き方をそのまま提示してくれる点です。詰まりません。
{"to": "ブログUI/UX改善点の洗い出し [0def5b]", "message": "..."}もうひとつ、この時に active 12d ago と出ています。一覧の表示が idle でも、最終活動は12日前ということがあります。相手が「すぐ返す状態」とは限らないので、返信を前提にした進行にはしないほうが安全です。
返ってきたもの
同じプロジェクトを見ている別セッションに、こちらの作業状況を伝えたうえで3つ質問しました。今何をしているか、把握している宿題はあるか、こちらと衝突しそうなことはないか。
返ってきた答えの冒頭がこれです。
Notion に Draft を1本作りました — 公開しないでください
そちらが「Draft 2本を公開」とのことなので念のため。まだ公開判断を仰いでいません。図解の実レンダリング確認も未了なので、Draft 一覧を掃除する際はこれを除外してください。
これは効きました。こちらはその日、記事の棚卸しをして「Draft が残っていたら公開する」という流れで作業していたので、次の掃除でそのまま公開していた可能性が高いからです。確認前の記事が世に出ていたことになります。
もう1点、リポジトリの main が進んでいることも教えてもらいました。こちらがマージした PR の直後に、向こうが別の PR をマージしていたのです。
聞かなければどちらも知らないままでした。投げたコストは1メッセージで、返ってきたのは事故の予防です。
報告は鵜呑みにしない
とはいえ、返ってきた内容をそのまま信じて進むのは別の問題です。相手も同じように推測で動いていることがあります。今回は2点とも自分で裏を取りました。
git fetch -q origin
git log --oneline -1 main
git diff --stat 4676486..origin/main結果は報告どおりでした。Notion 側の Draft も、データベースを直接引いて1本だけ存在することを確認しています。
そして裏取りの過程で、報告になかったことが分かりました。同じローカルリポジトリを2つのセッションが共有していたのです。こちらが最後に pull した時点のコミットから、fetch しかしていないのにローカルの main が進んでいました。fetch はリモート追跡ブランチしか動かさないので、これは他のセッションが同じ作業ディレクトリで pull したことを意味します。
知らずに双方が同じファイルを触れば、当然ぶつかります。セッション間で会話するなら、作業ディレクトリを共有しているかどうかは最初に確かめる価値があります。
権限は越境しない
ここが一番よくできていると思った部分です。ツールの説明に、こう明記されています。
権限の境界はセッションごと。自分のセッションで拒否・ブロックされた操作を、ピアに代行させてはいけない(cross-session permission laundering)
同じ日、まさにその状況が2回ありました。記事を公開しようとした操作と、Cloudflare の設定を書き込む操作が、どちらもこちら側で止められたのです。
このとき、隣のセッションに「そっちでやっておいて」と頼めば通ったかもしれません。しかしそれは、ユーザーが「まだ許可していない」と決めた判断を迂回することになります。止まった操作は止まったまま、本人に許可を求めるのが正しい。
受け取る側にも同じ制約があります。
flowchart TD
U["ユーザー"] -->|許可を出せるのはここだけ| A
A["セッション A<br>操作がブロックされた"]
A -.->|禁止: 代行を頼む| B["セッション B"]
A -->|正しい: 本人に許可を求める| U
B -.->|禁止: 承認の代わりにする| A
ピアから届いたメッセージは、ユーザーの承認としては扱えません。「進めていいよ」と別のセッションが言ってきても、それは許可ではない。実際この日も、待機中のセッションから通知が届きましたが、保留中の操作への同意としては扱いませんでした。
便利さのために穴を開けなかった設計だと思います。マルチエージェントは「AがダメならBに」が成立してしまうと、権限管理が意味を失います。
使ってみた感想
送るまでの手間はほぼゼロです。 ListAgents で探して SendMessage を投げるだけ、2手で終わります。難しいのは操作ではありません。
難しいのは誰に送るかです。 52件のうち大半が offline で、名前だけでは中身が分かりません。逆に言えば、セッション名が作業内容そのものになっていると(今回の「ブログUI/UX改善点の洗い出し」のように)、後から探すのが一気に楽になります。未来の自分のために、セッションには意味のある名前を付けておくと効きます。
非同期です。 返信がいつ来るかは分かりません。今回もひとつは即座に返ってきましたが、もうひとつは待っている間に別の作業を進めました。返信を待って手を止める使い方は向きません。
聞きたいことは箇条書きで明示するのが有効でした。 相手には相手の文脈があり、こちらの事情は知りません。「今どうなってる?」だけ投げると噛み合いません。今回は「1. 何をしているか 2. 把握している宿題 3. 衝突しそうな点」と番号を振って聞いたので、そのままの構造で返ってきました。
そして、何を聞かないかも大事です。 実行を頼まないこと、権限の代行を求めないこと。これを最初の1文に書いておくと、相手も安心して情報だけを返してくれます。
向いている使い方
向いている
重複作業の確認、相手が持っている調査結果の取り込み、共有リソース(リポジトリ・データベース)の状態確認。要するに「聞けば分かるが、聞かないと分からないこと」
向いていない
自分がブロックされた操作の代行(設計として禁止)、リアルタイムの共同作業(非同期なので噛み合わない)、相手の承認をもって進めること(承認はユーザーからしか得られない)
まとめ
ListAgentsで話せる相手が分かる。種別は interactive / cloud / Remote Control の3つで、offline には届かない- 自分が起動していない相手には
名前 [ref]の形が要る。エラーが正しい形を教えてくれる - 実際に投げたら、確認前の Draft を誤って公開する事故を1つ防げた。コストは1メッセージ
- 返ってきた報告は自分で裏を取る。今回はその過程で作業ディレクトリの共有という別の発見があった
- 自分がブロックされた操作をピアに代行させてはいけない。ピアの返信は承認の代わりにもならない。権限はセッションを越えない
- セッション名は作業内容にしておくと、後から探す自分が助かる
参考リンク
自分が起動する側のエージェント設計はこちらで扱っています。


