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

無料レッスン

複数のエージェントを使うべきとき

このレッスンのあとで: 複数のエージェントが割に合うのはいつかを、トークンの見積もりで示せる。

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

エージェントが多いほど賢いとは限らない

マルチエージェントのシステムとは、1回のモデル呼び出しが、別の呼び出しに仕事を渡すプログラムです。それぞれが自分のコンテキストを持ちます。エージェントを1つ足すたびに、トークンと時間がかかり、失敗の仕方も増えるので、使い方を知っておくことが大切です。

エージェントのチームは、次の一手として宣伝されがちです。本当にそうなることもあります。けれど、道具の整った1つのエージェントが、ずっと少ない費用で同じ仕事を済ませることも多いのです。

このレッスンのゴール

メモ

複数のエージェントが割に合うのはいつかを、トークンの見積もりで示せる。

キーワード

ことばいみ
コンテキストウィンドウ1つのエージェントが一度に持てる文の最大量
オーケストレーター仕事を分け、答えをまとめるエージェント
ワーカー1つの部分を担当して報告するエージェント
共通の文全エージェントが読み直す指示
結合した仕事各段階が前の結果を必要とする仕事
並列同時に進められる部分

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

各エージェントが共通の文を読み直す

1つのエージェントは、指示を1回読むだけです。チームは違います。オーケストレーターが読み、各ワーカーも読みます。ワーカーは自分のコンテキストを持ち、他の人のものは見えないからです。

つまりチームの費用は、共通の文をエージェントの数だけ読む分と、部分ごとの依頼と結果の分です。部分そのものは、担当するワーカーが1回読むだけです。

例: 報告書3本

だれが読むものトークン
1つのエージェント共通1500 + 報告書3本5500 + 答え4007400
オーケストレーター共通1500 + 依頼3つ600 + 最終3002400
ワーカー3人各自 共通1500 + 報告書1本 + 結果1つ10600
チーム全体オーケストレーターとワーカーの合計13000

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

分けて得をするのはいつか

1つのエージェントでは仕事を持てないとき、分けます。部分が互いに独立していて、速さが大事なときも、分けます。ある部分にきれいなコンテキストが必要で、前の文に惑わされたくないときも、分けます。

結合した仕事は分けません。段階2が段階1の正確な結果を必要とするなら、2つ目のエージェントは、情報が欠けた要約を挟むだけです。

よくある間違い

注意

仕事に名詞が複数あるからと、分けてしまう人が多くいます。数えるのは名詞ではなく、依存関係です。1つの記録を共有して順に編集する仕事は、1つのエージェントの仕事です。

モデル用の補助を書く(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"

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

モデル用の補助を書く(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 d = await res.json();' '    return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"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\");' 'const WINDOW = 8000; // 1つのエージェントが持てるトークン数' 'const NOTE = 200; // 依頼1つ、または結果1つ' 'const CASES = [' '  { name: \"報告書3本\", shared: 1500, parts: [1800, 2000, 1700], coupled: false },' '  { name: \"長い報告書1本\", shared: 1500, parts: [900], coupled: false },' '  { name: \"ファイル1つの編集\", shared: 1500, parts: [1200, 1000], coupled: true },' '  { name: \"文書10件\", shared: 1500, parts: Array(10).fill(900), coupled: false },' '];' > split.js"

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

費用のスクリプトを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function sum(list) { return list.reduce(function (a, b) { return a + b; }, 0); }' '// 1つのエージェントは、共通の文を1回、次に全部の部分を読んで、答えます。' 'function single(c) { return c.shared + sum(c.parts) + 400; }' '// チームでは、リーダーが共通の文を読み直し、各ワーカーも読み直します。' 'function team(c) {' '  const boss = c.shared + NOTE * c.parts.length + 300;' '  const workers = c.parts.map(function (p) { return c.shared + p + NOTE; });' '  return boss + sum(workers);' '}' >> split.js"

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

費用のスクリプトを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function choose(c) {' '  if (c.coupled || c.parts.length < 2) return \"1つ\";' '  if (single(c) > WINDOW) return \"複数\";' '  return team(c) <= 2 * single(c) ? \"複数\" : \"1つ\";' '}' 'async function main() {' '  for (const c of CASES) {' '    const x = Math.round((team(c) * 10) / single(c)) / 10;' '    console.log(c.name + \": 単独 \" + single(c) + \"、チーム \" + team(c) + \" (x\" + x + \")、選択 \" + choose(c));' '  }' '  const q = [{ role: \"user\", content: \"エージェント同士で分けてはいけない仕事を、1文で1つ挙げてください。\" }];' '  const r = await ask(q, \"1つのファイルを段階的に編集する仕事。各段階が前の段階を必要とするからです。\", 40);' '  console.log(\"モデル: \" + r.text.trim());' '}' 'main();' >> split.js"

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

費用のスクリプトを実行する

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

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

これは見積もりです

この Run は、チームを呼びません。記録済みの4つのケースで計算するだけです。本物のチームを動かすと、ラボのクレジットを一度に使い切ってしまうからです。トークンの大きさは作り物で、本物のシステムは自分の数字を測ります。

ライブ呼び出しは、1文を頼むだけです。

出力の一例

行何を示すか
報告書3本: 単独 7400、チーム 13000 (x1.8)、選択 複数1つのウィンドウに収まるが、チームは2倍未満
長い報告書1本: … 選択 1つ部分が1つなら、分けられない
ファイル1つの編集: … 選択 1つ結合した仕事は1つのエージェントに残る
文書10件: 単独 10900、チーム 29800 (x2.7)、選択 複数1つでは持てないので、費用を払う
モデル: …実行のたびに変わる1文

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

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

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