🌱

プロンプトを育ててAIの「いい感じ」をコントロールする

概要

こんにちは、エンジニアの籏野です。

昨今AIを用いた開発が非常に盛んになってきました。
弊社でもClaude Codeによる開発支援を中心として、ChatGPT/Google Agentspace等々の導入検討・および利用推進が進んでいます。

そんなAI活用において、もっとも重要なのが人間からの指示をAIに伝えるための「プロンプト」です。
今回の記事ではAIに意図した動作をさせるためにどのようにプロンプトを育てるべきか?を自分なりに実践した内容を共有したいと思います。

お題

なんらかの開発を行った後に「PRを作成する」という作業をAIに任せていきます。
AIエージェントとしてはClaude Codeの利用を想定していますが、おそらく他のエージェントでも活かせると思います。

リポジトリについては以前私の別の記事で作成したこちらを利用します。
記事に1件コメントをいただいていたのでこちらを対応しPRを作成させていただきました。
コメントいただきありがとうございました!

スタート状態

まずは何も考えずにClaude CodeにPRを作成するように指示を出してみます。

> 本ブランチのPRを作成して
Claude Codeのチャット履歴
> 本ブランチのPRを作成して

● Bash(git status)
  ⎿  On branch 1-fix-comment                               
     Your branch is up to date with 'origin/1-fix-comment'.

     nothing to commit, working tree clean

● Bash(git log --oneline -5)
  ⎿  fc462cb いただいたコメントに対応した
     6621800 fix: 型名の修正
     3ddeeb4 fix: 勝利条件判定を修正
     … +2 lines (ctrl+o to expand)

● Bash(git diff main...HEAD)
  ⎿  diff --git a/src/bit.ts b/src/bit.ts
     index 73d141e..34770f1 100644
     --- a/src/bit.ts
     … +14 lines (ctrl+o to expand)

● Bash(git push -u origin 1-fix-comment)
  ⎿  branch '1-fix-comment' set up to track 'origin/1-fix-comment'.
     Everything up-to-date

● Bash(gh pr create --title "fix: ビット演算の型定義を改善" --body "## Summary
      - ビット論理和(Or)と論理積(And)の型定義を改善…)
  ⎿  https://github.com/taku-hatano/tic-tac-toe-type/pull/2

● PRを作成しました: https://github.com/taku-hatano/tic-tac-toe-type/pull/2

このプロンプトで作成したPRはこちらになります。
一見いい感じのPRを作ってくれていますが、チーム開発等の実際の現場観点では以下の点が気になります。

  • マージ先の判定はどうなっているのか?
  • 変更内容をきちんと見ているのか?
  • PRのフォーマットは何に従っているのか?

AIは"いい感じ"に物事を判定して処理を進めてくれますが、この"いい感じ"の定義があいまいになればなるほど出力する結果と期待値の差が大きくなることが多いです。
そこで"いい感じ"をプロンプトを育てていくことでより具体的にコントロールしていくことがAIを活用していく上では重要となってきます。

では、上記の3点についてプロンプトを育てて具体的に対応していきましょう。

マージ先の判定

私が調べた限りになりますが、「マージ先を判定する」というのはとても難しい課題のようです。
調べたことについては省略しますが、これはAIやスクリプトによる判定よりも人間の方が詳しい領域と考えましたので以下のようなプロンプトを加えます。

## 1. マージ先の判定
- $1で指定したブランチをマージ先としてください
- マージ先が指定されなかった場合はそこで処理を終了し、ユーザーにブランチを指定するように指示してください。

※ $1はClaude CodeのSlash Commandの機能の一部で、スラッシュコマンドで受け取った内容をプロンプトに埋め込むことができます。

変更内容の取得

変更内容の具体的な取得方法をプロンプトに書き加えます。
プロンプト内にgit diffのようなコマンドを直接書くのもよいのですが、経験上複数のコマンドを書いていくとClaude Codeがその指示内容を忘れてしまったり、指示した内容から派生して別のことを始める場合もあります。
そのため具体的な手順が決まっているような内容はshスクリプト等に切り出してClaude Codeに実行させるのがよいと考えています。

今回は以下のようなスクリプトをClaude Codeに作成してもらいました。
https://github.com/taku-hatano/tic-tac-toe-type/blob/main/.claude/tools/get_change.sh

スクリプトの実行結果は以下の通りです。

=== PR変更内容取得 ===
現在のブランチ: 1-fix-comment
ターゲットブランチ: main

=== 変更内容の取得 ===
マージベース: 66218002a959b9edcc147e199c28157dcf2bff1b

ブランチのコミットメッセージ:
----------------------------------------
  fc462cb - いただいたコメントに対応した
  

変更ファイル一覧と統計:
 src/bit.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

=== ファイル別変更内容 ===
差分内容(変更量2000行以下のファイル):
----------------------------------------
diff --git a/src/bit.ts b/src/bit.ts
index 73d141e..34770f1 100644
--- a/src/bit.ts
+++ b/src/bit.ts
@@ -7,10 +7,10 @@
 type Bit = 0 | 1;
 
 // ビット論理和
-type Or<L extends Bit, R extends Bit> = `${L}${R}` extends `00` ? 0 : 1;
+type Or<L extends Bit, R extends Bit> = 1 extends L | R ? 1 : 0;
 
 // ビット論理積
-type And<L extends Bit, R extends Bit> = `${L}${R}` extends `11` ? 1 : 0;
+type And<L extends Bit, R extends Bit> = 1 extends L & R ? 1 : 0;
 
 // ビット否定
 type Not<T extends Bit> = {

=== 変更内容取得完了 ===
この情報を使用してPRを作成してください

上記のスクリプトを実行するようにプロンプトを追加します。

## 2. 変更内容の取得
以下のコマンドを実行して変更内容を取得してください。

bash .claude/tools/get_change.sh "$1"

PRのフォーマットの指定

多くのプロジェクトでは .github/pull_request_template.mdを用意している場合が多いと思いますので、Claude Codeにもこのテンプレートを利用するように指示を出しましょう。
それぞれのセクションにどのような情報を記載するのかを明記しておくと、より意図に沿ったPRを作成してくれます。

## 3. PR説明文の作成
これまで取得した変更内容等の情報を元に、@.github/pull_request_template.md をテンプレートとしてPRの説明部分を考えてください。
作成時には以下の項目を埋めてください。

- 概要
  - 本ブランチでの対応の背景を簡潔にわかりやすく記載する
    - 対応のもととなった事象の概要
    - 対応方針
- どのような変更か
  - 取得した差分情報を元に具体的にどのような変更かを記載する
  - すべてのファイルを網羅する必要はなく、主たる変更内容がレビュワーに伝わりやすい内容を心がけること

PR作成とユーザーへの確認依頼

最後にghコマンドを用いたPRの作成をClaude Codeに依頼します。
PR作成後にgh pr view --webを実行すると、PR作成後にブラウザ上でそのPRが開くので確認がすぐできて便利です。
今回もPRの作成についてはスクリプト化しました。

https://github.com/taku-hatano/tic-tac-toe-type/blob/main/.claude/tools/create_pr.sh

## 4. PRの作成
以下のコマンドを実行して、PRを作成してください。

bash .claude/tools/create_pr.sh "タイトル" "説明" "ベースブランチ"

実行してみる

これまでのプロンプトをまとめてClaude Codeに実行させたときのPRが以下になります。
https://github.com/taku-hatano/tic-tac-toe-type/pull/3

まだまだ粗削りではありますが、プロジェクト固有のフォーマットに従ったPRが作成できることを確認できました。

プロンプトの全文
Claude Codeのチャット履歴
> /create-pr is running… main

✻ Thinking…

  ユーザーは /create-pr のslash commandを実行しているようです。引数として main が指定されています。

  指示された手順を確認します:
  1. マージ先の判定 - main ブランチがマージ先として指定されている
  2. 変更内容の取得 - bash .claude/tools/get_change.sh "main" を実行
  3. PR説明文の作成 - .github/pull_request_template.md をテンプレートとして使用
  4. PRの作成 - bash .claude/tools/create_pr.sh を実行

  まず TodoWrite で作業を計画し、各ステップを実行していきます。

● PR作成作業を開始します。まず作業計画を立てます。

✻ Thinking…

  まず最初のタスクから開始します。マージ先ブランチの確認をします。引数で main が指定されているので、これをマージ先として使用します。

✻ Thinking…

  マージ先ブランチが main として確認できました。次に変更内容を取得します。

● Bash(bash .claude/tools/get_change.sh "main")
  ⎿  === PR変更内容取得 ===               
     現在のブランチ: 1-fix-comment-with-ai
     ターゲットブランチ: main
     … +36 lines (ctrl+o to expand)

✻ Thinking…

  変更内容が取得できました。次にPRテンプレートを読み込みます。

✻ Thinking…

  次にPRテンプレートを読み込みます。

● Read(.github/pull_request_template.md)
  ⎿  Read 15 lines (ctrl+o to expand)

✻ Thinking…

  PRテンプレートが確認できました。これをベースにPRの説明文を作成します。変更内容から、ビット演算の型定義で、OrとAndの実装方法を改善したようです。

✻ Thinking…

  変更内容とコミットメッセージから、この PR の目的と内容を分析します:

  - コミットメッセージ: "いただいたコメントに対応した"
  - 変更内容: src/bit.ts で、ビット演算の Or と And 型定義を修正
  - 具体的な変更:
    - Or<L extends Bit, R extends Bit>: `${L}${R}` extends `00` ? 0 : 1 から 1 extends L | R ? 1 : 0 に
    - And<L extends Bit, R extends Bit>: `${L}${R}` extends `11` ? 1 : 0 から 1 extends L & R ? 1 : 0 に

  これは TypeScript のユニオン型とインターセクション型を使った、より型安全で簡潔な実装に改善されています。

  PR説明文を作成しましょう。

● PR説明文を作成しました。変更内容を分析して適切な説明を作成します。

✻ Thinking…

  最後にPRを作成します。ここで適切なタイトルと説明文を用意してcreate_pr.shを実行します。

● Bash(bash .claude/tools/create_pr.sh "fix: ビット演算型定義の実装を改善" "## :rocket: 概要…)
  ⎿  PR作成処理を開始します...
     タイトル: fix: ビット演算型定義の実装を改善
     ベースブランチ: main
     https://github.com/taku-hatano/tic-tac-toe-type/pull/3
     PRをブラウザで開きます...

✻ Thinking…

  PRが正常に作成されました。https://github.com/taku-hatano/tic-tac-toe-type/pull/3 というURLでPRが作成されています。これで全ての作業が完了しました。

✻ Thinking…

  すべてのタスクが完了しました。ユーザーにPRが正常に作成されたことを報告します。

  PRの内容:
  - タイトル: "fix: ビット演算型定義の実装を改善"
  - URL: https://github.com/taku-hatano/tic-tac-toe-type/pull/3
  - 主な変更: src/bit.tsでビット演算のOrとAnd型定義をより型安全で簡潔な実装に改善

● PRの作成が完了しました。

  作成されたPR:
  - タイトル: fix: ビット演算型定義の実装を改善
  - URL: https://github.com/taku-hatano/tic-tac-toe-type/pull/3
  - ベースブランチ: main

  変更内容:
  - src/bit.tsのビット演算型定義を改善
  - Or型とAnd型の実装をテンプレートリテラル型からTypeScriptのユニオン型・インターセクション型を活用した実装に変更

  PRが正常に作成され、ブラウザで開く準備も整いました。

まとめ

今回の記事では「PRを作成する」というタスクをAIに実行させるにあたってどのようにプロンプトを育てればよいか?を紹介しました。
私の考えるプロンプトを育てるためのポイントをまとめると以下のようになります。

  • 前提
    • AIの"いい感じ"に実行する箇所を適切にコントロールする必要がある。
  • 具体的な施策
    • これまで人間が"いい感じ"にやっていたことを言葉やワークフローで表現する。
      • 本記事のように一度AIに簡単な指示を出して実行させてみて、人間があとから指摘して形作るのも効果的だと思います。
    • 機械的に判断できるような処理はスクリプトに切り出してしまう。
      • AIには「説明部分を考える」というような柔軟な思考が必要な部分を任せましょう。

さらに弊社では今回作成したようなプロンプトをベースに、「適切なラベルを付けたい」「新規作成だけでなく更新も行いたい」等々の要望を取り入れてプロンプトやエージェントが実行するスクリプトを育てており開発効率の改善に役立てています。
今回の記事を参考に皆さんも自分たちのプロンプトを育ててみてはいかがでしょうか?

この記事を書いた人

籏野 拓
2018年新卒入社

FORCIA Tech Blog

Discussion