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

無料レッスン

モデルに画像と文書を送る

このレッスンのあとで: 私は、入力が画像や文書になると何が変わるかを説明できます。

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

入力が文章でないとき

マルチモーダル入力とは、リクエストに文章のほか、画像や文書が入ることです。モデルはそれを読めますが、サービスは大きなファイルを運び、種類を確かめなければならず、画像やページごとの料金もかかります。リクエストは、数百バイトから数メガバイトに増えることがあります。

ユーザーがレシートを撮り、十ページの契約書も送ります。一つのリクエストに、パートが三つあり、断られる理由も三通りあります。

このレッスンのゴール

メモ

私は、入力が画像や文書になると何が変わるかを説明できます。

キーワード

ことばいみれい
パートリクエストの一部分。文章、画像、文書のどれか
メディアタイプファイルの形式を表す札image/png
ペイロードの大きさリクエストが運ぶバイト数
ページ数の上限文書に許すページ数の最大
単価画像一枚、またはページ一枚の費用

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

ラボはテキストだけです

注意

ラボのモデルのエンドポイントは、テキストを受け取ります。Run から画像や文書は送れません。このレッスンは、レッスン用に作った記録済みのリクエストの形から始め、コードで確かめます。

リクエストは、パートのリストになる

文章だけの入力は、一つの文字列です。マルチモーダルの入力は、パートのリストで、それぞれが種類とデータを持ちます。ファイルのデータはバイトで運ばれ、多くは文字に直されるので、三分の一ほど大きくなります。

下は、このレッスンのために作った、記録済みの形です。本物の提供元は、それぞれ別の項目名を使います。必ず、その説明書を読んでください。

記録済みのリクエストの形

コード: node
{ "messages": [{ "role": "user", "content": [
    { "type": "text", "text": "このレシートには何が書かれていますか。" },
    { "type": "image", "media": "image/png", "data": "<base64、412000 バイト>" },
    { "type": "document", "media": "application/pdf", "data": "<base64、880000 バイト>" }
] }] }

送る前に、パートごとに確かめる

自分で決めた規則で、パートごとに確かめます。メディアタイプ、バイト数、ページ数です。合計も確かめます。画像が何枚か、全部で何バイトかです。

早めに、はっきりした理由をつけて断ります。提供元で失敗したリクエストは、アップロードの手間と、ときにはお金を、すでに使っています。

例: 上限と価格

パート中身確認費用(単位)
1テキスト、1800 文字ここでは上限なし2
2画像、png、412000 バイト許可、5 MB 未満4
3画像、gif、90000 バイトgif はリストにない4
4文書、24 ページ20 ページの上限を超える48

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

費用は、画像とページごと

文章はトークンごとに払います。画像やページは、決まった額か、大きさで決まるトークン数で払うことが多いです。呼び出しの前に足し合わせておくと、予算の規則で高いリクエストを断れます。

できるなら、送る量を減らします。画像を小さくするか、必要なページだけを送ります。

よくある間違い

注意

ファイルの名前や拡張子を信じてしまう人は多いです。名前が png でも、中身は違うことがあります。サーバー側でバイトから種類を確かめ、大きさの上限も守ります。拡張子は手がかりで、事実ではありません。

モデル用の補助を書く(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' 'const { ask } = require(\"./model\");' '// 記録済みの作り物のリクエスト。提供元ごとに、形は違います。' 'const request = { parts: [' '  { type: \"テキスト\", chars: 1800 },' '  { type: \"画像\", kind: \"png\", bytes: 412000 },' '  { type: \"画像\", kind: \"gif\", bytes: 90000 },' '  { type: \"文書\", pages: 24, bytes: 880000 },' '] };' 'const LIMITS = { images: 3, imageBytes: 5000000, pages: 20, kinds: [\"png\", \"jpeg\"] };' 'const PRICE = { image: 4, page: 2, thousandChars: 1 }; // 作り物の単位' > shapes.js"

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

形の検査を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function check(req) {' '  const problems = [];' '  let images = 0;' '  let cost = 0;' '  req.parts.forEach(function (p, i) {' '    const n = i + 1;' '    if (p.type === \"テキスト\") cost += Math.ceil(p.chars / 1000) * PRICE.thousandChars;' '    if (p.type === \"画像\") {' '      images++;' '      cost += PRICE.image;' '      if (LIMITS.kinds.indexOf(p.kind) < 0) problems.push(\"パート \" + n + \": 形式 \" + p.kind + \" は許可されていません\");' '      if (p.bytes > LIMITS.imageBytes) problems.push(\"パート \" + n + \": 画像が大きすぎます\");' '    }' >> shapes.js"

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

形の検査を書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' '    if (p.type === \"文書\") {' '      cost += p.pages * PRICE.page;' '      if (p.pages > LIMITS.pages) problems.push(\"パート \" + n + \": ページ数が多すぎます\");' '    }' '  });' '  if (images > LIMITS.images) problems.push(\"画像が多すぎます\");' '  return { problems: problems, cost: cost };' '}' >> shapes.js"

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

形の検査を書く(4)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const result = check(request);' 'result.problems.forEach(function (p) { console.log(\"問題:\", p); });' 'console.log(\"費用:\", result.cost, \"単位(作り物の価格)\");' 'async function main() {' '  const text = \"レシートの文字: パン 210 円、牛乳 105 円、合計 315 円。合計はいくらですか。\";' '  const sample = \"合計は 315 円です。\";' '  console.log(\"テキストだけの本物の呼び出し:\", await ask([{ role: \"user\", content: text }], sample, 40));' '}' 'main();' >> shapes.js"

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

記録済みのリクエストを検査

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

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

出力の一例

行何を示すか
問題: パート 3: 形式 gif は許可されていませんメディアタイプがリストにない
問題: パート 4: ページ数が多すぎます24 ページは上限の 20 を超える
費用: 58 単位テキスト 2、画像二枚で 8、文書 48
テキストだけの本物の呼び出しテキストの質問への短い答え。または、ラベル付きの記録済みサンプル

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

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

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