TL;DR
- 2027年度開始の新試験「プロフェッショナルデジタルスキル試験(PD試験)」の対策問題がほぼゼロだった
- Claudeを活用してオリジナル演習問題を150問生成・検証・サイト公開した
- プロンプト設計・品質管理・JS配列のデバッグなど、技術的なハマりどころが多かった
- 最終的に問題演習道場として公開し、IPA公式サンプル問題10問と合わせて計160問を無料提供中
はじめに:なぜ150問も作ることになったのか
背景
2027年度から、IPAの試験制度が大きく変わります。応用情報技術者試験・高度試験が再編され、**プロフェッショナルデジタルスキル試験(PD試験)**が新設されます。
しかし、試験発表から日が浅いためか、PD試験の対策問題がほぼ存在しないという状況でした。
- 市販の問題集:なし(2026年時点)
- IPA公式サンプル問題:マネジメント・システム合わせて10問のみ
- ネットの演習サイト:ほぼ皆無
「自分が勉強したいのに問題がない。なら作るしかないか…」
そういう経緯で、生成AIを使ってオリジナル問題を150問作り、無料の問題演習サイトとして公開することにしました。
作るもの:問題の仕様を決める
まず「どんな問題を作るか」の仕様を固めました。
問題形式
PD試験の科目B(シナリオ型)に合わせた四肢択一問題。
- 試験区分:マネジメント / システム(各75問)
- 問題形式:シナリオ+選択肢a〜d
- 解答:正解選択肢(a/b/c/d)
- 解説:なぜその選択肢が正解か、他の選択肢はなぜ不正解か
データ構造
フロントエンドで動的に問題を表示するため、JavaScriptの配列としてデータを持たせる設計にしました。
const ALL_Q = [
{
type: "practice",
exam: "PD(マネジメント)試験 科目B 演習",
num: "演習問1",
question: "A社のIT部門リーダーであるBさんは...",
a: "ア. コスト削減を最優先とし...",
b: "イ. リスクを説明した上で...",
c: "ウ. 移行を中断し...",
d: "エ. セキュリティを最優先として...",
answer: "b",
explanation: "<strong>正解:イ</strong><br>..."
},
// ... 159問続く
];
Claudeへの問題生成プロンプト設計
最初は雑なプロンプトで試してみましたが、品質がバラバラで使い物になりませんでした。試行錯誤の末、以下のプロンプト構造に落ち着きました。
最終的なプロンプト構造
あなたはIPA試験の問題作成の専門家です。
プロフェッショナルデジタルスキル試験(PD試験)のマネジメント区分・科目B(シナリオ型)の
演習問題を作成してください。
【出力形式】
以下のJavaScriptオブジェクト形式で出力してください:
{
type: "practice",
exam: "PD(マネジメント)試験 科目B 演習",
num: "演習問XX",
question: "【問題文:200字程度のシナリオ+設問】",
a: "ア. 【選択肢A】",
b: "イ. 【選択肢B】",
c: "ウ. 【選択肢C】",
d: "エ. 【選択肢D】",
answer: "【正解の選択肢キー:a/b/c/dのいずれか】",
explanation: "<strong>正解:【選択肢記号】</strong><br>【正解理由100字以上】<br>【各不正解選択肢の理由】"
}
【品質要件】
- 実務的なシナリオ(DX推進・PM・ITIL・システム監査等)を設定すること
- 正解が明確で、根拠を説明できること
- 誤選択肢も「一見もっともらしい」ものにすること
- 解説はなぜ正解なのか、なぜ他の選択肢が不正解なのかを明記すること
- 出題分野:【ここに分野名を指定】
【出題分野の例】
DX戦略・デジタルビジネス / プロジェクトマネジメント / ITIL・サービスマネジメント /
システム監査・内部統制 / 情報セキュリティマネジメント 等
プロンプト設計のポイント
① 出力形式を厳密に指定する
最初はフリーフォーマットで出してもらったら、あとで手直しが大変でした。JavaScriptオブジェクトの形式をそのままプロンプトに書いて、そのまま使えるコードを出力させることが重要でした。
② 分野を1問ごとに指定する
「マネジメント系の問題を75問出して」だと、特定の分野に偏ります。分野リストを作って1問ずつ指定した方が、バランスよく生成できました。
# 分野ローテーションの例
domains_management = [
"DX戦略・デジタルビジネス",
"プロジェクトマネジメント(PMBOK)",
"ITサービスマネジメント(ITIL)",
"システム監査・内部統制",
"情報セキュリティマネジメント",
"組織・人材マネジメント",
"ITガバナンス・リスクマネジメント",
"ビジネスアーキテクチャ・EA",
]
for i, domain in enumerate(domains_management * 10): # 75問分
prompt = BASE_PROMPT.replace("【ここに分野名を指定】", domain)
# Claude APIを呼び出す
③ 解説の粒度を指示する
「解説を書いて」だけだと短くなりがちです。「なぜ正解か・なぜ不正解か両方書いて、100字以上」と明示的に指示することで、学習に使える解説になりました。
品質チェック:生成した問題の検証
150問生成しただけでは終わりません。品質チェックが重要です。
チェックポイント
1. 正解の偏り確認
from collections import Counter
answers = [q['answer'] for q in all_questions]
print(Counter(answers))
# Counter({'b': 42, 'a': 40, 'c': 35, 'd': 33}) のような分布を確認
特定の選択肢に正解が偏っていると不自然な問題集になるので、均等になるよう再生成しました。
2. 問題文の重複チェック
同じシナリオ・同じ状況が繰り返されていないかを確認しました。
import difflib
questions_text = [q['question'] for q in all_questions]
for i, q1 in enumerate(questions_text):
for j, q2 in enumerate(questions_text):
if i >= j:
continue
ratio = difflib.SequenceMatcher(None, q1, q2).ratio()
if ratio > 0.6:
print(f"類似度高: 問{i+1} と 問{j+1} ({ratio:.2f})")
3. JS構文チェック:ここが一番ハマった
150問をJavaScript配列として結合したところ、ブラウザでエラーが出てボタンが全部動かなくなるという事態が発生しました。
Uncaught SyntaxError: Unexpected token '{'
Node.jsで構文チェックスクリプトを書いて原因を探しました。
// check_js.js
const fs = require("fs");
const content = fs.readFileSync("kakomon_quiz_js_only.txt", "utf8");
// 配列部分を抽出してevalでパース
const match = content.match(/const ALL_Q\s*=\s*(\[[\s\S]*\]);/);
if (!match) {
console.error("配列が見つかりません");
process.exit(1);
}
try {
const arr = eval(match[1]);
console.log(`[OK] 配列パース成功 要素数: ${arr.length}`);
} catch (e) {
console.error(`[NG] パースエラー: ${e.message}`);
}
二分探索で問題のある問題を特定した結果、問50と問51の間にカンマが抜けていたことが判明。
// NG:カンマが抜けている
{..., explanation: "...(GPU利用はWebGPU等の別API)。"} // ← ここのカンマが抜けていた
{type:"practice", exam:"...", num:"演習問51",...}
// OK:カンマを追加
{..., explanation: "...(GPU利用はWebGPU等の別API)。"}, // ← カンマ追加
{type:"practice", exam:"...", num:"演習問51",...}
生成AIが出力したコードをそのまま結合するとこういうことが起きるので、必ずプログラムで構文検証することをおすすめします。
サイトへの組み込みとデプロイ
問題データが完成したら、WordPress上に問題演習ページとしてデプロイしました。
フロントエンドの構成
<!-- 問題表示エリア -->
<div id="quiz-container">
<div id="question-text"></div>
<div id="choices"></div>
<div id="explanation" style="display:none;"></div>
</div>
<script>
// ALL_Q配列(150問分のデータ)
const ALL_Q = [ ... ];
// 出題ロジック
function loadQuestion(index) {
const q = currentQuestions[index];
document.getElementById('question-text').innerHTML = q.question;
// 選択肢を動的生成...
}
</script>
デプロイ時の工夫
WordPressのページエディタでは大量のJavaScriptをそのまま貼り付けると壊れることがあるため、WordPress REST APIを使ってプログラム的に更新しました。
import requests
BASE = 'https://www.pds-siken.com'
headers = {
'Authorization': 'Basic YOUR_APP_PASSWORD',
'Content-Type': 'application/json',
}
with open('quiz_page.html', 'r', encoding='utf-8') as f:
content = f.read()
r = requests.post(
f'{BASE}/wp-json/wp/v2/pages/30',
json={'content': content, 'status': 'publish'},
headers=headers,
)
print(r.status_code, r.json().get('link'))
やってみてわかったこと・反省点
よかった点
- 150問を短期間で生成できた:手作業では数ヶ月かかるところを大幅に短縮
- 解説の質が意外と高い:ITILやPMBOKの説明はClaudeが得意な領域
- フォーマットの一貫性:プロンプトで厳密に指定すれば、出力が揃う
反省・改善点
- 難易度のコントロールが難しい:易しすぎる問題・難しすぎる問題が混在した
- 最新情報の扱い:AIの学習データのカットオフ以降の情報(最新のシラバス等)は反映されない→手動でレビューが必要
- シナリオの多様性:大量生成すると「IT部門リーダーのAさんが…」というパターンが多くなる→プロンプトでペルソナを指定すると改善
完成したもの
こうして完成した160問の問題演習サイトを無料公開しています。
PD試験 問題演習道場
収録内容
| カテゴリ | 問題数 |
|---|---|
| IPA公式サンプル問題(マネジメント) | 4問 |
| IPA公式サンプル問題(システム) | 6問 |
| オリジナル演習問題(マネジメント区分) | 75問 |
| オリジナル演習問題(システム区分) | 75問 |
| 合計 | 160問 |
- 会員登録不要・完全無料
- 全問に詳しい解説付き
- ランダム出題・ジャンル別・間違えた問題だけ再チャレンジ等
PD試験の対策をこれから始める方は、ぜひ使ってみてください。
対策サイトトップ(試験概要・スケジュールも掲載)→ https://www.pds-siken.com/
おわりに
「問題がないなら作る」という発想でスタートして、生成AIのおかげで現実的な時間・コストで実現できました。
生成AIで問題を作るときは:
- 出力フォーマットを厳密に定義する
- 分野を1問ずつ指定してバランスを取る
- プログラムで構文・品質を必ず検証する
この3点が特に重要だと感じました。同じように「自分用の問題集を作りたい」方の参考になれば幸いです。
もし問題の質に対してフィードバックがあればコメントください。引き続き問題を増やしていく予定です!