👨‍💻

AIエージェントを育てながら使って見えた5つの設計と運用の記録

に公開

※本記事の検証と構築は 2026年4月時点 の情報に基づきます。

はじめに

Claude Codeをベースに、自分専用の秘書エージェントを作り始めて10日が経ちました。Gmail・カレンダー・Slackと連携し、朝のブリーフィングや定期通知を自動化する想定で、コツコツと機能を足してきました。

動くようにはなった一方で、メンテナンス負担が想像以上に大きかったので、時系列で整理します。

このエージェントの基本設計

  • 名前は16世紀イングランドの政治家 William Cecil から拝借(エリザベス1世に長年仕えた国務長官)
  • 役割:意思決定を支える参謀。「自分が決める」のではなく「最善の判断を下せるよう情報を整理する」存在
  • 行動原則:率直な進言/情報収集と整理/最終決定はユーザーに委ねる/長期的視野/セキュリティとプライバシーの番人

技術スタックは Claude Code(Claude Opus 4.7) + Obsidian Vault + MCP サーバー(Gmail/Calendar/Slack)。tmux で常駐起動。

10日間の主要アップデート

1. Slack通知経路の安定化

最初は Incoming Webhook で通知していましたが、メンション通知が不安定でスマホへのプッシュ通知が発火しない事象が頻発。Bot Token + chat.postMessage API に切替えたところ、プッシュ通知が安定しました。

技術的な背景:Slackでは Incoming Webhook 経由の投稿は「外部インテグレーションからの発言」として扱われ、モバイルプッシュ通知の経路に乗りにくい仕様があります。一方 Bot Token + chat.postMessage は「Slack App による正規の発言」として扱われるため、通常のメンション通知パイプラインに乗り、プッシュ通知が安定して発火します。

学び:Webhookは便利だが、本格的な通知用途には Bot Token のほうが信頼性が高い

2. 定期実行アーキテクチャの試行錯誤

次に GitHub Actions(cron)で動かす案を試行。しかし「自分のデータがクラウド経由になる」ことへの違和感と管理コストから方針転換。Claude Code のセッション内 /loop 機能に移行しました。アイドル時のみ発火するため会話を中断しません。

学び:常駐マシン前提なら、ローカル実行で十分。ただし「セッション依存性」は設計上のリスクとして明記する必要あり

3. MCP接続戦略の見直し(最大の躓き)

Google系(Gmail/Calendar)はローカルMCPサーバーを使う設計でした。しかしある朝、該当ツールが一切ロードされない事象が発生。

調査の結果、MCPプロトコル標準の notifications/initialized をエラー応答する実装不具合が判明。claude mcp list では「Connected」と表示されますが、実際にはツールの初期化が失敗していました。Claude AI のMCPコネクタに移行することで解決。

学び:「接続OK」表示と「実際に使える」は別。stdioで直接プロトコル通信して挙動を確認する診断手段を持っておくと早い

4. 起動時自動化(SessionStart hook)

「おはよう」と話しかけても朝のブリーフィングが起動しないことがありました。原因は CLAUDE.md に「運用手順ファイルを参照する」とだけ記載しており、「おはよう → 運用手順を実行」という明示的なトリガー指示が書かれておらず、参照タイミングが曖昧だったから。

2つで対処しました:CLAUDE.md にトリガーワード動作を明記し、SessionStart hook で運用手順ファイルを起動時に自動注入。これでトリガー漏れがほぼゼロに。

学び:自動化したい挙動は、文書化しただけでは動かない。トリガー条件を明示するか、hookで強制するかが必要

5. permissions の棚卸し

開発を進めるうち、settings.local.jsonpermissions.allow が 80 件まで膨らみました。承認プロンプトを減らすため都度追加した結果、可読性が極端に悪化。

棚卸しを実施:1回限りの具体コマンド削除/個別の Bash(curl ...) をワイルドカード化/用途別グルーピング。結果、80 → 59 件、可読性は大幅向上しました。

before / after のイメージ(値はダミー):

// Before:個別パターンが何十件も並ぶ状態
{
  "permissions": {
    "allow": [
      "Bash(curl -X POST -H 'Authorization: Bearer xoxb-XXXX...' --data '{\"channel\":\"C0XXXXXXX\",\"text\":\"test\"}' https://slack.com/api/chat.postMessage)",
      "Bash(curl -X POST -H 'Authorization: Bearer xoxb-XXXX...' --data '{\"channel\":\"C0XXXXXXX\",\"text\":\"新着なし\"}' https://slack.com/api/chat.postMessage)",
      "Bash(curl -X GET -H 'Authorization: Bearer xoxb-XXXX...' https://slack.com/api/chat.getPermalink)",
      "Bash(python3 -c \"import sys,json; print(json.load(sys.stdin)['choices'][0]['message']['content'])\")",
      "Bash(python3 -c \"import sys,json; c=json.load(sys.stdin)['choices'][0]['message']; print(c.get('content',''))\")"
      // ...同様のパターンが数十件
    ]
  }
}
// After:用途別にワイルドカードで集約
{
  "permissions": {
    "allow": [
      "Bash(curl:*)",
      "Bash(python3 -c ':*)",
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push:*)",
      "Bash(gh auth:*)",
      "Bash(gh repo:*)"
    ]
  }
}

※ Bot Token や実際のチャンネルIDはダミー文字列に置き換えています。実運用では sandbox.network.allowedDomains で通信先を限定するなど、ワイルドカード化とサンドボックス制約を組み合わせて使うのが安全です。

学び:「都度足す」運用は必ず肥大化する。月1で棚卸しの時間を確保するか、整理ルールをあらかじめ持つ

最大の学び:動かしてからが本番

10日間ふりかえると、メンテナンス負担の根本は 「機能数」ではなく「責務の複合と二重管理」 でした。

  • エージェント定義ファイルが2箇所にコピーされていて同期義務がある(バックアップ目的)
  • 1つの運用手順ファイルに10種類の責務が詰まっている
  • 優先事項リストが3ファイルに複製されている

新機能を1つ足すと、関連ファイルが2〜3箇所更新されるのが当たり前になり、それが翌週の自分への借金になっていきます。「便利そうだから足す」では確実にメンテ地獄に

「足さない判断基準」を持つ

今、自分に課しているルール:

基準 通す例
合理化(既存機能を簡素化) 自動アーカイブで手動運用を減らす
安全性向上 バックアップ、ヘルスチェック
日常的価値(週3回以上使う) Gmail定期チェック、カレンダー集約

「あれば便利」レベルは却下、「なくて困る」レベルだけ採用。

次に取り組むこと

  • ファイル構造の再設計(責務別ディレクトリ化を検討中)
  • セッション依存性の軽減策
  • スキルとプロンプトの役割分担の明文化

機能追加よりも、今ある機能を整理して持続可能な状態にする ほうが優先度が高い段階だと感じています。

おわりに

エージェント開発は「動く」までは早く、「持続可能に運用する」までが長い、と痛感しています。便利な拡張やプラグインの誘惑は強いですが、自分の手に負える範囲を見極める設計判断こそが、長く使えるAIエージェントの核なのかもしれません。

Discussion