プロンプトを版とテスト付きで保つ
プロンプトライブラリとは、版とテストを付けて、ファイルとして保つプロンプトのフォルダです。チャットの一通に入ったプロンプトは、なくなり、誤って写され、見つけた人に書き換えられます。
ファイルなら、コードと同じように、見直し、試し、元に戻せます。
このレッスンのゴール
メモ
プロンプトを、版とテスト付きのファイルとして保てます。
キーワード
| ことば | いみ | れい |
|---|---|---|
| ライブラリ | ファイルで保つプロンプトのフォルダ | |
| 変数 | コードが埋める、名前のある穴 | {name} |
| 版 | どの編集かを示す番号 | |
| 変更履歴 | 何をなぜ変えたかの一覧 | |
| 規則 | プロンプトが必ず持つ言い回し | |
| 監査 | すべてのプロンプトを一度に調べること |
学生が入力するセルは、このプレビューでは空白です。
一つのプロンプトファイルに何を入れるか
プロンプトは一つずつファイルにします。例は refund-reply.txt です。穴は {name} のように波かっこで書く変数にして、コードが埋めます。版の番号をファイルに付け、変更履歴に何が変わったかを一行書きます。
隣にテストを置きます。テストには、プロンプトが必ず持つ規則を入れます。
版の番号が教えること
| 変更 | 上げる桁 | 1.2.3 から |
|---|---|---|
| 誤字を直した | patch | 1.2.4 |
| 制限や例を足した | minor | 1.3.0 |
| 変数を変え、呼ぶ側も直す | major | 2.0.0 |
学生が入力するセルは、このプレビューでは空白です。
モデル用の補助を書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// 応答に含まれるトークン数。なければ null。' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
モデル用の補助を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' '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 || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"status \" + res.status);' ' const d = await res.json();' ' return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' ' } catch (error) {' ' console.log(\"記録済みサンプル: モデルが答えませんでした (\" + error.message + \")。\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' 'module.exports = { ask };' >> model.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ライブラリの検査を書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const OLD = \"役割: あなたはバス会社の案内係です。\n依頼: {name} さんの返金について返信を書く。\n制限: 40 字以内。日付は約束しない。\";' 'const RULES = [\"40 字以内\", \"日付は約束しない\"];' > lib6.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ライブラリの検査を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function variables(text) {' ' const names = [];' ' for (const f of text.match(/\{[a-z_]+\}/g) || []) {' ' if (names.includes(f.slice(1, -1)) === false) names.push(f.slice(1, -1));' ' }' ' return names;' '}' 'function fill(text, values) {' ' const gone = variables(text).filter(function (n) { return (n in values) === false; });' ' if (gone.length > 0) return { ok: false, missing: gone };' ' let out = text;' ' for (const n of Object.keys(values)) out = out.split(\"{\" + n + \"}\").join(values[n]);' ' return { ok: true, text: out };' '}' >> lib6.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ライブラリの検査を書く(3)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function lost(oldText, newText) {' ' return RULES.filter(function (r) { return oldText.includes(r) && newText.includes(r) === false; });' '}' 'async function main() {' ' console.log(\"変数: \" + variables(OLD).join(\"、\"));' ' const bad = fill(OLD, {});' ' console.log(\"値なしで埋める: ok \" + bad.ok + \"、足りない \" + bad.missing.join(\"、\"));' ' const edit = OLD.replace(\"日付は約束しない。\", \"\");' ' console.log(\"この編集で失う規則: \" + lost(OLD, edit).join(\"、\"));' ' const filled = fill(OLD, { name: \"美咲\" });' ' const reply = await ask([{ role: \"user\", content: filled.text }], \"美咲さん、返金を確認しています。\", 80);' ' console.log(\"モデル: \" + reply.text);' '}' 'main();' >> lib6.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
悪い編集を断って実行する
docker exec -w /home/node/project agent node lib6.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
Run が表示するもの
最初に変数を並べます。次に、値なしで埋めると断られ、足りない名前が示されます。続いて、制限を消す編集で失う規則を並べます。その編集は断られます。
最後の行は、埋めたプロンプトへの短い答えです。モデルがなければ、先に「記録済みサンプル」と出ます。
よくある間違い
注意
「共有のプロンプトの小さな編集は安全だ」と考えがちです。短い編集でも、ほかのコードが頼っていた制限を消すことがあります。どんなに小さくても、保存する前に規則のテストを走らせてください。