型は繰り返し使う小さな形
プロンプトの型とは、決まった問題を直すために、目的を持って使うプロンプトの形です。ペルソナ、テンプレート、批評と書き直し、制約を先に、の四つを扱います。
型に名前があると、チームでプロンプトを話し、試せます。「これは制約を先にの型だ」は、行動につながる一文です。
このレッスンのゴール
メモ
少数のプロンプトの型を、目的を持って使えます。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 型 | 使い道が分かっているプロンプトの形 | |
| ペルソナ | モデルに演じてもらう立場 | |
| テンプレート | 穴を埋めて使うプロンプト | |
| プレースホルダー | テンプレートの穴 | {{name}} |
| 批評 | 悪いところの一覧 | |
| 制約 | 答えが守る決まり |
学生が入力するセルは、このプレビューでは空白です。
四つの型は何をするか
ペルソナは、立場と話し方を決めます。テンプレートは、コードが穴を埋めるので、どのプロンプトも同じ形になります。批評と書き直しは、先に欠点を探し、次に直させます。制約を先には、決まりを依頼の前に置くので、忘れられません。
型は組み合わせられます。テンプレートが、制約から始まってもかまいません。
四つの型と、それが直すもの
| 型 | プロンプトの目印 | 直すもの |
|---|---|---|
| ペルソナ | 「あなたは」で始まる | ぶれる話し方 |
| テンプレート | {{name}} のような穴 | ばらばらなプロンプト |
| 批評と書き直し | 二つの段階を頼む | 最初の下書きのまま |
| 制約を先に | 「ルール:」で始まる | 最後に忘れられる決まり |
学生が入力するセルは、このプレビューでは空白です。
モデル用の補助を書く(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 prompts = [' ' \"あなたは優しい数学の先生です。分数を説明してください。\",' ' \"ルール: 40 字以内。専門用語なし。\n依頼: 潮の満ち引きを説明して。\",' ' \"{{name}} さんに {{topic}} のお知らせを書いてください。\",' ' \"この段落を批評してから、書き直してください。\",' ' \"潮の満ち引きを説明してください。\",' '];' > pat4.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
型の判定を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function patternOf(p) {' ' if (p.includes(\"批評\") && p.includes(\"書き直\")) return \"批評と書き直し\";' ' if (p.startsWith(\"ルール:\") || p.startsWith(\"制限:\") || p.startsWith(\"制約:\")) return \"制約を先に\";' ' if (p.includes(\"{{\") && p.includes(\"}}\")) return \"テンプレート\";' ' if (p.startsWith(\"あなたは\") || p.startsWith(\"次の役になって:\")) return \"ペルソナ\";' ' return \"ふつう\";' '}' 'function fill(t, values) {' ' let out = t;' ' for (const key of Object.keys(values)) out = out.split(\"{{\" + key + \"}}\").join(values[key]);' ' return out;' '}' >> pat4.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
型の判定を書く(3)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' prompts.forEach(function (p, i) { console.log((i + 1) + \": \" + patternOf(p)); });' ' const filled = fill(prompts[2], { name: \"美咲\", topic: \"遠足の集合時間\" });' ' console.log(\"埋めた結果: \" + filled);' ' const reply = await ask([{ role: \"user\", content: filled }], \"美咲さん、遠足の集合は朝 8 時に校門前です。\", 80);' ' console.log(\"モデル: \" + reply.text);' '}' 'main();' >> pat4.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
型の名前を出して実行する
docker exec -w /home/node/project agent node pat4.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
Run が表示するもの
五行で、各プロンプトの型が出ます。ペルソナ、制約を先に、テンプレート、批評と書き直し、ふつうの順です。調べる順番は決まっていて、目印が二つあるときは、最初に合ったものになります。
そのあとテンプレートを埋めて送ります。最後の行は短い答えで、モデルがなければ先に「記録済みサンプル」と出ます。
よくある間違い
注意
「ペルソナを付けると、モデルが正確になる」と考えがちです。役割は話し方と詳しさを決めますが、モデルが持たない事実は足しません。ペルソナは調子に、制限と例は正しさに使ってください。