クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

見つけた出典から答える方法

このレッスンのあとで: 見つけた文章からプロンプトを作り、その文章だけで答えさせられる。

70分のレッスンコマンド7件AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

出典付きの答え

検索拡張生成 (RAG) は、まず文章を見つけ、次に、言語モデルに、その文章だけを使って答えるよう頼みます。記憶で答えるモデルは、自信ありげに間違えることがありますが、出典を示すモデルは確かめられるので、これが大切です。

利用者が、土曜日は何時に開くかを尋ねます。サイトは2つの文章を見つけ、モデルに尋ね、答えを、もとの文章と一緒に表示します。

このレッスンのゴール

メモ

見つけた文章からプロンプトを作り、その文章だけで答えさせられる。

キーワード

ことばいみれい
コンテキストプロンプトに入れる文章
プロンプトモデルに送る文章
引用文章を指す印[1]
根拠がある与えた文章だけに基づいていること
断り分からない、と伝える答え

学生が入力するセルは、このプレビューでは空白です。

文章をプロンプトに入れる

モデルは、あなたの文書を読んでいません。ですから、プロンプトが文書を運びます。モデルが1つを指せるように、各文章に番号を付けます。そのあと、質問と決まりを足します。

文章は、少なく、短くします。言葉が1つ増えるごとに費用がかかり、長いプロンプトは、答えを確かめにくくします。

例: プロンプトの部分

部分例役目
決まり次の文章だけを使って答える答えに根拠を持たせる
引用の決まり使った文章を [1] のように示す答えを確かめられるようにする
逃げ道なければ「わかりません」と返す作り話の答えを防ぐ
文章[1] 土曜日は午前10時に開きます使ってよい事実だけ
質問土曜日は何時に開きますか答える内容

学生が入力するセルは、このプレビューでは空白です。

返ってきたものを確かめる

プロンプトは頼みます。強制はしません。モデルは、存在しない文章を引用したり、与えていない事実を足したり、引用を忘れたりします。

ですから、プログラムが確かめます。引用の印を見つけ、1つずつ照らし合わせます。引用のない答えは、出典付きとして示しません。

例: 答えごとの扱い

答えプログラムのすること
[1] を引用し、文章1がある文章1の出典と一緒に表示する
[7] を引用し、文章は2つだけ信用しない
何も引用しない出典付きとして示さない
わかりません。そのまま表示し、出典は付けない

学生が入力するセルは、このプレビューでは空白です。

1回だけ尋ねて、答えを確かめる

次のスクリプトは answer.js です。先に、補助の model.js を保存します。プロンプトをラボのモデルへ送る補助で、モデルが答えないときは「記録済みサンプル」と表示し、スクリプトに書いた答えを使います。モデルを呼ぶのは1回だけです。

そのあと、プロンプトを作り、尋ね、引用を見つけ、答えが断りかどうかを言います。個人的なことは、プロンプトに入れません。

モデルの補助を書く(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\");' '// 検索が見つけた文章。Run の呼び出しを短い1回にするため、ここに書いてあります。' 'const passages = [' '  { source: \"hours-weekend\", text: \"土曜日は午前10時に開き、午後2時に閉まります。日曜日は休館です。\" },' '  { source: \"hours-weekday\", text: \"つばめ図書館は平日、午前9時に開き、午後6時に閉まります。\" },' '];' > answer.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

答えのスクリプトを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const question = \"土曜日は何時に開きますか。\";' 'function buildPrompt(question, passages) {' '  const lines = [\"次の文章だけを使って答えてください。使った文章は [1] のように番号で示してください。文章に答えがないときは、次の一文だけを返してください: わかりません。\", \"\"];' '  passages.forEach(function (one, i) { lines.push(\"[\" + (i + 1) + \"] \" + one.text); });' '  lines.push(\"\", \"質問: \" + question);' '  return lines.join(\"\n\");' '}' >> answer.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

答えのスクリプトを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// 記録済みサンプル。モデルが答えないときだけ使います。' 'const sample = \"土曜日は午前10時に開きます [1]。\";' 'function citedSources(reply) {' '  const found = [];' '  (reply.match(/\[(\d+)\]/g) || []).forEach(function (mark) {' '    const one = passages[Number(mark.slice(1, -1)) - 1];' '    if (one && found.indexOf(one.source) < 0) found.push(one.source);' '  });' '  return found;' '}' >> answer.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

答えのスクリプトを書く(4)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const prompt = buildPrompt(question, passages);' '  console.log(prompt);' '  const reply = await ask([{ role: \"user\", content: prompt }], sample, 120);' '  console.log(\"答え:\", reply);' '  const cited = citedSources(reply);' '  console.log(\"出典:\", cited.length > 0 ? cited.join(\", \") : \"示されていません\");' '  console.log(\"わかりませんと言ったか:\", /わかりません/.test(reply) ? \"はい\" : \"いいえ\");' '}' 'main();' >> answer.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

実行して答えを読む

コマンド
docker exec -w /home/node/project agent node answer.js

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

出力の一例

行表示されるかもしれない内容
プロンプト決まり、番号付きの2つの文章、質問
答え土曜日は午前10時に開きます [1]。
出典hours-weekend
わかりませんと言ったかいいえ

学生が入力するセルは、このプレビューでは空白です。

よくある間違い

注意

文章だけを使うよう頼めば、モデルは必ずそうする、と考える人が多くいます。決まりは、作り話の可能性を下げますが、なくしません。確認を残し、質問を、文章にない内容に変えて、逃げ道が働くのを見ます。

このラボとソースについて: AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。