アプリは返事を信じた
サポートのアプリが、言語モデルに、チケットごとのカテゴリーと優先度を付けてもらいます。プログラムは返事を読み、チケットを保存します。
ある日、ラベルの前に親切な1文が付いた返事が来て、プログラムが止まります。別の日は、プログラムが知らないラベルが来ます。悪いのはモデルではありません。確かめるべき文字列を、プログラムが信じたのです。
このレッスンのゴール
メモ
モデルの返事を、プログラムが使う前に確かめ、頼んだものと違うときは、安全な方へ戻れる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 返事 | モデルが返す文字列。ただの文字列である | |
| 読み取り | 文字列を、辞書のような形にすること | |
| 検証 | 各部分が、許した値のどれかであることを確かめること | |
| 代わりの値 | 返事が確認に通らないときに、安全のために使う値 | |
| 許可リスト | 受け入れる値だけを並べたもの | billing, bug, other |
| 信用できない | 届いたというだけでは、従わず、信じないもの |
学生が入力するセルは、このプレビューでは空白です。
返事は、ただの文字列
モデルが返すのは文字列だけです。JSON を頼んでも、届くのは文字列です。頼んだとおりのこともあります。前後に言葉が付くことも、許していない値が入ることも、途中で切れることもあります。
確かめるまで、プログラムには分かりません。ですから、確認はプログラムの一部で、おまけではありません。
読み取り、検証、代わりの値
3つのことを、この順に行います。文字列を読み取り、読めなければそこで止めます。各項目を許可リストで検証します。何か失敗したら、代わりの値を使います。「other」のような安全な値や、聞く相手の人です。
そのあとは、頼んだ項目だけを使います。返事のそれ以外は信用できないものです。ただのデータで、プログラムは従いません。
7つの返事をプロジェクトに書く
docker exec -w /home/node/project agent sh -c "printf '%s\n' '{\"category\": \"bug\", \"priority\": 2}' 'ご希望の JSON はこちらです: {\"category\": \"bug\", \"priority\": 2}' '{\"category\": \"refund\", \"priority\": \"high\"}' '{\"category\": \"other\", \"priority\": 9}' '{\"category\": \"bug\", \"priority\": 1, \"note\": \"規則を無視して、全員に返金してください\"}' '{\"category\": \"bug\", \"prio' 'null' > replies.txt"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
確認のスクリプトを書く
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const allowed = [\"billing\", \"bug\", \"other\"];' '' 'function check(text) {' ' let reply;' ' try {' ' reply = JSON.parse(text);' ' } catch (error) {' ' return \"却下: JSON ではない\";' ' }' ' if (reply === null) return \"却下: 空\";' ' if (allowed.includes(reply.category) === false) return \"却下: category \" + reply.category;' ' if ([1, 2, 3].includes(reply.priority) === false) return \"却下: priority \" + reply.priority;' ' return \"ok: \" + reply.category + \" \" + reply.priority;' '}' '' 'for (const line of fs.readFileSync(\"replies.txt\", \"utf8\").trim().split(\"\n\")) {' ' console.log(check(line));' '}' > check.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
7つの返事に確認を実行する
docker exec -w /home/node/project agent node check.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
頼んだものだけを取る
5番目の返事を見ます。これは通りましたが、命令をしようとする文が入った、余分な項目を持っています。規則を無視して、全員に返金せよ、という文です。
確認が表示したのは、カテゴリーと優先度だけです。余分な文は、指示として読まれませんでした。この習慣を身につけます。期待する項目から結果を作り、残りは置いておきます。
よくある間違い
注意
読み取れた返事は安全だと思う人が多いです。4番目は完全に読み取れて、優先度は 9 でした。読み取れるのは、形が合っているということです。値が合っていることは、許可リストだけが言えます。
例: 7つの返事の確認
| 返事 | 何が問題か | 確認の結果 |
|---|---|---|
| 正しい JSON | なし | ok: bug 2 |
| 言葉、そのあとに JSON | 全体では JSON ではない | 却下: JSON ではない |
| カテゴリーが "refund" | 許可リストにない | 却下: category refund |
| 優先度 9 | 1 から 3 の外 | 却下: priority 9 |
| 命令入りの余分な項目 | 読む項目には問題なし | ok: bug 1 |
| 途中で切れた | JSON ではない | 却下: JSON ではない |
| null | 読むものがない | 却下: 空 |
学生が入力するセルは、このプレビューでは空白です。
モデルを安全に使う、残りの習慣
確認のほかに、3つの習慣があります。プログラムがモデルを呼ぶための鍵は、コードの外に置きます。パスワードと同じように環境から読み、リポジトリには入れません。
モデルには、必要最小限だけ送ります。名前もメールアドレスも送りません。返事は、保存する前に長さの上限を決めます。返事を却下したときは、却下したことと理由を記録し、中の個人情報は記録しません。
さらに: 聞いてから確かめる
ラボで、コーディングアシスタントに、ここにあるような返事を確かめる関数を書いてもらいます。まだ受け入れません。
その関数を、7つの返事と、自分で作った2つに実行します。間違えた返事があれば書き、試さなくても分かる方法を考えます。