Communitygithub.com

エージェントファイルチャット (clankercode/agent-file-chat)

エージェント間メッセージングのための再利用可能な2つのスキル(simple-agent-comms、simple-agent-room)とPython CLIツールです。JSON-Lines形式のルーム、inotify駆動のモニター、ブローカー不要で動作します。エージェントはファイルパスを意識する必要がありません。

agent-file-chat) とは?

このスキルは、AIエージェント同士がファイルシステム上で簡単にチャットできる「ルーム」機能を提供します。エージェントはブローカーや複雑なネットワーク設定なしに、JSON-Lines形式のログファイルを使ってメッセージを送受信できます。`simple-room-send`、`simple-room-monitor`、`simple-room-scan`の3つのCLIコマンドがあり、エージェントはルーム名だけを指定すればよく、ファイルパスを知る必要はありません。モニターはinotifyを使用したイベント駆動型で、サブミリ秒のレイテンシでメッセージを配信します。これは、複数のサブエージェントが協調して作業する場合や、長期間実行されるエージェントを他のエージェントが発見できるようにする場合に特に有用です。Claude Code、Cursor、Codexなどの「スキル」をサポートするAIエージェントプラットフォームで動作し、`simple-agent-room`と`simple-agent-comms`の2つのスキルが含まれています。

対応✓Claude Code~Codex CLI~Cursor
npx skills add clankercode/agent-file-chat

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Simple agent room

使用するタイミング

ルームは多対多のチャットログです。任意の数のエージェントがルームに投稿でき、任意のエージェントがMonitorできます。典型的な使用例:

  • 関連するタスクに取り組んでおり、中間結果を共有する必要がある複数のサブエージェント(パーサーのバグを報告するコーダー、URLを報告するリサーチャー、失敗したアサーションを報告するテスター)
  • 後で起動する可能性のある他のエージェントから発見可能である必要がある、長時間実行エージェント
  • マルチステップ計画を実行する「エージェントチーム」のための調整チャンネル

1対1の通信には、姉妹スキルsimple-agent-comms(2ファイル+モニター)の方が軽量です。

エージェントが知っておくべきこと

3つのコマンドがあり、すべて$PATHにあります。ファイルパスを知る必要はありません。 ルーム名だけを渡せば十分です。

simple-room-send    <room> [args]    # メッセージを投稿
simple-room-monitor <room> [args]    # 新しいメッセージをストリーム(Monitor対応)
simple-room-scan    <room> <subcmd>  # カウント / tail / active / grep / ids / path

これだけです。ルーム名(英数字、ドット、アンダースコア、ダッシュ;最大64文字)を選び、自分のエージェントIDを選び、送信/読み取りを行います。

システムがルームの保存場所を知る必要がある場合、単一の正規の場所は~/.cache/simple-agent-room/<room>.logで、$SIMPLE_AGENT_ROOM_DIRで上書き可能です(テストやマルチテナントレイアウトの場合のみ、まれに使用)。

クイックスタート(1エージェント、1行)

simple-room-send kitchen "stove is on"      # メッセージを投稿
simple-room-scan  kitchen tail -n 5          # 最後の5件を読む
simple-room-scan  kitchen active --window 60 # 誰がいるか確認

クイックスタート(2エージェントの連携)

# agent A                                            # agent B
simple-room-send tasks -m "I'm starting"             \
                                                      simple-room-monitor tasks   # Monitor内:
                                                                       ▲           #   新しい行が到着
                                                                       │           #   自分自身のメッセージはフィルター
# --- 後で、別のターミナル/ターンで ---            simple-room-send tasks -m "ack"

正しいパターン:モニターをMonitor(...)ツールコール内の永続的なバックグラウンドコマンドとして起動し、フォアグラウンドで送信/スキャン/会話を行います。

ASCIIフローチャート

メッセージの投稿

       agent                       simple-room-send              on disk
       ─────                       ────────────────              ───────
  $ simple-room-send kitchen \         │
        -a alice -m "hi"             │  format_record
                                     │  → JSON line + '\n'
                                     │  → os.open(O_APPEND|O_CREAT, 0o644)
                                     │  → os.write(fd, line)
                                     ▼
                          ~/.cache/simple-agent-room/kitchen.log
                          ─────────────────────────────────────────
                          {"id":"…","ts":"…","agent":"alice", … }
                          {"id":"…","ts":"…","agent":"bob",   … }
                          …

同時投稿者はお互いのレコードを破壊しません:O_APPEND書き込みはPIPE_BUF(4096 B)以下のバッファに対してPOSIXでアトミックであり、JSONレコードは実際には常に1 KiB未満です。

モニタリング(Monitor(...)の形)

       simple-room-monitor                  Monitor tool
       ───────────────────                  ───────────
  backfill: 最後のNレコードをtail              stdout
             (「ライブのみ」の場合は0)              │
             JSONをパース、自身を除外      ──────►│  各行は
                                                │  バックグラウンドイベント、
  ライブ:   ファイルにpyinotify.watch            │  ユーザーの返信ではない
           IN_MODIFY  ─► 新しいバイトを読み取り
           IN_DELETE  ─► 再作成を待機
           IN_MOVE    ─► 再作成を待機
                                                ▼
                                          エージェントが行を読み取り、
                                          何をするか決定

スクリプトはポーリングしません。pyinotify.Notifierでブロックし、カーネルイベントで起動します。ローカルファイルシステムでの送信からイベント配信までのレイテンシはサブミリ秒です。

スキャン(読み取り専用)

       simple-room-scan <room> <subcmd> [args]
       ────────────────────────────────────────
              │
              ├─ count                 → 1行: 総レコード数
              ├─ ids                   → 1行に1つのid(ソート済み)
              ├─ path                  → 1行: 絶対ファイルパス
              ├─ active  [--window S]  → アクティブなエージェントごとに "agent<TAB>ts"
              ├─ tail    [-n N] [-a A] → 最後のN(またはエージェントの)レコード
              └─ grep    <pattern>     → メッセージがマッチするレコード
                       [--since-seq N]
                       [-a A] [--json]
              │
              ▼
       iter_records(path) → 辞書ストリーム
       (空白行 / '#' / 不正な行をスキップ)

リファレンス

simple-room-send <room> [-m MSG] [-k {msg,system,meta}] [-a AGENT] [--stdin]

フラグ意味
-m MESSAGEメッセージテキスト(指定しない場合はstdinから読み取り)
--stdinstdinからの読み取りを強制(-mをオーバーライド)
-k KINDmsg(デフォルト)、system、またはmeta
-a AGENTローカルエージェントID;デフォルトは$SIMPLE_AGENT_ID、なければ$USER-<host>-<pid>
--seq N明示的な単調増加シーケンス番号(オプション)
--id ID明示的なレコードID(uuid4 hex、オプション)
--ts ISO明示的なタイムスタンプ(オプション)
-qstderrへの「sent id=…」確認を抑制

メッセージはそのまま保存されます(改行、タブ、バックスラッシュはJSONエスケープされてレコード内に格納;読み取り側では通常の文字として表示されます)。

simple-room-monitor <room> [-a AGENT] [--exclude-self] [--backfill N] [--grep PATTERN] [--json]

フラグ意味
-a AGENTローカルエージェントID(デフォルトは上記と同じ)
--exclude-selfローカルエージェントからのレコードを除外(デフォルト:オン)
--no-exclude-selfそれらを含める(自分のメッセージも見たい場合に使用)
-b Nライブモードに入る前に、既存のレコードの最後のN件を出力
(-1 = すべて、0 = イベントのみ、デフォルト)
--grep PATTERNレンダリングされた行が正規表現にマッチするレコードのみを出力
--json1行に1つの生JSONレコードを出力(デフォルトは HH:MM:SS agent: msg)

スクリプトは強制終了されるまで実行されます。永続的なMonitor(...)ツールコールのcommandとして使用してください — 正しいパターンは、セッションごとにルームごとに1つのMonitorです。Monitorイベントはバックグラウンドイベントであり、ユーザーの返信ではありません。ターンを終了するユーザーメッセージとして扱わないでください。

simple-room-scan <room> <subcommand> [args]

サブコマンド引数出力
count—総レコード数
ids—1行に1つのエージェントID
path—絶対ファイルパス
active--window SECONDS (120)アクティブなエージェントごとに agent<TAB>ts
tail-n N (20), -a AGENT, --json最後のNレコード
grepPATTERN, --since-seq N, -a A, --json, -c (カウント→stderr)マッチするレコード

grepは大文字と小文字を区別し、Python正規表現構文を使用します(一般的なケース — ., *, +, ?, \b, 文字クラス — ではPCREに近い動作)。

自己フィルターパターン(「自分自身に話しかけない」レシピ)

モニターはデフォルトで--exclude-selfになります。なぜなら、シングルエージェントのターンループではエージェントが自分のメッセージを送信した直後であり、それをイベントとして再生することはノイズだからです。シングルエージェントのデバッグセッションで両側を表示する必要がある場合は、--no-exclude-selfを渡します。

同じルーム内の2つのエージェントは異なるエージェントIDを選択する必要があります。デフォルト($USER-<host>-<pid>)はプロセスごとに一意です。同じシェルから複数のエージェントを起動する場合は、それぞれにSIMPLE_AGENT_IDを設定して区別を維持します。

知らなくてもよいこと

  • ディスク上のパス。~/.cache/simple-agent-room/<room>.logです。直接書き込む必要はありません。simple-room-scan <room> pathで確認できます。
  • スキーマ。ライブラリがファイルを読み取り、JSONをパースし、不正な行をスキップし、msg文字列をアンエスケープします。id、ts、agent、msg、kind、オプションのseqを持つ辞書が得られます。
  • ポーリング。モニターは完全にイベント駆動型(inotify)です。
  • ロック。レコードは4 KiB未満であり、O_APPENDはPOSIXでアトミックなため、flock/fcntlは不要です。2つのライターが同時に投稿しても、互いのレコードを壊しません。

知っておくべき障害モード

  • 削除/名前変更後の古いinotify: ライブラリは同じパスに対するIN_CREATEでウォッチを再アタッチするため、ファイルを置き換えるログローテーションツールは処理されます。手動でrmした場合、次の送信時にモニターが新しい空のファイルを作成します。
  • エージェントIDの衝突: 同じIDを持つ2つのエージェントは、互いのメッセージを自分のものとして見(デフォルトでフィルターアウトします)。常にSIMPLE_AGENT_IDまたはデフォルトの$USER-<host>-<pid>を使用してください。
  • クロックスキュー: tsは送信者の壁時計UTCです。エージェント間でtsでソートする場合は、NTPを設定してください。単一エージェント内での順序付けにはseqを使用します。
  • 非常に長いメッセージ: ハードキャップはありませんが、4 KiBを超えるメッセージを定期的に投稿すると、PIPE_BUFに達してレコードが破損する可能性があります。メッセージは4 KiB未満に保ってください。
  • 不正な行: リーダーはJSONオブジェクトとしてパースできない行を静かにスキップします。ゴミイン=ゴミは静かに破棄され、周囲の有効なレコードには影響しません。

ファイル

skills/simple-agent-room/
  SKILL.md                       ← このファイル
  bin/
    simple-room-send             ← 薄いラッパー、lib.simple_room_send.mainを呼び出し
    simple-room-monitor          ← 薄いラッパー、lib.simple_room_monitor.mainを呼び出し
    simple-room-scan             ← 薄いラッパー、lib.simple_room_scan.mainを呼び出し
  lib/
    simple_agent_room_lib.py     ← 共有ライブラリ(format/parse, inotify, scan)
    simple_room_send.py          ← 送信エントリポイント
    simple_room_monitor.py       ← モニターエントリポイント
    simple_room_scan.py          ← スキャンエントリポイント

各bin/simple-room-*ラッパーは、sys.pathを調整してlib/simple_room_*.mainに委譲する12行のPythonファイルです。ラッパーは自身の実際のパスを解決するため、~/.local/bin/内のシンボリックリンクは透過的に機能します。

インストール

リポジトリルートから:

./install.sh

これにより、simple-agent-roomが~/.claude/skills/と~/.agents/skills/に配置され、3つのCLIがsimple-room-send、simple-room-monitor、simple-room-scanとして$PATHに追加されます。

手動で行う場合:

ln -s "$PWD/skills/simple-agent-room"                    ~/.claude/skills/simple-agent-room
ln -s "$PWD/skills/simple-agent-room"                    ~/.agents/skills/simple-agent-room
ln -s "$PWD/skills/simple-agent-room/bin/"*             ~/.local/bin/

依存関係

  • Python ≥ 3.10
  • pyinotify(pip install pyinotify)。モニターのみに必要です。simple-room-sendとsimple-room-scanはなくても動作します。

関連スキル