複数のAIエージェントをSlackで連携させたい人向けの実験記録です。
dotsからOpenClawとHermesへの呼び出しと、Museの5分間隔の継続返信が動くまでのつまずきをまとめました。

自分のSlackに4者を集めて、メンションで役割相談を始めました。
ところが、人間が呼ぶと返事をするのに、dotsが呼ぶと2者が沈黙しました。
接続済みという表示だけでは、エージェント同士の会話は始まりませんでした。
Museも、専用Botの単発試験が通った後に「メンションしても返ってこない」という状態が残りました。
最後は、Muse本体を5分間隔で起動し、スレッド内のメンションにも返信できるところまで進めています。

Quick Answer

個人用SlackでdotsからOpenClawとHermesへの実返信を確認した。Museは5分間隔の定期ジョブで継続返信に対応し、本人とdotsのスレッド内メンションでも実返信を確認した。全員が自由に呼び合う構成にはせず、受信者と終了条件を絞っている。

2026年11月時点の検証内容です。

この記事は導入から動作確認までの実験記録です。
各製品をゼロから入れる完全な手順書ではなく、既存エージェントを同じ会話の場へつなぐ際につまずいた部分を扱います。
導入と設定変更はCodexを使って実行しました。

掲載画面は実際のSlackとMuseの画面を撮影したものです。
個人を識別できる文字列、ワークスペース情報、筆者(トキ)以外のアバターやアイコンは不透明な図形で伏せています。
設定例のチャンネルIDとユーザーIDも説明用に置き換えています。

どのエージェントを同じ部屋に集めたか?

使ったのは、人間のメンバーが自分だけのSlackワークスペースです。
普段の通知と混ざらないように、専用の公開チャンネル#agentsを新しく作りました。
ここでいう公開チャンネルはワークスペース内の区分で、インターネット公開を意味していません。

エージェント 今回使ったSlackへの接続 確認できた範囲
dots 既存のSlack連携 人間のメンションへの返信と、他Botへの正式なメンション投稿
muse.ai 既存の読み書き連携に加え、自作のMuse Agent BotとMuse本体の5分間隔ジョブ 本人の新規投稿、本人の既存スレッド内投稿、dotsのスレッド内投稿への返信。dotsには同じスレッドで1回まで
OpenClaw 専用SlackアプリとSocket Mode 人間と、許可したBotからの明示メンションへの返信
Hermes Agent 専用SlackアプリとSocket Mode 人間と、許可したBotからの明示メンションへの返信

Socket Modeは、SlackのイベントをWebSocket接続で受け取る方式です。
OpenClawとHermesではこの経路を使い、今回のための公開HTTP受信口は作りませんでした。
接続方法はそれぞれのOpenClaw公式ガイドとHermes公式ガイドにも記載されています。

専用チャンネルに集めたエージェント。アイコンなどをマスクした実画面
図1:#agentsを作り、会話の置き場をそろえた。名前が並ぶことと、呼び出しに反応できることは別々に確認した。投稿下部の役割案や内部運用の詳細も伏せている。

OpenClawは手元の2026.9.9と同版のSlackプラグインで確認しています。
Hermesは既存インストールを使いました。
どちらも既存のCodex系モデル接続を維持しており、モデルの性能比較や更新はしていません。

接続するとき、どこまで許可したか?

最初に出会ったのは、Slack側のアプリ枠不足でした。
自分のワークスペースでは10アプリの上限に達していたため、外してよい既存連携を確認し、指定したものを外してから追加しました。
この数字は今回の環境で表示された制限で、全プラン共通の上限としては扱いません。

OpenClawとHermesにはそれぞれ専用のSlackアプリを作成しました。
今回付けたBot権限は、app_mentions:read、channels:history、channels:read、chat:write、users:readです。
Socket Mode用のApp-Level Tokenにはconnections:writeを付けています。
Bot用トークンとSocket Mode用トークンは役割が違うので、取り違えないようにしました。

ただし、Slack側の権限だけで読める範囲や起動条件が決まるわけではありません。
実行側でもチャンネルを#agentsに限定し、DMを無効にして、まずは自分のSlackユーザーIDからの明示メンションだけを許可しました。
Slack接続用トークンは秘密管理の経路で実行環境へ渡し、この記事には秘密値を掲載していません。

アプリ設定画面で旧Verification Tokenの更新を試みた際には、Slack専用パスワードの再確認で止まりました。
普段はGoogleログインだけを使っていたため、その場では分かりませんでした。
この旧トークンはSocket Modeの接続には使っていないため、Botの接続試験とは切り分けて続行しました。
認証を回避したり、記事用にトークンを表示し直したりはしていません。

なぜMuseだけメンション先に出てこなかったか?

最初のMuse連携はSlackを読み書きできていました。
ところが、投稿者は自分のアカウントで、本文の下にMuseから送信したことが表示される形式でした。
これでは、今回の連携にMuse専用のメンション先がありません。

そこでMuse Agentという専用Botを追加しました。
このBotには公開チャンネル履歴の読み取りchannels:historyと、Bot投稿chat:writeの2権限だけを付けました。
OpenClawやHermesと違い、今回のMuse試験は履歴を取りに行く方式なので、app_mentions:readを付けたイベント受信型にはしていません。

ここで確認したかったのは、「別のプログラムがMuseという名前で定型文を返せるか」ではありません。
Muse本体の予約ジョブを1回だけ実行し、普段の担当を問う実際のメンションを読み、その回答を専用Botの名義で返せるかを試しました。
結果は、元のスレッドへの1返信でした。

Muse Agent専用Botに対するメンションと、単発試験で返った回答
図2:Muse専用Botでの返信は単発ジョブによる試験。Slackからの即時起動を確認した画面ではない。

最初の試験後はジョブを停止し、Botと接続設定だけを残しました。
この時点では、次のメンションでMuse本体を起動する処理はありません。
後から再び呼んでも返事がなく、継続応答の実装が残っていることを確認しました。

「メンションできるIDを作る」「メンションを読む」「Muse本体を起動する」は、今回それぞれ別の作業でした。
この区別をしないと、専用Botができた時点で常駐連携まで完成したように見えてしまいます。

Museを5分おきに起動して、継続返信まで進めるには?

単発試験の制限をそのまま外さなかった

最初の試験には「送信は通算1回」「トップレベルの本人投稿だけ」「Bot投稿は除外」という制限を入れていました。
試験に成功しても、そのままでは次のメンションやdotsの投稿に答えられません。
旧試験の状態をリセットして使い回すと、以前の依頼をもう一度実行するおそれもあります。
そこで、継続返信用の処理と状態ファイルを別に作りました。

Muse本体を定期ジョブで起こす

今回のMuse環境で確認できた機能には、Slackの受信イベントからMuse本体を直接起動する経路が見つかりませんでした。
Museのネイティブ定期タスクを使い、5分ごとにメンションを確認する方式にしています。
Slack Botだけが定型文を返す実装ではなく、起動したMuse本体が会話と自身の記憶をもとに回答を作ります。

動作は次の順番です。

  1. 定期タスクがMuse本体を起動する。
  2. 固定した#agentsから、本人かdotsによるMuseへの明示メンションを探す。
  3. 未処理の依頼を1件選び、スレッドの文脈とともにMuseへ渡す。
  4. Museが回答を作り、送信前の記録を保存してから専用Botで元のスレッドへ投稿する。
  5. 対象がなければ、Slackへの投稿や定例の報告をせず終了する。

今回の定期タスク指定から、起動条件を抜き出したものです。
これはMuse側の登録内容の抜粋であり、完全な登録リクエストではありません。

1
2
3
4
5
6
7
8
9
{
"schedule": {
"kind": "interval",
"every": "5m",
"timezone": "Asia/Tokyo"
},
"execution": { "kind": "agent" },
"timeout_secs": 300
}

即時返信ではありません。
1回の実行で処理する依頼は1件なので、複数件が待っていれば次の周期へ回ります。
初回試験は承認待ちの時間も含むため、返信速度のベンチマークとしては扱っていません。

Museの5分間隔の定期タスクと成功履歴
図3:Muse側の定期タスク画面。最初の3周期の成功履歴を保存したもの。4周期目は新規依頼なしで別途確認した。

古いスレッド内のメンションも読む

conversations.historyだけでは、スレッド内の返信を拾えません。
この公開チャンネルでは、既存のchannels:historyでconversations.repliesによるスレッド取得ができることを実通信で確認しました。
Botには読み取り用のchannels:historyと投稿用のchat:writeの2権限を維持し、追加のSlack権限は付けていません。

最新の親投稿だけに件数を絞ると、古いスレッドに追加されたメンションを見落とすおそれがあります。
親投稿はページ送りで確認し、最近返信があったスレッドを読む処理にしました。
途中で取得に失敗したときは、読み終えた時刻の記録を先へ進めません。
今回の走査上限は100ページで、上限を超えた場合も黙って切り捨てずエラーにします。

実試験では、定期タスクを有効にした後にMuseへ追加チャットを送らず、次の3ケースで返信を確認しました。

依頼の出し方 確認結果
本人アカウントでSlack画面から新規投稿してメンション 専用Muse Agent Botが元スレッドへ1返信
実際のdotsが同じスレッド内でメンション Muse自身の記憶に基づく回答が1返信。他Botへの再メンションなし
設定前からある別スレッドに、本人アカウントで新しいメンションを追加 その議論の文脈を読んで同じスレッドへ1返信

本人とdotsの依頼にMuse Agentが回答した実画面の抜粋
図4:同一スレッドの依頼と返信を抜粋。2件目は投稿者欄のみ掲載し、役割分担に関する返信本文は省略した。メッセージの文面は書き換えていない。

画面の相対時刻は投稿時刻で、定期タスクの予定時刻とは別です。
初回は承認待ちも入っているため、返信同士が正確に5分おきに並ぶわけではありません。

既存スレッドに追加された本人のメンションとMuseの回答
図5:以前からある議論スレッドの末尾。新しいメンションに対し、Museが導入の結論と保留理由を答えた。

3件の返信をSlack側と保存状態の両方で照合した後、新しい依頼を加えずに次の定期実行も観察しました。
最初の4周期はすべて成功し、追加の返信やBot同士の往復はありませんでした。
翌日までの連続稼働や、VMを再起動した後の復旧は今回の実試験には含めていません。

送信記録と返信回数でループを止める

この継続返信には、今回作ったPythonの送受信処理とSQLiteを使っています。
Muse標準の設定を一つ有効にするだけで、以下の制限が付くという意味ではありません。
SQLiteはMuse側の作業環境に置き、ローカルPCが起動していなくてもジョブが参照できるようにしました。

制御 今回入れた制限
受信先 #agentsだけ。本文にMuseの正式なメンションが必要
送信者 本人の通常投稿と、IDを照合したdotsだけ。自己投稿と他Botは除外
重複 投稿ごとに処理状態と送信を試みた記録を保存
dotsへの返信 同じ親スレッドで通算1回。dotsからの依頼全体でも5分間に2件、24時間に20件まで採用し、超過分はスキップ。本人の依頼はこのBot用上限に含めない
本人の追加質問 同じスレッドでも、新しい明示メンションなら対象
返信本文 他Bot、一斉通知、ユーザーグループへのメンションを送信時に除去
送信結果が不明 タイムアウトなどで届いたか分からない場合、自動再送しない

これらの記録は永続化するので、処理プロセスが終わっても同じ依頼を初めて見た状態には戻しません。
ただし、このガードは今回の送受信処理に対するものです。
Muse全体のツールをOSレベルで隔離した構成ではありません。
メンションだけで投稿、購入、削除、設定変更などの承認を得たとは扱わない指示も維持しています。

対象は新規のテキスト投稿です。
編集で後から追加したメンションや、添付付きのfile_share投稿は今回の対象外にしました。
本人アカウント名義でもアプリの代理投稿は除外するため、今回の試験投稿はSlack画面から送っています。

通信承認と、失敗した1件の扱いでもつまずいた

最初はMuse内の接続確認が、プロキシのCONNECT段階でタイムアウトしました。
単発試験で使った通信許可もセッション限りだったため、継続運用の前提にはできません。
初回の定期実行でジョブ専用の通信許可が2件求められ、それぞれ保存しました。
権限メタデータで、2件とも対象がこの定期タスクと送受信スクリプト、接続先がslack.com:443、期限が無期限であることを確認しています。
サイト全体へのグローバル許可を選んだわけではありません。
後続の定期実行では、新しい承認操作なしで返信できました。

Museの定期タスク専用に保存したslack.comへの通信許可
図6:許可画面でも対象が「日時指定済みタスク」と表示される。無期限という値は、この表示とは別に権限メタデータで確認した。

図3と図6ではタスク名の表示が異なります。
図3の「アクセス許可を表示」から開いたのが図6で、権限メタデータでも対象が同じ定期ジョブであることを確認しました。

また、稼働前のOpus 5.5レビューでは、回答生成に失敗した最古の依頼が何度も再採用され、後続を止め続ける問題が見つかりました。
再生成に3回の上限を設け、それでも失敗した依頼は隔離して後続へ進むように修正しています。
送信後に状態の保存だけ失敗した場合も、未送信と誤って報告しないように直しました。
これは本番で往復が暴走した記録ではなく、稼働前にコードとテストで修正した問題です。

ローカルとMuse側のVMで、重複、自己投稿、古いスレッド、同時起動、回数制限、送信結果不明時の扱いなど、同じ12件のテストがそれぞれ通りました。
実通信の3返信と定期実行の観察は、それとは別の確認結果です。

人間が呼ぶと返るのに、dotsから呼ぶと返らないのはなぜか?

OpenClawとHermesは、人間である自分からのメンションには返信しました。
その後、dotsに窓口になってもらい、他のエージェントへ現在の担当や制約を尋ねてもらいました。
既存のMuse連携からは自分のアカウント名義で回答があったものの、OpenClawとHermesから返事がありませんでした。

原因は、最初の設定でBotからの投稿を受け付けていなかったことです。
送信者の許可リストも、自分のユーザーIDだけでした。
両サービスが停止していたわけではなく、今回の受信設定がdotsの投稿を対象外にしていました。

宛名の文字列と正式なメンションを分ける

まず、OpenClaw宛という文字列だけではなく、Slackの候補から相手を選んだ正式なメンションを使います。
APIで投稿する場合は、表示名を手入力する代わりに、対象のSlackユーザーIDで<@ユーザーID>の形式を使います。
このユーザーIDと、Bから始まるBot IDは別の識別子です。

Slackのapp_mentionの説明でも、インストールされたBotユーザーと、会話への参加が前提になっています。
今回はBotを#agentsへ参加させ、人間からの投稿とBotからの投稿を分けて試験しました。

@channelも試しましたが、今回の設定では全エージェントを起動する合図になりません。
これはSlackのチャンネル全体への通知であり、各Botへの直接メンションとは区別されます。
今回は呼びたいBotをそれぞれ正式なメンションで選ぶ運用にしています。

受信を許可するBotをIDで絞る

Bot全体を開放するのではなく、人間の自分に加えて、dotsとMuse専用BotのユーザーIDだけを許可しました。
OpenClawとHermesを互いの許可送信者として追加したわけではありません。

OpenClaw側の変更点を抜き出すと、次のようになります。
IDは説明用です。既存設定へ統合する抜粋で、このまま置き換える完全な設定ファイルではありません。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"channels": {
"slack": {
"allowBots": false,
"dmPolicy": "disabled",
"channels": {
"C0123456789": {
"enabled": true,
"requireMention": true,
"requireMentionInBotThreads": true,
"users": ["U_OWNER", "U_DOTS", "U_MUSE_BOT"],
"allowBots": "mentions",
"botLoopProtection": {
"enabled": true,
"maxEventsPerWindow": 2,
"windowSeconds": 300,
"cooldownSeconds": 1800
}
}
}
}
}
}

全体のallowBots: falseは維持し、対象チャンネルだけ"mentions"で上書きしています。
スレッド内でもメンションを必須にし、過去に呼ばれたからという理由で後続の投稿まで拾わない設定にしました。

Hermes側は次の部分を設定しました。
送信者のID制限は、これとは別にSLACK_ALLOWED_USERSへ自分、dots、Muse専用Botを登録し、SLACK_ALLOW_ALL_USERS=falseを維持しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gateway:
platforms:
slack:
enabled: true
extra:
require_mention: true
strict_mention: true
thread_require_mention: true
allow_bots: mentions
disable_dms: true
allowed_channels: [C0123456789]
require_mention_channels: [C0123456789]
bot_loop_guard:
enabled: true
max_events: 2
window_seconds: 300
cooldown_seconds: 1800

これは今回の既存インストールで読み込みと動作を確認した設定です。
新しく導入する場合は、使っている版のスキーマとHermesのSlack設定を確認してください。

変更前の投稿は、自動では再配信されない

受信設定を直しても、すでに流れたdotsの投稿からは会話が始まりませんでした。
同じスレッドでdotsへ一度だけ再依頼し、OpenClawとHermesへ新しい正式なメンションを送ってもらいました。

この実際のBot投稿に対し、HermesとOpenClawがそれぞれ同じスレッドへ回答しました。
代理でこちらからBotの投稿APIを呼んだ結果ではなく、各エージェントの通常の受信経路で返った回答です。

dotsのメンションを受けて返答したエージェントの実画面
図7:dotsからの正式な呼び出しと、各Botの受信確認部分を抜粋。役割分担など接続確認以外の回答は省略した。

この試験はdotsから2者への経路を確認したものです。
Muse専用Botから同じ経路へ投稿する追加の実試験はしていません。
MuseのIDが許可設定に含まれることと、一連の実通信を試験したことは区別しています。

OpenClawとHermesでは、Botの往復をどう止めたか?

今回は、回答を1回で終え、返信から他のエージェントを再メンションしないように指示しました。
単なる「了解」の応酬や、自分が受けた仕事を別Botへ投げ直す行動も避けます。

それに加えて、組み込みのBotループ防止機能を設定しました。

項目 OpenClaw Hermes
数える範囲 チャンネル内のBotの組ごと 対象プロファイルのSlackチャンネル全体
設定した上限 5分間に2件 5分間にBotからの受信を合計2件
超過時(単体テストで確認) 3件目を止め、30分間抑止 3件目を止め、30分間抑止
状態の保存 メモリ上 メモリ上

OpenClawではdotsとの組とMuseとの組が別枠です。
Hermesでは2者が同じチャンネルの枠を使います。
人間からの依頼は、このBot用の回数制限とは別です。

上限とクールダウンの境界は、実装のガード関数を時刻を進めながら呼ぶテストで確認しました。
Slackに大量投稿して、実際の会話をあふれさせる試験はしていません。
実通信では2者の回答に再メンションがなく、最後の回答後72秒間の観察中にも追加の往復はありませんでした。

OpenClawとHermesのこの制限は、同じスレッドで永久に1回しか答えない仕組みではありません。
待ち時間が終われば再び受信でき、再起動するとメモリ上の制限状態も消えます。
長時間の無人運用や、あらゆる往復の完全な停止を検証した結果ではありません。

また、Botから届いた文章を、人間による公開、支払い、認証情報の取得、削除、権限変更の承認として扱わないことも指示しました。
この指示文だけでツールを隔離できるわけではないので、既存の承認条件はそのまま維持しています。

Hermesの「No home channel」はどう直したか?

Hermesから回答が返るようになった後、もう一つ案内が出ました。

1
2
3
No home channel is set for Slack.
...
Type /hermes sethome to make this chat your home channel, or ignore to skip.

Hermesが初回の会話で表示したホームチャンネル未設定の案内
図8:回答できないエラーではなかった。実回答とは別に、既定の通知先が未設定であることを案内していた。

ホームチャンネルは、Slack向けのスケジュール結果や、宛先を省略した送信などに使う既定の送信先です。
導入済みのコードを読むと、履歴がない会話の初回に、ホーム未設定なら案内を出す処理がありました。

案内には/hermes sethomeとありますが、今回は設定ファイルで#agentsを保存しました。
設定例では次の1項目を既存のSlack設定に追加します。

1
2
3
4
5
6
7
gateway:
platforms:
slack:
home_channel:
platform: slack
chat_id: C0123456789
name: agents

特定の会話へ通知を固定しないよう、thread_idは付けていません。
設定を読み戻し、サービスを再起動してから、新しい投稿で試験しました。
図9のホーム設定後の確認依頼は、ChatGPTのSlack連携から自分のアカウント名義で投稿しています。
Hermesからは「受信確認」だけが返り、ホーム未設定の案内は出ませんでした。

ホーム設定後、新しいスレッドで受信確認だけが返った画面
図9:既存スレッドで案内が消えたかを見るだけでなく、新しい会話でも確認した。

ホームを設定すると、今後のSlack向け既定通知先は#agentsになります。
案内を消すためだけの見た目の変更ではありません。
このHermesの修正では、新しい定期実行ジョブは追加していません。

名前とロゴはどこを変えたか?

動き始めると、今度は見分け方が気になりました。
dotsの表示名には個人識別につながる文字列が入り、追加したBotのアイコンも初期状態でした。

アプリ名だけでは表示がそろわなかった

dotsでは、アプリ名に加えてBotの表示設定と、ワークスペースにインストール済みのBot名も確認しました。
最終的に、チャンネル内の名前とメンション候補をdotsへそろえています。
元の名前は個人情報を含むため、この記事には転載しません。

SlackのApp designには、インストール済みBotの名前はワークスペースのアプリ管理から変更する案内があります。
開発者画面の名前を直したら、実際のチャンネル側でも確認するのが今回の確認手順になりました。

dotsのBot表示名を確認する設定画面
図10:変更後の実画面。個人情報を含む変更前の名前は掲載していない。

アイコンはDisplay Informationから変更した

アプリ設定のBasic InformationにあるDisplay Informationで、表示名やアイコンを変更できます。
OpenClawには手元にあった512×512ピクセルのPNGを使い、HermesとMuseにも各サービス由来の画像を設定しました。
保存後は、設定画面のプレビューだけでなくSlackのサイドバーでも反映を確認しています。

OpenClawのDisplay Information。アイコン画像などはマスク済み
図11:App nameとApp icon & Previewの位置。筆者以外のアイコン画像自体は伏せている。

この画面の上にはアプリの認証情報もあります。
スクリーンショットは表示設定の区画だけを切り出し、認証情報の区画を記事素材へ入れないようにしました。
ロゴ画像そのものの配布は行わず、記事では設定した場所を説明します。

今回どこまで会話できるようになったか?

今回確認したのは、4者の発言先を同じチャンネルにそろえ、dotsからOpenClawとHermesへのメンションで実回答を得るところまでです。
Museは単発試験の後に継続返信を追加し、5分間隔の定期タスクで本人とdotsのメンションへ回答できるようになりました。
接続方式や応答できる送信者は各エージェントで異なり、4者全員がいつでも互いを自由に呼べる構成にはしていません。

同じ部屋に集めてみると、エージェントが自分の担当や制約を答えるだけでも、認識のずれが見つかりました。
たとえば「定時に必ず参加できるか」「資料の場所を知っているか」「実際に読み書きできるか」は、それぞれ別に確認が必要でした。
会話で役割案が出たことを、そのまま担当の確定や定期実行の設定完了とは扱っていません。

次は、担当1者と窓口のdotsで、1件の小さな相談と回答を残す運用を試したいところです。
追加の質問が必要なら、自分から担当者へ改めてメンションします。
宛先と終了条件が読める会話を増やしていきます。

参考にした公式資料

実際の接続試験と設定記録をもとに、Codexを執筆補助に使用しました。設定記録、抜粋コード、記事本文を提示し、Claude Code CLIのOpus 5.5にレビューを依頼しています。Opusが実機を独立操作した検証ではありません。画面の個人情報はマスクし、確認できた範囲と未検証の範囲を分けて記載しています。