はじめに
こんにちは。IT本部 AI・データ戦略統括部 データ基盤部 AIジャーニー推進グループで、エンジニアをしている小野寺です。
私たちのチームは、ふだんの開発に AI 駆動開発をどんどん組み込もうとしています。スクラムのスプリントに Devin を「もう一人のメンバー」として組み入れ、外部ツールの利用申請への記入といった定型作業を少しずつ AI に任せてきました。今回紹介するのは、その申請エージェントのプロンプトを AI 自身に毎週改善させる取り組みです。
申請エージェントとは
私たちは、ツールの利用申請を代行する AI エージェントを社内で運用しています。「Claude を使いたい」「Linear を使いたい」「Cursor を使いたい」といった外部ツールを業務で使うには、社内の申請フォームに記入して提出し、上長承認・法務確認・CERT 確認などの審査を経る必要があります。こうした申請には kintone(サイボウズ)を使っていて、ユーザーと対話しながらエージェントが記入し、申請の下書きを作成します。
申請によっては入力すべき項目が多く、フィールド間の依存関係(あるフィールドの値によって別のフィールドの必須状態が変わる、など)も入り組んでいます。人が埋めるだけでもそれなりに骨が折れる作業です。
申請は、承認者から修正依頼つきで戻ってくる「差し戻し」になることがあります。返ってくるコメントには、たとえば「この項目は『はじめて利用するツール』を選んでください。過去の申請を見ても確認が済んでいないようです」といった、具体的な指摘が書かれています。
差し戻しのたびに、プロンプトを手で直していた
エージェントの振る舞いはプロンプトで決まります。だから差し戻しが来たら、私はその指摘を読んで、プロンプトの該当箇所に「こういうときはこう選ぶ」というルールを書き足します。するとそのパターンは直る。けれどしばらくすると、今度は少し違うパターンでまた差し戻される。また書き足す。この手直しが、ずっと続いていました。
定型作業はできるだけAIに寄せていきたい、というのがチームの方針です。この「差し戻しを読んでプロンプトを直す」作業は、やっていることがかなり定型的で、まさにうってつけの候補でした。そこで、この手直し自体を AI に毎週やってもらうことにしました。
なぜDevinなのか
正直なところ、定期的に回すだけなら GitHub Actions のスケジュール実行でも Google Cloud Scheduler でも、やり方はいくらでもあります。それでも Devin に任せたのには、2つ理由があります。
ひとつは、Devin がリポジトリを読んでコードを理解し、どこを直すべきかを自ら判断して動けることです。スクリプトで自動化するには変更手順を事前に書き切る必要がありますが、Devin は「差し戻しコメントをもとにプロンプトの適切な箇所を改善しろ」という曖昧な指示でも、リポジトリを読んで自分で対処します。週次で無人実行したいこの用途には、この判断力が合っていました。
もうひとつは、DeNAが自律型AIソフトウェアエンジニアの「Devin」を全社導入していて、2,000人以上が使える状態になっていることです( 参考: DeNAのDevin全社導入 )。私たちのチームでも、Devinをスプリントの「もう一人のメンバー」として数え、積極的に使い倒していく方針でした。せっかく全社で環境が整っているなら、こういう定型作業こそ任せてみたい、というのが出発点です。
仕組みとしては、Devinの「Playbook」と「Scheduled Sessions」を組み合わせています。Playbook は、やってほしい手順をまとめた指示書で、Claude の「Skill」に相当するものです。ただ、Playbook単体では定期実行はできません。スケジュールは「Scheduled Sessions」という別の機能が担っていて、0 9 * * 1 のようなcron式でタイミングを指定します。ここにPlaybookを紐づけておくと、毎週月曜の朝、同じ手順でDevinがセッションを立ち上げ、調査からPull Request作成までをひととおりやってくれます。実行してみて手順に直したいところが出てきたら、Playbookのほうを書き足して翌週の精度を上げる、という育て方もできます。
毎週月曜、Devinがやること
毎週月曜の朝9時、Devinが次のことを自動でやります。
- エージェントとの会話ログや、申請についた差し戻しコメントから、つまずいている箇所を集める
- くり返し出ているものを数件に絞る
- プロンプトの該当箇所を直す
- テストを通す
- Draft の Pull Request を出す
私がやるのは、作成された Pull Request をレビューしてマージするだけです。
差し戻しは毎週新しく生まれるので、この5ステップは一度で終わらず、毎週くり返します。
改善のネタは現場に転がっている
ひとつは、申請に付いた差し戻しコメントです。承認者が「ここはこう直してください」と書いてくれるので、これはほとんど改善の指示そのものです。もうひとつは、ユーザーとエージェントの会話ログです。申請の下書きを準備するやり取りの中で、エージェントが的外れな入力をしたとき、ユーザーは「いや、そうじゃなくて」「そこは違う」と訂正します。その訂正には、プロンプトに足りていない判断基準が表れています。会話のやり取りは OpenTelemetry 経由で Langfuse(LLM 向けの観測基盤)にトレースとして記録されています。そのトレースからユーザーの訂正発話を引っ張ってきます。
これらを拾うときは、まずキーワードで当たりをつけます。会話ログなら「違います」「修正して」「ではなく」「やり直し」といった訂正の言い回し、エラーログなら特定のエラーコードを正規表現で拾う、という具合です。ただ、こうしたキーワードは文脈違いも一緒に拾ってしまいます。たとえば「Xではなく、Yを選んでください」という、エージェントへの指示文そのものに「ではなく」が入っていたりする。そこで、同じ問題が一定回数以上くり返し出てきたものだけを採用するようにしています。一度きりの言葉に振り回されないための、簡単だけど効くフィルターです。
つまずきの多くは「書かれていなかった基準」
差し戻しや会話ログのつまずきを追っていくと、「エージェントが間違った判断をした」というより「そもそも判断基準がプロンプトに書かれていなかった」ケースが、運用開始から1ヶ月ほどの時点ではほとんどでした。
プロンプトは数百行ある長い指示文で、「各フィールドの入力ルール」「申請種別ごとの分岐条件」「ユーザーへの確認が必要なケース」などのセクションに分かれています。Devinが直すのはその一部だけです。たとえば、ある確認項目でこんな追記が入りました(社内固有の表現は一般化しています)。
### 法務確認の選択ルール
- ツールの登録情報に「法務確認は任意」と記載されていても、
条件付きの注記がある場合はその条件を申請者に確認してから選ぶ
- 「法務確認は不要(上記のいずれにも該当しない)」は、
登録情報に法務確認に関する記述がある限り選択しない
足したのは数行です。エージェントを賢くしたわけではなく、人間なら暗黙にやっている判断を、言葉にして渡しただけ。多くのつまずきは、この「言語化されていなかった基準」を埋めることで起きにくくなりました。
3週かけて直る:一度では直りきらない
この仕組みは毎週月曜に動いていて、ツール利用申請のプロンプト改善は、これまで毎回マージしてきました。6月の4週(6/1・6/8・6/15・6/22)でそれぞれ1本ずつ、計4本です。
やってみると、1本の修正で完結したケースはほぼありませんでした。法務確認の選択ミスを例にとると、6月1日の週に修正を入れたあと、翌週また別のパターンで差し戻しが来ました。6/8・6/15と続き、同じ箇所に3週かけて修正が入りました。6/22 の週でも、法務確認まわりの選択ミスが上位テーマとして再び出てきています。実際に申請が行われてはじめて出てくるパターンがあって、最初から全部書ききることはなかなか難しいようです。
変更量はそれぞれ数行から十数行と小さく、いきなり大きく書き換わることはありません。ある週には2つの問題をまとめて直したこともあります。新しい差し戻しが生まれ続けるかぎり改善のネタは尽きず、使われるほど直っていきます。
人間が握っておくところ
AIにコードを直させてPull Requestまで自動で出させる以上、放っておけば際限なく書き換えられてしまいます。そこで、変更できる範囲をいくつか縛っています。
- 直していいのはプロンプトの本文だけ。エージェントのロジックには触らせない
- 1回の変更行数に上限を設ける
- テストが全部通らなければ Pull Request は作らせない
- 作るのは必ず Draft。自動マージはしない
- 最後は人間がレビューしてマージする
チームとしても、認証まわりやインフラ設定など「AIが触らない領域」はあらかじめ決めていて、そこはそもそも対象外にしています。
AIには候補を作るところまでをやってもらい、取り込むかどうかは人間が握る。この役割分担にしてから、安心して任せられるようになりました。
同じ仕組みを作るには
ここからは、同じ仕組みを試してみたい方に向けて、組み立ての勘所を書いておきます。
Devin の Playbook は、リポジトリの中に Markdown ファイルとして置けます。やってほしい手順を文章でそのまま書き下しておくと、Devin はそれを読んで動きます。私たちの Playbook(手順書)は、だいたいこんな形です(社内固有の表現は一般化しています。Step 1・4 は環境準備やブランチ作成のため省略しています)。
## 手順
### Step 2. 差し戻し理由を集める
過去一定期間の申請レコードから差し戻しコメントを集め、ファイルに保存する。
### Step 2.5. 会話ログを分析する
Langfuse のトレースから、ユーザーの訂正発話やエラーを抽出する。
取得できないときは差し戻しコメントだけで次に進む。
### Step 3. テーマ別に集計する
差し戻しコメントと会話ログを突合し、同じ問題に両方からヒットがあれば件数を合算する。
採用するのはヒット件数が min_theme_count 以上のテーマ、上位 max_themes 件まで。
### Step 5. プロンプトを編集する
特定したセクションだけを編集する。base_prompt(プロンプト本文)以外には触らない。
変更後に git diff で行数を確認し、max_edit_lines を超えたら最重要 1 テーマに絞って書き直す。
### Step 6. 検証する
構文チェックと関連テストを実行する。
テストが失敗したら変更を縮小する。テストの安易な書き換えは禁止。
## ガードレール(必読)
- base_prompt 限定: フェーズ判定などのロジック関数には触らない
- max_edit_lines 厳守: 超える場合は最重要 1 テーマに絞る
- テスト書き換え禁止: 既存テストを通すためにプロンプト側を調整する
- draft 必須: PR は必ず draft で作る
- マージ前デプロイ禁止: PR がマージされる前にデプロイを試みない
手順だけでなく、歯止めも同じファイルに文章として書き込めます。「テスト書き換え禁止」「draft 必須」といったルールが、外側の仕組みではなく地の文として並んでいるだけです。文章を読んで自律的に判断する Devin だからこそ、これで効きます。手順を変えたくなったらこのファイルを直すだけで、翌週の動きが変わります。
出力される Draft PR の体裁も、テンプレートとして Playbook に書いておけます。集計サマリ・採用テーマ・検証結果が決まった形で並ぶので、レビューのとき何を見ればいいかが毎回同じです。
## Summary
直近の差し戻しコメントと Langfuse トレース分析をもとに、
上位数件のテーマに対応するプロンプトのセクションを改善しました(draft)。
## 集計サマリ
- 対象期間: <from> 〜 <to>
- 差し戻しレコード数: <n>
- Langfuse トレース数: <n>(ユーザー修正: <n>, エラー: <n>)
- 採用テーマ(件数順): ...
## 検証
- [x] 構文チェック通過
- [x] テスト全通過
- [ ] dev 反映後の動作確認(マージ後に人間が実行)
## デプロイ注意
この PR がマージされても自動デプロイはされません。マージ後に人間が反映します。
Langfuse のトレースには、ユーザーの発話とエージェントの応答が observation という単位で残っています。訂正の言い回しを正規表現で拾うだけなので、LLM は使いません。観測基盤の作りによって読み出し方は変わるので、まずは手元のログをどう取り出せるかを確かめるのがいいと思います。
おわりに
差し戻しコメントや会話ログを読み、どこを直すか考えてプロンプトに反映する。この一連の「プロンプト改善」を、これまでは毎回自分の手でやっていました。今回作ったのは、その作業そのものをAIに渡し、毎週回し続ける仕組みです。完全自動にはせず、レビューとマージという最後の判断だけ人間に残しているのがポイントです。
この仕組みは最初、1種類の申請のために作りました。kintone からフォーム定義を実行時に取得する設計にしたことで、対応リストに登録するだけで申請種別を増やせます。申請が増えるほど差し戻しコメントや会話ログも増え、同じ改善ループがそのまま広がっていきます。
私たちのチームでは、こうした定型作業を1つずつAIに任せていく取り組みを続けています。「エージェントは作ったけれど、その後の手入れが大変」という方の参考になればうれしいです。
最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。