RPi5上でAIエージェント(OpenClaw + Claude)を動かして、メールやMastodonの返信を自動生成させているのだが、「AIが勝手に送信する」のはさすがに怖い。というわけで「返信案を作る → Discordに通知 → 人間がOKしたら送信」という流れを整備した。

以前の構成(自動返信)

Gmailの未読メールをAIが読んで、返信文を考えて、そのまま送信する、という完全自動だった。5分ごとにcronが走っていた。 実際のところ、しばらく使ってみると「まあ大丈夫かな」という場面が多かったのだが、やはり何か間違えたときのリスクが気になる。

新しい構成(Human in the Loop)

[cron 30分ごと]
  ↓
未読メール/Mastodon新着をチェック
  ↓
AIが返信案を作成
  ↓
承認待ちファイルに保存(IDを発行)
  ↓
Discordに通知
  「📧 返信案があります [ID: a1b2c3d4]
   From: ○○さん
   件名: ○○について
   ---
   (返信文)
   ---
   → 送信OKなら「メール送信 a1b2c3d4」と言ってください」
  ↓
自分がDiscordで「メール送信 a1b2c3d4」と返信
  ↓
AIが実際に送信
Mastodonも同様で、返信案をDiscordに出してもらって、内容を確認してからOKを出す。

実装

承認待ちの管理は pending_approvals.json というファイルで。
[
  {
    "id": "a1b2c3d4",
    "type": "email",
    "draft": "お世話になっております...",
    "meta": {
      "thread_id": "xxxxx",
      "subject": "○○について",
      "from": "someone@example.com"
    },
    "created_at": "2026-03-12T22:00:00"
  }
]
pending_manager.py というスクリプトでIDの追加・一覧・削除ができる。cronジョブはこれを使って案を追加するだけで、実際の送信はDiscordでの指示を受けた後にメインのClaudeが実行する。

感想

「AIが勝手に動く」より「AIが案を出して人間が判断する」ほうが、精神的にも楽だし、実際の精度も上がる気がする。間違いを事前に止められるし、AIの文章のクセも学習できる。 完全自動化は夢だが、今のところはこの半自動スタイルがちょうどいい。