1 ページの設計の書き方
1 ページの設計は、モデルを使った機能がどう動き、どう失敗するかを、作る前に書き出したものです。ゲートウェイ、キュー、評価、予算、代替、安全の規則を一か所にまとめます。どれも、紙の上なら安く決まり、あとから足すと高くつくからです。
二人の技術者が、別々のレート制限を覚えていました。設計のページが決着をつけ、スクリプトがそのページを確かめられます。
このレッスンのゴール
メモ
私は、モデルを使った機能の 1 ページの設計を書けます。
キーワード
| ことば | いみ |
|---|---|
| 設計のページ | 機能がどう動くかを書いた一枚 |
| 要件 | 設計が満たすべき一文 |
| 代替の手段 | モデル呼び出しが失敗したときの動き |
| 予算 | 機能が使ってよい額の上限 |
| 評価 | 決まったケースで品質を試すテスト |
学生が入力するセルは、このプレビューでは空白です。
六つのセクションで機能を覆う
話題ごとに、短いセクションを一つずつ書きます。ゲートウェイ: キー、上限、モデルの選び方。キュー: どの呼び出しがジョブか、再試行の上限。評価: ケースと合格の線。予算: 上限と、届いたときの動き。代替: 呼び出しが失敗したときに、ユーザーが見るもの。安全: プロンプトに入れてよいものと、ログに残すもの。
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' '// チケット要約機能の 1 ページ設計。レッスン用の作り話です。' 'const design = {' ' gateway: \"呼び出す側はクライアントキーを使います。ゲートウェイは一分に 60 件のレート制限をかけ、モデルを選びます。\",' ' queue: \"要約は一つのジョブです。ワーカーが実行し、再試行は三回までです。\",' ' evals: \"答えが分かっている四十のケースがあります。プロンプトの版ごとに合格率を比べます。\",' ' budget: \"チームごとに一日の上限を置きます。超えたら、機能はそう伝えて止まります。\",' ' fallback: \"モデルが失敗したら、二つ目のモデルを試し、そのあとチケットの最初の数行を見せます。\",' ' security: \"チケットには個人情報が入ることがあるので、プロンプトには必要なものだけを渡します。\",' '};' > design.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
設計の検査を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const reqs = [' ' { id: \"R1\", section: \"gateway\", words: [\"クライアントキー\", \"レート制限\"] },' ' { id: \"R2\", section: \"queue\", words: [\"ジョブ\", \"再試行\"] },' ' { id: \"R3\", section: \"evals\", words: [\"ケース\", \"合格率\"] },' ' { id: \"R4\", section: \"budget\", words: [\"一日の上限\"] },' ' { id: \"R5\", section: \"fallback\", words: [\"簡単な答え\"] },' ' { id: \"R6\", section: \"security\", words: [\"個人情報\", \"ログ\"] },' '];' >> design.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
設計の検査を書く(3)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function check(d, rs, maxChars) {' ' const out = [];' ' rs.forEach(function (r) {' ' const text = (d[r.section] || \"\").toLowerCase();' ' if (text.trim() === \"\") { out.push(r.id + \": セクション \" + r.section + \" がありません\"); return; }' ' r.words.forEach(function (w) { if (text.indexOf(w) < 0) out.push(r.id + \": \" + w + \" がありません\"); });' ' });' ' let n = 0;' ' for (const k in d) n += d[k].length;' ' if (n > maxChars) out.push(\"長すぎます: \" + n + \" 文字\");' ' return out;' '}' 'const problems = check(design, reqs, 300);' 'problems.forEach(function (p) { console.log(\"問題:\", p); });' 'console.log(\"満たした要件:\", reqs.length - problems.length, \"/\", reqs.length);' >> design.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
設計のページを検査する
docker exec -w /home/node/project agent node design.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
この Run にモデルは要りません
検査は文章に対するふつうのコードで、呼び出しはしません。補助スクリプトは、あとの演習のために書きます。モデルを呼ぶ Run は、答えがないとき、ラベル付きの記録済みサンプルを表示します。
設計は作り話です。本物の設計には、自分たちのサービスと数字を書きます。
出力の一例
| 行 | 何を示すか |
|---|---|
| 問題: R5: 簡単な答え がありません | 代替が、最後にユーザーが見るものを言っていない |
| 問題: R6: ログ がありません | 安全のセクションが、ログに触れていない |
| 満たした要件: 4 / 6 | 四つのセクションが、各問いに答えた |
学生が入力するセルは、このプレビューでは空白です。