プロンプト、検索、微調整の選び方
モデルを使った機能を変える方法は三つあります。よいプロンプト、検索、そして微調整です。検索(RAG、検索拡張生成)は、関係する文書を取ってきて、呼び出しと一緒に送る方法です。微調整(ファインチューニング)は、自分の例でモデルをさらに訓練する方法です。
直せる問題も費用も、三つで大きく違います。それでもチームは、いちばん高いものを最初に選びがちです。
サポートのチームが、会社らしい口調で、今週の価格表に沿って、決まった形式で答えさせたいと考えています。必要は三つで、同じ解決策とは限りません。
このレッスンのゴール
メモ
私は、ある必要に対して、よいプロンプト、検索、微調整のどれを選ぶかを決められます。
キーワード
| ことば | いみ |
|---|---|
| プロンプト | 呼び出しと一緒に送る指示と例 |
| 検索 | 文書を取ってきて、呼び出しと一緒に送ること |
| 微調整 | 自分の例で、モデルをさらに訓練すること |
| 訓練用の例 | 入力と、望む出力の組 |
| 知識 | 答えが頼りにする事実 |
学生が入力するセルは、このプレビューでは空白です。
ここでは微調整は動かしません
注意
ラボでは、モデルの微調整はできません。このレッスンは判断の演習です。尋ねる問いと、教えるための規則を示します。微調整で何が得られるかは言いません。それは、自分の事例で測ってください。
どんな種類の問題かを尋ねる
四つの問いを順に尋ねます。答えは、非公開か、変わる事実に頼っていますか。モデルは、口調や形式のような形で失敗していますか。例を付けた明確なプロンプトを試しましたか。十分な例と、測る方法はありますか。
事実なら検索です。形なら、まずプロンプトです。微調整は、プロンプトが失敗し、例がそろったときだけです。
例: 五つの必要
| 必要 | 最初の問い | 最初の一歩 |
|---|---|---|
| 親しみやすい口調 | 例つきのプロンプトで失敗するか | プロンプト。失敗して例があれば微調整 |
| 毎週変わる価格 | 事実は変わるか | 検索: 微調整した事実は古くなる |
| 決まった出力形式 | 例で示せるか | プロンプト。出力を読み取って確かめる |
| 社内マニュアルからの答え | 事実は非公開か | 検索。出典を表示する |
| 呼び出しあたりの費用を下げる | プロンプトの大きさは | まず測る。短いプロンプトか小さいモデル |
学生が入力するセルは、このプレビューでは空白です。
選択ごとの費用と限界
プロンプトは、変えるのが安く、戻しやすい反面、呼び出しのたびにトークンを使います。検索は、保管場所と検索を足し、検索が外れると失敗します。微調整は、例と、訓練の実行と、育てていく新しいモデルが要り、事実を新しく保てません。
どれも、足りない要件や、悪い評価は直せません。まず、成功を決める事例を書きます。
よくある間違い
注意
微調整はモデルに新しい事実を教える、と考える人は多いです。実際は、おもに文体や形式を整えます。変わる事実は、文書を直せばその日のうちに答えが変わる、検索に置きます。
モデル用の補助を書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 200 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"status \" + res.status);' ' return (await res.json()).choices[0].message.content;' > model.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
モデル用の補助を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' } catch (error) {' ' console.log(\"記録済みサンプル: モデルが答えませんでした (\" + error.message + \")。\");' ' const list = [].concat(sample);' ' const turn = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' ' return list[Math.min(turn, list.length - 1)];' ' }' '}' 'module.exports = { ask };' >> model.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
判断の規則を書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const cases = [' ' { need: \"親しみやすい口調\", privateDocs: false, factChanges: false, promptFails: true, examples: 800 },' ' { need: \"毎週変わる価格\", privateDocs: false, factChanges: true, promptFails: false, examples: 0 },' ' { need: \"決まった出力形式\", privateDocs: false, factChanges: false, promptFails: false, examples: 40 },' ' { need: \"社内マニュアルからの答え\", privateDocs: true, factChanges: false, promptFails: true, examples: 60 },' ' { need: \"呼び出しあたりの費用を下げる\", privateDocs: false, factChanges: false, promptFails: false, examples: 0 },' '];' > decide.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
判断の規則を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function choose(c) {' ' const retrieve = c.privateDocs || c.factChanges;' ' const tune = c.promptFails && c.examples >= 500;' ' if (retrieve && tune) return \"検索と微調整\";' ' if (retrieve) return \"検索\";' ' if (tune) return \"微調整\";' ' if (c.promptFails) return \"例を集める\";' ' return \"プロンプト\";' '}' 'cases.forEach(function (c) { console.log(c.need + \":\", choose(c)); });' >> decide.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
判断の規則を書く(3)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const text = \"product と price というキーだけの JSON で答えてください。自転車、12000 円。\";' ' const sample = JSON.stringify({ product: \"自転車\", price: 12000 });' ' const answer = await ask([{ role: \"user\", content: text }], sample, 60);' ' let valid = true;' ' try { JSON.parse(answer); } catch (error) { valid = false; }' ' console.log(\"まずプロンプト:\", answer);' ' console.log(\"JSON として正しいか:\", valid);' '}' 'main();' >> decide.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
規則を五つの場合に当てる
docker exec -w /home/node/project agent node decide.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
規則は教えるための規則です
Run が当てはめるのは、読みやすい規則で、測定ではありません。例が 500 件というしきい値は、演習のために決めた数です。自分のしきい値は、自分の事例と評価から決めます。
本物の呼び出しは、いちばん安い一歩を試します。JSON を求めるプロンプトを送り、読み取れるかで確かめます。
出力の一例
| 行 | 何を示すか |
|---|---|
| 親しみやすい口調: 微調整 | プロンプトは失敗し、例が 800 件ある |
| 毎週変わる価格: 検索 | 事実が変わる |
| 呼び出しあたりの費用を下げる: プロンプト | 失敗はないので、まずプロンプトを測る |
| JSON として正しいか | true か false: 読み取れたかを見て、中身は読まない |
学生が入力するセルは、このプレビューでは空白です。