答えの出どころを見せる
引用とは、答えの中の印で、その答えの出どころの資料を指すものです。確かめられる答えのほうが信用されやすく、印はプログラムでも確かめられるからです。
図書館のチャットボットが、遅れた本は1日10円だと答え、その後ろに[2]と付けます。読む人が資料2を見ると、同じ規則が書いてあります。
このレッスンのゴール
メモ
私は、答えがどの出典を使ったかを示せます。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 出典 | 答えが使ってよい、文章の一節 | |
| 引用 | 答えから、その出典を指すこと | |
| 印 | 引用を作る、角かっこの番号 | [2] |
| 根拠のある答え | 与えた出典に基づいている答え | |
| 使われない出典 | どの印も指していない出典 |
学生が入力するセルは、このプレビューでは空白です。
出典に番号を付け、印を頼む
出典を一つずつ、番号を付けてプロンプトに書きます。[1]、[2]、[3] のようにします。そして、その出典だけを使い、事実のあとに番号を書くよう、モデルに頼みます。
ここでの出典は、スクリプトに書いた文章です。本物の出典の集め方は、あとのモジュールで扱います。与えた内容にとどまっている答えは、根拠のある答えです。
例: 出典と答え
| 部分 | 文章 |
|---|---|
| 出典 [1] | 会員は、本を6冊まで、3週間借りられます。 |
| 出典 [2] | 返却が遅れた本は、1日につき10円かかります。 |
| 質問 | 本は何冊借りられますか。遅れたときの料金はいくらですか。 |
| 答え | 本は6冊まで借りられます[1]。遅れると、1日10円かかります[2]。 |
学生が入力するセルは、このプレビューでは空白です。
どの印にも出典があるか確かめる
モデルは、出典が3つしかないのに [4] と書くことがあります。プログラムは、それに気づけます。印をすべて見つけ、それぞれの番号を、出典 ID のリストと比べます。
使われていない出典や、印のない文も探します。答えが何を落としたかがわかります。
よくある間違い
注意
「印があれば、答えは正しい」と考える人が多いです。印が証明するのは、出典が存在することだけです。モデルは、ある事実に違う出典を付けることがあります。確認は最初のふるいで、大事なことは、人が出典を読みます。
モデルの補助を書く(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 SOURCES = [' ' { id: 1, text: \"会員は、本を6冊まで、3週間借りられます。\" },' ' { id: 2, text: \"返却が遅れた本は、1日につき10円かかります。\" },' ' { id: 3, text: \"図書館は、平日の午前9時に開き、午後5時に閉まります。\" },' '];' > cite5.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
引用の確認を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function sourceText() {' ' return SOURCES.map(function (s) { return \"[\" + s.id + \"] \" + s.text; }).join(\"\n\");' '}' 'function markersIn(reply) {' ' const found = [];' ' const re = /\[(\d+)\]/g;' ' let match = re.exec(reply);' ' while (match) { found.push(Number(match[1])); match = re.exec(reply); }' ' return found;' '}' >> cite5.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
引用の確認を書く(3)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function check(reply) {' ' const ids = SOURCES.map(function (s) { return s.id; });' ' const markers = markersIn(reply);' ' const missing = markers.filter(function (n) { return ids.includes(n) === false; });' ' return { markers: markers, missing: missing, ok: markers.length > 0 && missing.length === 0 };' '}' 'function show(label, result) {' ' console.log(label + \" 印 \" + JSON.stringify(result.markers) + \"、出典なし \" + JSON.stringify(result.missing) + \"、ok: \" + result.ok);' '}' >> cite5.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
引用の確認を書く(4)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const rule = \"次の番号付きの資料だけを使って答えてください。事実のあとに、その資料の番号を角かっこで書いてください。例: [1]。資料に書かれていなければ、「わかりません」と答えてください。\n\" + sourceText();' ' const question = \"本は何冊借りられますか。遅れたときの料金はいくらですか。\";' ' // 記録済みのサンプル。モデルが答えないときだけ使う。' ' const sample = \"本は6冊まで借りられます[1]。遅れると、1日10円かかります[2]。\";' ' const reply = await ask([{ role: \"system\", content: rule }, { role: \"user\", content: question }], sample, 80);' ' console.log(\"返事:\", reply);' ' show(\"確認:\", check(reply));' ' show(\"作り話の返事:\", check(\"貸出期間は3週間です[4]。\"));' '}' 'main();' >> cite5.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
質問して、印を確かめる
docker exec -w /home/node/project agent node cite5.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
出力の一例
| 行 | 表示されるかもしれないもの |
|---|---|
| 返事 | 2つの短い文。それぞれの終わりに [1] のような印 |
| 確認: | 印 [1,2]、出典なし []、ok: true(返事が出典の中にとどまったとき) |
| 作り話の返事: | 印 [4]、出典なし [4]、ok: false(いつも) |
学生が入力するセルは、このプレビューでは空白です。