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

無料レッスン

検索結果の再ランキング

このレッスンのあとで: 短い結果リストを二回目の通過で並べ替え、それがコストに見合ったかを説明できる。

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

正解のページが四位にある

再ランキングとは、検索が返した短いリストを、もう一度よく見て並べ替えることです。一回目の検索は速い代わりに大ざっぱで、答えのページが一位とは限らないので、役に立ちます。

お金を返してもらう方法を聞く人がいます。返金の規約のページは四位で、一位はカード払いのページです。二回目の目で、返金の規約のページが一位に上がります。

このレッスンのゴール

メモ

短い結果リストを二回目の通過で並べ替え、それがコストに見合ったかを説明できる。

キーワード

ことばいみ
一回目の通過索引全体に対する速い検索
二回目の通過上位の結果だけを時間をかけて見ること
再ランカー短いリストをもう一度採点するもの
候補二回目が並べ替えてよい結果
再現率の天井一回目が決める、到達できる最良の値
上位 k のヒット出典が上位 k に入った質問の割合

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

広くて安い通過のあと、狭い通過

すべてのページを念入りに見るのは遅すぎます。そこで検索は二段階で動きます。一回目は安くて広く、数百万ページを数十ページに絞ります。二回目は遅くて狭く、残った分だけを読みます。

下の数字は作り物ですが、形は本物です。念入りに見るのは、短いリストだからできます。

例: 各通過のコスト

通過見るページ数一ページの時間合計の時間
一回目1,000,0000.00002 ms20 ms
二回目205 ms100 ms
全部に二回目1,000,0005 ms5,000 秒

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

再ランカーは単純な規則でもよい

再ランカーは、短いリストをもう一度採点するものです。学習済みのモデルでも、言語モデルでも、自分で書いた規則でもかまいません。Run の規則は、題に質問の語があれば 3 点、本文にあれば 1 点です。

言語モデルの再ランカーは読みが深い代わりに、質問ごとに呼び出しとトークンと時間がかかります。まず規則で始め、測ります。

よくある間違い

注意

再ランカーは、一回目が見落としたページを見つけられると考える人がいます。できません。渡されたものを並べ替えるだけなので、天井は一回目が決めます。答えが上位 20 に入っていなければ、二回目でも出てきません。

モデルの補助を書く(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 query = [\"返金\", \"お金\", \"返品\"];' 'const found = [' '  { id: \"c1\", title: \"カード 支払い\", body: \"お金 アカウント 引き落とし\" },' '  { id: \"c2\", title: \"返金 期限\", body: \"お金 戻る 返品 承認 5日\" },' '  { id: \"c3\", title: \"荷物 追跡 注文番号\", body: \"番号 入力 場所 確認\" },' '  { id: \"c4\", title: \"返金 お金 返品 規約\", body: \"30日 以内 荷物 返送 返金 申請\" },' '  { id: \"c5\", title: \"メールアドレス 変更\", body: \"アカウント 開く 編集\" },' '];' > rerank1.js"

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

再ランカーを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function count(text) {' '  const w = text.toLowerCase().split(\" \");' '  return query.filter(function (q) { return w.includes(q); }).length;' '}' 'function points(c) { return 3 * count(c.title) + count(c.body); }' 'function ids(list) { return list.map(function (c) { return c.id; }).join(\" \"); }' >> rerank1.js"

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

再ランカーを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  console.log(\"一回目:\", ids(found));' '  const second = found.slice().sort(function (a, b) { return points(b) - points(a); });' '  console.log(\"二回目:\", second.map(function (c) { return c.id + \"=\" + points(c); }).join(\" \"));' '  console.log(\"二回目が読んだ箇所の数:\", found.length);' '  const top = second.slice(0, 3);' '  const lines = top.map(function (c, i) { return (i + 1) + \". \" + c.title; });' '  const prompt = \"質問「お金を返してもらうには」に最も合う箇所はどれですか。番号だけで答えてください。\" + lines.join(\" \");' '  const reply = await ask([{ role: \"user\", content: prompt }], \"1\", 5);' '  const pick = Number(reply.text.trim().charAt(0));' '  console.log(\"モデルの選択:\", pick >= 1 && pick <= 3 ? top[pick - 1].id : \"はっきりした選択なし\");' '}' 'main();' >> rerank1.js"

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

実行して順を比べる

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

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

二回目が見合わないとき

上位の数か所のヒット率を、前と後で測ります。ほとんど動かなければ、その通過はやめます。一回目がすでに正しいとき、リストが短いとき、遅れが遅延の予算を超えるときも同じです。

Run は代用品で、記録済みの候補五つと規則です。本物は本物の索引と本物のモデルを使います。

出力の例

行意味
一回目: c1 c2 c3 c4 c5記録済みの一回目の順
二回目: c4=10 c2=5 c1=1 ...規則が c4 を先頭に上げる
二回目が読んだ箇所の数: 5コスト。読んだ箇所で数える
モデルの選択: c4本物の選択か、記録済みサンプル

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

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

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