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

無料レッスン

遅延の予算とストリーミング

このレッスンのあとで: 遅延の予算を決め、ストリーミングが何を変えるかを言うことができる。

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

遅延の予算とは

遅延とは、利用者が答えを待つ時間です。遅延の予算とは、許す時間の最大で、一つのリクエストの各段階で分け合います。

コスト、トレース、信頼性のモジュールでは、パーセンタイルとタイムアウトを学びます。このレッスンは、さらに進みます。リクエスト全体の予算と、ストリーミングが変えるものと変えないものです。

このレッスンのゴール

メモ

遅延の予算を決め、ストリーミングが何を変えるかを言うことができる。

キーワード

ことばいみれい
遅延利用者が待つ時間
最初のトークンまでの時間最初の言葉が出るまでの待ち600 ms
合計時間最後の言葉が出るまでの待ち
ストリーミング言葉を、できた順に送ること
予算許す時間の最大。段階で分け合う
ミリ秒1000 分の 1 秒

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

二つの時間: 最初の言葉と最後の言葉

返答は、最初の言葉が出るまでに少しかかり、そのあとは言葉ごとに少しずつかかります。最初の時間が、最初のトークンまでの時間です。最後が合計時間です。

合計時間は、最初のトークンまでの時間に、トークンごとの時間とトークンの数をかけたものを足した数です。

例: 二つの返答

返答最初のトークンまで1 トークンごとトークン数合計
短い60020301200
長い600203006600

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

よくある間違い

注意

ストリーミングで、返答が速くなると考える人が多いです。速くなりません。最後の言葉は、まったく同じ時刻に届きます。変わるのは、利用者が最初に言葉を見る時刻で、待ちが短く感じられます。

待ちを感じるのはどこか

ストリーミングがないと、利用者は合計時間まで何も見えません。あると、最初のトークンまでの時間のあとに言葉が見え、読み始められます。

長い返答では、違いが大きくなります。例では、最初の言葉を待つ時間が 6600 から 600 ミリ秒に減り、6000 の節約になります。

ストリーミングの代償

重要

返答全体を検査する前に、言葉が表示されます。安全の検査のように、全文が要る検査は、先に動かせません。ストリーミングをオンにする前に、その扱いを決めておきます。

予算を段階で分ける

リクエストの段階は、モデルだけではありません。待ち行列で待ち、資料を探し、返答を検査します。時間を順に足します。

途中までの合計が、初めて予算を超える段階が、最初に直すか、削る段階です。

例: 予算 1000

段階時間途中までの合計1000 を超える?
待ち行列150150いいえ
資料の検索400550いいえ
モデルの最初のトークン6001150はい。最初に超える
安全の検査2001350はい。350 超過

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

助っ人 model.js を書く(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"

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

助っ人 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 data = await res.json();' '    const text = data.choices[0].message.content;' '    return { text, inTokens: count(data, \"prompt_tokens\"), outTokens: count(data, \"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\");' 'function total(r) { return r.ttft + r.perToken * r.tokens; }' 'function first(r) { return r.streamed ? r.ttft : total(r); }' 'const replies = [' '  { name: \"短い返答\", ttft: 600, perToken: 20, tokens: 30, streamed: false },' '  { name: \"長い返答\", ttft: 600, perToken: 20, tokens: 300, streamed: false },' '  { name: \"長い返答(ストリーム)\", ttft: 600, perToken: 20, tokens: 300, streamed: true },' '];' > latency.js"

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

遅延のスクリプトを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const parts = [[\"待ち行列\", 150], [\"資料の検索\", 400], [\"モデルの最初のトークン\", 600], [\"安全の検査\", 200]];' 'function budget(limit) {' '  let sum = 0;' '  let over = \"なし\";' '  for (const p of parts) {' '    sum = sum + p[1];' '    if (sum > limit && over === \"なし\") over = p[0];' '  }' '  return \"合計 \" + sum + \"、残り \" + (limit - sum) + \"、最初に超えた部分: \" + over;' '}' >> latency.js"

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

遅延のスクリプトを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  for (const r of replies) console.log(r.name + \": 最初 \" + first(r) + \"、合計 \" + total(r));' '  console.log(\"予算 1000: \" + budget(1000));' '  console.log(\"予算 2000: \" + budget(2000));' '  const started = Date.now();' '  const reply = await ask([{ role: \"user\", content: \"短く一文で答えてください。言葉が早く出ると、利用者がうれしいのは、なぜですか。\" }], \"すぐに読み始められるので、待つ時間が短く感じられるからです。\", 80);' '  console.log(\"モデル: \" + reply.text);' '  console.log(\"返答全体の測った待ち時間: \" + (reply.recorded ? \"測っていません\" : Date.now() - started + \" ms\"));' '}' 'main();' >> latency.js"

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

遅延の計算を動かす

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

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

Run の出力

行意味
短い返答: 最初 1200、合計 1200ストリームなし。最初の言葉は合計の時刻
長い返答: 最初 6600、合計 6600ストリームなし。返答が長いので、待ちも長い
長い返答(ストリーム): 最初 600、合計 6600ストリーム。最初は早く、合計は同じ
予算 1000: 合計 1350、残り -350、最初に超えた部分: モデルの最初のトークン直す段階
予算 2000: 合計 1350、残り 650、最初に超えた部分: なし予算を増やすと、どの段階も超えない
モデル: ...ラボからの一文。モデルが答えなければ記録済みサンプル
返答全体の測った待ち時間: ...本物の ms。記録済みサンプルなら測っていません

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

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

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