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

無料レッスン

本番のトレースから評価ケースを作る

このレッスンのあとで: 使われている中での失敗を、残してはならないものを残さずに、ケースにできる。

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

実際の失敗が、最良のテストになる

本番からの評価とは、実際の失敗をテストケースにすることです。必要な理由は、お客様がテストの作者も思いつかない不具合を見つける一方、そのメッセージには、残してはならない名前、住所、番号が含まれるからです。

店のエージェントが、今週4回失敗しました。そのチャットのどの部分を、テストのセットに入れてよいでしょうか。

このレッスンのゴール

メモ

使われている中での失敗を、残してはならないものを残さずに、ケースにできる。

キーワード

ことばいみ
トレース実際の1回の実行の記録
マスク個人情報を目印に置き換えること
サンプリングどのトレースを読むかを選ぶこと
対照ケース壊れてはならないものを示すために残す、合格したトレース
ドリフトセットが変わり続け、同じものを測らなくなること

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

どのトレースを読むかを選ぶ

すべてのトレースは読めません。サンプリングで選びます。ユーザーが報告した失敗や、チェックが示した失敗を、すべて取ります。修正で、うまく動いていたものが壊れないように、合格したトレースを数件、対照ケースとして加えます。

失敗がケースになるのは、起きるべきだったことを、人が書いてからです。

例: 6件のトレースが4つのケースになる

トレース結果どうなるか
t1失敗ケースになる。メールを置き換える
t2ok対照ケースになる
t3失敗ケースになる。電話番号を置き換える
t4失敗ケースになる
t5失敗除く。マスク後の入力が t4 と同じ
t6ok選ばない

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

保存する前に、個人情報を取り除く

マスクは、名前、住所、番号を、[メール] のような目印に置き換えます。読んで試せる規則で行い、モデルに頼んではいけません。期待するテキストもマスクします。

そのあと確かめます。できあがったケースの中で、消えているはずのものを探します。住所が残るケースは、テストのセットの中の情報漏えいです。

セットがドリフトしないようにする

ドリフトとは、セットが気づかないうちに変わり、先月の点数が同じ意味を持たなくなることです。セットにバージョンを付けます。ケースは、人が見直してからだけ加えます。毎晩動くスクリプトでは加えません。

大きさに上限を設け、重複を除きます。1つの不具合が大量に流れ込んでも、ほかを圧倒しないようにするためです。

記録済みのトレースを書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// 店のエージェントの、作り話のトレース。人物も番号も架空です。' 'const traces = [' '  { id: \"t1\", outcome: \"failed\", user: \"注文A17を返金してください 連絡先 [email protected] です。\", expected: \"どの商品かを尋ね、1回だけ返金する\" },' '  { id: \"t2\", outcome: \"ok\", user: \"注文B02は どこですか?\", expected: \"発送済みと伝える\" },' '  { id: \"t3\", outcome: \"failed\", user: \"注文C11の件で +81-90-1234-5678 に 電話してください。\", expected: \"ヘルプのページを案内し、電話は約束しない\" },' > traces.js"

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

記録済みのトレースを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  { id: \"t4\", outcome: \"failed\", user: \"荷物は どこですか? [email protected]\", expected: \"注文を調べ、番号を尋ねる\" },' '  { id: \"t5\", outcome: \"failed\", user: \"荷物は どこですか? [email protected]\", expected: \"注文を調べ、番号を尋ねる\" },' '  { id: \"t6\", outcome: \"ok\", user: \"こんにちは\", expected: \"お客様に挨拶する\" },' '];' 'module.exports = { traces };' >> traces.js"

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

ケースの作成を書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { traces } = require(\"./traces\");' 'function redact(text) {' '  return text.split(\" \").map(function (word) {' '    let core = word;' '    let tail = \"\";' '    while (core.length > 0 && \"。、?.,?\".includes(core[core.length - 1])) {' '      tail = core[core.length - 1] + tail;' '      core = core.slice(0, -1);' '    }' '    if (core.includes(\"@\")) return \"[メール]\" + tail;' '    const digits = core.split(\"\").filter(function (c) { return c >= \"0\" && c <= \"9\"; }).length;' '    const plain = core.split(\"\").every(function (c) { return (c >= \"0\" && c <= \"9\") || c === \"+\" || c === \"-\"; });' '    if (plain && digits >= 7) return \"[電話番号]\" + tail;' '    return word;' '  }).join(\" \");' '}' > cases.js"

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

ケースの作成を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const seen = [];' 'const cases = [];' 'const dropped = [];' 'let okSeen = 0;' 'traces.forEach(function (trace) {' '  const made = { input: redact(trace.user), expected: redact(trace.expected), source: trace.id };' '  if (trace.outcome === \"ok\") {' '    if (okSeen % 2 === 0) { made.kind = \"対照\"; cases.push(made); }' '    okSeen = okSeen + 1;' '    return;' '  }' '  if (seen.includes(made.input)) { dropped.push(trace.id); return; }' '  seen.push(made.input);' '  made.kind = \"失敗\";' '  cases.push(made);' '});' >> cases.js"

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

ケースの作成を書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'cases.forEach(function (one, at) {' '  console.log(\"ケース \" + (at + 1) + \" (\" + one.kind + \"、\" + one.source + \" から): \" + one.input);' '});' 'console.log(\"重複として除いた: \" + dropped.join(\"、\"));' 'const left = cases.filter(function (one) { return one.input.includes(\"@\") || one.input.includes(\"1234\"); });' 'console.log(\"個人情報が残るケース: \" + left.length);' 'console.log(\"セット バージョン1、ケース数 \" + cases.length);' >> cases.js"

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

トレースからケースを作る

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

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

作成が表示するもの

行示すこと
ケース1から4失敗3件と対照1件。個人情報は置き換え済み
除いたものt5
残った個人情報0
セットバージョン1、ケース4件

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

試してみましょう

ヒント

traces.js に、[email protected] のようなアドレスを含む、失敗したトレースを足して、もう一度実行します。ケースには [メール] と出るはずです。次に cases.js の redact の呼び出しを外して、何が漏れるかを見ます。

よくある間違い

注意

ユーザーのメッセージだけをマスクする人がいます。期待するテキスト、トレースの id、ツールの引数にも、同じアドレスが入ることがあります。残す項目はすべてマスクするか、必要な項目だけを残します。そして、できあがったセットに、消えているはずのものが残っていないかを試します。

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

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