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

無料レッスン

エージェントが終えられるタスクを書く

このレッスンのあとで: エージェントが終えられ、自分で確かめられるタスクの仕様を書くことができる。

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

エージェントへのタスクの書き方

コーディングエージェントは、モデルを使ってコードを読み、ファイルを変え、コマンドを動かすプログラムです。エージェントは、あなたが書いたタスクをもとに働きます。だから、返ってくるものはタスクで決まります。

「売店のコードをよくして」と頼むと、四十のファイルが変わって返ってくることがあります。はっきりしたタスクなら、確かめられる小さな変更が返ります。前に学んだのは、アシスタントに一つの質問をうまく聞くことでした。このレッスンでは、エージェントのためにタスクを丸ごと書きます。

このレッスンのゴール

メモ

エージェントが終えられ、自分で確かめられるタスクの仕様を書くことができる。

キーワード

ことばいみれい
コーディングエージェントモデルを使ってコードを読み、ファイルを変え、コマンドを動かすプログラム
タスクの仕様一つの仕事のために書いた指示
範囲仕事に含まれる部分
完了条件仕事が終わったと示す確認node --test が通る
範囲外仕事で触ってはいけないもの

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

タスクには五つの部分がある

目的は、何が変わるかを一文で言います。範囲は、仕事に含まれる部分を言います。ファイルの一覧は、エージェントが書いてよい場所を言います。

完了条件は、テストのコマンドのように、動かせる確認の名前を言います。範囲外は、そのままにするものを言います。エージェントは止まって聞くことがほとんどありません。だから、どの部分も、エージェントが推測しそうな問いに答えます。

例: あいまいなタスクと、はっきりしたタスク

部分あいまいなタスクはっきりしたタスク
目的売店のコードをよくするtotal に学生割引 10 パーセントを入れる
範囲書いていないtotal だけ
ファイル書いていないshop.js と shop.test.js
完了条件書いていないnode --test が通り、新しいテストが 2 つある
範囲外書いていない値段と表示のしかた

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

よくある間違い

注意

タスクがあいまいなら、エージェントが聞いてくれると考える人が多いです。たいていのエージェントは、推測して先へ進みます。すると、すき間は、あなたが選んでいない選択になります。エージェントを動かす前に、範囲外と完了条件を書きましょう。

先にスクリプトでタスクを調べる

確認の一覧を使えば、よくあるすき間が一瞬で見つかります。このスクリプトは、記録した三つの仕様 A、B、C を持っています。欠けた部分、「改善」のようなあいまいな言葉、四つ以上のファイル、テストのない完了条件を探します。

ここでは、エージェントを動かしません。Run は言葉だけを調べるので、最初の三行は全員で同じです。

助っ人 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\");' 'const VAGUE = [\"いい感じ\", \"改善\", \"きれいに\", \"整理\", \"ちゃんと\", \"もっと\"];' 'const PARTS = [\"goal\", \"scope\", \"files\", \"done_when\", \"out_of_scope\"];' 'const NAMES = { goal: \"目的\", scope: \"範囲\", files: \"ファイル\", done_when: \"完了条件\", out_of_scope: \"範囲外\" };' 'const specs = {' '  \"A\": { goal: \"売店のコードを改善して、整理してください\" },' '  \"B\": { goal: \"total に学生割引 10 パーセントを入れる\", scope: \"total だけ\",' '    files: [\"shop.js\", \"shop.test.js\", \"prices.js\", \"README.md\"], done_when: \"node --test が通る\",' '    out_of_scope: \"値段\" },' '  \"C\": { goal: \"total に学生割引 10 パーセントを入れる\", scope: \"total だけ\",' '    files: [\"shop.js\", \"shop.test.js\"], done_when: \"node --test が通り、新しいテストが 2 つある\",' '    out_of_scope: \"値段と表示のしかた\" },' '};' > spec.js"

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

仕様の確認を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function problems(s) {' '  const out = PARTS.filter(function (p) { return s[p] === undefined || s[p].length === 0; })' '    .map(function (p) { return NAMES[p] + \"がない\"; });' '  // 日本語には単語の間の空白がないので、部分一致で探す。' '  if (s.goal) VAGUE.forEach(function (v) { if (s.goal.indexOf(v) >= 0) out.push(\"あいまい: \" + v); });' '  if (s.files && s.files.length > 3) out.push(\"ファイルが多すぎる\");' '  const d = s.done_when ? s.done_when.toLowerCase() : \"\";' '  if (s.done_when && d.indexOf(\"test\") < 0 && d.indexOf(\"テスト\") < 0) out.push(\"完了条件にテストがない\");' '  return out;' '}' >> spec.js"

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

仕様の確認を書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  Object.keys(specs).forEach(function (name) {' '    const found = problems(specs[name]);' '    console.log(\"仕様 \" + name + \": \" + (found.length === 0 ? \"準備完了\" : \"直しが必要 \" + JSON.stringify(found)));' '  });' '  const q = \"短く一文で答えてください。コーディングエージェントへのタスクに完了条件が要るのは、なぜですか。\";' '  const sample = \"確かめる方法がないと、エージェントはいつ止めるか分からず、人もうまくいったか分からないからです。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 80);' '  console.log(\"モデル: \" + reply.text);' '}' 'main();' >> spec.js"

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

仕様の確認を動かす

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

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

Run の出力

行意味
仕様 A: 直しが必要 [...]四つの部分が欠け、あいまいな言葉が二つある
仕様 B: 直しが必要 ["ファイルが多すぎる"]一つのタスクに四つのファイルは広すぎる
仕様 C: 準備完了すべての部分があり、確認はテストである
モデル: ...ラボからの一文。モデルが答えなければ記録済みサンプル

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

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

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