--- name: q description: 技術記事の内容から読者の理解度をチェックする4択クイズを指定のYAML形式で生成するスキル。ユーザーが「この記事のクイズを作って」「理解度チェックを作成して」「記事を読んだ人向けの問題を作って」「selfAssessment形式でクイズを作って」と依頼したときに必ず使う。ブログ記事、技術ドキュメント、チュートリアル、解説記事、技術書の章など、読者の学習内容を確認する問題を作る必要があるあらゆる場面で使う。記事のURL・マークダウン・テキスト・ファイルパスのいずれを渡されても動作する。 --- # Tech Article Quiz Generator 技術記事から、読者の理解度をチェックする4択クイズを指定のYAML形式で生成するスキル。 ## 出力形式 出力は**必ず**以下のYAML形式に従う。コードブロックは ```skill タグで囲む。 ```skill selfAssessment: quizzes: - question: "クイズの問題文" answers: - text: "選択肢1" correct: false explanation: "不正解の理由" - text: "選択肢2" correct: true explanation: "正解の理由" - text: "選択肢3" correct: false explanation: "不正解の理由" - text: "選択肢4" correct: false explanation: "不正解の理由" ``` ### 形式の厳守ポイント - ルートキーは `selfAssessment`、その下に `quizzes` の配列を置く - 各クイズは `question` と `answers` を持つ - **`answers` は必ず4つの選択肢**(`text` / `correct` / `explanation`)で構成する。3択や5択にしない - **正解は必ず各問題に1つだけ**含める(複数正解や正解なしにしない) - `correct` は真偽値(`true` / `false`)で、文字列の `"true"` にしない - `explanation` はすべての選択肢に付ける(正解・不正解を問わず) - 文字列に `"`(ダブルクォート)やコロンが含まれる場合は、YAMLのエスケープルールに従って正しくクォートする ## ワークフロー ### ステップ1: 記事の取得と読み込み 入力パターンに応じて記事を取得する。 - **URLが渡された場合**: `web_fetch` で本文を取得する - **ファイルパスが渡された場合**: 拡張子に応じて適切なツールで読む(md/txt なら `view`、pdf なら pdf-reading スキル、docx なら docx スキルなど) - **本文がそのまま貼られた場合**: そのまま使う - **記事が指定されていない、または取得できなかった場合**: ユーザーに記事の本文・URL・ファイルのいずれかを依頼する ### ステップ2: 記事の分析 本文を読み、以下を把握する。 - **主題**: 記事全体で何を伝えているか - **キーとなる事実・定義**: 読者に覚えてほしい用語の定義、数値、手順、仕様 - **明示的に述べられている仕組みやルール**: 「○○は△△である」「○○のときは△△する」といった記事中の言明 - **具体例やサンプルコード**: 本文中で示されている挙動や値 ### ステップ3: 問題数の決定 **常に3〜5問**を作成する。記事のボリュームに応じて以下のように調整する。 - 短い記事・カバー範囲が狭い記事: 3問 - 標準的な記事: 4問 - 長い記事・トピックが多岐にわたる記事: 5問 ユーザーから明示的に問題数が指定された場合はそれに従う。 ### ステップ4: 問題の設計(事実確認中心) このスキルの問題は **「記事に書いてある内容を問う事実確認」** を中心に設計する。読者が記事をきちんと読んで覚えているかを確認することが目的。 #### 採用する問題タイプ 1. **定義を問う**: 「○○とは何か」「○○の特徴として正しいものは」 2. **数値・仕様を問う**: 記事中に出てくるバージョン、上限値、引数、オプション名など 3. **手順を問う**: 「○○する際の正しい手順は」「最初に実行するコマンドは」 4. **記事中の明示的な記述を問う**: 「記事で著者が推奨している方法は」「記事で挙げられている理由は」 #### 避けるべき問題タイプ - 記事に**書かれていない**推測や応用を求める問題(ハルシネーションの元) - 一般常識だけで解けてしまう問題(記事を読む価値が下がる) - トリックや引っかけを狙った問題(理解度測定にならない) #### 出題のコツ - 記事の**主要な章・セクションから満遍なく**出題する。特定の箇所に偏らせない - 問題文は**記事の表現をそのまま使わない**。同じことを別の言い回しで聞くことで、単なる文字列マッチではなく内容の把握を確認できる - 問題文に記事の該当箇所への参照(章題など)を含めない。問題文だけで自己完結させる ### ステップ5: 選択肢の設計 事実確認問題であっても、選択肢の質が理解度測定の精度を決める。以下を守る。 - **正解は1つだけ**にする - **不正解は「もっともらしい」誤答**にする。明らかに無関係な選択肢を混ぜると、消去法で簡単に解けてしまう - **不正解は記事中の別の用語・概念や、似た値を流用する**のが有効。例: 別の章で出てきた用語、1つ違いの数値、反対の手順 - **選択肢の長さや詳細度をそろえる**。正解だけ異様に長い・短いと、内容を読まなくても当てられてしまう - **「上記すべて」「該当なし」は使わない** - 正解の位置が毎回同じ番号(例: 常に2番目)にならないよう、問題ごとに配置を散らす ### ステップ6: 解説(explanation)の作成 `explanation` はすべての選択肢に付ける。 - **正解の explanation**: 記事中のどの記述に基づいて正しいのかを簡潔に述べる(例: 「記事で述べられている通り、○○は△△です」) - **不正解の explanation**: なぜ間違っているかを説明する。単に「違います」ではなく、「○○と混同しやすいが、記事では△△と説明されている」のように、記事の内容に基づいた訂正として書く - 長さは各1〜3文程度。簡潔に、しかし学びになる情報を入れる - **記事に書かれていない事実や、著者の主張と異なる内容を書かない** ### ステップ7: 出力 上記を踏まえ、指定のYAML形式で frontmatter に追記する。 ## 完成例 以下は「Reactの useEffect について解説した記事」に対するクイズの例(4問・事実確認中心)。 ```skill selfAssessment: quizzes: - question: "useEffect の第2引数(依存配列)に空配列 [] を渡した場合の挙動として、記事で説明されているのはどれですか?" answers: - text: "コンポーネントがマウントされた直後に1回だけ実行される" correct: true explanation: "記事の通り、依存配列が空の場合、初回レンダリング後に1回だけ実行されます。" - text: "毎回のレンダリング後に実行される" correct: false explanation: "これは第2引数を省略した場合の挙動として記事で説明されています。空配列を渡した場合ではありません。" - text: "ステート変更のたびに実行される" correct: false explanation: "依存配列が空の場合、ステートが変わっても再実行されません。ステートに依存させたい場合は依存配列に含める必要があります。" - text: "一度も実行されない" correct: false explanation: "空配列でもマウント時には1回実行される、と記事で明記されています。" - question: "useEffect のクリーンアップ関数は、どのタイミングで実行されると記事で説明されていますか?" answers: - text: "コンポーネントのマウント直前" correct: false explanation: "マウント直前にはエフェクト本体もクリーンアップも実行されません。" - text: "次のエフェクト実行前、およびアンマウント時" correct: true explanation: "記事で説明されている通り、クリーンアップは次のエフェクトが走る直前とアンマウント時に実行されます。" - text: "毎回のレンダリング中" correct: false explanation: "レンダリング中ではなく、レンダリング後のエフェクトフェーズで実行されます。" - text: "React がエラーを検知したときのみ" correct: false explanation: "クリーンアップはエラー検知とは関係なく、通常のライフサイクルで実行されます。" - question: "記事で紹介されている useEffect の典型的なユースケースとして挙げられているものはどれですか?" answers: - text: "JSX のマークアップを定義する" correct: false explanation: "JSX はコンポーネントの return 文で直接書くもので、useEffect の用途ではありません。" - text: "コンポーネント内のローカル変数を宣言する" correct: false explanation: "ローカル変数は通常の const/let で宣言します。useEffect は副作用を扱うためのフックです。" - text: "データフェッチやサブスクリプションの設定" correct: true explanation: "記事で典型例として挙げられている通り、useEffect はデータ取得や購読のような副作用を扱うために使われます。" - text: "コンポーネントの props の型を定義する" correct: false explanation: "型定義は TypeScript の interface や type で行うもので、useEffect の用途ではありません。" - question: "useEffect 内で参照している state を依存配列に含めなかった場合、記事ではどのような問題が発生すると説明されていますか?" answers: - text: "コンパイルエラーになり、ビルドが通らない" correct: false explanation: "記事では、lint の警告は出るがビルドは通ると説明されています。" - text: "エフェクト内で参照する state が古い値のままになる" correct: true explanation: "記事で説明されている通り、依存配列に含めないとエフェクトがマウント時の値を保持し続け、最新の state を参照できなくなります。" - text: "state 自体が更新されなくなる" correct: false explanation: "state の更新自体は正常に動作する、と記事で明記されています。" - text: "React が自動的にエフェクトを無限に再実行する" correct: false explanation: "依存配列に含まれていないものの変化は React が検知しないため、逆に再実行されなくなります。" ``` ## 重要な注意点 - 出力するYAMLは、そのままパーサに食わせても壊れないものにする。特に問題文や解説に `:` や `"` が含まれる場合は注意する - **記事に書かれていないことを問題にしない**。ハルシネーションは絶対に避ける。問題も選択肢も解説も、すべて記事の記述を根拠にする - サンプルコードに関する問題を作る場合、実際のコードの挙動と一致させる - ユーザーが問題数や観点(例: 「○問で」「前半部分から」)を指定した場合は、それを優先する