- AI ⚙️
エラーを生成AIに聞くプロンプトの書き方|スタックトレースの渡し方
エラーを生成AIに聞くときは、「目的・期待した動き・実際の動き・エラー全文・該当コード・環境とバージョン・再現手順・試したこと」の8項目を、区切りをつけて渡すのが基本です。 エラー文の1行だけを貼ると、AI は足りない情報を推測で補うことになり、当てはまらない一般論が返りやすくなります。
この記事では、8項目を埋めるだけの質問テンプレートと記入例、Java・Python・JavaScript・SQL のスタックトレースで残す行と省ける行の早見表、貼る前のマスク項目チェックリスト、そして原因の仮説・最小再現コード・修正後の確認手順を引き出す追い質問テンプレートを載せました。スタックトレースはすべてこの記事のために動かして出したもので、どの行が何を表すかを実物で確かめられます。
確認環境:Ubuntu 24.04、OpenJDK 21.0.10、Python 3.11.15、Node.js 22.22.2、PostgreSQL 16.15、MySQL 8.0.46。掲載したエラー出力は、この環境で実行した結果です(ファイルのパスは /home/taro/app、DB 名は appdb に置き換えています)。プロンプトの書き方は Anthropic・OpenAI・GitHub Copilot の公式ドキュメント(2026年10月5日に閲覧)の記載に沿っています。この記事はテンプレート集で、AI の回答例は載せていません。
エラーを聞くプロンプトの早見表
| 項目 | 書くこと | 書き方の例 | 省くとどうなるか |
|---|---|---|---|
| 目的 | 何を作っていて、今回なにを知りたいか | 備品予約の登録処理。原因と直し方を知りたい | 直し方ではなく用語の解説が返る |
| 期待した動き | 本来どうなるはずか | 2件とも「予約しました」と表示される | 何を正解とするかが伝わらない |
| 実際の動き | 何が起きたか。どこまで動いたか | 1件目は表示、2件目で例外が出て止まる | 途中まで動いた手がかりが使われない |
| エラー全文 | 例外の種類・メッセージ・スタックトレース | 加工せずコードブロックに貼る | 行番号と原因の例外が抜ける |
| 該当コード | トレースに出た自分のファイルの関数と呼び出し元 | 行番号がずれないよう範囲を明記 | 一般的な書き直し案だけが返る |
| 環境とバージョン | OS、言語、フレームワーク、DB、実行方法 | Ubuntu 24.04、OpenJDK 21.0.10 | 別の版向けの書き方が混ざる |
| 再現手順 | 入力データと実行コマンド | java ReservationApp、入力は2件 |
再現できず推測の回答になる |
| 試したこと | 試した内容とその結果 | 1件目だけにすると最後まで動く | 試し済みの案がもう一度返る |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「エラーを生成AIに聞くプロンプトの書き方|スタックトレースの渡し方」
8項目を埋めるだけの質問テンプレート
次のテンプレートをコピーし、各タグの中を埋めて貼ります。分からない項目は消さずに「不明」と書くと、AI がその点を質問で確かめやすくなります。
あなたは <言語・フレームワーク名> に詳しいエンジニアです。
下のエラーについて、原因の候補と確かめ方を教えてください。
<goal>
(目的)何を作っていて、今回なにを知りたいか
</goal>
<expected>
(期待した動き)本来どうなるはずか
</expected>
<actual>
(実際の動き)何が起きたか。どこまで動いたか。毎回か、ときどきか
</actual>
<error>
(エラー全文)例外の種類・メッセージ・スタックトレースを加工せずに貼る
</error>
<code>
(該当コード)ファイル名と行の範囲を書き、トレースに出た関数と呼び出し元を貼る
</code>
<environment>
(環境とバージョン)OS/言語/フレームワーク・ライブラリ/DB/実行方法
</environment>
<steps>
(再現手順)
1.
2.
3.
</steps>
<tried>
(試したこと)試した内容と、その結果
</tried>
<output_format>
1. エラー文が示している事実(どのファイルの何行目で、何が起きたか)
2. 原因の候補を可能性の高い順に3つ。それぞれ根拠にした行を引用する
3. 候補ごとの確かめ方(追加するログ、実行するコマンド)
4. 情報が足りない場合は、推測で埋めずに質問する
修正コードは、原因が1つに絞れてから出してください。
</output_format>
タグで区切っているのは、指示・状況・貼り付けた素材を取り違えにくくするためです。Anthropic の公式ガイドは、指示・文脈・入力が混ざるプロンプトでは内容ごとに XML タグで囲むことを勧めており、OpenAI の公式ガイドも Markdown の見出しや XML タグで区切りを示す書き方を紹介しています。見出し(## エラー全文 など)で区切る形に置き換えても構いません。
記入例(架空の備品予約アプリ)
後の節に載せる Java の例外を題材に、テンプレートを埋めた例です。エラー全文は「Java の例」の節の出力をそのまま貼ります。
あなたは Java に詳しいエンジニアです。
下のエラーについて、原因の候補と確かめ方を教えてください。
<goal>
備品予約アプリの登録処理を作っています。2件目の予約で止まる原因と直し方を知りたいです。
</goal>
<expected>
2件の予約がどちらも「〜を〜に予約しました」と表示される。
</expected>
<actual>
1件目(プロジェクター)は表示される。2件目(会議室A)で例外が出て止まる。毎回同じ。
</actual>
<error>
(「Java の例」の節にあるスタックトレース全文を貼る)
</error>
<code>
ReservationApp.java の 9〜20 行目(parseDate と reserve)と、23〜26 行目(入力データ)を貼る
</code>
<environment>
Ubuntu 24.04/OpenJDK 21.0.10/外部ライブラリなし/javac でコンパイルし java ReservationApp で実行
</environment>
<steps>
1. javac ReservationApp.java
2. java ReservationApp
3. 2件目の入力は item=会議室A、date=2026/10/06
</steps>
<tried>
入力を1件目だけにすると最後まで動く。2件目の item を別の名前に変えても同じ例外が出る。
</tried>
<output_format>
(テンプレートと同じ)
</output_format>
スタックトレースで残す行・省ける行の早見表(言語別)
基本はエラー全文をそのまま貼ります。 数百行になる場合や、文字数の上限に当たる場合だけ、次の表に沿って絞ります。絞ったときは「…(ライブラリ内の N 行を省略)…」と書き残し、省略したことが分かるようにします。
| 言語・DB | 必ず残す行 | 省ける行 | 読む向き |
|---|---|---|---|
| Java | 先頭の例外行/Caused by: で始まる行すべて/自分のパッケージの at 行/各 Caused by: の直後の数行 |
java.base/ やフレームワーク内部の連続した at 行/... N more |
一番下の Caused by: が元の原因 |
| Python | 最終行(例外の種類とメッセージ)/自分のファイルの File 行とその下のコード行/例外をつなぐ説明の行 |
標準ライブラリやパッケージ内(/usr/lib/python3.x/、site-packages/)の File 行 |
下が新しい呼び出し。連鎖は上のブロックが元の原因 |
| JavaScript(Node.js) | 冒頭の「ファイル:行」とコード行と ^/例外の種類とメッセージ/自分のファイルの at 行/末尾の Node.js の版 |
node:internal/ で始まる at 行 |
上の at 行が発生箇所 |
| PostgreSQL | ERROR:/LINE と ^/DETAIL:/HINT:/CONTEXT:/実行した SQL |
なし(短いので全部貼る) | LINE の ^ が位置、CONTEXT が関数内の場所 |
| MySQL | ERROR 番号 (SQLSTATE) とメッセージ全文/実行した SQL |
なし(短いので全部貼る) | near '…' がつまずいた位置 |
表計算ソフトに貼れるタブ区切り版です。
言語・DB 必ず残す行 省ける行 読む向き
Java 先頭の例外行、Caused by: の行すべて、自分のパッケージの at 行 java.base/ やフレームワーク内部の連続した at 行、... N more 一番下の Caused by: が元の原因
Python 最終行、自分のファイルの File 行とコード行、例外をつなぐ説明の行 標準ライブラリやパッケージ内の File 行 下が新しい呼び出し。連鎖は上のブロックが元の原因
JavaScript(Node.js) 冒頭のファイル:行とコード行、例外の種類とメッセージ、自分のファイルの at 行、Node.js の版 node:internal/ で始まる at 行 上の at 行が発生箇所
PostgreSQL ERROR、LINE、DETAIL、HINT、CONTEXT、実行した SQL なし LINE の ^ が位置
MySQL ERROR 番号 (SQLSTATE) とメッセージ全文、実行した SQL なし near '…' がつまずいた位置
Java の例:Caused by をすべて残す
次のコードは、2件目の日付が 2026/10/06(スラッシュ区切り)のため例外になります。
import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.List;
public class ReservationApp {
record Request(String item, String date) {}
static LocalDate parseDate(String text) {
return LocalDate.parse(text);
}
static String reserve(Request req) {
try {
LocalDate day = parseDate(req.date());
return req.item() + " を " + day + " に予約しました";
} catch (DateTimeParseException e) {
throw new IllegalStateException("予約を登録できません: item=" + req.item(), e);
}
}
public static void main(String[] args) {
List<Request> requests = List.of(
new Request("プロジェクター", "2026-10-05"),
new Request("会議室A", "2026/10/06"));
requests.stream().map(ReservationApp::reserve).forEach(System.out::println);
}
}
javac ReservationApp.java のあと java ReservationApp で実行した出力です。
プロジェクター を 2026-10-05 に予約しました
Exception in thread "main" java.lang.IllegalStateException: 予約を登録できません: item=会議室A
at ReservationApp.reserve(ReservationApp.java:18)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:722)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at ReservationApp.main(ReservationApp.java:26)
Caused by: java.time.format.DateTimeParseException: Text '2026/10/06' could not be parsed at index 4
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2108)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2010)
at java.base/java.time.LocalDate.parse(LocalDate.java:435)
at java.base/java.time.LocalDate.parse(LocalDate.java:420)
at ReservationApp.parseDate(ReservationApp.java:10)
at ReservationApp.reserve(ReservationApp.java:15)
... 9 more
先頭の例外(IllegalStateException)は自分で包み直したもので、元の原因は下の Caused by: の行にあります。先頭の数行だけを貼ると「予約を登録できません」しか伝わらず、日付の形式という手がかりが届きません。... 9 more は、上のトレースの末尾9行と同じ呼び出しが続くことを表す省略表示です。
絞る場合は次の形にします。自分のクラス(ReservationApp)の行と Caused by: の行を残しています。
Exception in thread "main" java.lang.IllegalStateException: 予約を登録できません: item=会議室A
at ReservationApp.reserve(ReservationApp.java:18)
…(java.base/java.util.stream の 8 行を省略)…
at ReservationApp.main(ReservationApp.java:26)
Caused by: java.time.format.DateTimeParseException: Text '2026/10/06' could not be parsed at index 4
…(java.base/java.time の 2 行を省略)…
at java.base/java.time.LocalDate.parse(LocalDate.java:435)
at java.base/java.time.LocalDate.parse(LocalDate.java:420)
at ReservationApp.parseDate(ReservationApp.java:10)
at ReservationApp.reserve(ReservationApp.java:15)
自分のコードから最初に呼んだライブラリのメソッド(ここでは LocalDate.parse)の行は残すと、どの API に何を渡したかが伝わります。
Python の例:最終行と、連鎖の上のブロックを残す
設定の文字列を JSON として読む処理です。2回目の呼び出しは、キーが単一引用符で囲まれているため例外になります。
import json
def load_settings(text):
return json.loads(text)
def max_days(text):
try:
settings = load_settings(text)
except json.JSONDecodeError as e:
raise RuntimeError("設定を読み込めません") from e
return settings["max_days"]
if __name__ == "__main__":
print(max_days('{"max_days": 14}'))
print(max_days("{'max_days': 14}"))
python3 reserve.py の出力です。
14
Traceback (most recent call last):
File "/home/taro/app/reserve.py", line 10, in max_days
settings = load_settings(text)
^^^^^^^^^^^^^^^^^^^
File "/home/taro/app/reserve.py", line 5, in load_settings
return json.loads(text)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/json/decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
^^^^^^^^^^^^^^^^^^^^^^
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/taro/app/reserve.py", line 18, in <module>
print(max_days("{'max_days': 14}"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/taro/app/reserve.py", line 12, in max_days
raise RuntimeError("設定を読み込めません") from e
RuntimeError: 設定を読み込めません
Python は Java と並びが逆で、各ブロックの最終行が例外の種類とメッセージ、その上へ向かって呼び出し元が並びます。例外が連鎖しているときは The above exception was the direct cause of the following exception: の行で2つのブロックに分かれ、上のブロックが元の原因(ここでは JSONDecodeError)です。最後の RuntimeError だけを貼ると、JSON の書き方という手がかりが抜けます。
省けるのは /usr/lib/python3.11/json/ の3組(File 行・コード行・^ の行で計9行)です。ただし json.decoder.JSONDecodeError: ... の行は必ず残します。
JavaScript(Node.js)の例:冒頭のコード行と ^ を残す
2件目のデータに user が無いため例外になります。
const reservations = [
{ id: 1, item: "プロジェクター", user: { name: "sato" } },
{ id: 2, item: "会議室A" },
];
function label(r) {
return `${r.item}(${r.user.name})`;
}
function printAll(list) {
return list.map(label);
}
console.log(printAll(reservations));
node reserve.js の出力です。
/home/taro/app/reserve.js:7
return `${r.item}(${r.user.name})`;
^
TypeError: Cannot read properties of undefined (reading 'name')
at label (/home/taro/app/reserve.js:7:30)
at Array.map (<anonymous>)
at printAll (/home/taro/app/reserve.js:11:15)
at Object.<anonymous> (/home/taro/app/reserve.js:14:13)
at Module._compile (node:internal/modules/cjs/loader:1705:14)
at Object..js (node:internal/modules/cjs/loader:1838:10)
at Module.load (node:internal/modules/cjs/loader:1441:32)
at Function._load (node:internal/modules/cjs/loader:1263:12)
at TracingChannel.traceSync (node:diagnostics_channel:328:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:237:24)
Node.js v22.22.2
冒頭の3行(ファイルと行番号、その行のコード、位置を示す ^)は、どの式が undefined だったかを直接示すので必ず残します。at 行は上が発生箇所で、node:internal/ や node:diagnostics_channel で始まる6行は Node.js 内部の読み込み処理なので省けます。at Array.map の行は、配列の処理の途中だと分かる手がかりになるので残します。末尾の Node.js v22.22.2 は環境情報を兼ねます。
SQL の例:ERROR から CONTEXT まで全部と、実行した SQL を貼る
SQL のエラーは短いので絞らず、実行した SQL とテーブル定義を一緒に貼るのが要点です。次の定義を用意しました。
CREATE TABLE items (id int PRIMARY KEY, name text NOT NULL);
CREATE TABLE reservations (
id int PRIMARY KEY,
item_id int NOT NULL REFERENCES items(id),
reserved_on date NOT NULL
);
INSERT INTO items VALUES (1, 'プロジェクター');
次の check.sql を PostgreSQL 16 の psql -d appdb -f check.sql で流します。
SELECT id, item_name FROM items;
INSERT INTO reservations VALUES (10, 99, '2026-10-06');
CREATE FUNCTION add_reservation(p_id int, p_item int, p_day text) RETURNS void AS $$
BEGIN
INSERT INTO reservations VALUES (p_id, p_item, p_day::date);
END;
$$ LANGUAGE plpgsql;
SELECT add_reservation(11, 1, '2026/13/06');
\set VERBOSITY verbose
SELECT id, item_name FROM items;
psql:check.sql:1: ERROR: column "item_name" does not exist
LINE 1: SELECT id, item_name FROM items;
^
psql:check.sql:2: ERROR: insert or update on table "reservations" violates foreign key constraint "reservations_item_id_fkey"
DETAIL: Key (item_id)=(99) is not present in table "items".
psql:check.sql:8: ERROR: date/time field value out of range: "2026/13/06"
HINT: Perhaps you need a different "datestyle" setting.
CONTEXT: SQL statement "INSERT INTO reservations VALUES (p_id, p_item, p_day::date)"
PL/pgSQL function add_reservation(integer,integer,text) line 3 at SQL statement
psql:check.sql:10: ERROR: 42703: column "item_name" does not exist
LINE 1: SELECT id, item_name FROM items;
^
LOCATION: errorMissingColumn, parse_relation.c:3722
| 行の先頭 | 表す内容 | この例での手がかり |
|---|---|---|
ERROR: |
何が起きたか | 列が無い/外部キー制約に反した/日付の値が範囲外 |
LINE と ^ |
SQL のどの位置か | item_name の位置 |
DETAIL: |
具体的な値 | item_id が 99 の行が items に無い |
HINT: |
PostgreSQL からの提案 | 日付の解釈の設定に触れている |
CONTEXT: |
関数の中のどこか | add_reservation の3行目の INSERT |
\set VERBOSITY verbose を付けると、5桁のエラーコード(ここでは 42703)が加わります。メッセージが日本語で出る環境でもコードは変わらないので、AI に渡す手がかりとして役立ちます。
同じ内容を MySQL 8.0 で流したときの出力です(mysql appdb -e "…" で1文ずつ実行)。
ERROR 1054 (42S22) at line 1: Unknown column 'item_name' in 'field list'
ERROR 1452 (23000) at line 1: Cannot add or update a child row: a foreign key constraint fails (`appdb`.`reservations`, CONSTRAINT `reservations_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`))
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
ERROR 1292 (22007) at line 1: Incorrect date value: '2026/13/06' for column 'reserved_on' at row 1
3つ目は SELECT id name FROM items WHERE; を流した結果です。MySQL は エラー番号(1064)と括弧内の SQLSTATE(42000)、near '…' の3点が手がかりになります。near '' のように中身が空のときは、文の終わりでつまずいたことを表しています。
貼る前のチェックリスト(マスクする項目の一覧)
エラー文やログ、設定ファイルには、外に出したくない値が混ざることがあります。貼る前に次の項目を置き換えます。 置き換えは「消す」より「種類が分かる目印に替える」ほうが、AI が文脈を読み取りやすくなります。
| 確認 | 項目 | 見つかりやすい場所 | 置き換えの例 |
|---|---|---|---|
| □ | API キー・アクセストークン | 環境変数の出力、設定ファイル、HTTP ヘッダー | <TOKEN> |
| □ | パスワード | 接続文字列(postgresql://user:pass@host)、ログ |
<MASKED> |
| □ | 秘密鍵・証明書 | -----BEGIN ... PRIVATE KEY----- で始まるブロック |
<PRIVATE_KEY> |
| □ | Cookie・セッション ID・JWT | リクエストヘッダー、ブラウザの開発者ツールの出力 | <JWT> |
| □ | 氏名・メールアドレス・電話番号・住所 | ログ、テストデータ、SQL の INSERT 文 | <EMAIL>、<TEL> |
| □ | 会員番号・社員番号などの識別子 | ログ、URL のパラメーター | user-001 などの仮の値 |
| □ | 社内のホスト名・IP アドレス・URL | 接続先、スタックトレース内の URL | db.example.internal、<IP> |
| □ | ホームディレクトリのユーザー名 | ファイルパス(/home/名前/) |
/home/<USER>/ |
| □ | 顧客名・取引先名・製品のコード名 | パッケージ名、テーブル名、コメント | acme、sample などの仮の名前 |
| □ | 業務データの中身 | SELECT の結果、ダンプ、CSV | 同じ形の架空データ3行に差し替え |
| □ | 利用ルールの確認 | 勤務先や契約で、外部サービスへ貼ってよい範囲が決まっているか | ルールに沿ったツールを使う |
置き換えたあとも、行番号・例外の種類・メッセージの文言・値の形式(区切り文字や桁数)は変えないのがコツです。たとえば日付の 2026/10/06 を「日付」と書き換えると、スラッシュ区切りという原因の手がかりが消えます。
マスク用の Python スクリプト(コピペ用)
よくある形の値を目印に置き換えるスクリプトです。標準ライブラリだけで動きます。
import re
import sys
RULES = [
("秘密鍵", r"-----BEGIN [A-Z ]*PRIVATE KEY-----.*?-----END [A-Z ]*PRIVATE KEY-----", "<PRIVATE_KEY>"),
("Authorizationヘッダー", r"(?i)\b(authorization:\s*(?:bearer|basic))\s+\S+", r"\1 <TOKEN>"),
("JWT", r"\beyJ[\w-]+\.[\w-]+\.[\w-]+", "<JWT>"),
("アクセスキーID", r"\bAKIA[0-9A-Z]{16}\b", "<ACCESS_KEY_ID>"),
("パスワード・トークン類", r"(?i)\b(password|passwd|pwd|secret|token|api[_-]?key)(\s*[=:]\s*)(\"[^\"]*\"|'[^']*'|[^\s&;,]+)", r"\1\2<MASKED>"),
("URL内のパスワード", r"(\w+://[^\s:/@]+):[^\s@/]+@", r"\1:<MASKED>@"),
("メールアドレス", r"[\w.+-]+@[\w-]+(?:\.[\w-]+)+", "<EMAIL>"),
("IPアドレス", r"\b(?:\d{1,3}\.){3}\d{1,3}\b", "<IP>"),
("電話番号", r"\b0\d{1,4}-\d{1,4}-\d{4}\b", "<TEL>"),
("ホームディレクトリのユーザー名", r"(/home/|/Users/|C:\\Users\\)[^/\\\s:]+", r"\1<USER>"),
]
def mask(text):
counts = {}
for label, pattern, repl in RULES:
text, n = re.subn(pattern, repl, text, flags=re.S)
if n:
counts[label] = n
return text, counts
if __name__ == "__main__":
masked, counts = mask(sys.stdin.read())
sys.stdout.write(masked)
for label, n in counts.items():
print(f"[mask] {label}: {n}件", file=sys.stderr)
架空の値を入れたログ sample.log で試します。
2026-10-05 09:12:44 ERROR reserve failed user=sato.hanako@example.com from 192.0.2.15
File "/home/hanako/app/reserve.py", line 12, in max_days
DATABASE_URL=postgresql://app:Passw0rd-example@db.example.internal:5432/appdb
Authorization: Bearer abc123.example.token
api_key = "EXAMPLE-KEY-0000"
連絡先 03-0000-0000
python3 mask.py < sample.log の出力です。
2026-10-05 09:12:44 ERROR reserve failed user=<EMAIL> from <IP>
File "/home/<USER>/app/reserve.py", line 12, in max_days
DATABASE_URL=postgresql://app:<MASKED>@db.example.internal:5432/appdb
Authorization: Bearer <TOKEN>
api_key = <MASKED>
連絡先 <TEL>
[mask] Authorizationヘッダー: 1件
[mask] パスワード・トークン類: 1件
[mask] URL内のパスワード: 1件
[mask] メールアドレス: 1件
[mask] IPアドレス: 1件
[mask] 電話番号: 1件
[mask] ホームディレクトリのユーザー名: 1件
行番号と例外まわりの文言はそのまま残り、値だけが置き換わっています。スクリプトが拾うのは形の決まった値だけなので、氏名・顧客名・ホスト名・業務データは上のチェックリストで目視します。出力を貼る前に、置き換え件数([mask] の行)と本文を一度見直してください。
追い質問テンプレート
最初の回答を受けたあとに使う定型です。会話の続きに貼ります。
原因の仮説を複数出させる
修正案の前に、原因の仮説を3つ以上、可能性の高い順に挙げてください。
仮説ごとに次の4点を表にしてください。
- 根拠(エラー文やコードのどの行か。行を引用する)
- 当たっていれば観察できるはずのこと
- 確かめ方(追加するログ、実行するコマンド、変える入力)
- 外れていた場合に次に見る場所
コードやログから確認できないことは「不明」と書き、推測で断定しないでください。
1つの答えに決め打ちさせず、確かめ方とセットで候補を並べさせるのがねらいです。Anthropic の公式ガイドには、調査の作業では競合する仮説を複数立てて確からしさを記録していく、という指示例が載っています。
最小再現コードを作らせる
このエラーを再現する最小のコードを作ってください。
- 1ファイルで完結し、外部サービス・DB・設定ファイルに依存しない
- 入力データはコードの中に直接書く(架空の値にする)
- 元のコードから、エラーに関係しない処理を取り除く
- 実行コマンドと、出るはずのエラー文の1行目を添える
- 言語とバージョン:<例:OpenJDK 21>
取り除いてよいか判断できない処理があれば、取り除く前に質問してください。
受け取ったコードは手元で実行し、同じエラーが出ることを確かめてから次へ進みます。先ほどの Java の例を最小にすると、次の1ファイルになります。
import java.time.LocalDate;
public class Repro {
public static void main(String[] args) {
System.out.println(LocalDate.parse("2026/10/06"));
}
}
java Repro.java の出力です。元のトレースの Caused by: と同じ例外が出ており、原因が日付の形式にあると分かります。
Exception in thread "main" java.time.format.DateTimeParseException: Text '2026/10/06' could not be parsed at index 4
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2108)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2010)
at java.base/java.time.LocalDate.parse(LocalDate.java:435)
at java.base/java.time.LocalDate.parse(LocalDate.java:420)
at Repro.main(Repro.java:5)
修正後の確認手順を出させる
修正案と一緒に、直ったことを確かめる手順を出してください。
1. 修正前に、同じ入力でエラーが再現することを確かめるコマンド
2. 修正後に、同じ入力で期待した結果になることを確かめるコマンドと、期待する出力
3. 修正の影響を受けそうな、これまで動いていた入力を2〜3個(期待する出力つき)
4. 追加しておくとよい自動テストのケース名と入力・期待値の表
変更は、原因の箇所に必要な最小限にしてください。変更した行と理由を一覧にしてください。
Java の例では、スラッシュ区切りの形式を指定する修正を入れ、直した入力と、もともと動いていた入力の両方を流して確かめました。
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Fixed {
public static void main(String[] args) {
DateTimeFormatter slash = DateTimeFormatter.ofPattern("yyyy/MM/dd");
System.out.println(LocalDate.parse("2026/10/06", slash));
System.out.println(LocalDate.parse("2026-10-05"));
}
}
2026-10-06
2026-10-05
GitHub Copilot の公式ドキュメントは、提案されたコードは内容を理解してから取り入れること、自動テストやツールで確かめることを勧めています。確認手順まで AI に書かせておくと、この確認に入りやすくなります。
回答がかみ合わないときの立て直し
ここまでの内容を整理します。
- 確認できた事実:<例:最小再現コードで同じ例外が出た>
- 外れた仮説:<例:文字コードの違いではなかった>
- 新しく分かったこと:<追加したログの出力を貼る>
この3点を前提に、残っている仮説を並べ直し、次に確かめることを1つだけ提案してください。
同じ会話でやり取りが長くなったら、上の整理と8項目のテンプレートを新しい会話に貼り直す方法もあります。GitHub Copilot の公式ドキュメントは、望む回答が得られないときは言い方を変えたり依頼を小さく分けたりすること、別の作業に移るときは新しいスレッドで始めて履歴を関係のあるものに保つことを勧めています。
公式ドキュメントの記載とテンプレートの対応表
この記事のテンプレートが、各社の公式ドキュメントのどの記載に沿っているかをまとめます。
| テンプレートでしていること | Anthropic | OpenAI | GitHub Copilot |
|---|---|---|---|
| 目的・期待・実際を具体的に書く | 明確で直接的に書く。背景や理由を添える | 指示・例・文脈を分けて書く | 要件を具体的に書く。先に全体像、次に細部 |
| タグや見出しで区切る | 指示・文脈・入力を XML タグで囲む | Markdown と XML で区切りを示す | — |
| エラー文とコードを先に、依頼を最後に | 長い資料は上に置き、問いは最後に置く | — | — |
| 該当コードを示す | 根拠になる部分を先に引用させる | 必要な文脈情報を含める | 関係するファイルを開き、関数名などを名指しする |
| 出力の形と手順を番号で指定 | 順序が大事な手順は番号つきで書く | — | 複雑な作業は小さく分ける |
| 仮説を複数出させる | 調査では競合する仮説を複数立てる | — | — |
| 修正後に確かめる | 終える前に条件に照らして検証するよう頼む | — | 提案を理解してから使う。自動テストで確かめる |
| かみ合わないときに言い直す | — | — | 言い換える、分ける、履歴を関係のあるものに保つ |
「—」は、今回開いたページにその項目の記載が見当たらなかったことを表します。
よくある質問
Q. スタックトレースは全部貼るべきですか、絞るべきですか?
A. 貼れる長さなら全部貼ります。絞るのは、長すぎて貼れないときです。そのときも、例外の種類とメッセージの行、原因の例外(Java の Caused by:、Python の連鎖の上のブロック)、自分のファイルの行は残し、省いた場所に「…(省略)…」と書きます。
Q. エラーが出ないのに結果が違うときは、何を貼ればよいですか? A. 「エラー全文」の代わりに、入力・期待した出力・実際の出力を並べて貼ります。途中の値を表示するログを数か所に入れ、その出力を添えると、どこで値が変わったかを絞り込めます。
Q. コードはどこまで貼ればよいですか? A. スタックトレースに出た自分のファイルの関数と、その呼び出し元までが目安です。行番号がトレースと合うよう、ファイル名と行の範囲を書き添えます。設定ファイルや入力データが関係しそうなら、マスクしたうえで形が分かる数行を付けます。
Q. 英語のエラー文は日本語に訳してから貼ったほうがよいですか? A. 原文のまま貼ります。エラー文の文言は検索や照合の手がかりになるので、訳すと情報が減ります。説明は日本語でほしい場合は、出力形式に「日本語で説明」と書き添えます。
まとめ
- 8項目(目的・期待した動き・実際の動き・エラー全文・該当コード・環境とバージョン・再現手順・試したこと)を、タグや見出しで区切って渡す
- スタックトレースは全文が基本。絞るときは、例外の行・原因の例外・自分のファイルの行を残す
- Java は一番下の
Caused by:、Python は最終行と連鎖の上のブロック、Node.js は冒頭のコード行と^が要点 - SQL は ERROR から CONTEXT までの全行と、実行した SQL・テーブル定義を一緒に貼る
- 貼る前にキー・パスワード・個人情報・社内のホスト名を目印に置き換える。行番号と値の形式は変えない
- 追い質問で仮説を複数・最小再現コード・修正後の確認手順を引き出し、手元で動かして確かめる
参考・出典
- Anthropic「Prompting best practices」 https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices (2026年10月5日に閲覧)
- OpenAI「Prompt engineering」 https://developers.openai.com/api/docs/guides/prompt-engineering (2026年10月5日に閲覧)
- GitHub Docs「Best practices for using GitHub Copilot」 https://docs.github.com/en/copilot/get-started/best-practices (2026年10月5日に閲覧)
- GitHub Docs「Prompt engineering for GitHub Copilot Chat」 https://docs.github.com/en/copilot/concepts/prompting/prompt-engineering (2026年10月5日に閲覧)
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「エラーを生成AIに聞くプロンプトの書き方|スタックトレースの渡し方」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。