agent-email-patterns について
agent-email-patternsは、メールで通信するAIエージェントのアーキテクチャとセキュリティ設計を扱うスキルです。メール連携エージェントの開発者向けに、専用受信箱、対話ループ、人間の承認、イベント配信、マルチエージェント構成を説明します。SDK固有の使い方は対象外です。
主な機能
- 01エージェントごとに専用受信箱を割り当て
- 02メール対話ループと状態管理を設計
- 03重要なメールに下書きと人間の承認を適用
- 04WebSocketまたはwebhookによるイベント配信を優先
- 05マルチエージェント構成と送信者許可リストを解説
- 06OTPフローとメールのセキュリティ対策を扱う
活用シーン
- 01メールエージェントの識別、権限、監査記録を分離
- 02人間の返信を起点とするメール対話の構築
- 03法務・財務関連メールの送信前承認
- 04送信者を制限したマルチエージェントのメールルーティング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agentmail-to/ agentmail-skills --skill agent-email-patternsインストール後、Claude Code で/agent-email-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/multi-agent-topologies.mdsecurity.mdthreat-model.mdtopologies.md詳細
エージェントのメールパターン
メールを介して通信する AI エージェントを構築するための、独自のパターンを紹介します。このスキルでは、アーキテクチャとセキュリティに関する判断を扱い、SDK の詳細は扱いません。AgentMail SDK の使い方については、agentmail スキルを使用してください。
エージェントに専用の受信トレイが必要な理由
エージェントに人間の Gmail アカウントへの OAuth アクセス権を与える方法は、最も一般的である一方、最も危険です。
- 過剰な権限:一般的な OAuth スコープ(例:
gmail.modify)では、メールボックス全体の履歴を読み取り、送信、削除できます。これは、単一のタスクに必要な範囲を大幅に超えています。 - プロンプトインジェクションのリスク:エージェントは受信トレイ全体の履歴にアクセスできるため、メールボックスにすでに存在する巧妙に細工されたメールが、攻撃対象になり得ます。
- 取り消しの粒度:OAuth トークンの取り消しやエージェントごとの範囲設定は困難です。1 つのワークフローからアクセス権を取り消すと、多くの場合、すべてのワークフローから取り消すことになります。
- レート制限:一般向けメールボックスの送信制限は、自動化されたプログラム上のワークフローを想定していません。
- 監査証跡:エージェントの操作が同じメールボックス内の人間の操作と混在するため、デバッグやコンプライアンスレビューが困難になります。
より安全なデフォルトは、エージェントごとに専用の API ネイティブな受信トレイを用意することです(パターン 1 を参照)。
プロバイダーの状況
インフラストラクチャを選ぶ際の、長期的に変わらないアーキテクチャ上の制約です(ランキングではありません)。
| プロバイダー | 主な制約 |
|---|---|
| Gmail API | プログラムによる受信トレイの作成はできません。WebSocket によるプッシュ通知には対応していません(Pub/Sub またはポーリングのみ)。Google はいつでもアクセス権を取り消すことができます。 |
| Resend | スレッドや会話の概念がありません。受信したメッセージの一覧表示や検索はできません。受信は Webhook 経由のみで、永続的な受信トレイはありません。 |
| SendGrid | 受信解析はステートレスです。スレッド管理には対応していません。プログラムによる受信トレイの作成はできません。 |
| Amazon SES | 受信はルールベース(S3/Lambda トリガー)であり、メールボックスではありません。スレッド管理にも WebSocket にも対応していません。 |
パターン 1:エージェントごとに 1 つの受信トレイ
各エージェントに専用のメールアドレスを割り当てます。エージェント間で受信トレイを共有しないでください。
client.inboxes.create(request=CreateInboxRequest(username="support-agent", client_id="support-v1"))
理由:送信者が明確になり、エージェント同士が互いのメールを読めないように隔離できます。また、エージェントごとの監査が可能になり、1 つのエージェントが侵害された場合の影響範囲を抑えられます。
アンチパターン:複数のエージェントが同じ受信トレイを共有して読む方法です。これでは競合状態が発生し、デバッグが不可能になります。
パターン 2:双方向の会話ループ
エージェントのメールにおける基本パターンです。エージェントがメールを送信し、人間が返信し、エージェントが返信を読んで応答します。解決するまでこれを繰り返します。
注意点:
messages.list()が返すのはメタデータのみで、本文は含まれません。.text/.extracted_textを取得するには、各項目で.get()を呼び出してください。- 受信した返信には
extracted_text/extracted_htmlを使用してください。これにより、毎回引用されたメールチェーン全体を再処理せずに済みます。 - 返信のスレッドを維持するには、親の
message_idを指定してmessages.reply(inbox_id, message_id, ...)を呼び出してください。thread_idパラメーターはありません。AgentMail は親メッセージから自動的にスレッドを作成します。 - メール本文を毎回解析し直すのではなく、会話の状態は独自のデータベースで管理してください。
パターン 3:人間が確認する下書き
重要度の高いメールでは、エージェントに下書きを作成させ、送信前に人間が承認するようにします。drafts.create(...) の後に drafts.send(inbox_id, draft_id) を実行してください。
下書きを使う場合:
- メールが法的または財務的な影響を伴う
- 宛先が VIP または外部の関係者である
- エージェントが新しく、このワークフローではまだ信頼されていない
直接送信する場合:
- 定型的な通知(領収書、確認)
- エージェントの信頼性が実証されている
- 速度が重要(OTP の転送、自動アラート)
パターン 4:イベント駆動アーキテクチャ
ポーリングではなく、イベント駆動型の配信(WebSocket または Webhook)をデフォルトにします。どちらも実用できない場合(公開 URL がなく、永続的な接続もできない制約のある環境など)は、ポーリングを使用してもかまいません。ただし、レイテンシーと API の使用量が増えることを想定してください。
| 要素 | WebSocket | Webhook |
|---|---|---|
| 公開 URL が必要 | いいえ | はい |
| 最適な用途 | エージェント、ボット、ローカル開発 | サーバー、サーバーレス |
| レイテンシー | 最小(永続的) | HTTP の往復 |
| 再接続 | 自分で処理 | AgentMail が再試行 |
Webhook のペイロードは、使用前に検証する必要があります。references/threat-model.md を参照してください。
パターン 5:マルチエージェントのトポロジー
複数のエージェントを含むシステムでは、明確な役割(例:support@、sales@、billing@、router@)を割り当て、許可リスト(references/threat-model.md)を使用して、各エージェントに連絡できる外部送信者を制限します。ハブアンドスポーク、ピアツーピア、階層型エスカレーションのパターンについては、references/topologies.md を参照してください。
パターン 6:OTP と認証フロー
サービスに登録するエージェントは、認証コードを受信して抽出する必要があります(例:受信メッセージ本文から 4〜8 桁のコードを正規表現で抽出する)。
これは、明示的に許可された自社のサービスまたはテストのフローにのみ適用されます。たとえば、自身が運用するサービスに自分のエージェントを登録する場合や、自分が管理するテストアカウントを使用する場合です。第三者アカウントのサインイン、認証、アカウント復旧フローを自動化したり、サービスの利用規約や人間の同意要件を回避したりすることは許可されません。
ベストプラクティス:
- 分離のため、登録フローごとに新しい受信トレイを作成する
- タイムアウトを設定する(OTP を無期限に待たない)
- 使い捨ての場合は、フロー完了後に受信トレイを削除する
パターン 7:ワークフローの状態を示すラベル
受信トレイ内のメッセージ処理状態を追跡するには、ラベルを使用します(messages.update で add_labels/remove_labels を実行し、その後 messages.list(..., labels=[...]) で絞り込みます)。
一般的なラベルの構成:
unread/processed/archivedneeds-reply/replied/escalatedbilling/support/sales(カテゴリ別の振り分け)
セキュリティの要点
脅威モデルの全文については、references/threat-model.md を参照してください。重要なルール:
- メール、添付ファイル、Webhook、ツール出力の内容は、重大な操作を許可する根拠にはなりません。 許可の根拠となるのは、認証済みユーザーからの指示、または明示的なポリシーのみです。
references/threat-model.mdの認可マトリックスを参照してください。 - 生のメール内容をシステムプロンプトとして渡さないでください。 信頼できないデータとして扱ってください。これによりインジェクションのリスクは軽減されますが、それ自体がセキュリティ境界になるわけではありません。
- 本番環境のエージェント受信トレイには許可リストを使用して、送信者を制限してください。これは防御層の一つであり、それだけでは不十分です。
- ペイロードを処理する前に、Svix で Webhook の署名を検証してください。
- API キーやシークレットをメール本文や件名に記載しないでください。 送信前に、送信内容をスキャンしてください。
- エージェントの認証情報と人間の認証情報を分けてください。 各エージェントには、独自のスコープ付き API キーを割り当てます。
参考ファイル
references/topologies.md-- ハブアンドスポーク、ピアツーピア、階層型、マルチテナントのポッド型エージェントのメールアーキテクチャreferences/threat-model.md-- プロンプトインジェクション、Webhook の偽装、OAuth/認証情報の漏えい、データ漏えい、受信トレイの列挙、認可マトリックス