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

無料レッスン

AI機能の最初の版を作る

このレッスンのあとで: 私は、測れる中でいちばん単純な版を作れます。

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

AI機能の最初の版

AI機能の最初の版は、測れる中でいちばん単純なものです。プロンプトが一つ、モデルが一つ、小さなテスト用の質問の集まりです。採点できないものは改善できないので、大切です。

ひだまり町立図書館には、要件書ができました。チームは、9行のシートから答えるアシスタントを作り、10問で採点します。

このレッスンのゴール

メモ

私は、測れる中でいちばん単純な版を作れます。

キーワード

ことばいみれい
ファクトシートアシスタントが使ってよい事実の短い一覧
テストケース答えに入るべき数字とセットの質問c4
評価テストケースと、それぞれを採点する規則
チェック一つの答えを合格か不合格にする規則
ベースライン最初の得点。あとの版が超える基準

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

プロンプト一つ、モデル一つ、シート一枚

最も単純な版には、部品が4つあります。規則を書いたシステムプロンプト。その中に入れたファクトシート。モデル一つ。答えのチェック一つ。

検索も、記憶も、二つ目のモデルもありません。ない部品は、まだ失敗できません。得点が必要だと言ったときだけ、一つ足します。

例: 版1

部品最初の版では
プロンプト短い一文で答える
ファクトシート9つの事実を、プロンプトに貼る
モデル一つ。プラットフォームが選ぶ
チェック正しい数字があり、他の数字がなく、40文字まで

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

評価とは、ケースと規則

テストケースは、質問と、答えに入るべき数字です。チェックは、毎回同じ規則で答えを採点します。

ここでのチェックは、失敗を4種類に分けます。断り。シートにない作り話の数字。正しい数字がないあいまいな答え。40文字を超える長すぎる答えです。日本語は語の区切りがはっきりしないので、長さは文字数で数えます。

まず10件から始める

10件は、わざと少なくしています。答えを全部読めて、なぜ失敗したかが見えます。

ケースは、簡単なものではなく、人が実際に聞くことから選びます。あとで本物の失敗が出たら、11件目として足します。評価は、証拠とともに育ちます。

よくある間違い

注意

見栄えの良いデモが評価だと考える人が多いです。デモは、自分で選んだ一件です。評価は、選んでいない多くのケースを、毎回同じ規則で採点したものです。デモが示すのは、動きうることです。

モデルの補助を書く(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 SHEET = \"貸出は3週間。更新は2回。延滞料は日ごとに20円。開館は9時から17時。貸出は8冊まで。貸出券の再発行は5日。学習室は4時間まで。印刷はページごとに10円。18歳未満は無料。\";' 'const LIMIT = 40; // 答えに許す文字数の上限' 'const SHEET_NUMBERS = SHEET.match(/[0-9]+/g);' > eval.js"

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

評価を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const RAW = [' '  [\"c1\", \"本は何週間借りられますか。\", \"3\", \"本は3週間借りられます。\", false],' '  [\"c2\", \"本は更新できますか。\", \"2\", \"はい、2回まで更新できます。\", false],' '  [\"c3\", \"延滞料はいくらですか。\", \"20\", \"延滞料は日ごとに50円です。\", false],' '  [\"c4\", \"何時に開きますか。\", \"9\", \"毎日9時に開きます。\", false],' '  [\"c5\", \"何時に閉まりますか。\", \"17\", \"夕方に閉まります。\", false],' >> eval.js"

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

評価を書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  [\"c6\", \"何冊まで借りられますか。\", \"8\", \"一度に8冊まで借りられます。\", false],' '  [\"c7\", \"貸出券の再発行には何日かかりますか。\", \"5\", \"再発行には7日かかります。\", false],' '  [\"c8\", \"学習室を一日中予約できますか。\", \"4\", \"お答えできかねます。\", true],' '  [\"c9\", \"印刷はいくらですか。\", \"10\", \"印刷は、ページごとに10円です。白黒とカラーは同じ値段です。支払いはカウンターで、カードか硬貨でお願いします。\", false],' >> eval.js"

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

評価を書く(4)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  [\"c10\", \"子どもは登録できますか。\", \"18\", \"18歳未満は無料で登録できます。\", false],' '];' 'const CASES = RAW.map(function (r) {' '  return { id: r[0], q: r[1], expect: r[2], reply: r[3], length: Array.from(r[3]).length, refused: r[4] };' '});' >> eval.js"

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

評価を書く(5)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function kind(c) {' '  if (c.refused) return \"refusal\";' '  const found = c.reply.match(/[0-9]+/g) || [];' '  for (const n of found) {' '    if (SHEET_NUMBERS.includes(n) === false) return \"invented\";' '  }' '  if (found.includes(c.expect) === false) return \"vague\";' '  if (c.length > LIMIT) return \"long\";' '  return \"ok\";' '}' 'const counts = {};' 'for (const c of CASES) {' '  const k = kind(c);' '  counts[k] = (counts[k] || 0) + 1;' '  console.log(c.id, k);' '}' 'console.log(\"記録済みの実行 v1:\", CASES.length, \"件中\", counts.ok, \"件が合格\");' 'console.log(JSON.stringify(counts));' 'require(\"fs\").writeFileSync(\"eval-v1.json\", JSON.stringify(CASES, null, 1));' >> eval.js"

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

評価を書く(6)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function live() {' '  const system = \"次のシートだけを使い、短い一文で答えてください。\" + SHEET;' '  const messages = [{ role: \"system\", content: system }, { role: \"user\", content: \"何時に開きますか。\" }];' '  const reply = await ask(messages, \"毎日9時に開きます。\", 40);' '  const found = reply.match(/[0-9]+/g) || [];' '  console.log(\"ライブの質問:\", reply);' '  console.log(\"数字 9 を含む:\", found.includes(\"9\"), \"(得点には入りません)\");' '}' 'live();' >> eval.js"

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

版1を採点する

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

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

Run の表示

行意味
c1 から c10それぞれ ok、invented、vague、refusal、long のどれか
記録済みの実行 v110 件中 5 件が合格
JSON の行ok 5、invented 2、vague 1、refusal 1、long 1
ライブの質問短い呼び出し。得点には入らない

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

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

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