Fine-tuningは「教師データ作り」で決まる? baseline_dataset_v0.5作成とdataset_v1.0設計編
はじめに
LLMをFine-tuningすれば、本当に回答品質は向上するのでしょうか。
Fine-tuningの解説では、
- データセットを用意する
- モデルを学習する
- 学習後のモデルを評価する
という流れがよく紹介されます。
しかし、実際に試そうとすると、もっと手前に大きな問題があるのではと感じるようになりました。
実際lossが下がっても、全然イケてないことが多いです。
これは掲載中のなろう系小説の第一話を書かせるためにSFT+LoRAでチューニングしても全く精度が上がらなかったり、有名どころのマーケティングデータセットをSFT+LoRAでチューニングしてもやっぱり精度が上がらないという現象がありました。 結果最新モデルにすると精度が上がるというありきたりの結果になっています。
このことから
単にサンプルのデータセットを使ってファインチューニング出来たというやり方ではなく、生成出力の精度が期待通り向上したという結果を出すためにファインチューニングスキル以上に何が重要なのか検証するための実証実験を行っています。
今回は検証計画の仮説データセットとして LLMのみで生成したbaseline v0.5の作成と、dataset v1.0
を作成するところと、データセットの品質をどう評価するのか?という評価設計の所まで行います。
この記事を読むために最低限知っておけばよいこと
Fine-tuning:既存LLMを追加データで調整すること
SFT:正解例を見せて学習させる方法
LoRA:モデル全体ではなく一部だけ効率よく学習する方法
Dataset:モデルに学ばせる例題集
Baseline:改善前の比較基準
TL;DR
今回行ったのは、キャッチコピー生成モデルを評価する前段階となる baseline_dataset_v0.5 の作成と、90問から未評価30問の dataset_v1.0 を抽出する作業です。
- 衣・食をテーマに、Datasetの基本型と最初の30パターンを
gpt-5.6 solで作成 - 同じ基本型を使い、
opus5とgemini-3.1 proにも各30パターンを作成してもらった - 3つのJSONを結合し、異なる商品条件を持つ90問を作成
- 90問すべてに対して、次の4モデルでキャッチコピーを生成
gpt-5.6 solopus5gemini-3.1 protokyotech-llm/Qwen3-Swallow-32B-SFT-v0.2
- 結果として、90問×4候補=360件のキャッチコピー候補を持つDatasetになった
- 評価・分類・抽出の3設計を順番に固定し、入力条件だけで90問を分類
- 衣食、商品10分類、出題元のHard quotaを満たす30問を抽出し、
dataset_v1.0を作成 - 抽出後の120候補へHard Gateを実行し、コピー有識者へ渡せる77候補、専門確認待ち8候補、類似・権利確認待ち3候補、棄却32候補に分離
- Hard Gate通過候補だけを収録した有識者向け依頼資料を作成。コード/LLMとコピー有識者の担当を分離
この記事では baseline_dataset_v0.5 の作成、評価・分類・抽出の詳細設計、実際の90問分類と30問抽出、品質評価前のHard Gate、有識者依頼資料の作成までを扱います。コピー品質の5軸評価やモデル比較はまだ実施しません。有識者評価済みのDatasetは次段階の dataset_v1.5 とします。
この記事の位置付け
この記事は、前回の実験計画で示した「STEP 1:baseline_dataset_v0.5を作る」の作業編です。
前回の記事では、Fine-tuningを始める前に、衣食に関するキャッチコピーを、LLMが生成した際に有効なのは、 LLMモデルの性能なのか、学習するデータなのか、チューニング技術なのかという仮説と、同じように評価設計の重要性に基づいて、人とLLMのアウトプットをどう評価するのかについて計画を立てました。
今回は基本的なデータセットの形と初期状態のアウトプットを元に有識者が評価出来る前まで進めてみます。
今回の作業範囲は次のとおりです。
この記事では、キャッチコピーの良し悪しやモデルの順位は評価しません。ただし、品質評価へ渡せない候補を除くHard Gateは実行し、System/LLMとコピー有識者の担当を分けた評価票まで作成します。
今回のVersion定義
実際の作業内容に合わせ、DatasetのVersionを次のように整理します。
| Version | 内容 | 状態 |
|---|---|---|
baseline_dataset_v0.5 |
90問と4モデルの未評価キャッチコピー候補 | 今回作成 |
dataset_v1.0 |
評価・分類・抽出設計を固定し、90問から選んだ未評価30問と抽出provenance | 今回作成 |
dataset_v1.5 |
LLM評価と有識者評価、最終裁定を追加した30問 | 評価工程で作成 |
v0.5 は評価前の90問を揃えた段階、v1.0 は評価対象30問を再現可能な手順で固定した段階です。モデル名を隠した評価、採否理由、REJECT_ALL、有識者による修正版は v1.5 に追加します。この区切りは、前回の実験計画で示したVersionの流れを維持しています。
最初にDatasetの基本型を決める
今回扱うテーマは、衣・食に関する商品のキャッチコピーです。
単純に商品名とキャッチコピーだけを保存すると、そのコピーが何を狙って作られたのか分かりません。そこで、商品情報からコピーへ至る条件を、次の基本型で持たせました。
{
"product": "軽量ランニングシューズ",
"target": "週末にランニングする30代会社員",
"feature": "従来モデルより20%軽量",
"benefit": "長距離でも疲れにくい",
"tone": "シンプル・都会的",
"constraint": "15文字程度",
"use_model": "gpt-5.6 sol",
"copy_a": "軽さは、走りを変える。"
}
| フィールド | 内容 |
|---|---|
product |
商品名 |
target |
想定する購入者・利用者 |
feature |
商品の特徴や機能 |
benefit |
利用者が得られる価値 |
tone |
コピーの表現トーン |
constraint |
文字数などの生成条件 |
use_model |
この問題の基本データを作ったモデル |
copy_* |
各モデルが生成したキャッチコピー |
各LLMへ答えてもらったのは、次の入力条件に対するキャッチコピーです。
商品
+ ターゲット
+ 特徴
+ ベネフィット
+ トーン
+ 文字数制約
↓
キャッチコピー
STEP 1:gpt-5.6 solで基本型と30パターンを作る
最初に gpt-5.6 sol を使い、衣・食をテーマとしたDatasetの基本型と30パターンを作りました。
gpt_product_copy_samples_30.json
30件はすべて同じJSON構造を持ち、商品、ターゲット、特徴、ベネフィット、トーン、文字数制約、キャッチコピーを保存しています。
ここで作ったのは、後から正解として学習させる教師データではありません。複数モデルへキャッチコピーを作らせるための問題の基本型です。
STEP 2:opus5とgemini-3.1 proでも各30パターンを作る
次に、gptで作った基本型をもとに、opus5 と gemini-3.1 pro にも衣・食のDatasetを各30パターン作ってもらいました。
当初fableを使う予定でしたが、opusに変更しています。(あとでfable使うかも)
opus_product_samples_30.json
gemini_catchcopy_samples.json
| 基本データを作ったモデル | 問題数 |
|---|---|
| gpt-5.6 sol | 30 |
| opus5 | 30 |
| gemini-3.1 pro | 30 |
| 合計 | 90 |
3モデルが同じ30問へ回答したのではなく、各モデルが同じ基本型を使って、それぞれ異なる30問を作っています。そのため、結合後は90種類の商品条件を持つ問題プールになります。
STEP 3:3つのJSONを90問へマージする
3ファイルはいずれもJSON配列なので、jqで連結しました。
jq -s 'add' \
gpt_product_copy_samples_30.json \
opus_product_samples_30.json \
gemini_catchcopy_samples.json \
> merged.json
jqの -s は複数の入力JSONを1つの配列として読み込み、add は今回のような配列同士を連結します。
作成後の件数と内訳を確認しました。
jq 'length' merged.json
jq -r 'group_by(.use_model)[] | "\(.[0].use_model): \(length)"' merged.json
90
gemini-3.1 pro: 30
gpt-5.6 sol: 30
opus5: 30
STEP 4:90問すべてに4モデルのキャッチコピーを追加する
90問をマージした後、それぞれの商品条件に対して次の4モデルでキャッチコピーを生成しました。
| モデル | Dataset内の記録名 |
|---|---|
| GPT | gpt-5.6 sol |
| Opus | opus5 |
| Gemini | gemini-3.1 pro |
| Swallow | tokyotech-llm/Qwen3-Swallow-32B-SFT-v0.2 |
ここでようやくある意味今回の実験の主役であるswallowが出てきます。
この段階では他のLLMよりも相当見劣りするswallowですが、swallowの良い点は、
東工大(現東京科学大学)が日本語用にQwen3をチューニングしてくれているので、
このベースを活かしつつSFT/LoRA/DPOなどを駆使してどこまで最新の有償モデルまで近づけられるのか?
がこの実験をする大きな意味の一つでもあります
各問題には、4モデルが生成したコピーを copy_a〜copy_d として保存しています。
ここで注意が必要なのは、copy_a が常にGPT、copy_b が常にGeminiという固定配置ではないことです。最初にその問題を作ったモデルの回答を copy_a として残しているため、元のDatasetによって配置が変わります。
| 問題を作ったモデル | copy_a | copy_b | copy_c | copy_d |
|---|---|---|---|---|
| gpt-5.6 sol | gpt | gemini | opus | Swallow |
| gemini-3.1 pro | gemini | gpt | opus | Swallow |
| opus5 | opus | gpt | gemini | Swallow |
この対応を失わないよう、各行に copy_models を追加しました。
"copy_models": {
"copy_a": "gpt-5.6 sol",
"copy_b": "gemini-3.1 pro",
"copy_c": "opus5",
"copy_d": "tokyotech-llm/Qwen3-Swallow-32B-SFT-v0.2"
}
これにより、評価画面ではモデル名を隠しつつ、評価後にどのモデルの回答だったかを戻せます。
STEP 5:Swallowのキャッチコピーをローカル生成する
4モデル目のSwallowには、tokyotech-llm/Qwen3-Swallow-32B-SFT-v0.2 を使いました。
Apple Silicon上でMLX-LMを使い、90問の商品属性から copy_d を生成しています。
UV_CACHE_DIR=.uv-cache uv sync
UV_CACHE_DIR=.uv-cache uv run python generate_copy_d.py --audit-prompts
UV_CACHE_DIR=.uv-cache uv run python generate_copy_d.py
Swallowへ渡す入力からは、既存の copy_a〜copy_c とモデル名を除外しました。既存コピーを見せず、同じ商品条件だけを使って新しいキャッチコピーを生成するためです。
生成中に処理が止まっても続きから再開できるよう、生成が完了した行から merged.json へ保存する形にしています。一部のバッチ応答で期待した出力形式にならない行があったため、その行だけ個別に再生成しました。
作成したbaseline_dataset_v0.5
最終的な merged.json は、次の構成になりました。
| 項目 | 件数 |
|---|---|
| 問題数 | 90 |
| 商品数 | 90 |
| 1問あたりのキャッチコピー | 4 |
| キャッチコピー候補総数 | 360 |
| gptの回答 | 90 |
| opusの回答 | 90 |
| geminiの回答 | 90 |
| Swallowの回答 | 90 |
1レコードには、1つの商品条件と4モデルのキャッチコピーが入っています。
{
"product": "軽量ランニングシューズ",
"target": "週末にランニングする30代会社員",
"feature": "従来モデルより20%軽量",
"benefit": "長距離でも疲れにくい",
"tone": "シンプル・都会的",
"constraint": "15文字程度",
"copy_a": "軽さは、走りを変える。",
"copy_b": "飛ぶように、走ろう。",
"copy_c": "20%軽く、もっと遠くへ。",
"copy_d": "軽さが続く、週末ランで遠くへ",
"copy_models": {
"copy_a": "gpt-5.6 sol",
"copy_b": "gemini-3.1 pro",
"copy_c": "opus5",
"copy_d": "tokyotech-llm/Qwen3-Swallow-32B-SFT-v0.2"
},
"use_model": "gpt-5.6 sol"
}
90問から30問へ進む前に、3つの設計を分ける
そこで、次の3つを別の設計として順番に固定します。
| 順番 | 設計 | 決めること | 成果物 |
|---|---|---|---|
| 1 | 評価設計 | 何を良いコピーと判定し、誰が何を担当するか | evaluation-design-v0.4.md |
| 2 | 分類設計 | 90問をどの属性で分類するか | classification-design-v1.0.md |
| 3 | 抽出設計 | 分類結果から30問をどう選ぶか | sampling-design-v1.0.md |
重要なのは、評価設計と分類・抽出を混ぜないことです。評価設計はコピーの採否を決めるルール、分類設計は問題の特徴を記述するルール、抽出設計は母集団から評価対象を選ぶルールです。
設計1:何を良いコピーと判定するか
概略
4候補を見せて「一番良いものを選んでください」だけでは、評価者ごとに「良い」の意味が変わります。また、4つとも実務では使えないのに相対的な1位が正解扱いされる問題も起きます。
追加調査と有識者依頼の作業量を踏まえ、Backendの厳密さを保ちながら、有識者の画面は必要な品質判断だけに絞りました。
| Layer | 内容 | 主担当 |
|---|---|---|
| 0a | 文字数・形式Gate | code |
| 0b | 入力整合、日本語、安全・誇大、重複・rights Gate | LLM。UNCERTAINだけ専門確認 |
| 1 | 5軸×5段階の品質評価 | コピー有識者 |
| 2 | 採用/修正/不採用、必要な修正版 | コピー有識者 |
| 3 | A〜D/TIE/REJECT_ALL、Gold Copy | コピー有識者 |
| 4 | 7軸評価とGold再現性の検証 | LLM Judge。後工程 |
ここでいう「有識者」はコピーライターです。法務・表示・rightsの専門確認が必要なUNCERTAIN案件とは依頼先を分けます。コピー有識者に文字数を数えてもらったり、日常的なHard Gateを再判定してもらったりはしません。
調査で特に重要だったのは、広告の創造性を「独自性」だけで測れないことです。広告創造性はdivergenceとrelevanceの相互作用で説明され、67論文・93 dataset・878 effect sizesを統合したmeta-analysisでも、originalityだけでなくappropriatenessを含めた方が消費者反応との関係が強いと報告されています。
- Modeling the Determinants and Effects of Creativity in Advertising
- A Meta-Analysis of When and How Advertising Creativity Works
また、スローガンの好意度にはmessage clarity、benefit提示、creativityが関連するという研究があります。そこで「分かりやすい」と「価値が伝わる」を同じ軸へ押し込まず、メッセージ明瞭性とベネフィット・価値提案へ分けます。
詳細設計1:匿名化した同じ入力を使い、依頼項目は分ける
コピー有識者とLLMには、次の入力と匿名化したコピー1件を使います。ただし、評価票は同一にしません。
product / target / feature / benefit / tone / constraint
+
匿名化したキャッチコピー1件
単独評価中は、生成モデル名、copy_a などの元の位置、ほかの候補、既存評価を見せません。候補IDを固定seedでA〜Dへ再採番します。System側はHard Gateと7軸LLM Judgeの詳細を保持できますが、有識者のExcelへは表示しません。
詳細設計2:Hard Gateはコード/LLM側で先に通す
| ID | 判定項目 | PASS | FAIL | UNCERTAIN / WARNING |
|---|---|---|---|---|
| H1 | 制約遵守(code) | 指定文字数・形式を満たす | 明確に違反 | 制約文自体が曖昧 |
| H2 | 入力整合性(LLM) | 入力にない事実を足していない | 数値、効果、素材、保証等を捏造 | 常識表現か追加主張か判断困難 |
| H3 | 日本語成立(LLM) | 自然に意味が通る | 文法破綻、文字化け、意味不明 | 解釈が分かれる |
| H4 | 安全・表示リスク(LLM) | 過度な断定がない | 治療、保証、誇大な性能断定等 | 法務・表示等の専門判断が必要 |
| H5 | 重複・rights risk(LLM) | 限定scopeで強い類似なし | 今回の限定scopeでは自動FAILにしない | Dataset内の強い構文重複はWARNING |
H1〜H4に1つでも FAIL があれば評価対象から除外します。H2〜H4の UNCERTAIN は PENDING_SPECIALIST とし、コピー品質評価とは別の専門確認へ送ります。H5の WARNING は PENDING_RIGHTS_CHECK とし、Gold化前に多様性とrightsを確認します。
文字数は、前後の空白を除き、Unicode NFC正規化後に数えます。句読点と記号も1文字です。「N文字以内」はN以下、「N文字程度」は暫定的にN±20%を許容します。H1はプログラムで実行し、今回の30問×4候補では120件中105件がPASS、15件がFAILでした。これはコピー品質の採点ではなく、配布前の適格性確認です。
H2〜H5を実行するために準備したもの
H2〜H5は、判定項目の文章だけでは安定して実行できません。そこで次の4点を固定しました。
-
hard-gate-spec-v1.1.md:各Gateの境界と最終分岐 -
hard-gate-prompt-v1.1.md:一般的な主観表現や比喩を入力外事実と誤認しないための実行指示 -
hard-gate-result.schema.json:候補ID、PASS/FAIL/UNCERTAIN、Reason Code、根拠を必須にした構造化出力 -
run_hard_gate.py:10件単位のbatch、失敗batchだけの再試行、入力・prompt・schemaのSHA-256、処理時間を保存するrunner
判定モデルは gpt-5.6-sol、reasoning effortはhighです。入力へ生成モデル名は含めず、候補IDと6つの商品条件、匿名コピー、分類上のrisk、別設問との機械的類似度だけを渡しました。OpenAIのモデル仕様上、gpt-5.6-sol はStructured Outputsに対応しています。
なお、生応答へ持たせたモデル自己申告欄はGPT-5またはjudge名を返し、canonical model IDとして安定しませんでした。そのためmodel provenanceには使わず、runnerがCLIへ渡した--model値と実行ログを正本にしています。判定結果の集計・分岐も自己申告欄には依存しません。
20候補で校正してから105候補へ進めた
最初のHard Gate v1.0を20候補へ適用したところ、3つの過剰判定が見つかりました。
- 同一設問のA〜Dは同じBriefを共有するため、H5の類似比較対象にすると誤警告になる
- 「おいしく」「ぬくもり」「守る」など、商品カテゴリで自然な主観表現・比喩を入力外事実と誤認する
- 入力側に健康・安全riskがあるだけで、候補文がその主張をしていなくてもH4を保留する
そこでv1.1では、H5から同一設問内比較を除外し、一般的な非定量表現を許容し、H4を候補文が実際に表明した主張だけで判定するよう変更しました。再校正20件では、意図した棄却3件を残しながら、過剰判定を解消できたため本実行へ進めました。校正結果を黙って上書きせず、v1.0とv1.1の結果・監査記録を別々に保存しています。
有識者にも今回抽出した校正対象分についても確認してもらいます。
105候補へH2〜H5を本実行した結果
H1を通過した105候補を11batchで判定しました。処理時間は890.288秒、再試行は0回でした。Gateごとの件数は次のとおりです。
| Gate | PASS | FAIL | UNCERTAIN | WARNING |
|---|---|---|---|---|
| H2 入力整合性 | 88 | 14 | 3 | 0 |
| H3 日本語成立 | 101 | 3 | 1 | 0 |
| H4 安全・表示risk | 83 | 12 | 10 | 0 |
| H5 重複・rights risk | 101 | 0 | 0 | 4 |
1候補が複数GateでFAIL/UNCERTAINになる場合があるため、上の列を単純加算して最終件数にはしません。H1の15件も含む全120候補の最終分岐は次のとおりです。
| 最終分岐 | 件数 | 次の扱い |
|---|---|---|
READY_FOR_EXPERT_LIMITED_RIGHTS_SCOPE |
77 | コピー有識者の5軸評価へ進める |
REJECT_SYSTEM_GATE |
17 | H2〜H4のFAILにより除外 |
REJECT_CONSTRAINT |
15 | H1の文字数制約FAILにより除外 |
PENDING_SPECIALIST |
8 | 表示・健康・安全等の専門確認へ送る |
PENDING_RIGHTS_CHECK |
3 | 類似表現・rights確認へ送る |
上表は候補を重複なく数えるための主分岐です。H5 WARNINGは4候補あり、そのうち1候補はH4の専門確認待ちでもあります。実作業用のrights確認queueには重複を含む4候補を入れ、警告を取りこぼさないようにしました。
たとえば、「窮屈になりにくい」を「ストレスフリー」、「費用を減らせる」を「今年はゼロ」、「疲れにくい」を「どこまでも歩ける」と強めた候補は棄却されました。一方、専門的な表示判断が必要な生理・健康表現は、コピー有識者へ判断させず別queueへ保留しています。
今回のH5は、120候補内の機械的類似比較とモデル知識に限定しています。外部Web検索、商標調査、既存広告DB照合、法律判断は実施していません。したがってH5のPASSは、公開・採用時の権利安全を保証するものではありません。
詳細設計3:有識者は5軸×5段階で採点する
軸名だけを定義しても、人間とLLMは同じ「4点」を意味しません。そこで全軸の1〜5点を操作的に定義します。
| 軸・重み | 1点 | 3点 | 5点 |
|---|---|---|---|
| わかりやすさ 15% | 意味や主訴求を安定して解釈できない | 意味は分かるが主訴求がやや曖昧 | 一読で単一の主訴求と顧客価値が明確 |
| ターゲット・商品適合 20% | 対象・商品条件とずれる、または汎用的 | 商品には合うが対象者の場面・欲求との結び付きが弱い | 対象者固有の場面・欲求と商品特徴が自然に結び付く |
| ベネフィット訴求 25% | Feature説明だけで利用価値がない | 利点は分かるが一般的で、因果が弱い | Featureを対象者に意味のある具体価値へ無理なく変換 |
| 独自性・印象 20% | 常套句・template中心で印象に残らない | 工夫はあるが見慣れている | 商品に根差した新鮮な表現で適切な印象を残す |
| コピーとしての完成度 20% | 説明文的・不自然・冗長 | 成立するが語感・リズム・toneが平板 | 簡潔さ、語感、リズム、toneが整いそのまま使える |
1・3・5をAnchorとし、2は1と3の中間、4は3と5の中間です。軸ごとの長文理由は求めず、候補全体について1〜2文の理由だけを依頼します。これにより作業量を抑えつつ、点数境界のブレを減らします。
LLM Judge側では、明瞭性、ターゲット関連性、ベネフィット、商品整合性、独自性、tone、表現完成度の7軸をBackend分析用に保持できます。ただし、この7軸を有識者用Excelへそのまま載せません。
記憶性と行動喚起力を総合点から外した理由
2024年のJournal of Consumer Researchでは、800以上のスローガン、実験、eye tracking、field studyを通じ、好まれやすい言語特性と記憶されやすい言語特性が一致しない場合が示されています。有識者やLLMが「覚えられそう」と答えても、実際の記憶を測ったことにはなりません。そのため、perceived_memorabilityは参考Outcomeとして残し、総合点へ加えません。
また、現在の入力にはcampaign objective、placement、conversion goalがありません。「買いたくなるべきか」「ブランド好意を作るべきか」を評価者が勝手に補うことになるため、行動喚起力も外し、コピーそのものの完成度と引力へ置き換えます。売上やCTRは、将来の消費者調査・A/B testで別に測ります。
詳細設計4:加重点と実務判断を分ける
weighted_score =
clarity / 5 × 15
+ fit / 5 × 20
+ benefit / 5 × 25
+ originality / 5 × 20
+ craft / 5 × 20
加重点は比較・分析用であり、閾値だけで実務判断を自動決定しません。有識者は別に 採用 / 修正 / 不採用 を付けます。高得点でも修正が必要、または中程度の得点でも核となる発想は採用できる、というプロの判断を残すためです。
詳細設計5:単独採点と商品別の実務判断を分ける
加重scoreとは別に、有識者へ「実務でこのまま採用するか」を聞きます。
採用 / 修正 / 不採用
修正では理由と修正版を必須にします。商品ごとの比較では A / B / C / D / TIE / REJECT_ALL を使い、REJECT_ALLでは共通理由、1つのGold Copy、その意図を必須にします。相対1位を無理に正解へしません。
2026年の人工知能学会会議録でも、広告コピーの相対比較から言語化されていない評価基準を蓄積・精緻化し、Criteria Driftを追跡する枠組みが報告されています。ただし、この研究はLOW/HIGH二値分類であり、今回の5軸Rubricを直接検証したものではありません。そこで本プロジェクトでは、Criteria Driftをcalibration中だけ許し、本評価開始後はRubricを固定します。
詳細設計6:有識者をGold、LLMをJudge候補にする
有識者とLLMを50:50で平均しません。有識者評価をGold Labelとし、LLM Judgeがその基準を再現できるかを測ります。MLflowもdomain expertのfeedbackでJudgeをalignする手順を提供し、OpenAIもLLM Judgeを人間ラベルとのagreement確認後にscaleすることを推奨しています。
有識者への依頼資料は、30問を確定してから作成します。今回のExcelでは、最終30問から分類層の異なる5問を校正用に固定しました。有識者はまず校正Sheetを独立に記入し、2点以上の差、判定不一致、想定外理由を確認します。Anchor確定後、校正5問も本評価Sheetで改めて採点します。校正結果は上書きせず、本評価中の新観点は emergent_criteria へ記録します。
詳細設計7:一致度を目的別に測る
| 比較対象 | 指標 | 暫定Gate |
|---|---|---|
| 有識者A vs Bの各軸 | ordinal Krippendorff's alpha | 0.67以上で暫定、0.80以上を目標 |
| LLM vs 有識者Gold | weighted kappa、MAE、±1点以内率 | MAE 1.0以下、±1点以内90%以上 |
| 3段階実務判断 | Macro-F1+raw agreement | Macro-F1 0.75以上、agreement 80%以上 |
| pairwise winner | pairwise agreement | 80%以上 |
Krippendorff's alphaは有識者間、weighted kappaとMAEはLLMとGoldの距離に使い分けます。0.67や0.80などは絶対的な真理ではなく、不一致を検出してRubricを直すための暫定Gateです。
LLM Judgeの7軸にも操作的定義とAnchorを与えますが、score説明の提示順にもbiasがあり得ます。calibrationでは5段階のscore説明をbalanced permutationし、各scoreが各位置に1回ずつ現れるようにします。候補間比較もA/BとB/Aの両順序で実行し、勝者が反転した場合は position_unstable=true としてTIEまたは人間裁定へ回します。
採用可能候補が0件なら REJECT_ALL、優劣を評価軸で説明できなければ TIE とします。
設計2:90問をどんな属性で分類するか
概略
分類の目的は、良いコピーを探すことではなく、90問の問題構成を可視化することです。分類には入力の6項目だけを使い、copy_a〜copy_d と評価結果は使いません。
use_model は意味分類から除外しますが、GPT、Opus、Geminiが各30問を作ったという出題provenanceは保持します。これは後の抽出で、特定モデルが作った問題へ偏らないためです。
詳細設計1:分類Schema
| 分類項目 | 値・意味 |
|---|---|
domain |
衣 / 食 |
product_group |
衣5分類+食5分類 |
appeal_axis |
機能、時短、快適、健康、感情の5軸 |
target_scene |
通勤、日常、運動、調理・食事、睡眠、防災など |
benefit_type |
FUNCTIONAL / EMOTIONAL / MIXED |
constraint_mode |
WITHIN / APPROX |
constraint_band |
12字以内 / 13〜15字 / 16〜20字 / 21字以上 |
has_numeric_claim |
数値根拠の有無 |
claim_risk |
LOW / MEDIUM / HIGH |
difficulty_score |
5つの難易度flagの合計、0〜5 |
difficulty_band |
LOW / MEDIUM / HIGH |
source_creator |
gpt / opus / gemini。provenance専用 |
商品分類は次の10種類です。
| 衣 | 食 |
|---|---|
| トップス・インナー | 主食・惣菜 |
| アウター | 飲料 |
| ボトムス・ワンピース | 菓子・間食 |
| 靴・靴下 | 健康・栄養 |
| 部屋着・小物 | 調味料・素材 |
訴求軸は、機能・性能、時短・利便性、悩み・快適性、健康・安心・素材、感情・上質・体験 の5つです。複数に当てはまる場合は、benefit が最も強く約束している価値を主軸とし、副軸も別フィールドへ残します。
詳細設計2:難易度を5つのflagへ分解する
| flag | trueになる条件 |
|---|---|
strict_length |
「以内」で15字以下、または複数の形式制約がある |
target_and_scene |
属性だけでなく具体的な利用場面まで表現する必要がある |
numeric_grounding |
数値・割合・時間・回数を正確に扱う必要がある |
claim_sensitivity |
健康、身体、性能、保証の誇大表現riskがある |
functional_to_emotional |
機能説明を感情・体験価値へ変換する必要がある |
trueの数が0〜1なら LOW、2〜3なら MEDIUM、4〜5なら HIGH とします。単に「難しい」と主観でラベルを付けず、難しさの原因を残すのが狙いです。
詳細設計3:分類を凍結してから抽出する
文字数、以内/程度、数値有無は規則で抽出し、意味ラベルはCodebookに従って付けます。境界事例は入力フィールドを根拠に人間が裁定します。90件の欠損と頻度を確認し、分類Versionと merged.json のhashを付けた sampling_frame_v1.0 を凍結します。
抽出結果を見てから都合よく分類を変えると、選択バイアスが入るため、分類を直した場合は30問抽出も最初からやり直します。
実施結果:90問を分類した
この設計を classify_and_select_v1.py へ実装し、90問すべてへラベルを付けました。意味分類には6つの入力フィールドだけを使い、copy_a〜copy_d は参照していません。use_model は出題元quotaのためだけに保持しました。
| 項目 | 結果 |
|---|---|
| 分類件数 | 90 / 90 |
| 欠損 | 0 |
| 入力SHA-256 | ee045a0855563081c48c2abcb695f91de85dd438a955393a1f5204927da1fe3a |
| 成果物 | classification_frame_v1.0.json |
アームカバーを着用小物、完全食グミを栄養目的、真空米びつを食関連器具の境界例として扱うなど、境界判断は classification_reason に残しました。
設計3:分類結果から30問をどう選ぶか
概略
抽出時にはコピー本文も評価点も使いません。Hard quotaを必ず満たし、その中で90問の属性分布に最も近い30問を選びます。
詳細設計1:必ず満たすHard quota
| 軸 | quota |
|---|---|
| 総数 | 30 |
| テーマ | 衣15 / 食15 |
| 商品分類 | 10分類×3 |
| 出題元 | gpt 10 / opus 10 / gemini 10 |
出題元の均衡は、回答モデルの点数を揃える操作ではありません。3モデルがそれぞれ30問を作ったため、商品選択や表現傾向が特定の出題元へ偏らないようにするblockです。
詳細設計2:母集団比へ近づけるSoft target
- 訴求5軸は各6問を第一目標にする
- 難易度LOW / MEDIUM / HIGHは各10問へ近づける
- 利用場面、文字数制約、数値有無、claim risk、benefit typeは90問の構成比との差を最小化する
- 同一または非常に近い商品・利用場面の重複を減らす
母集団に少ない属性を無理に等分すると、今度は90問全体を代表しない30問になります。そのため、Hard quota以外は母集団比を基準にします。
詳細設計3:再現可能な選択にする
各商品群から3件を選ぶ候補を固定seedで探索し、Hard quotaを満たす組合せだけを比較します。その中で、Soft targetの期待件数との差と類似問題の重複penaltyが最も小さい候補を採用しました。
記録するのは、元ファイルのSHA-256、分類Version、抽出Version、seed、Hard quotaの検証結果、各Soft targetの母集団比・期待件数・選択件数・偏差、採用した source_index です。
実施結果:30問を抽出しdataset_v1.0を作成した
旧 selected_30.json は、次の3条件までは満たしていました。
| 抽出軸 | 現行案 |
|---|---|
| テーマ | 衣15 / 食15 |
| 商品分類 | 10分類×3 |
| 訴求軸 | 5軸×6 |
一方、難易度、利用場面、文字数制約、数値有無、claim risk、benefit type、出題元均衡は抽出条件に入っていません。現行30問の出題元は gpt 15 / opus 10 / gemini 5 です。
このファイルは selection draft として残し、新設計で抽出をやり直しました。
| 実行項目 | 値 |
|---|---|
| 固定seed | 20260821 |
| 探索した組合せ | 750,000 |
| Hard quotaを満たした比較候補 | 27,879 |
| 採用objective | 40.333333 |
これは固定seed探索で見つけた最良解であり、global optimumは保証していません。再現性のため、この制約も selection_report_v1.0.json に明記しました。
Hard quotaの結果は次のとおりです。
| 軸 | 抽出結果 |
|---|---|
| 総数 | 30 |
| テーマ | 衣15 / 食15 |
| 商品分類 | 10分類×3 |
| 出題元 | gpt 10 / opus 10 / gemini 10 |
Soft targetは、訴求軸が健康7、快適6、感情5、時短5、機能7でした。難易度はLOW 11、MEDIUM 16、HIGH 3です。母集団のHIGHが3件しかなかったため、各10へ無理に揃えず、3件すべてを残しました。
確定した30問と4候補を dataset_v1.0.json、抽出条件・分布・source indexを selection_report_v1.0.json に保存しました。ここで初めて、旧draftではなく dataset_v1.0 と呼びます。
dataset_v1.0からv1.5へ
dataset_v1.0 に含めるのは、分類済み30問、4候補、抽出provenanceです。正式な正解ラベルはまだありません。匿名候補とモデルの復号表は expert_candidate_mapping_v1.0.json として内部管理し、有識者には渡しません。
30問を確定してから、有識者依頼資料を作る
共有された作業例では、90問のまま評価Excelを先に作っていました。しかし今回の正しい工程は、分類設計を90問へ適用し、30問を抽出して dataset_v1.0 を固定してから依頼資料を作る順序です。
今回作成したExcelは次の5Sheetです。
| Sheet | 内容 |
|---|---|
01_依頼概要 |
目的、対象、Systemと有識者の役割、実施順序 |
02_評価基準 |
5軸の重みと1・3・5点Anchor |
03_校正評価 |
分類層を跨ぐ5問の校正用評価 |
04_本評価 |
抽出済み30問の匿名・単独評価 |
05_商品別総合 |
A〜D/TIE/REJECT_ALL、Gold Copy |
H1のFAIL 15件、H2〜H4で棄却した17件、専門確認待ち8件、主分岐で類似・rights確認待ちとなった3件を単独評価Sheetから除外しました。H5 WARNINGは4件ですが、1件は専門確認待ちと重複します。Excelは、Hard Gateを通過した77候補だけを収録した配布版です。30問すべてに少なくとも1候補が残っています。有識者にはHard Gateの内部Reason Codeや証拠抽出を依頼しません。
次工程では、System Hard Gate、コピー有識者の5軸評価、7軸LLM Judgeを別々のsourceとして保存し、不一致を消さずに追跡します。MLflowのFeedbackも、プログラム検査、LLM judge、人間評価を別の評価sourceとして扱い、複数評価者の不一致や人間によるoverrideを保持できる設計です。
有識者の最終裁定、採用・不採用理由、REJECT_ALL、必要な修正版と、LLM Judgeの比較結果まで加えたものを dataset_v1.5 とします。
まとめ
今回行ったのは、キャッチコピー生成モデルを評価するための90問と回答候補を揃え、設計に従って90問を分類し、未評価30問の dataset_v1.0 を固定し、Hard Gate後の有識者依頼資料を作る作業です。
gpt-5.6 solで基本型と30問を作成
↓
opus5とgemini-3.1 proでも各30問を作成
↓
3つをマージして90問にする
↓
90問へ4モデルのキャッチコピーを追加
↓
90問×4候補=360件のbaseline_dataset_v0.5
↓
良いコピーの評価基準を固定
↓
入力6項目で90問を分類
↓
Hard quotaと母集団比から30問を抽出
↓
未評価30問のdataset_v1.0
↓
120候補へコード/LLM Hard Gateを実行
↓
通過77候補から有識者依頼資料を作成
この段階では、どのモデルが優れているかはまだ評価していません。
次の作業は、保留した8候補を表示・健康等の専門確認へ、重複を含む4候補を類似・rights確認へ送り、並行して通過77候補のコピー有識者校正と5軸評価を始めることです。その後、LLM Judgeとの一致度を検証します。有識者の最終裁定まで追加した段階が dataset_v1.5 です。
参考資料
- 前回記事:LLMのFine-tuningは「教師データ作り」で決まる?[実験計画編]
- 評価基準に関する調査メモ(共有会話)
- 有識者依頼とLLM Hard Gateの役割分担(共有会話)
- jq Manual
- MLX-LM batch_generate example
- Qwen3-Swallow-32B-SFT-v0.2 Model Card
- OpenAI Evaluation best practices
- MLflow GenAI:Feedback
- MLflow Custom Judges
- MLflow Judge Alignment
- Weighted Krippendorff's Alpha is a More Reliable Metrics for Multi-Coders Ordinal Annotations
- Modeling the Determinants and Effects of Creativity in Advertising
- A Meta-Analysis of When and How Advertising Creativity Works
- A study of the antecedents of slogan liking
- Intel Inside: The Linguistic Properties of Effective Slogans
- Training-Free GRPOによるCriteria Drift観測:広告コピー品質評価のための自己進化型評価基準
- Am I More Pointwise or Pairwise? Revealing Position Bias in Rubric-Based LLM-as-a-Judge