社内のAI活用の取り組みとして、Backlogに投稿されるのをトリガーに、AIが内容を読んでソースコードを修正し、結果をTeamsに報告してくれる仕組みを作っています。
何ができるのか
ある案件で、お客様からの改修要望や不具合報告をBacklogで受けています。
以前はこうでした。
- Backlogの通知に気づく
- 内容を読んで管理表に起票する
- コードを直す
- テストを回す
- 管理表を更新して、状況を報告する
これが今はこうなっています。
- お客様がBacklogに投稿する
- (ここが全部自動) AIが投稿を読んで管理表に起票し、コードを修正し、テストを回し、管理表を更新する
- Teamsに「何をやったか」「自分が次に何をすべきか」が通知で届く
- 通知を見て、デプロイや回答の承認だけ人間がやる。Teamsのスレッドで返信すれば、AIと会話しながら追加の修正も頼める
人間の仕事が「手を動かす」から「判断する」に変わった、というのが一番大きな変化です。
全体構成
構成はシンプルで、Dockerコンテナ 1 つが受け口と実行を兼ねています。
お客様│ 課題・コメントを投稿(添付ファイルも)▼Backlog ──Webhook──▶ 受信サーバー(Node.js)│ 添付ファイルをAPIで取得│ ジョブをキューに積んで直列実行▼Claude Code(ヘッドレス実行)│ ・課題を分解して管理表(Excel)に起票│ ・ソースコードを修正│ ・テストを実行してグリーンまで確認│ ・管理表を更新▼Teams通知(Power Automate経由)▲└── スレッドに返信すると、同じ文脈でAIが回答・追加修正(会話ループ)
ポイントをいくつか。
Claude Codeは「ヘッドレス」で動かしています
Claude Codeというとターミナルで対話しながら使うイメージですが、claude -p "指示" の形で非対話実行ができます。
Webhookを受けたサーバーがこのコマンドを叩くだけで、コードの調査から修正、テスト実行までAIが自律的に進めてくれます。
GitHubもPull Request(PR)も使っていません。
よくあるAIコーディング連携はPR作成がゴールですが、この案件はサーバー上の作業コピーを直接修正する構成にしました。
何をどこまで自動でやらせるかは、実行時にAIへ許可するツールの範囲で制御しています。
添付ファイルも読みます。
Backlogの投稿にはスクリーンショットやExcelがよく付いてきます。
Webhook自体には添付の中身が入ってこないので、受信サーバーがBacklog APIでダウンロードしてAIに渡しています。画像やPDFはClaude Codeがそのまま読めるので、「スクショの画面のこの表示がおかしい」という報告にも対応できます。
AIが触れるのは、マウントした案件フォルダの中だけです。
管理表(Excel)もソースコードの作業コピーも、社内サーバー上のコンテナにマウントした案件専用フォルダに置いています。
AIの読み書きはこの範囲に閉じており、ここが「内と外」の境界です。
クラウドや外部サービスに影響する操作は自動では行いません。
作り方(ざっくり)
細かい実装は今回は省くとして、それぞれの設定の勘所だけ紹介します。
Backlog側:Webhookの登録だけ
プロジェクト設定 → インテグレーション → Webhook で、受信サーバーのURLを登録します。
通知イベントは「課題の追加・更新・コメント」に絞っています。
BacklogのWebhookには署名検証の仕組みがないので、URLに自前のトークンをクエリパラメータで付けて(https://…/webhook?token=ランダムな長い文字列)、サーバー側で照合するのが実質的な認証になります。
もう1つ、添付ファイル取得用にAPIキーを発行しておきます。Webhookのペイロードには添付の中身が入ってこないため、受信後にAPIで取りに行く必要があるからです。
APIキーは自動連携専用のBacklogユーザーで発行しておくと、AIの投稿と人間の投稿を区別できて後々便利です。
Node.js側:Webhookを受けてclaudeコマンドを叩くだけ
受信サーバーの本体は、実はとても素朴です。エンドポイントは実質1本で、やることは「トークン照合 → すぐ200を返す → ジョブをキューに積む」だけ。AIの実行は数十分かかることがあるので、Webhookの応答とは切り離して非同期で処理します。
キューから取り出したジョブは、child_processでClaude Codeを起動します。
const { execFile } = require('node:child_process');execFile('claude', ['-p', prompt, // 課題の内容を含む指示文'--output-format', 'json', // 結果とセッションIDをJSONで受け取る'--allowedTools', ALLOWED_TOOLS, // AIに許可する操作のリスト], { cwd: WORKSPACE }, (err, stdout) => {const result = JSON.parse(stdout);// result.session_id を課題キーに紐付けて保存しておく});
ポイントは--output-format jsonで受け取れるセッションIDです。
このセッションIDと課題キー、通知メッセージを受信サーバーが課題ごとに作る記録ファイル(JSON)にセットで保存しています。
スレッドの返信イベントには親メッセージのセッションIDが含まれるので、それをキーにこの記録を検索して「どの課題のセッションか」を特定し、続きから再開します。
あとは、ジョブを直列で処理すること(同じリポジトリや管理表を同時に触らせない)と、サーバーが社内にある場合の公開経路(うちはCloudflare Tunnelを使っています)くらいで、特別なことはしていません。
なお実運用では、セッション情報の永続化、非対話実行時の権限設計、タイムアウトやエラー時のリトライ、--resume時もオプションは毎回指定が必要な点、などにも考慮が必要です。
Teams側:Power Automateのフローを2本
Teams通知はPower Automateを経由しています。フローは2本だけです。
1本目(通知用):「HTTP要求の受信時」トリガーのフローを作り、発行されたURLをサーバー側に設定します。サーバーは{"text": "通知本文"}をPOSTするだけで、フローが受け取った本文をチャネルに投稿します。スキーマ定義も凝った整形も不要で、最小構成ならアクション2つで動きます。
2本目(返信用):「チャネルに新しい返信が追加されたとき」トリガーのフローで、返信の本文と投稿者をサーバーの返信用エンドポイントへPOSTします。
これが全体構成の図に描いた会話ループの正体で、サーバー側は受け取った本文を--resume付きでClaude Codeに渡しているだけです。
投稿者を渡しているのは、AI自身の投稿への反応を弾いて無限ループを防ぐためです。
Bot Frameworkでちゃんとしたボットを作る方法もありますが、Azure Bot登録などの初期コストがかなり重いので、「まず動かす」ならPower Automate 2本がおすすめです。
なお1本目の「HTTP要求の受信時」トリガーはプレミアムコネクタ扱いのため、お使いのライセンスによっては追加コストが発生する点だけご確認ください。
通知の設計
作ってみて一番調整が必要だったのは、実はAIまわりではなくTeams通知の文面でした。
最初は「何を修正したか」の報告を送っていたのですが、報告として綺麗でも、受け取った自分が次に何をすればいいのか分からないんですね。対応済みという通知が来ても、それがデプロイ待ちなのか、見ているだけでいいのか、通知からは判断できません。結局管理表を見に行くことになって、自動化した意味が半減していました。
そこで通知を「やったこと」「あなたの対応」「ボール(次のアクションが誰にあるか)」の3点セットに変えました。
【No.80/対応済】○○取り込み処理の判定条件の修正
やったこと:条件に該当するデータを正しいステータスで登録するよう修正し、自動テストまで確認済み
あなたの対応:★確認環境へのデプロイをお願いします
現在のボール:自分
「あなたの対応:なし(報告のみ)」も明記するのがコツで、書いていないだけなのか本当に何もないのかが区別できないと、結局確認しに行くことになります。AIの自動化は「AIが何をしたか」より「人間が何をすべきかが一目で分かるか」で使い勝手が決まる、というのが運用してみての実感です。
安全面の考え方
お客様の投稿文や添付ファイルがそのままAIへの指示になる構成なので、安全面は多層で守っています。
- AIに許可する操作を明示的なリストで制限(使えるコマンドを絞る)
- APIキーなどの秘密情報はAIの実行環境に渡さない
- 実行はコンテナ内に隔離し、対象案件の作業コピーだけを開放
- 作業コピー内の設定ファイル(CLAUDE.mdやフック類)をAIが自動で読み込む挙動も踏まえ、読み込ませる設定の範囲を管理する
- Backlogへの書き込みなど外部に影響する操作は自動では行わない
このあたりは別記事で詳しく書く予定です。
運用してみて
数週間の運用で30件超の投稿を処理し、起票からコード修正・テスト・報告までを自動で完走できるケースが着実に増えています。時間切れ対策(1回の実行時間に上限があるため、作業を分割して積む仕組み)や、プロンプトの書き方(禁止事項を具体的に書く、迷ったときの判断基準を全部書く)など、運用で得た知見も追って記事にしていきます。
「Backlogに書くだけでAIが直してくれる」は、やってみると思った以上に日々の景色が変わります。同じような受託開発の体制で回している方の参考になれば嬉しいです。

