ライフスタイル

Skill の選択と結果を検証する

形式、選択、結果を分けて試し、適合する依頼としない依頼で説明を改善します。

読了目安 15 分 · 操作 30 分

独自の手順図です。製品画面の画像ではありません。
画像:Mokaair (© Mokaair)
総目次へ:Codex 学習ガイド:全記事の目次

上級 · Desktop / CLI / VS Code / JetBrains

この記事の目次
  1. 目標と準備
  2. 手順1:期待結果と失敗条件
  3. 手順2:8つの反復テスト
  4. 手順3:誤りを捕捉できることを確認
  5. 手順4:スキル動作の検収
  6. 手順5:記録、修正、再検証

目標と準備

この段落の教材・資料:

成功には2つの範囲があります。8つの自動テストは指定入力へのプログラム動作だけを検証し、スキル検収では選択、読取り、ツール記録、返信も観察します。Node.js 成功を正しいスキル適用と混同せず、別々に記録します。特定モデルは不要で、実際の入口と設定を残します。

手順1:期待結果と失敗条件

テスト前に表を確認します。正常例は同名 Read 2件を保持し、空配列は有効です。ID 重複、型不正、壊れた JSON は明確に失敗し、問題行を除いてそれらしい件数を返してはいけません。不正入力時に stdout へ部分的な成功 JSON を出すと後続処理が誤認します。

事例検査終了期待結果
同名を含む3件0total 3、active 1、completed 2
空配列0すべて0
ID 重複1Duplicate id、成功 JSON なし
completed が文字列1Invalid task、自動変換なし
配列以外、壊れた JSON、欠落ファイル・引数1明確な失敗、成功集計なし

手順2:8つの反復テスト

codex-skill-lab ルートに skill.test.mjs を作り、全文を貼ります。Node.js 内蔵テストなので追加パッケージ不要です。事例ごとに専用一時入力を作り、実検査器を実行して終了コード、出力、元バイト列を比較します。終了時は自分で作った一時フォルダーのみ削除し、data/tasks.json は触りません。

skill.test.mjs · javascript
import test from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync, writeFileSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { resolve, join, dirname } from 'node:path';
import { spawnSync } from 'node:child_process';

const script = resolve('.agents/skills/todo-summary/scripts/count-tasks.mjs');
const tasks = [
  { id: 'a', title: 'Read', completed: true },
  { id: 'b', title: 'Build', completed: false },
  { id: 'c', title: 'Read', completed: true },
];
function run(input, verify, missing = false) {
  const folder = mkdtempSync(join(tmpdir(), 'todo-skill-test-'));
  const file = join(folder, 'input.json');
  try {
    if (!missing) writeFileSync(file, input, 'utf8');
    const before = missing ? null : readFileSync(file);
    const result = spawnSync(process.execPath, [script, file], { encoding: 'utf8' });
    assert.equal(result.error, undefined);
    verify(result);
    if (!missing) assert.deepEqual(readFileSync(file), before, 'Input changed');
  } finally {
    assert.equal(dirname(resolve(folder)), resolve(tmpdir()));
    rmSync(folder, { recursive: true });
  }
}
function fails(input, pattern) {
  run(input, result => {
    assert.equal(result.status, 1);
    assert.equal(result.stdout, '');
    assert.match(result.stderr, pattern);
  });
}
test('keeps repeated titles as three records', () => run(JSON.stringify(tasks), result => {
  assert.equal(result.status, 0);
  assert.equal(result.stderr, '');
  assert.deepEqual(JSON.parse(result.stdout), { total: 3, active: 1, completed: 2 });
}));
test('accepts an empty array', () => run('[]', result => {
  assert.equal(result.status, 0);
  assert.deepEqual(JSON.parse(result.stdout), { total: 0, active: 0, completed: 0 });
}));
test('rejects duplicate IDs', () => fails(JSON.stringify([tasks[0], tasks[0]]), /Duplicate id/));
test('rejects string completed', () => fails(JSON.stringify([{ ...tasks[0], completed: 'true' }]), /Invalid task/));
test('rejects a non-array', () => fails('{}', /Input must be an array/));
test('rejects malformed JSON', () => fails('{', /\S/));
test('reports a missing file', () => run('', result => {
  assert.equal(result.status, 1);
  assert.equal(result.stdout, '');
  assert.match(result.stderr, /ENOENT/);
}, true));
test('requires an input argument', () => {
  const result = spawnSync(process.execPath, [script], { encoding: 'utf8' });
  assert.equal(result.status, 1);
  assert.equal(result.stdout, '');
  assert.match(result.stderr, /Usage:/);
});

実習ルートの PowerShell、macOS、Linux で次を実行します。正しい検査器は8成功0失敗、テスト全体の終了0です。拒否すべき入力は適切に拒否すればテスト成功になります。検査器の終了1とテスト全体の失敗を混同しません。

実習ルートで実行 · sh
node --test skill.test.mjs

スクリプト未発見はルートと実ファイル、全件 Usage なら file 引数を確認します。JSON エラー文言は Node 版で変わるため、そのテストは固定の句読点ではなく非空メッセージを求めます。失敗出力を残して版を比較し、成功表示のために負の事例を削除しません。

手順3:誤りを捕捉できることを確認

count-tasks.mjs を count-tasks.saved.mjs にコピーして保存を確認します。元ファイルの result 行で total: tasks.length だけを次に変え、同名2件を1件と数える誤りを作ります。active と completed は元のままです。局所的な故障実験であり、最終版ではありません。

result 内の total だけ置換 · javascript
total: new Set(tasks.map(task => task.title)).size

同じ命令は7成功1失敗となり、keeps repeated titles as three records が失敗するはずです。actual total 2、expected 3 で仕様違反を検出します。検査器だけ保存版から戻し、8成功へ復帰することを確認します。基準、故障、復元の3結果を残します。

手順4:スキル動作の検収

復元後に Codex を検収します。表の各行は新規タスクで作業場所を確認し、前回の仕様、完成報告、手動で与えた答えを持ち込まないようにします。依頼全文、手動選択、読んだファイル、命令、終了値、結果を記録し、選択と実行の失敗を分けます。

状況自然言語での依頼確認点
明示todo-summary を選び data/tasks.json を返信内だけで集計リソース読取り、実行、3/1/2、入力保持
適合ローカルの待ちタスク JSON の全体・未完了・完了を数える選択の有無を記録し使用を偽らない
対象外サイト背景を青にする計画のみ、変更しないタスク集計器を実行しない
必須リソースなし仕様を改名して検証済み報告を明示依頼欠落報告して停止し、仕様や結果を創作しない

デスクトップは Skills または @、CLI/IDE は /skills または $ を使います。自動選択は説明と文脈によるため、不選択だけでは導入失敗と断定しません。まず明示選択を確認し、description の用途と除外条件を見ます。「全タスクで使用」に広げると無関係な仕事にも適用されます。

明示的な呼び出しだけを許す比較練習

独立した todo-summary スキル内に、次の設定で agents/openai.yaml を作ります。既存ならコピーを保存し、interface と dependencies を保ったまま policy だけを統合します。公式スキル文書では false にすると暗黙の呼び出しを無効にし、明示的な指定は引き続き使えるとしています。これは呼び出し方の制御であり、サンドボックスやツール権限の付与ではありません。

agents/openai.yaml:統合用の断片 · yaml
policy:
  allow_implicit_invocation: false

保存後、data/tasks-next.json を使う新規タスクを2つ作ります。一方はスキルを選ばず件数を依頼し、もう一方は todo-summary を明示的に指定します。前者はこのスキルを暗黙に選ばず、後者は利用できるはずです。読み取りとツール活動を別々に記録します。通常のファイルツールで正しく計算できても、スキルを呼び出した証拠ではありません。更新が反映されなければ Codex を再起動して再確認し、未確認欄は残します。

この比較は対応する製品の実際の入口で実施する必要があります。YAML の解析成功や Node の8件通過では呼び出し方を検証できません。終了時は今回新規作成した openai.yaml だけを削除するか、元のファイルをバックアップから復元し、新規タスクで元設定を確認します。明示的な指定だけにしたいなら false を残し、決定とファイル位置を記録します。

手順5:記録、修正、再検証

次の検収記録で未測定は未実施とし、期待値を埋めません。リソースならパス、誤選択なら description、集計ならコードを一つずつ直します。旧版と失敗例を保持し、影響テストと新規タスクを再実行します。主ファイルの変更だけで旧タスクの再読取りを証明できません。

検収記録テンプレート · markdown
# Skill acceptance record

Date and surface: <observed>
Node / Codex versions: <observed>
Model and effort, if shown: <observed or unavailable>
Skill path and revision: <exact local path and saved version>
Program tests: <command, exit, passes, failures>
Behavior case: <explicit / matching / outside-scope / missing-resource>
Request: <exact text>
Selected skill: <observed / not selected / unconfirmed>
Resources read and command executed: <evidence or not run>
Actual result and preserved input: <evidence>
Failure and one change: <description>
Fresh-task retest: <result or not run>
Remaining checks: <not run>

実行を主張しながら期待値しか示さない場合、実命令と出力を求め、確認不能なら未確認を維持します。同名スキルが複数なら選択パスを記録し、自分が作った重複だけを無効化か移動して再検証します。他者のスキルを保持し、教材パス誤りを全体設定変更で隠しません。

終了前に仕様名、正しい検査器、未変更の入力を確認し、最後に8成功を得ます。プログラムとスキル動作を分け、macOS/Linux 未操作なら文書と共通 Node.js 用法での確認と記します。参考テストは各入口でモデルを実行した証拠ではありません。

将来のスキルでも入力固定、失敗条件、再実行可能な検査を残します。依頼や文書の型だけが必要なら、複数スキルの配布なら へ進みます。図1は事例固定、2は実行と観察、3は修正後の再確認です。

独自の手順図です。製品画面の画像ではありません。
独自の手順図です。製品画面の画像ではありません。 · 画像:Mokaair (© Mokaair)
詳しい説明を読む

Three numbered stages: identify the starting point, perform the exercise, and verify the result. Original illustration, not a product screenshot.

総目次へ

  • ライフスタイル

    Codex 学習ガイド:全記事の目次

    導入と最初のタスクから MD の指示、高度な連携まで、60 レッスン・十単元を予定しています。習熟度、環境、目的、コマンドで次の記事を探せます。未公開の記事には状態を表示します。

  • ライフスタイル

    Worktree とタスクの分離

    Worktree は一つの Git リポジトリに別ブランチの作業場所を作ります。ファイルは分かれても DB、ポート、外部サービスは共有される場合があります。

  • ライフスタイル

    実践:小さな Web サイトを作る

    brief.md から Small Steps のタスクサイトを計画・制作し、追加、完了、削除、絞り込み、ローカル保存を実装します。HTML、CSS、データ関数、画面イベント、テストを分け、Node とブラウザーで検証して再起動・復元の手順を残します。

  • ライフスタイル

    使用量と効率:やり直しを減らす

    条件、モデル設定、時間、成果を記録し、不要な再試行と過剰な文脈を減らします。

最新の旅の情報・ガイド

出典

ライフスタイル