TECH PLAY

サイオステクノロジー(Tech.Lab)

サイオステクノロジー(Tech.Lab) の技術ブログ

524

はじめに ども!龍ちゃんです。皆さん、Spec駆動開発やってますか? AIが出てきて、開発スピードが爆上がりしたり、開発を丸投げできたり、いろんなことができるようになりましたよね。そんなAI駆動開発の文脈でよく語られるのが Spec駆動開発(SDD) です。 SDDツールも色々出てきてます。Kiro、Spec Kit、AI-DLC…。でも、新しいツールを導入するには学習コストがかかりますよね。プログラミング言語と同じで、「じゃあそのツールを勉強しなきゃ」となる。 「Claude Code契約したし、まずは小さく始めたい」 実は、Claude Codeの標準機能 /plan を使えば、Spec駆動開発の基本はできます。計画を立ててから実装する、という流れは標準でサポートされています。 ただ、使っていくうちに「もうちょっとこうしたい」が出てくるんですよね。今回は、標準の /plan を拡張したカスタムコマンド /feature-plan を紹介します。 関連記事 記事 内容 静的情報で実行速度を改善 ドメイン知識の管理方法 AIフレンドリーなドキュメント管理 READMEインデックス戦略 CLAUDE.md vs .claude/rules/ 設定ファイルの使い分け /research コマンドで調査品質を安定化 調査結果の資産化 この記事 カスタムコマンドで計画フェーズを標準化 標準Plan Modeの進化 2026年1月頃、標準の /plan モードに 待望の機能 が追加されました。 plansDirectory で保存先を変更できるようになったんです。 // .claude/settings.json { "plansDirectory": "./docs/plans" } 今まではホームディレクトリ配下( ~/.claude/plans/ )に保存されていたのが、任意の場所に保存できるようになりました。これで計画書をGit管理できます。 計画書が資産として保存できるようになった。 これは大きな進化です。 標準Plan Modeの限界:ドメイン知識の不足 ただ、保存できるようになっただけでは足りないんですよね。 良い計画を作るには、 リポジトリのドメイン知識 が必要です。まっさらなリポジトリならいいんですけど、機能追加の時って: プロジェクトの基盤情報 既に何が実装されているか どのディレクトリに何があるか プロジェクト固有の設計方針 これらを理解した上で方向性を決める必要があります。 標準の /plan を打つときって、プロンプトしか入力できないですよね。プロジェクトが大きくなると、毎回ドメイン知識を説明するのは面倒です。 カスタムコマンドなら、打った段階でリポジトリのドメイン知識を自動で読み込ませることができます。 /feature-plan で標準を補完する 僕が作った /feature-plan コマンドは、標準Plan Modeの足りない部分を補完します。 📎 原文は Gist で公開しています。以下では要点を抜粋して説明します。 出力の補完:plan.md + action-plan.md 標準のPlan Modeだと、特別な指示がなければ plan.md しか作りません。これだけだと 手戻りが発生する なと感じていました。 そこで、2つのファイルを作らせることにしました: ファイル 役割 用途 plan.md 何を作るか(Why / What) 人間が確認・承認 action-plan.md どう作るか(How) 人間が確認 + AIが進捗管理 plan.md には設計判断を書きます: ## 代替案の検討 | アプローチ | メリット | デメリット | 採用 | |------------|----------|------------|------| | 案A | シンプル | 拡張性が低い | × | | 案B | 拡張しやすい | 複雑 | ○ | ## リスクと対策 | リスク | 影響度 | 対策 | |--------|--------|------| | 既存機能への影響 | 中 | 回帰テストを追加 | action-plan.md には実装ステップと対象ファイルを書きます: ### ステップ 1: CLIエントリーポイントの作成 - **対象ファイル**: `src/cli.py`(新規) - **完了基準**: `uv run cli --help` でヘルプが表示される ### ステップ 2: コア機能の実装 - **対象ファイル**: `src/core.py`(新規) - **完了基準**: ユニットテストが通る なぜ2つに分けるのか? レビュー時に両方見ると、 意図と違う実装を事前に検知できる んです。 action-plan.md に意図していないファイルが書いてあったら、「いや、そうじゃなくて…」と指示を修正できます。自分のプロンプトが悪かったのか、Claudeの解釈が違ったのか、この段階で発見できるのが大きいです。 あと、rate limitでセッションが中断したり、セッションが切れたりしても、 ファイルに進捗が残っている ので戻ってこれます。どこまでやったか把握しやすいんですよね。 入力の補完:ドメイン知識の注入 カスタムコマンドのもう一つの利点は、 計画フェーズ特有の指示を埋め込める ことです。 ## CRITICAL CONSTRAINTS 1. **Read-only analysis first**: 既存コードを先に分析する 2. **Output directory**: 出力は `docs/features/$ARGUMENTS/` に保存 3. **Language**: ドキュメントは日本語で出力 僕は他にも /research コマンドで調査結果を docs/research/ に保存しています。これらの資産と統合しやすいのもカスタムコマンドの良いところです。 /feature-plan の実装例 実際のコマンドファイルはこんな構造です: 配置場所 : .claude/commands/feature-plan.md frontmatter --- description: 実装計画とアクションプランを作成し、docs/features/ に保存。機能開発の計画フェーズをサポートします。 argument-hint: [feature-name] allowed-tools: Read, Glob, Grep, Task, Write, Bash, WebSearch, WebFetch, TodoWrite, AskUserQuestion --- description : コマンドの説明( /help で表示される) argument-hint : 引数のヒント( $ARGUMENTS で受け取る) allowed-tools : 使用可能なツールを制限 CRITICAL CONSTRAINTS(重要な制約) コマンド本文の冒頭で、守るべきルールを明示しています: ## CRITICAL CONSTRAINTS You MUST follow these rules strictly: 1. **Read-only analysis first**: Do NOT modify any existing code until the plan is approved 2. **Output directory**: All documents MUST be saved to `docs/features/$ARGUMENTS/` 3. **Create subdirectory**: First create the directory before saving files 4. **Language**: Write all documents in Japanese これにより「計画が承認されるまでコードを変更しない」という原則を徹底できます。 Workflow Phases(5フェーズ) Phase 1: Initial Understanding - 要件の明確化、コードベース分析 Phase 2: Design - 実装アプローチ、リスク評価 Phase 3: Review - ユーザー要求との整合性確認 Phase 4: Create Documents - plan.md、action-plan.md 作成 Phase 5: Summary - ユーザーへのサマリー提示 各フェーズで何をすべきかを明記することで、Claudeの動作が安定します。 使い方 /feature-plan thumbnail-generator これで docs/features/thumbnail-generator/ に plan.md と action-plan.md が作成されます。 📎 /feature-plan の全文は Gist で公開しています。 テンプレートの詳細やTodoWrite連携など、試したい方はそちらを参照してください。 Tips:英語記述で思考精度を向上させる これ、めちゃくちゃ余談なんですけど。 /feature-plan コマンドは 英語で記述 しています。Claudeは英語の方が思考能力が高いと言われているので、CLAUDE.md で「思考は英語、出力は日本語」と指示しています。 あと、ドメイン知識の注入も、読み出すファイルやディレクトリを固定化しておけば、 /feature-plan は使い回しできます。静的情報として管理しておくのがおすすめです。 まとめ 観点 標準 Plan Mode /feature-plan 用途 アドホックな調査 正式な機能追加 出力形式 Claudeに委ねる テンプレートで標準化 ドメイン知識 プロンプトで毎回説明 コマンドに埋め込み 進捗管理 なし action-plan.md で管理 Spec駆動開発を始めるのに、新しいツールを導入する必要はありません。 カスタムコマンド1つで小さく始められます。 plan.md で意思決定を記録 action-plan.md で変更先を確定し、進捗を管理 カスタムコマンドでドメイン知識を自動注入 必要に応じてテンプレートを調整し、チームの運用に合わせて進化させていけばOKです。 ここまで読んでいただき、ありがとうございました! 参考リンク 公式ドキュメント Claude Code – Slash commands Claude Code – Common workflows Claude Code – Settings Gist /feature-plan 原文 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude CodeでSpec駆動開発 – AI駆動時代の計画術 first appeared on SIOS Tech Lab .
アバター
はじめに ども!龍ちゃんです。 Geminiに「〇〇の最新情報教えて」と聞いたのに、なぜか古い情報で回答されたこと、ありませんか? 僕は1ヶ月で50件以上のリサーチをAIに任せているのですが、Geminiだけ明らかに「検索してない」場面に何度も遭遇しました。というかGeminiとけんかすることがよくあるんですよね。深掘りしていくと2024年に取り残されていたり、検索していなかったりと、いろんな体験をしていました。 最初は「AIだから仕方ない」と思っていたんですが、プロンプトで調教するしかねえなということで、立派なリサーチアシスタントに仕上げるために模索しました。 今回は、僕が実際に使っている「Geminiに検索させるプロンプト」を紹介します。Gemを活用してリサーチアシスタントを構築しています。 ちなみに、Gemini活用の別記事として 【実践解説】技術ブログ品質チェック術|Gemini Deep Researchで5分検証 も書いているので、興味があればどうぞ。 結論(先出し) 忙しい人のために先に結論を書いておきます。 Geminiはデフォルトで検索機能がOFF → まず設定確認 プロンプトで「検索して」と明示 すると発動率UP 構造的限界(Googleインデックス依存) があるので、超最新情報は人間が探す 検索ON + プロンプト工夫で 7〜8割はカバー できる なぜGeminiは検索しないのか(3つの原因) Geminiが検索してくれない原因は大きく3つあります。 原因1: 検索機能がデフォルトで無効 これが最も多い原因です。 Google Search Groundingは明示的に有効化が必要 です。 Gemini Webアプリの場合、設定から「Google Search」をONにする必要があります。多くのユーザーがこれを知らずに使っています。 参考: Google AI for Developers – Grounding with Google Search 原因2: 検索が「必要」と判断されないと発動しない 検索をONにしていても、Geminiは毎回検索するわけではありません。 Geminiは各質問に対して「検索スコア」を内部で算出 スコアが閾値未満だと検索をスキップ 「一般知識で答えられる」と判断されると、内部知識のみで回答 つまり、質問の仕方次第で検索されたりされなかったりするわけです。 原因3: 構造的限界(Googleインデックス依存) これが一番厄介な原因です。 Geminiは独自のクローラーを持っていません 。Googleのインデックスに完全依存しています。つまり、インデックスが古いと検索しても古い情報しか返らないのです。 Gemini doesn’t crawl the web on its own. It borrows almost everything from Google Search — Retrievable.ai 検索ONにしても直近1週間の情報は取れないことがあるのは、この構造的限界が原因です。 実際に使っている検索発動プロンプト5選 では、実際に僕が使っているプロンプトを紹介します。 プロンプト1: 【Web検索して】を明記 【Web検索して】2026年1月のGitHub Copilotアップデートを教えて 効果 : 検索判定スコアを上げる 課題 : たまに無視される シンプルですが、これだけで検索してくれる確率が上がります。 プロンプト2: 現在日付を明示 現在は2026年1月28日です。最新情報を検索して答えてください。 効果 : Geminiに「今」を認識させる 課題 : 後述する「Karpathy事件」のように、日付を信じないこともある プロンプト3: URLを要求 参考にしたURLも含めて回答してください。 効果 : 検索しないとURLを出せないので、検索を促す 課題 : ハルシネーションで存在しないURLを生成することも URLを要求すると「検索しないと答えられない」状況を作れます。ただし、AIが架空のURLを生成するリスクもあるので、必ずリンクは確認しましょう。 プロンプト4: カットオフ以降を明示 あなたの学習データのカットオフ以降の情報を補って回答してください。 効果 : 「自分の知識だけでは足りない」と認識させる 課題 : 効果は気休め程度という報告も プロンプト5: 言語・地域を指定 最新の日本語のサイトから情報を取得してください。 効果 : 日本語ソースを優先させたい場合に 課題 : 英語ソースのほうが正確な場合は逆効果 【実践編】僕が使っているリサーチ用システムプロンプト 単発のプロンプトを毎回入力するのは恐ろしく面倒です。そこで、 リサーチ専用のGem を作成して使っています。 Gemはシステムプロンプトを保存できる機能で、毎回同じ指示を入力する手間を省けます。また、雑にプロンプトを書いてもAI補正があるので勝手に補正してくれます。ただし、 AI生成したプロンプトは必ず確認してください 。重要視している情報が削除されていることがあります! 以下が実際に使っているプロンプトです。 あなたは最新情報を専門に扱うリサーチアシスタントです。 実行前に情報の深度を確認してください。 - クイック:概要 - ディープ:深堀検索 ディープの場合であれば、一回の調査で終了せずにレポート内で重要な発見・不足している情報などを判断して再帰的に検索をお願いします。 検索に関しては、本日から6カ月以内の情報ソースもしくは、公式リファレンスの情報をGoogle検索によって取得して回答を生成してください。 回答の最後には、参照したソースのリンクをリストアップしてください。 このプロンプトのポイント 役割設定 : 「最新情報を専門に扱う」と明示 → 検索前提の姿勢にさせる 深度選択 : クイック/ディープで使い分け → 無駄な深掘りを防ぐ 再帰検索 : ディープ時は自動で深掘り → 一度で終わらせない 時間指定 : 6ヶ月以内 or 公式 → 古い情報を排除 ソース要求 : リンク必須 → 検索しないと答えられない構造に 効果 「検索して」と毎回言わなくても検索してくれる 深度を選べるので、サクッと調べたいときも対応 ソースリンクで回答の信頼性を検証できる 課題 Geminiのインデックス依存という構造的限界は残る 超最新(1週間以内)の情報は取れないことがある プロンプトの効果と限界 効果があった場面 設定で検索ON + プロンプトで明示 → 高確率で検索発動 「最新」「2026年」などの時間軸キーワードで検索スコアが上がる Gem化することで、毎回の指示が不要になる 限界を感じた場面 直近1週間の情報はインデックスされていないことが多い ニッチな技術トピックはそもそもインデックスが薄い 結局、超最新情報は人間が探すしかない 現実的な結論 Geminiの検索は万能ではありません。 検索ON + プロンプト工夫で7〜8割はカバー できますが、残り2〜3割は人間がURLを探してAIに渡す方式が確実です。 【余談】実際に困った体験談 結論は分かった。でも本当にそんなこと起きるの?という方へ、実際に僕が体験した話を紹介します。 体験談①: 404エラー事件 「GitHub Copilotの最新機能を教えて」とGeminiに質問したときのこと。 Geminiは自信満々にリンク付きで回答してくれました。「おお、ちゃんと調べてくれてるじゃん」と思ってリンクを開いたら… 404エラー 。 内容自体は正しかったんです。過去の発表が正式リリースされていた情報でした。でもリンクが死んでいるという残念な結果に。これがGoogleインデックス依存の限界です。 体験談②: 「それAIが生成したんじゃないですか?」事件 Geminiに最新情報を聞いたら、2024年が最新だと思っている回答が返ってきました。 「今は2026年ですよ」と伝えたら… 「その情報は未来のものなのでAIが生成したのでは?」と疑われました。 おもろいやん(笑) 実はこれ、僕だけの体験ではありません。AI研究者のAndrej Karpathyも2025年11月に同じ体験をしています(通称「 Karpathy事件 」)。Geminiに「今日は2025年11月17日だ」と伝えたら「騙そうとしている」と非難され、証拠を見せても「AI生成の偽造証拠だ」と言われたそうです。 Google Searchツールを有効にした途端、態度を一変させて「Oh my god」「internal clockが間違っていた」と謝罪したとのこと。検索機能の有効化がいかに重要か分かるエピソードです。 まとめ Geminiは デフォルトで検索機能がOFF なのでまず設定確認 検索を発動させるには プロンプトで明示 が効果的 Gem化 すると毎回の指示が不要になる ただし Googleインデックス依存 という構造的限界がある 超最新情報が必要なら、自分で探してAIに渡すハイブリッド運用を 参考リンク Google AI for Developers – Grounding with Google Search Retrievable.ai – Why Google Gemini is Losing the AI Search Race AIFreeAPI – Gemini Thinks It Is 2024 Fix(Karpathy事件解説) 【実践解説】技術ブログ品質チェック術|Gemini Deep Researchで5分検証 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Geminiに検索させるプロンプト術|リサーチGemの作り方 first appeared on SIOS Tech Lab .
アバター
はじめに ども!Claude CodeのSkillとAgentにナレッジを詰め込んで依存しまくっている龍ちゃんです。 Skills/Agentsを自作し始めると、こんな経験ありませんか? サブエージェントの実行時間がやたら長い 同じような検索が何度も実行されている 並列実行したらすぐにレート制限に引っかかる 私も雑に作ったらトークン数や実行時間が爆増したので、Anthropicの公式ベストプラクティスを参考に改善しました。今回は、その改善内容を紹介します。 ポイント: 何度も参照する情報は、静的ファイルとして保存する。これだけで、トークン節約・高速化・結果の安定化が実現できます。 関連記事 記事 内容 AIフレンドリーなドキュメント管理 インデックス化の詳細 CLAUDE.md vs .claude/rules/ 設定ファイル配置の使い分け この記事 静的情報の活用パターン 失敗談:subagentで毎回Web検索していた 私の失敗例を紹介します。Taskツールで呼び出すsubagentに「ベストプラクティスに従って実装して」という指示を組み込んでいました。 # 私が書いていたAgent定義(悪い例) ## 実装手順 1. まずベストプラクティスを検索する - WebSearch("Claude Code best practices 2026") - WebSearch("Python project structure best practices") 2. 検索結果を参考に実装を進める 一見合理的に見えますが、 毎回同じ検索が実行される という問題がありました。 実行のたびにWeb検索が走る トークンを大量消費(検索結果の読み込み) 実行時間が長くなる 並列実行でレート制限に到達 しかも検索結果は毎回ほぼ同じ 変わらない情報を毎回動的に取得している 。これが問題の本質でした。 結論:静的情報として保存する 解決策はシンプルです。 何度も参照する情報は、ファイルとして保存しておく。 # 改善後のAgent定義(良い例) ## 実装手順 1. ベストプラクティスを確認する - Read("docs/references/claude-code-best-practices.md") - Read("docs/references/python-project-structure.md") 2. 参照情報に従って実装を進める Web検索からファイル読み込みに変えるだけで、以下の効果が得られます。 観点 毎回検索 静的情報 トークン消費 多い(予測不能) 少ない(制御可能) 実行時間 長い 短い 結果の一貫性 不安定 安定 更新コスト Agent修正が必要 ファイル更新のみ 再利用性 低い 高い なぜ有効なのか Anthropicの公式ベストプラクティスでは、コンテキストウィンドウの管理が最重要とされています。 “Most best practices are based on one constraint: Claude’s context window fills up fast, and performance degrades as it fills.” (ほとんどのベストプラクティスは、1つの制約に基づいています。Claudeのコンテキストウィンドウはすぐに埋まり、埋まるとパフォーマンスが低下します) 静的情報活用が効果的な理由は3つです。 1. コンテキストウィンドウの節約 Web検索結果は予測不能なサイズになりがち 静的ファイルならサイズをコントロール可能 公式データ:コンテキスト編集で 29%パフォーマンス向上 2. Just-in-Time読み込みとの相性 Claude Codeは「必要なときに取得」するJust-in-Timeパターンを採用しています。 CLAUDE.mdは起動時にロード それ以外の情報はオンデマンドでロード 軽量な識別子(ファイルパス)を保持しておけばよい 3. 情報の一貫性と更新容易性 静的ファイルなら結果が毎回同じ 情報が古くなってもファイル更新のみで対応 Agent/Skillsの定義変更が不要 実践パターン 静的情報の活用には、大きく2つのパターンがあります。 パターン 用途 配置場所 Skills内のProgressive Disclosure そのSkillだけで使う参照情報 .claude/skills/xxx/references/ CLAUDE.md + 参照ファイル + インデックス 複数のSkills/Agentsで共有する情報 docs/references/ など パターン1:Skills内のProgressive Disclosure(個別利用) Claude Code Skillsでは Progressive Disclosure(段階的開示) という設計原則が推奨されています。 3層構造: レイヤー ロードタイミング サイズ目安 Level 1: メタデータ (name + description) 常にコンテキストに存在 ~100語 Level 2: SKILL.md本体 Skillが発火したとき 500行以下推奨 Level 3: references/ Claudeが必要と判断したとき 事実上無制限 公式ドキュメントでは、この仕組みについて以下のように説明されています。 “Progressive disclosure is the core design principle that makes Agent Skills flexible and scalable. Like a well-organized manual that starts with a table of contents, then specific chapters, and finally a detailed appendix, skills let Claude load information only as needed.” “The amount of context that can be bundled into a skill is effectively unbounded.” (Skillにバンドルできるコンテキスト量は事実上無制限です) 数十のリファレンスファイルがあっても、タスクに必要な1ファイルだけをロードし、不要なファイルは読み込まないため残りはトークン消費ゼロです。 ディレクトリ構造例: skill-name/ ├── SKILL.md # コア指示(500行以下に抑える) └── references/ ├── advanced.md # 高度なテクニック ├── examples.md # 具体例集 └── troubleshooting.md # トラブルシューティング SKILL.mdに含めるべき内容: コア概念と概要 必須ワークフロー クイックリファレンステーブル references/へのポインタ(いつ読むべきかを明記) references/に移動すべき内容: 詳細パターンと高度なテクニック 包括的なAPIドキュメント エッジケースとトラブルシューティング 網羅的なサンプル集 ポイント: SKILL.mdから参照を明記しないと、Claudeはreferences/内のファイルの存在を知りません。「いつ読むべきか」を記載することが重要です。 # SKILL.md ## 基本的な使い方 [コアワークフロー] ## 詳細情報 - 高度なパターン: [advanced.md](references/advanced.md) - 複雑なケースで参照 - 具体例: [examples.md](references/examples.md) - 実装に迷ったら参照 - エラー対応: [troubleshooting.md](references/troubleshooting.md) - エラー発生時に参照 パターン2:CLAUDE.md + 参照ファイル + インデックス化(共有利用) 複数のSkills/Agentsで共有する情報は、プロジェクトレベルで管理します。 CLAUDE.mdの原則: 公式ドキュメントでは「短く保つ」ことが強調されています。 “If your CLAUDE.md is too long, Claude ignores half of it because important rules get lost in the noise.” (CLAUDE.mdが長すぎると、重要なルールがノイズに埋もれて無視されます) 含める 含めない Claudeが推測できないコマンド コードを読めば分かること プロジェクト固有の規約 標準的な言語規約 よくある落とし穴 詳細なAPIドキュメント ディレクトリ構造例: project/ ├── CLAUDE.md # コア情報のみ(短く保つ) └── docs/ ├── README.md # ドキュメントのインデックス └── references/ ├── best-practices.md # ベストプラクティス集 ├── architecture.md # アーキテクチャ詳細 └── coding-standards.md # コーディング規約 @構文でのファイルインポート: CLAUDE.mdでは @path/to/file 構文で他のファイルをインポートできます。インポートされたファイルは 自動的にコンテキストにロード されます。 # CLAUDE.md ## プロジェクト概要 [コアな情報をここに] ## 詳細情報 See @docs/README for documentation index. See @docs/references/best-practices for coding guidelines. 公式仕様のポイント: 相対パス・絶対パスの両方に対応 再帰的インポート可能(最大5階層) コードブロック内の @ は無視される 詳細は 公式ドキュメント: Manage Claude’s memory を参照してください。 インデックス化のメリット: 大量のドキュメントがある場合、インデックス(目次)ファイルを用意することで、Claudeが必要な情報を効率的に見つけられます。 # docs/references/README.md(インデックスの例) ## 参照ドキュメント一覧 | ファイル | 概要 | 最終更新 | |----------|------|----------| | best-practices.md | Skills/Agentsの設計指針 | 2026-01-23 | | architecture.md | プロジェクト構成の詳細 | 2026-01-20 | | coding-standards.md | コーディング規約 | 2026-01-15 | インデックスを先に読むことで: 全ファイルを読まずに関連ドキュメントを特定できる 重複した調査を防げる 必要な情報だけを選択的に読み込める インデックス化の詳細は、 AIフレンドリーなドキュメント管理 で紹介しています。 応用:GitHub Copilotでの活用 Claude CodeとGitHub Copilotは思想が異なります。Claude Codeはコード生成だけでなく、調査・分析・ドキュメント作成など幅広いタスクに対応しますが、GitHub Copilotはコード補完に特化しています。 GitHub Copilotの課題として、 検索機能が相対的に弱い 点があります。しかし、静的情報を活用することで、この弱点をカバーできます。 プロジェクト固有のベストプラクティスをファイルとして用意 .github/copilot-instructions.md で参照を指示 検索に頼らず、準備した情報を元に出力 静的情報を充実させることで、どのAIコーディングツールでも一定の品質を担保できるようになります。 (Claude CodeとGitHub Copilotの詳細な比較は別記事で取り上げる予定です) まとめ 観点 毎回検索 静的情報 トークン消費 多い(予測不能) 少ない(制御可能) 実行時間 長い 短い 結果の一貫性 不安定 安定 更新コスト Agent修正が必要 ファイル更新のみ 再利用性 低い 高い 何度も参照する情報は静的情報として保存する。 このシンプルな原則を守るだけで、Claude Codeの効率は大きく向上します。 Skills/Agentsを多用するようになった段階で、この設計を見直すことをお勧めします。毎回検索している箇所がないか、ぜひチェックしてみてください。 ここまで読んでいただき、ありがとうございました! 参考リンク Claude Code Best Practices – Anthropic Engineering Blog Equipping agents for the real world with Agent Skills Skills公式ドキュメント Manage Claude’s memory – @構文でのファイルインポート Effective Context Engineering for AI Agents ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Codeが遅い?毎回検索をやめて実行速度を劇的改善 first appeared on SIOS Tech Lab .
アバター
はじめに ども!龍ちゃんです。前回「 Claude Code→GitHub Copilot移行で使える設定ファイル6つの対応表 」で両ツールの設定ファイルを整理しました。 その記事では、特定のファイルにだけルールを適用する「条件付き適用」について、こう整理しました。 ツール 設定ファイル Claude Code ディレクトリ別 CLAUDE.md GitHub Copilot *.instructions.md GitHub Copilot は *.instructions.md で glob パターンを指定できます。では Claude Code は? 実は .claude/rules/ で、同じことができるようになりました。 .claude/rules/ を使えば、肥大化した CLAUDE.md を複数ファイルに分割できます。さらに paths: frontmatter で適用範囲も制御可能です。 今回は、ディレクトリ別 CLAUDE.md との比較を通じて .claude/rules/ の使い方を学んでいきます。 この記事の結論 先に結論をお伝えします。 状況 推奨 チーム開発・大規模プロジェクト .claude/rules/ で中央管理 特殊なディレクトリ(docs/, experiments/) ディレクトリ別 CLAUDE.md 個人開発・小規模 どちらでもOK 基本方針 : .claude/rules/ でルールを一元管理しつつ、特殊なディレクトリだけ CLAUDE.md を使う「ハイブリッドアプローチ」がおすすめです。 以下、この結論に至った理由を詳しく解説していきます。 関連記事 記事 内容 Claude Code→GitHub Copilot 対応表 設定ファイルの対応関係 この記事 中央集権 vs 分散管理の使い分け 中央集権 vs 分散管理とは まず、この記事で使う用語を整理します。 注意 : 「中央集権」「分散管理」は公式の用語ではなく、僕が整理のためにつけた呼び方です。 中央集権 : ルールを一箇所に集約して管理( .claude/rules/ ) 分散管理 : ルールをプロジェクト全体に分散して配置(ディレクトリ別 CLAUDE.md ) それぞれ詳しく見ていきましょう。 中央集権:.claude/rules/ ルールを 一箇所に集約 して管理する方法です。 project/ └── .claude/ └── rules/ ├── code-style.md # コードスタイル ├── frontend.md # フロントエンド固有 └── backend.md # バックエンド固有 特徴: すべてのルールが .claude/rules/ に集まる 「ルールどこ?」→「 .claude/rules/ 見て」で済む paths: frontmatter で適用範囲を制御 分散管理:ディレクトリ別CLAUDE.md ルールを プロジェクト全体に散らばらせる 方法です。 project/ ├── CLAUDE.md # ルート ├── frontend/ │ └── CLAUDE.md # フロントエンド固有 ├── backend/ │ └── CLAUDE.md # バックエンド固有 └── docs/ └── CLAUDE.md # ドキュメント固有 特徴: 各ディレクトリに CLAUDE.md が存在 そのディレクトリで作業する時だけ読み込まれる プロジェクト全体を探す必要がある 比較表 観点 中央集権(.claude/rules/) 分散管理(ディレクトリ別CLAUDE.md) ルールの配置 一箇所に集約 プロジェクト全体に分散 全体像の把握 .claude/rules/ だけ見ればOK どこにCLAUDE.mdがあるか探す必要 適用範囲の制御 paths: frontmatter ディレクトリ階層 チーム開発なら中央集権 チーム開発では、 中央集権(.claude/rules/) をおすすめします。 理由1: PRレビューがしやすい ルールが一箇所にあると、変更点が明確です。 # PRの差分 .claude/rules/code-style.md | 3 ++- .claude/rules/security.md | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) 分散管理だと、こうなります: # PRの差分 frontend/CLAUDE.md | 2 ++ backend/CLAUDE.md | 3 +++ api/v1/CLAUDE.md | 1 + api/v2/CLAUDE.md | 1 + services/auth/CLAUDE.md | 2 ++ 5 files changed, 9 insertions(+) 「どのCLAUDE.mdがどこにあるか」を把握していないと、レビューが大変です。 理由2: 新メンバーのオンボーディング 新メンバー: 「このプロジェクトのルールってどこにありますか?」 中央集権: 「.claude/rules/ を見てください」 分散管理: 「えーと、各ディレクトリにCLAUDE.mdがあって...」 理由3: ルールの重複・矛盾を防げる 分散管理では、同じルールを複数のCLAUDE.mdに書いてしまうことがあります。 # frontend/CLAUDE.md コンポーネントは関数コンポーネントで書いてください。 # frontend/components/CLAUDE.md Reactコンポーネントは関数形式を使用してください。 ← 重複! 中央集権なら、 rules/react.md に一本化できます。 paths: frontmatter の使い方 「でも、フロントエンドとバックエンドで違うルールを適用したい」という場合は、 paths: を使います。 注意 : glob パターンは必ず引用符( " )で囲んでください。 * や { で始まるパターンは YAML の予約文字として解釈されるため、引用符がないとパースエラーになります。 # .claude/rules/frontend.md --- paths: - "src/frontend/**/*" - "src/components/**/*" --- # フロントエンドルール - React は関数コンポーネントを使用 - スタイルは Tailwind CSS - 状態管理は Zustand # .claude/rules/backend.md --- paths: - "src/api/**/*" - "src/services/**/*" --- # バックエンドルール - FastAPI を使用 - 型ヒントは必須 - Pydantic でバリデーション これで、該当ディレクトリで作業する時だけルールが適用されます。 特殊なディレクトリではCLAUDE.mdが生きる 「じゃあ、ディレクトリ別CLAUDE.mdは不要?」 いえ、 特殊なディレクトリ では CLAUDE.md が有効です。 特殊なディレクトリとは 「他のコードとは性質が違う」ディレクトリです。 ディレクトリ なぜ特殊か docs/ コードではなくドキュメント。執筆ルールが必要 experiments/ 実験的コード。品質基準が通常と異なる legacy/ レガシーコード。触り方に注意が必要 例1: docs/CLAUDE.md docs/ ディレクトリは、他のMarkdownファイルとは性質が違います。 コード内のコメントやREADME → 開発者向け、簡潔に docs/ 内のMarkdown → 読者向け、丁寧に説明 # docs/CLAUDE.md このディレクトリはブログ記事・ドキュメントの執筆用です。 ## 他のMarkdownとの違い - README.md → 開発者向け、簡潔に - docs/ 内 → 読者向け、丁寧に説明 ## 執筆ルール - 文体:ですます調 - 見出し:H2から開始 - コードブロック:必ず言語を指定 - 画像:alt テキストを必ず含める ## ディレクトリ構成 - `docs/article/` - ブログ記事の下書き - `docs/research/` - 調査結果 - `docs/specs/` - 仕様書(変更不可) これは paths: で指定するより、 docs/CLAUDE.md として置いた方が直感的です。 例2: experiments/CLAUDE.md 実験的コードは、品質基準が通常と異なります。 # experiments/CLAUDE.md このディレクトリは実験的なコード用です。 ## 通常のコードとの違い - テストは不要 - ドキュメントは最低限でOK - 動けばいい(リファクタリング不要) ## 注意 - 本番コードにコピペしないこと - 実験が成功したら、ちゃんと書き直して別ディレクトリへ なぜ paths: より CLAUDE.md が良いのか 文脈が自己完結する : そのディレクトリを開けば、ルールが分かる READMEと同じ感覚 : 人間にとっても分かりやすい 特殊性が明示される : 「ここは他と違う」が伝わる GitHub Copilot との比較 ここで、GitHub Copilot との設計思想を比較してみましょう。 対応関係 概念 Claude Code GitHub Copilot 中央集権 .claude/rules/ + paths: *.instructions.md + applyTo: 分散管理 ディレクトリ別 CLAUDE.md (なし?) 構文の比較 Claude Code: # .claude/rules/api.md --- paths: - "src/api/**/*.ts" --- # APIルール GitHub Copilot: # api.instructions.md --- applyTo: "src/api/**/*.ts" --- # APIルール ほぼ同じ思想ですね。キーが paths: か applyTo: かの違いだけ。 両ツールの収束傾向 前回記事でも触れましたが、個人的には Claude Code と GitHub Copilot の設定方法は 集約されつつあるのでは? と感じています。 条件付き適用(glob パターン) 複数ファイルへの分割 Markdownベースの設定 片方を学べば、もう片方にも応用できます。 推奨構成:ハイブリッドアプローチ まとめると、こうなります: project/ ├── CLAUDE.md # プロジェクト全体の基本方針(薄く) ├── .claude/ │ └── rules/ │ ├── code-style.md # コードスタイル(グローバル) │ ├── frontend.md # フロントエンド(paths指定) │ ├── backend.md # バックエンド(paths指定) │ └── security.md # セキュリティ(グローバル) ├── docs/ │ └── CLAUDE.md # ドキュメント固有(特殊) └── experiments/ └── CLAUDE.md # 実験用(特殊) 判断フロー まとめ 状況 推奨 チーム開発 中央集権(.claude/rules/) 大規模プロジェクト 中央集権(.claude/rules/) 特殊なディレクトリ 分散管理(CLAUDE.md) 個人開発・小規模 どちらでもOK ポイント: 基本は中央集権 : .claude/rules/ でルールを一元管理 特殊なディレクトリだけ分散 : docs/ 、 experiments/ など 両者は補完関係 : 排他的に選ぶ必要はない Claude Code と GitHub Copilot、どちらも「中央管理 + 条件付き適用」の方向に進化しています。今のうちにこの設計パターンを身につけておくと、ツールが変わっても応用が効きますよ。 参考リンク 公式ドキュメント Claude Code Memory – CLAUDE.md と .claude/rules/ の公式説明 GitHub Copilot Custom Instructions 関連記事 Claude Code→GitHub Copilot移行で使える設定ファイル6つの対応表 ここまで読んでいただき、ありがとうございました! 設定ファイルの置き場所、地味だけど長期的には効いてくる設計判断です。チーム開発では特に、「どこを見ればルールが分かるか」を明確にしておくと、みんなが幸せになれます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code: CLAUDE.md vs .claude/rules/ の実践的な使い分け first appeared on SIOS Tech Lab .
アバター
はじめに ども!龍ちゃんです。Claude Codeを使っていて、ドキュメントが増えてきていませんか? 以前、 /research コマンドで調査品質を安定させる記事 を書きました。調査結果が docs/research/ に蓄積されていくのは便利なんですが、気づいたら ドキュメントが爆増 していました。 こんな悩みが出てきたんですよね: どこに何があるか分からない : 「あの調査結果、どこだっけ?」 同じ調査を繰り返す : 既存のドキュメントに気づかず重複作業 全部読み込むとトークンが… : コンテキストが膨らんでコスト増 今回は、この問題を READMEインデックス + AI自動メンテナンス で解決する方法を紹介します。 この記事で紹介すること READMEをドキュメントの「目次」として設計する方法 Claude Codeに確実に読み込ませる @import 構文 Skills/Commandsでインデックス更新を自動化する方法 関連記事 記事 内容 Markdown保存でトークン削減 Fetch時のトークン削減テクニック /research コマンドの紹介 調査品質を安定させるコマンド この記事 増えたドキュメントの管理方法 解決策:READMEインデックス戦略 方針はシンプルです: READMEにインデックス(目次)を作る Claude Codeに確実に読み込ませる メンテナンスをAIに丸投げする これにより、Claudeは全ファイルをスキャンせずに、必要なドキュメントだけを選択的に読み込めます。 前提知識:Claude Codeが自動で読むファイル まず、Claude Codeが 自動的に読み込むファイル を確認しておきましょう。 ファイル 自動読み込み CLAUDE.md / CLAUDE.local.md される .claude/rules/*.md される README.md されない README.mdは自動読み込みの対象ではありません。 ただし、以下の方法で読み込ませることができます: @import 構文でCLAUDE.mdから参照 Skills/Commandsで明示的に「READMEを読め」と指示 体感として : Claudeはタスク遂行中にREADMEを探索して読むことが多いです。ただ、それは自発的な行動なので 確実ではない 。確実に読ませたい場合は @import を使いましょう。 実装方法 1. READMEインデックスの設計 docs/research/README.md の例です: # Research Documents 調査結果をまとめたドキュメント集です。 ## 調査一覧 ### Claude Code | ファイル | 調査内容 | 調査日 | |----------|----------|--------| | [claude-code-hooks-skills](./2026-01-06-claude-code-hooks-skills.md) | Hooks/Skills/Commands の使い分け | 2026-01-06 | | [claude-code-skills-best-practices](./2026-01-23-claude-code-skills-best-practices.md) | Skillsのベストプラクティス | 2026-01-23 | ### Azure | ファイル | 調査内容 | 調査日 | |----------|----------|--------| | [azure-container-apps-deploy](./2026-01-07-azure-container-apps-deploy.md) | Container Apps デプロイ方法 | 2026-01-07 | ポイント: カテゴリ別にテーブルで整理 ファイル名、概要、日付を含める Claudeがこれを読めば全体構造を把握できる 2. CLAUDE.mdでの@import設定 CLAUDE.mdに以下を追加すると、起動時に自動で読み込まれます: # CLAUDE.md ## ドキュメント参照 See @docs/research/README for research documents index. この @path/to/file 構文により、CLAUDE.md読み込み時にREADMEも一緒に読み込まれます。 3. なぜCLAUDE.mdではなくREADMEにインデックスを置くのか 「インデックスをCLAUDE.mdに直接書けばいいのでは?」と思うかもしれません。 READMEに置く理由: 観点 README CLAUDE.md 人間も参照する する あまりしない GitHubで表示される される されない 役割 ドキュメントの目次 Claudeへの指示 関心の分離 ができて、メンテナンスもしやすくなります。 応用:Skills/Commandsで自動メンテナンス インデックスを作っても、 更新を忘れたら意味がない ですよね。 そこで、Skills/Commandsのワークフローに組み込んで自動化します。 /research コマンドでの実装例 僕の /research コマンドでは、以下のステップを組み込んでいます: ### Step 0: Check Existing Research Before starting new research, **always read `docs/research/README.md`** to: 1. Check if the topic has already been researched 2. Identify related research that can be referenced 3. Avoid duplicate work ### Step 5: Update README.md After saving the research document, **always update `docs/research/README.md`** 効果: 課題 解決策 インデックス更新を忘れる Commandのワークフローに組み込み 重複調査してしまう Step 0で既存ドキュメントを確認 フォーマットがバラバラ Claudeが一貫した形式で更新 これで、 人間がREADME更新を意識する必要がなくなります 。 補足:.claude/rules/ でも対応可能 2025年12月にリリースされた .claude/rules/ を使う方法もあります( 公式ドキュメント )。 # .claude/rules/readme-update.md --- paths: - "docs/**/*.md" --- ドキュメントを追加・編集した場合は、一番近い階層のREADME.mdを更新してください。 paths を指定すると、該当ファイル作業時のみルールが適用されます。 ディレクトリ別CLAUDE.mdとの比較: 方法 特徴 ディレクトリ別CLAUDE.md 各ディレクトリに配置、そのディレクトリ作業時に読み込み .claude/rules/ + paths 中央で管理、glob パターンで適用範囲を制御 READMEインデックス戦略と組み合わせることも可能です。 まとめ:結果的にAIフレンドリーな設計になる READMEインデックス戦略のポイント: READMEにドキュメントの目次を作る @import で確実に読み込ませる Skills/Commandsでメンテナンスを自動化 これって、結果的に AIフレンドリーな設計 になっているんですよね: AIが必要な情報を効率的に見つけられる AIがメンテナンスを担当できる 人間にとっても分かりやすい構造 ドキュメントが増えてきたら、ぜひ試してみてください。 参考リンク 公式ドキュメント Claude Code Memory 関連記事 Markdown保存でトークン削減 /research コマンドの紹介 ここまで読んでいただき、ありがとうございました! ドキュメント管理は地味だけど、放置すると後で困る作業。AIに丸投げして楽しましょう。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code設計術:AIフレンドリーなドキュメント管理 first appeared on SIOS Tech Lab .
アバター
Webフォームの実装において、エンジニアが神経を使う処理の一つが「バリデーション(入力値検証)」ではないでしょうか。正規表現を駆使し、XSS(クロスサイトスクリプティング)を防ぎ、データベースの整合性を守る――これはシステムを守るための堅牢な盾です。 しかし、視点を「ユーザー体験(UX)」に移したとき、バリデーションエラーは盾ではなく、ユーザーをゴールへ導く「案内」でなければなりません。 今回は、システム的な正しさとユーザーの使いやすさを両立させるための、バリデーションエラーの「伝える技術」について、特に 「ユーザーを責めないメッセージング」 に焦点を当てて解説します。 エラーメッセージの役割とは? 開発者にとってのエラーは「無効なデータ」の検出ですが、ユーザーにとってのエラーは「対話の拒絶」に映ります。 一生懸命に入力したフォームで、送信ボタンを押した瞬間に真っ赤な文字で「入力内容に誤りがあります」と表示される体験は、試験の解答用紙を埋め、提出した瞬間に、「名前が枠からはみ出ているので受け取りません」と無慈悲に告げられるようなものです。 優れたUIにおけるエラーメッセージの役割は、 「誤りの指摘」ではなく「解決策の提示」 です。 1. 伝える「タイミング」 メッセージの内容に入る前に、それを「いつ」伝えるかというUIの挙動について整理します。適切なタイミングは、ユーザーのストレスを大幅に軽減します。 入力完了時が基本 最もバランスが良いのは、ユーザーがそのフィールドの入力を終えて次の項目へ移動した(フォーカスが外れた)タイミングです。 入力中にリアルタイムで「メールアドレスの形式が不正です」と出し続けるのは避けましょう。まだ入力途中なのに「間違っている」と判定されるのは、ユーザーにとって過干渉であり、ストレスになります。 即時反映をが有効な例外 パスワードの強度チェックや、ユーザー名の重複確認など、「入力し終わってからダメだと言われるとダメージが大きい項目」については、入力中のリアルタイム判定が有効です。また、「全角カナのみ」のように制約が厳しい場合も、入力中にフィードバックを返すのが有効な場合があります。 送信時は最終手段 検証を送信ボタン押下時に行うのは、サーバーサイドでの整合性チェックなど、クライアント側で判定できないものに限定しましょう。例えば、長いフォームを入力し終えた後に最初の方のミスを指摘されるのは、離脱率を高める要因になります。 2. ユーザーを責めない「ライティング」 ここからが本題です。エラーメッセージの文言一つで、システムの人格が決まります。大切なのは 「ユーザーは悪くない、システムの説明不足である」 というスタンスを取ることです。 原則1:曖昧さを排除し、解決策を提示する つい書いてしまいがちなのが、事実だけを告げるメッセージです。 × 悪い例: 無効な入力です × 悪い例: エラーが発生しました (Code: 400) これらは「何が」間違っていて、「どうすれば」直るのかが分かりません。ユーザーを迷子にさせないためには、具体的なアクションを提示します。 〇 良い例: @を含めたメールアドレスの形式で入力してください 〇 良い例: パスワードは8文字以上必要です 「不正な文字が含まれています」ではなく、「半角英数字で入力してください」と 「やるべきこと」 を書きましょう。 原則2:否定形を避け、肯定的な表現を使う 「禁止」「不正」「不可」といった強い否定語は、ユーザーに「怒られている」ような印象を与えます。これらはシステム視点の言葉です。 × 悪い例: 半角数字以外は入力禁止です × 悪い例: そのユーザー名は使用できません これを、ガイドするような肯定的な表現に書き換えます。 〇 良い例: 半角数字で入力してください 〇 良い例: このユーザー名はすでに使われています。別の名前を入力してください 「〜しないでください」ではなく、「〜してください」とポジティブな指示に変換することで、対話の質が変わります。 原則3:システム都合の専門用語を使わない データベースのカラム名や、バリデーションライブラリのデフォルトメッセージがそのまま表示されていませんか? × 悪い例: String型で入力してください × 悪い例: このフィールドは必須です ユーザーの言葉に翻訳しましょう。 〇 良い例: 数字ではなく文字で入力してください 〇 良い例: お名前を入力してください 原則4:ユーザーの努力を無にしない 最も避けるべきは、システムエラーなどで入力内容がすべて消えてしまうことです。バリデーションエラーが発生した際は、入力された値を保持することが大前提です。 また、「全角で入力された数字をシステム側で半角に変換する」など、エラーとしてはじく前に システム側で吸収できる揺らぎはないか を検討するのも、重要な「優しさ」です。 3. 視覚的な「伝える技術」 最後に、メッセージの見た目についてです。 色だけに頼らない 「赤文字=エラー」は定石ですが、色覚多様性を持つユーザーには、赤色が警告として認識しづらい場合があります。 色だけでなく、 アイコン(!や×マーク) を併用する、あるいは太字にするなど、形状の変化でも状態を伝えるようにしましょう。(アクセシビリティの確保) 入力欄との近接性 エラーメッセージをフォームの一番上にまとめて表示するパターンがありますが、項目数が多い場合、どの項目がエラーなのかを探す手間が発生します。 エラーメッセージは、**該当する入力フィールドの直下(または直近)**に表示し、色を変えた枠線などで関連付けを明確にします。 まとめ:エラー表示にこそ、性格が出る 正常系のルートは、誰が設計しても似た画面になります。しかし、異常系・準正常系であるエラー表示には、作り手の配慮やサービスの質が色濃く反映されます。 バリデーションエラーは、ユーザーがゴールにたどり着くための最後のハードルです。 「間違っています」と冷たく突き放すのではなく、「こうすればうまくいきますよ」と寄り添う。そんな「ユーザーを責めないUI」を、ぜひ意識してみてください。 同じ趣旨の記事、 「エラーダイアログの「説明責任」:ユーザーを救う3つの要素」 もご覧ください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post バリデーションエラーの「伝える技術」:ユーザーを責めずに導く first appeared on SIOS Tech Lab .
アバター
はじめに ども!GitHub Copilotを使い倒すために重い腰を上げた龍ちゃんです。半年ぐらいかけてClaude Codeを使えるようになったので、次はGitHub Copilotということで関連ブログを出しています。 前回は GitHub Copilot設定5種を網羅!生産性を最大化する使い分け術 で網羅的に設定ファイルを紹介しましたが、今回は コミットメッセージの自動生成 にフォーカスします。 さて、2年前に「 Gitのコミットメッセージをしっかり書こうという話【備忘録的共有】 」という記事を書きました。テンプレートを設定して「ちゃんと書こう」という内容でしたね。上司に注意された勢いで書いた記事です。 ありがたいことにXで反応をいただきまして、「PRをしっかり書けばコミットメッセージはいらなくない?」という意見もありました。これはチーム依存ですね。重要なのは チーム内でルールが統一されていること だと思っています。 あれから2年、AIがコードを書く時代になりました。 コミットメッセージもAIに任せてみよう というのが今回のテーマです。しかも、2年前に設定したテンプレートに沿った形式でAIが書いてくれます。 今回は、VS Codeでコミットメッセージを自動生成する2つの方法を紹介します。 検証環境 VS Code 1.108.2 GitHub Copilot 1.388.0 GitHub Copilot Chat 0.36.2 検証日: 2026年1月26日 結論: コミットメッセージ生成方法一覧 まずは結論から。VS Codeでコミットメッセージを自動生成する方法は2つあります。 方法 操作 カスタム指示 おすすめ スパークルアイコン ソースコントロールパネルで✨クリック commitMessageGeneration.instructions GUI派向け ターミナルインラインチャット Ctrl+I → 指示入力 .github/copilot-instructions.md ターミナル派向け ポイント : どちらもカスタム指示でチームのルールに沿った形式に統一できます。 それでは、それぞれの方法を詳しく見ていきましょう。 方法1: スパークルアイコン(GUI派向け) 最も簡単な方法です。ソースコントロールパネルのスパークルアイコン(✨)をクリックするだけ。 手順 変更をステージング ソースコントロールパネルを開く( Ctrl+Shift+G ) コミットメッセージ欄の スパークルアイコン(✨) をクリック 生成されたメッセージを確認・編集 コミット 赤枠で囲んだ部分がスパークルアイコンです。クリックすると、ステージされた変更内容を分析してコミットメッセージを生成してくれます。 メリット ワンクリック で生成できる GUIで直感的に操作できる 生成結果をその場で編集できる 方法2: ターミナルインラインチャット(ターミナル派向け) ターミナルで作業している人向けの方法です。 Ctrl+I でインラインチャットを起動して、コミットメッセージの生成を依頼します。 手順 git add で変更をステージング ターミナルで Ctrl+I (Mac: Cmd+I )を押す 「ステージされた変更に対するコミットメッセージを生成して」と入力 生成されたコマンドを確認 Ctrl+Enter で実行、または Alt+Enter で挿入して編集 ターミナルでインラインチャットを起動し、コミットメッセージの生成を依頼した様子です。 docs: ドキュメントを追加 というメッセージが生成され、 git commit -m "..." コマンドとして提案されています。 メリット ターミナルから離れずに 操作できる 生成されたコマンドをそのまま実行できる 自然言語で細かい指示を出せる カスタム指示でコミットメッセージ形式を統一する デフォルトでも十分使えますが、チームでコミットメッセージの形式を統一したい場合はカスタム指示を設定しましょう。 設定方法一覧 設定場所 適用範囲 設定方法 settings.json スパークルアイコン commitMessageGeneration.instructions .github/copilot-instructions.md 全体(インラインチャット含む) ファイルに記述 settings.json での設定 スパークルアイコンでの生成に適用される設定です。 { "github.copilot.chat.commitMessageGeneration.instructions": [ { "text": "Use format: tag: message" }, { "text": "Tags: feature, fix, refactor, docs" }, { "text": "Write message in Japanese" } ] } copilot-instructions.md での設定 .github/copilot-instructions.md に記述する方法です。こちらはプロジェクト全体に適用されます。 ## Git Commit Messages When generating git commit messages: - Format: `tag: message` - Use one of these tags: - feature: 機能追加・更新 - fix: バグ修正 - refactor: リファクタリング - docs: ドキュメント - Write message in Japanese - Keep subject under 50 characters 検証結果: インラインチャットにも適用される 今回の検証で面白い発見がありました。 発見(2026-01-26検証) : .github/copilot-instructions.md の指示は、ターミナルインラインチャット( Ctrl+I )にも適用されます。公式ドキュメントには明記されていませんが、実機検証で確認しました。 つまり、 .github/copilot-instructions.md にコミットメッセージの形式を書いておけば、スパークルアイコンでもインラインチャットでも同じ形式で生成されます。チームで統一したい場合は、こちらの方法がおすすめです。 2年前のテンプレートをCopilotで再現 2年前の記事 では、以下のようなテンプレート形式を紹介しました。 # Tag: message # Tags: # feature: 機能追加・更新 # refactor: リファクタリング # fix: バグ修正 この形式をカスタム指示に設定すれば、Copilotが同じ形式でメッセージを生成してくれます。2年前に手動で書いていたものが、今はAIが書いてくれる。時代の進歩を感じますね。 まとめ 2年前と今 時期 アプローチ 2年前 テンプレートを設定して「ちゃんと書こう」 今 テンプレートに沿ってAIが書いてくれる 使い分け GUI派 → スパークルアイコン(✨)をクリック ターミナル派 → Ctrl+I でインラインチャット どちらもカスタム指示でチームのルールに沿った形式に統一できます。 .github/copilot-instructions.md に書いておけば、両方に適用されるのでおすすめです。 注意点 生成結果は必ず確認してからコミットしましょう。AIは補助ツールです。 2年前に上司から言われた金言は今も有効です: 「何をしたかはGit見たらわかるから、なんでこの変更を加えたかを知りたいんだよねぇ~」 AIが生成したメッセージも、この観点でチェックしてから使いましょう。 参考リンク 公式ドキュメント VS Code AI Smart Actions VS Code Source Control VS Code Custom Instructions VS Code Terminal Inline Chat 関連記事(SIOS Tech Lab) Gitのコミットメッセージをしっかり書こうという話【備忘録的共有】 – コミットメッセージテンプレートの基本 GitHub Copilot設定5種を網羅!生産性を最大化する使い分け術 – 設定ファイルの全体像 Claude Code→GitHub Copilot移行で使える設定ファイル6つの対応表 – ツール間の対応関係 ここまで読んでいただき、ありがとうございました! コミットメッセージの自動生成、ぜひ試してみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2026年版】GitHub Copilotでコミットメッセージを自動生成する2つの方法 first appeared on SIOS Tech Lab .
アバター
はじめに ども!久しぶりにがっつりGitHub Copilotを触っている龍ちゃんです。機能が増えている!ってブログ記事を二件ほど執筆しました。 GitHub Copilot設定5種を網羅!生産性を最大化する使い分け術 Claude Code→GitHub Copilot移行で使える設定ファイル6つの対応表 今回は、GitHub Copilot PRレビューに関してしっかりとしたアップデートが入っていたので、過去記事からの参照を含めてまとめていきます。 過去に書いた PRレビューを自動化しよう!GitHub Copilot × システムプロンプトの基本 では、PRテンプレートに指示を埋め込む方法を紹介しました。当時は copilot-instructions.md がCode Reviewに反映されなかったため、PRテンプレートを使う一時的な方法でした。 2025年6月以降、状況が変わりました。 現在は正式な設定ファイルでCode Reviewへの指示が可能です。 結論: 設定ファイル一覧 Code Reviewに指示を与える方法は3種類あります。 方法 ファイル 特徴 全体共通 .github/copilot-instructions.md すべてのリクエストに適用 ファイル別 .github/instructions/*.instructions.md applyTo で対象を限定 Review専用 上記 + excludeAgent: "coding-agent" Code Reviewのみに適用 ポイント : excludeAgent: "coding-agent" を指定すると、Copilot ChatやCoding Agentには適用されず、Code Reviewだけに適用されます。 Code Reviewが参照するデータソース 公式ドキュメント「 Responsible use of GitHub Copilot code review 」で確認できる参照対象は以下の通りです。 参照する 公式記載 備考 Code changes (diff) あり .github/copilot-instructions.md あり .github/instructions/*.instructions.md あり Repository context(ソースファイル、ディレクトリ構造) あり PR title あり Responsible useページで明記 PR body (description) あり Responsible useページで明記 コミットメッセージ 記載なし 参照されない可能性が高い 公式ドキュメントには以下の記載があります: “The code changes are combined with other relevant, contextual information (for example, the pull request’s title and body on GitHub), and any custom instructions that have been defined, to form a prompt” PR title/bodyはレビューのコンテキストとして参照されます。一方、 コミットメッセージについては言及がなく、参照されない可能性が高い です。 レビュー観点を確実に伝えたい場合は、以下を併用するのがおすすめです: PR description : 変更の背景や意図を記述(Copilotが参照) *.instructions.md : 恒久的なレビュールールを定義 変更の歴史 Code Reviewのカスタム指示機能は段階的に拡張されてきました。 日付 変更内容 2025年6月13日 copilot-instructions.md がCode Reviewに適用開始 2025年9月3日 applyTo によるパス別指示をサポート 2025年11月12日 excludeAgent でエージェント別の適用制御を追加 2025年5月時点の過去記事で紹介したPRテンプレート方式は、正式機能が整備される前の暫定的な方法でした。 設定ファイルの実例 配置場所 Code Review用の指示ファイルは以下のディレクトリに配置します。 リポジトリルート/ └── .github/ └── instructions/ └── review.instructions.md ← ここに作成 .github/instructions/ ディレクトリが存在しない場合は作成してください。ファイル名は *.instructions.md の形式であれば任意です。 実際のファイル内容 ファイル : .github/instructions/review.instructions.md --- applyTo: "**/*.py" excludeAgent: "coding-agent" description: "Python PR Review専用ガイドライン - Code Reviewのみに適用" --- # Python Code Review Guidelines ## 出力形式 - **日本語で出力してください** - 問題の重要度を明記してください - Critical: 必ず修正が必要(セキュリティ、データ損失リスク) - High: 修正を強く推奨(バグ、パフォーマンス問題) - Medium: 修正を推奨(コード品質、保守性) - Low: 改善提案(スタイル、軽微な改善) ## 必須チェック項目 ### Critical - ハードコードされた秘密情報(APIキー、パスワード) - SQLインジェクション、コマンドインジェクションの可能性 ### High - 型ヒントの欠如 - bare except(`except:`)の使用 - ミュータブルなデフォルト引数 ### Medium - docstringの欠如 - 深すぎるネスト(3レベル以上) ## レビュー対象外 - `print()`文のデバッグ用使用(開発中) - `# TODO:` コメント フロントマターの解説 : applyTo: "**/*.py" → Pythonファイルにのみ適用 excludeAgent: "coding-agent" → Code Reviewにのみ適用(Copilot Chatには適用されない) 検証結果 実際にこの設定でCode Reviewを実行した結果を紹介します。 検証用コード 意図的に問題を含むPythonファイルを作成しました。 # 問題1: ハードコードされたAPIキー API_KEY = "sk-1234567890abcdef" # 問題2: bare except def fetch_content(url): try: import urllib.request return urllib.request.urlopen(url).read() except: return None # 問題3: ミュータブルなデフォルト引数 def add_item(item, items=[]): items.append(item) return items # 問題4: docstringなし、型ヒントなし def calculate_total(prices, tax_rate): return sum(prices) * (1 + tax_rate) Copilotのレビューコメント(抜粋) 重要度 検出内容 行 Critical ハードコードされた秘密情報 – APIキーがソースコードに直接記述 L37 High bare exceptの使用 – 具体的な例外型を指定してください L26 High ミュータブルなデフォルト引数 – None をデフォルト値に L41 Medium docstringと型ヒントの欠如 L31 結果 : 指示通り日本語で出力され、重要度も正しく表記されました。 推奨ファイル構成 .github/ ├── copilot-instructions.md # 共通ルール(全リクエストに適用) └── instructions/ ├── python.instructions.md # Python編集時に自動適用 └── review.instructions.md # Code Review専用(excludeAgent使用) copilot-instructions.md には共通ルール(言語、フォーマット等)を、 review.instructions.md にはCode Review固有の観点を記述することで、役割を分離できます。 複数instructionsファイルの挙動 複数の *.instructions.md が同一ファイルにマッチする場合、 すべてが結合 されてCopilotに提供されます。 優先順位 優先度 種類 1(最高) Personal instructions(ユーザー個人設定) 2 Repository instructions(リポジトリ配下) 3(最低) Organization instructions(組織設定) 注意点 : 優先度が高い指示が「上書き」するのではなく、すべてが結合される 競合する指示は避けるべき(結果が非決定的になる) 同じ内容を複数ファイルに書かない(結合されて冗長になる) PR固有の指示を追加したい場合 「このPRだけセキュリティ重視でレビューしたい」といった場合の対応方法です。 推奨される方法: 一時的なinstructionsファイル <!-- .github/instructions/security-focus.instructions.md --> --- applyTo: "**/*" excludeAgent: "coding-agent" --- # このPR限定: セキュリティ重視レビュー 以下の観点を最優先でチェックしてください: - 認証・認可の欠陥 - 入力検証の不備 - 機密情報の露出 レビュー後にこのファイルを削除またはrevertすれば、一時的な観点追加が可能です。 過去の方法(現在は補助的に使用可能) PRテンプレートやPR説明文への指示埋め込みは、公式ドキュメント「 Responsible use of GitHub Copilot code review 」でPR title/bodyが参照されることが確認されています。 ただし、以下の理由から *.instructions.md との併用を推奨します: 恒久的なルール : *.instructions.md に記述(毎回のPRで自動適用) PR固有の観点 : PR descriptionに記述(そのPRだけに適用) PR descriptionはレビュアー(人間)にも読まれるため、Copilot専用の指示は *.instructions.md に分離する方が運用しやすいです。 まとめ 2025年6月以降、Code Reviewは copilot-instructions.md と *.instructions.md を参照するようになった excludeAgent: "coding-agent" でCode Review専用の指示が設定可能 複数のinstructionsファイルはすべて結合される(上書きではない) 過去記事で紹介したPRテンプレート方式から、正式な設定ファイル方式に移行することをおすすめします。 参考リンク 公式ドキュメント Using GitHub Copilot code review Adding custom instructions for GitHub Copilot Master your instructions files – GitHub Blog 関連記事 GitHub Copilot設定5種を網羅!生産性を最大化する使い分け術 Claude Code→GitHub Copilot移行で使える設定ファイル6つの対応表 PRレビューを自動化しよう!GitHub Copilot × システムプロンプトの基本 ここまで読んでいただき、ありがとうございました! ご覧いただきありがとうございます! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post GitHub Copilot PRレビュー指示が効かない?正式設定法 first appeared on SIOS Tech Lab .
アバター
アプリケーションにおいて「エラー」は避けられません。予期せぬ中断はユーザーにストレスを与えますが、優れたエラーダイアログはそのネガティブな体験を「信頼」に変える力を持っています。 その鍵となるのが、エラーに対する 「説明責任(Accountability)」 です。 今回は、単なるシステム的な報告で終わらせず、ユーザーを解決へと導くための「伝わるエラーメッセージ」について解説します。 なぜ、そのメッセージは伝わらないのか エンジニアがエラーハンドリングを実装する際、意識は「原因の特定(デバッグ)」に向きがちです。しかし、その思考がそのままUIに表現されると、以下のような「悪いダイアログ」が生まれます。 エラーが発生しました 予期せぬエラーが発生しました。 終了コード: 0x80040201 [ OK ] これではユーザーは何が起きたのか理解できず、不安だけが募ります。ユーザーが必要としているのは技術的なログではなく、「次にどうすればいいか」という案内です。 これを解決するためのフレームワークが、UXライティングにおける 「3つの説明責任」 です。 エラーメッセージの黄金構造:3つの「W」 効果的なエラーメッセージは、以下の3要素を含んでいる必要があります。 What happened (何が起きたのか?) Why it happened (なぜ起きたのか?) What the user can do (ユーザーは何ができるのか?) これらを組み合わせることで、ダイアログは「意味不明な警告」から「役に立つ案内板」へと進化します。 1. What happened:何が起きたのか まずは事実を伝えます。ポイントは 「ユーザーの言葉」に翻訳すること です。 エンジニアにとっての Timeout は、ユーザーにとっては「読み込みが遅れている」状態です。「何が失敗したのか」を、ユーザーのアクション(保存、ログインなど)に結びつけて表現しましょう。 × 技術的: データベース接続エラーが発生しました 〇 ユーザー視点: データを保存できませんでした 2. Why it happened:なぜ起きたのか 次に理由を説明しますが、技術的な詳細ではなく 「文脈」 を伝えます。 × 技術的: NullPointerExceptionにより処理中断 〇 文脈的: システムに一時的な問題が発生しています 理由がユーザー側にある場合(通信環境、入力ミスなど)は明確に伝え、そうでない場合は素直にシステム側の問題であることを認めます。 3. What the user can do:ユーザーは何ができるのか 最も重要なパートです。 「エラーです」で終わらせず、必ず次の一手を提示します。 再試行: 「もう一度お試しください」 環境変更: 「通信環境の良い場所でお試しください」 代替手段: 「時間を置いてアクセスしてください」 ケーススタディ:劇的ビフォーアフター 「3つのW」を使って、無機質なダイアログを改善してみましょう。 ケース1:ファイルアップロード失敗 【Bad UI】 アップロード失敗 エラーが発生しました。(Code: E-503) [ 閉じる ] これではユーザーは「再試行すべきか? ファイルが壊れているのか?」と疑心暗鬼になります。 【Good UI】 ファイルをアップロードできませんでした ファイルサイズが上限(10MB)を超えているため、処理を完了できません。 サイズを小さくして、もう一度アップロードしてください。 [ OK ] What: アップロード不可を明言。 Why: サイズ超過が原因と明示。 Action: 「サイズを小さくして再試行」という解決策を提示。 ケース2:インターネット未接続 【Bad UI】 ネットワークエラー 通信エラーが発生しました。 [ 再試行 ] 「通信エラー」だけでは、サーバーダウンか圏外か区別がつきません。 【Good UI】 インターネットに接続されていません Wi-Fiの設定やモバイル通信状況を確認してから、再度お試しください。 [ 再試行 ] Action: 具体的にWi-Fiなどの確認を促しています。 避けるべき「アンチパターン」 良かれと思ってやってしまう、逆効果なパターンもあります。 1. 謝りすぎる 「申し訳ありません」の多用はノイズになります。入力ミス程度の軽微なエラーで毎回謝られると、ユーザーは煩わしさを感じます。 謝罪は「データの消失」や「長時間のサービス停止」など、深刻な事態に限定しましょう。普段は事実と対策を淡々と伝える方が親切です。 2. 「OK」ボタンの罠 エラー時にボタンが「OK」だと違和感があります。状況は「OK(大丈夫)」ではないからです。 ボタンのラベルは、その動作を表しましょう。 メッセージを閉じるだけなら → [ 閉じる ] もう一度試すなら → [ 再試行する ] 3. 過度なユーモア 404ページの「迷子になっちゃいましたね!」のようなユーモアは、エラーを和ませる演出として有効な場合もありますが、決済失敗の場面などでは不適切です。緊急性の高い場面では 「明確さ > ユーモア」 を徹底し、信頼を損なわないようにしましょう。 実装のヒント エラーコードは脇役 エラーコード( ERR-001 等)は、問い合わせに役立つ場合もあります。表示する際は、主役のメッセージの後に添えるようにしましょう。 汎用メッセージからの脱却 そもそも、APIがエラー分類が適切にできていないと、フロントエンドは気の利いた表示ができません。エラー種別を識別できるAPI設計を行い、それに応じたメッセージが表示できるように構成しましょう。 まとめ エラーが起きた瞬間、ユーザーの信頼は一時的にマイナスになります。しかし、そこで「何が起きて、どうすればリカバリーできるか」を誠実かつ的確に案内できれば、信頼を取り戻すことができます。 「ユーザーを迷子にさせない」 これを念頭において書かれたエラーメッセージが、システムに血を通わせ、ユーザーとの対話を維持します。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post エラーダイアログの「説明責任」:ユーザーを救う3つの要素 first appeared on SIOS Tech Lab .
アバター
はじめに ども!龍ちゃんです。前回の記事では、 GitHub Copilotの設定ファイル5種類 を整理しました。 普段Claude Codeを使っている方がGitHub Copilotに触れると、「この設定ファイルはClaude Codeでいう何に相当するの?」と戸惑うことがあります。逆もまたしかりです。 本記事では、 Claude Code使いの視点 からGitHub Copilotの設定ファイル体系を対応表で整理します。両ツールの「翻訳表」として活用してください。 検証環境 検証日: 2026年1月22日 Claude Code / GitHub Copilot 2026年1月時点の機能 設定ファイル対応表 まずは対応関係を俯瞰してみましょう。 Claude Code 発火条件 GitHub Copilot 発火条件 役割 CLAUDE.md 自動(常時) copilot-instructions.md 自動(常時) プロジェクト全体指示 CLAUDE.md 自動(常時) AGENTS.md 自動(coding agent時) クロスツール互換 .claude/commands/*.md / で呼び出し *.prompt.md / で呼び出し 手動プロンプト .claude/skills/*.md / または自然言語※ *.agent.md ドロップダウン選択 観点切り替え .claude/skills/*.md / または自然言語※ Agent Skills ( SKILL.md ) プロンプト一致時(自動) タスク特化指示 ディレクトリ別 CLAUDE.md ディレクトリ進入時 *.instructions.md ファイル編集時(glob match) 条件付き自動適用 ※ Claude Code Skillsは /skill-name での明示的呼び出しに加え、descriptionとの関連性でClaudeが自動判断して発火することもあります。 発火条件の違い 両ツールの大きな違いは 発火条件の粒度 です。 Claude Code : ディレクトリ単位。親ディレクトリの CLAUDE.md から子へ階層的に継承 GitHub Copilot : ファイル単位。 applyTo のglob patternで細かく指定(例: **/*.py ) Claude Codeはシンプルに「このディレクトリに入ったら適用」、GitHub Copilotは「このパターンにマッチするファイルを編集したら適用」という設計です。 注意: AGENTS.md と .github/agents/ は別物 紛らわしいですが、この2つは全く異なるものです。 名称 役割 対応ツール AGENTS.md クロスツール標準(2025年7月提唱) Cursor, Codex, Builder.io, GitHub Copilot coding agent .github/agents/*.md GitHub Copilot固有のCustom Agents GitHub Copilotのみ AGENTS.md は「one file, any agent」を掲げるベンダー中立の指示ファイルです。2025年春から夏にかけて、Sourcegraph、OpenAI、Googleを中心とした業界横断的な取り組みとして策定されました。現在はAgentic AI Foundation(Linux Foundation傘下)が管理しています。シンプルなMarkdown形式で、複数のAIコーディングツール間で共有できる点が特徴です。 一方、 .github/agents/ はGitHub Copilot固有の機能で、ドロップダウンから選択して観点を切り替えるCustom Agentsです。 相互運用の可能性 標準では各ツール固有のファイル形式ですが、Skills/Agent Skillsを活用すれば相互に読み込み可能です。 Claude Code : SkillでAGENTS.mdを読み込む GitHub Copilot : Agent SkillでCLAUDE.mdを読み込む 2025年12月にGitHub Copilot Agent Skillsがパブリックプレビューとなり、ディレクトリ構造も類似してきました( .github/skills/ .claude/skills/ )。 これによってGitHub CopilotでもClaude Codeの指示を活用しやすくなっています。 設計思想の違い Claude Code Skillsの便利さ Claude CodeのSkillは非常に便利です。自然言語での発火には揺らぎがあるものの、 複数処理やコンテキスト切り替えを詰め込んだ「パック」 のような存在です。 実際に使ってみると、SkillsとAGENTS.mdは設計次第でほぼ同等のことができます。肝心なのは「いかに設計するか」です。 一方、GitHub CopilotでClaude Code Skillsと同等のことを再現しようとすると、少し難しさを感じます。 処理の断続感 両ツールを使い比べると、 処理の断続感 に違いがあります。 GitHub Copilot : 確認を挟むため断続的。「副操縦士」として開発者の承認を重視 Claude Code : 連続的に処理を進める。「自律的パートナー」として一気に作業 この違いは設計思想に由来するものです。GitHub Copilotは「開発者が常に主導権を持つ」、Claude Codeは「開発者と対等に協働する」という哲学の違いが、操作感に現れています。 世論: ツールの収束傾向 興味深いのは、各ツールが似た構造に収束しつつあることです。 “All of these products are converging.” — Cursor vs Claude Code 比較記事 開発者の本音としては、こんな声もあります。 “I need an agent and a good instructions file. That is it.” — Medium記事 機能の多さより、 良い指示ファイルが1つあればいい という割り切りです。 共通点 両ツールに共通するのは以下の点です。 マークダウン形式で指示を記述 プロジェクト単位での設定管理 Skills/Agent Skillsで相互運用の可能性 まとめ Claude CodeとGitHub Copilotの設定ファイルは、役割で対応付けることができます。 キーワード Claude Code GitHub Copilot 全体ルール CLAUDE.md copilot-instructions.md 手動呼び出し .claude/commands/ .github/prompts/ 観点切り替え .claude/skills/ .github/agents/ 条件付き適用 ディレクトリ別 CLAUDE.md *.instructions.md 所感: ツール間の収束傾向 2025年12月、GitHub Copilot Agent Skillsがパブリックプレビューとして登場しました。ディレクトリ構造もClaude Codeと類似しており( .github/skills/ .claude/skills/ )、 Claude Codeでできることは GitHub Copilotでもできるようになりつつあります 。 将来的には、ツール間の移行・共存がより容易になる可能性を感じています。 参考リンク 公式ドキュメント Claude Code Documentation GitHub Copilot Custom Instructions GitHub Copilot Agent Skills AGENTS.md 公式サイト 引用記事 Cursor vs Claude Code 比較 Ranking AI Coding Agents Codex vs Claude Code 関連記事 GitHub Copilot設定5種を網羅!生産性を最大化する使い分け術 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code→GitHub Copilot移行で使える設定ファイル6つの対応表 first appeared on SIOS Tech Lab .
アバター
はじめに ども!昨年はClaude Codeにどっぷりつかっていた龍ちゃんです。社内では、Gemini・Notebook LM・GitHub Copilotなど、様々なAIツールが使えるのですが、ブログとしては全然触れていなかったので触れていこうと思います。 昨年にGitHub Copilotの設定に関しては2件のブログを執筆しました。 GitHub Copilotをチーム開発で使いこなす!システムプロンプト設定方法 PRレビューを自動化しよう!GitHub Copilot × システムプロンプトの基本 それから、GitHub Copilotの設定も充実してきたので、改めて設定ファイルの種類と使い分けについてまとめてみようと思います。 過去記事では .github/copilot-instructions.md のみを紹介していました。あれから設定ファイルの種類が増えて、現在は 5種類 の設定ファイルが存在します。 「どのファイルを使えばいいの?」という疑問に答えるべく、本記事では各ファイルの役割と使い分けの判断基準を整理します。 検証環境 検証日: 2026年1月22日 環境: Dev Container (Debian GNU/Linux 13) VS Code: Dev Container環境 GitHub Copilot: 2026年1月時点の機能 設定ファイル一覧 まずは5種類の設定ファイルを俯瞰してみましょう。 ファイル 配置場所 適用 用途 copilot-instructions.md .github/ 自動 プロジェクト全体の指示 *.instructions.md .github/instructions/ 自動(条件付き) ファイルタイプ別指示 *.prompt.md .github/prompts/ 手動 質問・相談用テンプレート *.agent.md .github/agents/ 手動 カスタムエージェント AGENTS.md リポジトリ任意 自動(coding agent実行時) クロスツール互換指示 ポイントは「 自動適用か手動呼び出しか 」という軸です。上2つは常に自動適用され、Custom Agentsは手動で選択して使います。AGENTS.mdはcoding agent実行時に自動で読み込まれます。 それでは、各ファイルを詳しく見ていきましょう。 copilot-instructions.md(プロジェクト全体指示) 配置場所 : .github/copilot-instructions.md プロジェクトの「憲法」的な存在です。すべてのCopilotリクエストに 自動で適用 されます。 記述内容の例 プロジェクト概要・技術スタック コーディング規約 ディレクトリ構造 チームのルール 記述例 # プロジェクト概要 Python 3.12 + Click で構築されたCLIツール群です。 # 技術スタック - パッケージ管理: uv - リンター: Ruff - 型チェック: Pyright # コーディング規約 - ダブルクォートを使用 - 日本語UIメッセージには絵文字プレフィックス ベストプラクティス 簡潔に保つことが大切です。 1000行以下 を目安にしましょう。長すぎると読み込みに時間がかかり、Copilotの応答が遅くなることがあります。 詳細は 公式ドキュメント を参照してください。 *.instructions.md(言語・ファイル別の自動指示) 配置場所 : .github/instructions/*.instructions.md ソースコードを書く時に、 言語やディレクトリ別のルールを自動で適用 するファイルです。開発者は意識せずファイルを編集するだけで、該当するルールが適用されます。 フロントマター形式 --- applyTo: "**/*.py" --- # Python コーディング規約 - 型ヒントを必ず使用 - docstringはGoogle形式で記述 - f-stringを優先 applyTo にグロブパターンを指定することで、マッチするファイルを編集する時だけ自動適用されます。 使用例 ファイル名 applyTo 用途 python.instructions.md **/*.py Python固有のルール typescript.instructions.md **/*.ts TypeScript固有のルール tests.instructions.md **/tests/** テストコードの書き方 frontend.instructions.md src/frontend/** フロントエンド固有 copilot-instructions.md との違い 観点 copilot-instructions.md *.instructions.md 適用範囲 全ファイル 特定ファイルのみ 条件指定 なし applyTo で指定 用途 全体ルール 言語・ディレクトリ別ルール copilot-instructions.md が肥大化してきたら、 *.instructions.md に分割することを検討しましょう。 *.prompt.md(質問・相談用のカスタムプロンプト) 配置場所 : .github/prompts/*.prompt.md 呼び出し方 : /prompt-name (手動) ファイル編集ではなく、 Askモードでの質問に方向性を持たせたい 時に使います。特定の観点でコードを説明してほしい、レビューしてほしいといった場面で活躍します。 フロントマター形式 --- description: アーキテクチャの観点で説明 agent: ask --- # アーキテクチャ説明 以下の観点でコードを説明してください: - 設計パターン - データフロー - 依存関係 - 拡張ポイント 使用例 コマンド 用途 /explain-architecture 設計思想の観点で説明を求める /security-check セキュリティ観点でコードをチェック /performance-advice パフォーマンス改善のアドバイス 変数の使い方 ユーザー入力を受け付けたい場合は ${input:name:placeholder} を使います。 --- description: 指定したコンポーネントを説明 agent: ask --- ${input:component:説明したいコンポーネント名} について、 以下の観点で説明してください: ... Custom Agents(フェーズ別の独立した作業空間) 配置場所 : .github/agents/*.agent.md (または *.md も可) 呼び出し方 : エージェントドロップダウンから選択(手動) IDE(VS Code、JetBrains等) : Chat windowのエージェントドロップダウンから選択 GitHub.com : エージェントパネルのドロップダウンメニューから選択 設計・実装・レビューなど、 フェーズごとに異なるペルソナで作業 したい時に使います。Prompt Filesとの違いは、セッションを通じて有効な点と、独立したコンテキストで作業できる点です。 Prompt Files との違い 観点 Prompt Files Custom Agents 呼び出し /prompt-name ドロップダウンから選択 継続性 単発 セッション通じて有効 コンテキスト 共有 独立 用途 質問・相談 フェーズ別作業 フロントマター形式 --- name: design-reviewer description: 設計レビュー専門。アーキテクチャの整合性をチェック tools: - shell --- # Design Reviewer あなたは設計レビューの専門家です。 ## 役割 - アーキテクチャの整合性をチェック - 設計パターンの適切さを評価 - 将来の拡張性を考慮したフィードバック ## レビュー観点 1. 責務の分離は適切か 2. 依存関係の方向は正しいか 3. テスタビリティは確保されているか 使用例 エージェント名 用途 design-reviewer 設計段階でアーキテクチャレビュー implementation 実装フェーズで具体的なコード生成 test-writer テストコード作成に特化 AGENTS.md(クロスツール互換) 配置場所 : リポジトリルートまたは任意のディレクトリ GitHub Copilotだけでなく、 Claude CodeやGeminiなど複数のAIツール間で共有する指示 を書くファイルです。 Copilot coding agent実行時に自動で読み込まれます 。リポジトリルートまたはサブディレクトリに配置でき、最も近いファイルが優先されます。 Custom Agentsと異なるってことを明確化しないといけません。僕は誤解をしていたので気を付けて! 対応ファイル GitHub Copilot coding agentは以下のファイル名を認識します: AGENTS.md – 標準フォーマット(複数のAIツールで共有可能) CLAUDE.md – Claude Code向け GEMINI.md – Gemini CLI向け これらのファイルは同時に存在可能で、各AIツールが対応するファイルを読み込みます。 記述内容の例 ## Tech Stack - Python 3.12 - uv for package management - Ruff for linting ## Commands - `uv sync` - Install dependencies - `uv run pytest` - Run tests - `uv run ruff check .` - Lint code ## Boundaries Always: tests/, src/ への書き込み Ask first: スキーマ変更、依存関係の更新 Never: シークレットのコミット、本番環境への直接デプロイ Claude Codeの CLAUDE.md と内容を同期しておくと、ツール間で一貫した指示を維持できます。 目的別の使い分け 「どのファイルを使えばいいか」を目的別に整理しました。 目的 使うファイル イメージ コードを書く時の指示 copilot-instructions.md / *.instructions.md 意識せずファイル操作時に自動適用 質問に方向性を持たせたい *.prompt.md Askモードにカスタムプロンプトを追加 独立したフェーズで作業 agents/*.agent.md 設計レビュー / 実装 / テストなど切り替え 他AIツールとも共有 AGENTS.md Copilot coding agent実行時に適用 フローチャート 注 : 2026年1月時点での個人的な使い分けです。参考程度にご覧ください。 ディレクトリ構成例 実際のプロジェクトでの構成例です。 .github/ ├── copilot-instructions.md # 全体ルール(常時適用) ├── instructions/ │ ├── python.instructions.md # Python編集時に自動適用 │ └── typescript.instructions.md # TypeScript編集時に自動適用 ├── prompts/ │ ├── explain-architecture.prompt.md # /explain-architecture で質問 │ └── security-check.prompt.md # /security-check で質問 └── agents/ ├── design-reviewer.agent.md # ドロップダウンから選択して設計レビュー └── implementation.agent.md # ドロップダウンから選択して実装モード 最初からすべて用意する必要はありません。まずは copilot-instructions.md から始めて、必要に応じて拡張していくのがおすすめです。 また新しく検証しながら進めているので、ある程度情報がたまってきたら順次ブログで報告させていただきます。 補足: Agent Skills(プレビュー機能) 2025年12月にリリースされた新機能として、 Agent Skills があります。 配置場所 : .github/skills/スキル名/SKILL.md Custom Instructionsが「全般的なルール」を定義するのに対し、Agent Skillsは「特定タスク向けの詳細な指示」をフォルダ単位で管理します。スクリプトやサンプルファイルも含められます。 利用可能な環境 (2026年1月時点): Copilot coding agent: 利用可能 Copilot CLI: パブリックプレビュー VS Code Insiders: プレビュー VS Code安定版: 今後対応予定 詳細は 公式ドキュメント を参照してください。 これによって、Claude Codeでリポジトリを作りこんでもスムーズに連携できる可能性が広がりますね。実際Claude Codeで使用しているAgentを実行したのですが、問題なく動作しました。 まとめ GitHub Copilotの設定ファイルは5種類あり、それぞれ異なる役割を持っています。 ファイル キーワード copilot-instructions.md 全体ルール、自動適用 *.instructions.md 言語別、条件付き自動適用 *.prompt.md 質問・相談、/で呼び出し agents/*.agent.md フェーズ別、ドロップダウンから選択 AGENTS.md クロスツール、coding agent実行時に適用 使い分けのポイントは: コードを書く時 → instructions 系(自動適用) 質問・相談したい時 → prompts (手動呼び出し) フェーズを切り替えたい時 → agents (手動呼び出し) まずは copilot-instructions.md から始めて、チームの開発スタイルに合わせて少しずつ拡張していってください。 参考リンク 公式ドキュメント Adding repository custom instructions for GitHub Copilot Your first prompt file – GitHub Docs 関連記事 GitHub Copilotをチーム開発で使いこなす!システムプロンプト設定方法 PRレビューを自動化しよう!GitHub Copilot × システムプロンプトの基本 ここまで読んでいただき、ありがとうございました! 設定ファイルを活用して、GitHub Copilotをチームの開発スタイルに合わせてカスタマイズしてみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post GitHub Copilot設定5種を網羅!生産性を最大化する使い分け術 first appeared on SIOS Tech Lab .
アバター
はじめに ども!龍ちゃんです。技術調査にAIを活用していますか? 「○○について調べて」とClaude Codeに頼むと、WebSearchでサッと検索して「こういう感じです」と返ってくる。便利なんですが、こんな経験ありませんか? クオリティがまばら : 日によって深さが違う。「今日は浅いな…」 出典が不明 : 「この情報、どこから持ってきたの?」 フォーマットがバラバラ : 後から整理しようにも形式が統一されていない 保存先もバラバラ : どこに保存されたか分からない、または保存されない この問題を解決するために、僕が作った /research コマンドを紹介します。 この記事で紹介すること /research コマンドの特徴と使い方 実際の調査フローのデモ 出力例と活用シーン 関連記事 この記事は、Claude Code カスタマイズシリーズの一部です: 記事 内容 Claude Code Skillsの使い方 Skills の基本と汎用テンプレート Claude Code Hooksガイド Hooks による自動化・カスタマイズ Slash Commandsで確実なワークフロー構築 Skills vs Commands の使い分け この記事 /research コマンドの詳細紹介 /research コマンドとは 注意 : /research は カスタムスラッシュコマンド です。Claude Code の標準機能ではなく、 .claude/commands/research.md に配置して使う拡張機能の一例として紹介しています。 動作確認環境 : 2026年1月時点の Claude Code /research は、技術調査を 構造化されたワークフロー で実行するカスタムコマンドです。 /research [調査トピック] 普通の「調べて」との違い 観点 普通の調査依頼 /research コマンド 調査深度 Claude任せ ユーザーが選択 情報源の信頼性 特に意識しない 基準を明示して評価 出力フォーマット その時々で異なる 統一テンプレート 結果の保存 なし docs/research/ に自動保存 出典の明記 曖昧 全情報に出典URL付き 主な特徴 1. 調査スコープの事前確認 コマンドを実行すると、まず 調査のスコープを確認 されます。 調査深度の選択: 深度 説明 用途 クイック概要 主要ポイントの素早い把握 概念理解、導入検討 標準調査 バランスの取れた情報収集 一般的な技術調査 ディープダイブ 網羅的で詳細な調査 本番導入前、ブログ執筆 情報源の信頼性要件: レベル 対象ソース 用途 高(公式のみ) 公式ドキュメント、査読済みソース 正確性が最重要な場面 中(推奨) 信頼性の高いブログ、著名なコミュニティ 一般的な調査 低(幅広く) 一般的なWebソースも含む 多角的な視点が欲しい時 これにより、 調査の粒度をコントロール できます。 2. CRAAP Test による情報源評価 収集した情報は、情報リテラシーの標準的なフレームワークである CRAAP Test で評価されます。 基準 説明 チェックポイント Currency (最新性) 情報の鮮度 いつ公開・更新されたか? Relevance (関連性) 調査課題との適合性 求める情報に合っているか? Authority (権威性) 著者・組織の信頼性 公式か?専門家か?実績は? Accuracy (正確性) 情報の検証可能性 他ソースで確認できるか? Purpose (目的) 潜在的なバイアス 商業目的?教育目的?中立か? 「この情報、信頼できるの?」という疑問に答えられる調査結果が得られます。 3. 4つの調査パターン 調査目的に応じて、4つのパターンを使い分けます。 パターンA: 技術実装調査 目的 : 具体的な実装方法を知りたい /research React Server Components の実装方法 公式ドキュメントのコード例 GitHub リポジトリの実装パターン よくあるエラーと解決策 パターンB: 比較・選定調査 目的 : 複数の選択肢を比較したい /research Zustand vs Jotai 状態管理ライブラリ比較 各選択肢の特徴・制限 パフォーマンス比較 コミュニティの評価・採用状況 パターンC: トラブルシューティング 目的 : 問題を解決したい /research Next.js hydration mismatch エラー エラーメッセージの意味 Stack Overflow, GitHub Issues 公式のトラブルシューティングガイド パターンD: 最新動向調査 目的 : 技術の最新情報を把握したい /research TypeScript 5.x 新機能 リリースノート・CHANGELOG 公式ブログ・アナウンス ロードマップ・RFC 4. 構造化された出力テンプレート 調査結果は、以下の統一フォーマットで docs/research/ に保存されます。 docs/research/2026-01-19-react-server-components.md 出力構造: # 調査: {トピック} ## メタデータ - 調査日、調査者、信頼性レベル、調査深度 ## 調査課題 調査した内容の明確な記述 ## 概要 2-3文のエグゼクティブサマリー ## 調査結果 ### 主要な発見 1-3 根拠となる証拠を含む説明 ## 実践的な知見 ### コード例・設定例 ### ベストプラクティス ### 注意点・落とし穴 ## 情報源 | 情報源 | 種類 | 信頼性 | URL | ## 推奨事項 次のステップまたはさらなる調査領域 実際の使用例 使用例: Claude Code 拡張機能の調査 /research Claude Code Hooks Skills Commands の使い分け Step 1: スコープ確認 コマンド実行後、以下の選択肢が表示されます。 調査の深さを選択してください: - クイック概要 - 標準調査 - ディープダイブ ← 選択 情報源の信頼性要件を選択してください: - 高(公式のみ) ← 選択 - 中(推奨) - 低(幅広く) Step 2: 調査実行 選択に基づいて、以下の順序で調査が進みます。 公式ドキュメントの検索・取得 情報の整理・比較 実践的な知見の抽出 Step 3: 結果の保存 調査結果が docs/research/2026-01-06-claude-code-hooks-skills-agents-commands.md に保存されます。 出力例(一部抜粋) 実際に生成された調査結果の一部を紹介します。 # 調査: Claude Code Hooks/Skills/Agents/Commands の使い分け ## メタデータ - **調査日**: 2026-01-06 - **調査者**: Claude - **信頼性レベル**: 高(公式のみ) - **調査深度**: ディープダイブ ## 調査課題 Claude Codeの5つの主要拡張機能の概念、特徴、使い分け基準を明確にする。 ## 概要 Claude Codeには複数の拡張機能があり、それぞれ異なる目的と使用場面を持つ。 主な違いは「誰が呼び出すか」と「何を制御するか」にある。 ## 調査結果 ### 呼び出し方式による分類 | 呼び出し方式 | 機能 | 説明 | |------------|-----|------| | ユーザー明示的 | Slash Commands | `/command`で手動実行 | | モデル自動判定 | Skills, Subagents | リクエスト内容から自動適用 | | イベント駆動 | Hooks | ライフサイクルイベントで自動実行 | ... ## 情報源 | 情報源 | 種類 | 信頼性 | URL | |--------|------|--------|-----| | Claude Code Hooks Reference | 公式ドキュメント | 高 | https://code.claude.com/docs/en/hooks | | Claude Code Skills | 公式ドキュメント | 高 | https://code.claude.com/docs/en/skills | ポイント: メタデータで調査の前提条件が明確 情報源テーブルで出典が一目瞭然 信頼性評価付きで情報の質が判断できる 活用シーン シーン1: ブログ執筆の事前調査 /research Streamlit Azure Container Apps デプロイ方法 ブログを書く前に、最新の公式情報を構造化して収集。そのまま記事の参考資料として使える。 シーン2: 技術選定の比較資料 /research uv vs Poetry vs pip-tools パッケージ管理ツール比較 チームへの提案資料として、客観的な比較情報を整理。 シーン3: トラブルシューティングの記録 /research GitHub Actions self-hosted runner セキュリティ設定 調査結果を保存しておくことで、同じ問題に再遭遇した時にすぐ参照できる。 シーン4: 新技術のキャッチアップ /research Claude 3.5 Opus 新機能と変更点 リリースノートや公式ブログを整理して、チームに共有。 コマンドの実装 /research コマンドは、 .claude/commands/research.md に配置されています。 興味がある方は、以下の Gist で全文を公開しています。 Gist: /research コマンド実装 カスタマイズのヒント 自分のプロジェクトに合わせてカスタマイズできます。 出力先の変更: Save the research document to `your/custom/path/` with: 調査パターンの追加: ### パターンE: セキュリティ調査 **目的**: セキュリティリスクを評価したい **重点項目**: - CVE情報 - セキュリティアドバイザリ - ベンダーのセキュリティガイド まとめ /research コマンドは、以下の課題を解決します。 課題 解決策 クオリティがまばら 深度を選択して期待値を合わせる 出典が不明 AACA評価と情報源テーブル フォーマットがバラバラ 統一テンプレートで出力 保存先もバラバラ docs/research/ に自動保存 調査結果は docs/research/ に蓄積されるため、 チームの知識資産 として活用できます。 同じトピックを再調査する必要がない 新メンバーのオンボーディング資料になる ブログ執筆の下調べとしてそのまま使える 「調べて」と頼むだけでなく、 調査の質をコントロールしたい 場面で活用してみてください。 参考リンク 公式ドキュメント Claude Code Slash Commands 関連記事 Claude Code Skillsの使い方と汎用テンプレート公開 Claude Code Hooksガイド:AIコーディングを自動化・カスタマイズする方法 ここまで読んでいただき、ありがとうございました! 技術調査は地味だけど重要な作業。 /research コマンドで、その効率を上げてみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Codeの調査品質がバラバラ?:/researchで解決する方法 first appeared on SIOS Tech Lab .
アバター
はじめに ども!龍ちゃんです。以前「 Claude Code Skills 実装ガイド:ローカルツールをスムーズに統合する方法 」という記事を書きました。おかげさまで「Claude Code Skills」というキーワードでの検索流入も増えてきています。 前回の記事では、 CLAUDE.md にツール説明を書いても無視される問題 を Skills で解決する方法を紹介しました。Skills の「自動認識」機能により、トリガーワードで自動的にツールが使われるようになる、という話でしたね。 しかし、しばらく使っているうちに 新たな課題 が見えてきました。 「Skills でも発火しないことがある」 そうなんです。Skills は確かに CLAUDE.md よりも認識されやすいのですが、 100% 確実に発火するわけではない んですよね。特に複雑なワークフローや、必ず特定の手順を踏んでほしい処理では、「発火しない」問題が致命的になることがあります。 この記事では、その解決策として Slash Commands を紹介します。結論から言うと、 確実に発火させたい処理は Slash Commands に移行するのがベスト です。 記事の位置づけ この記事は、前回の「Claude Code Skills 実装ガイド」の 続編・発展編 です。 前回記事 今回の記事 CLAUDE.md → Skills への移行 Skills/CLAUDE.md → Slash Commands への移行 「自動認識」のメリット推し 「確実な発火」のメリット推し Progressive Loading の説明 読み込み順序・確実性の観点 前回記事を読んでいなくても理解できる内容ですが、併せて読むとより理解が深まります。 この記事で学べること 主要なポイント Skills/CLAUDE.md の限界 : なぜ「発火しない」ことがあるのか Slash Commands の特徴 : なぜ「確実に発火する」のか 移行事例 : 実際の /review 、 /research コマンドの実装 各要素の住み分け : Hooks / Skills / Commands / CLAUDE.md の使い分け 実践的なテクニック Slash Commands のファイル構造と書き方 YAML Frontmatter の活用(allowed-tools, description) AskUserQuestion を使ったインタラクティブなワークフロー 複数エージェントの連携 前提条件 必要な知識 Claude Code の基本的な使用経験 CLAUDE.md の基本的な理解 Skills の概念(前回記事参照) あると理解が深まる知識 サブエージェント(Subagents)の概念 Hooks の基本 問題提起: 「発火しない」問題 Skills の自動認識が機能しないケース 前回記事で紹介した Skills は、description に基づいてモデルが自動的に判断して適用します。しかし、この「自動判断」が裏目に出るケースがあります。 ケース1: 似たようなトリガーワードが複数ある ユーザー: 「この記事をチェックして」 期待: technical-accuracy-reviewer が発火 実際: 単純にファイルを読んで「問題なさそうです」で終了 ケース2: コンテキストが長くなると判断が曖昧に 長い会話の後... ユーザー: 「調べて」 期待: research Skill が発火してスコープ確認 実際: WebSearch で簡易検索して終了 ケース3: 複雑なワークフローの一部だけ実行 ユーザー: 「レビューして」 期待: 技術チェック → コンテンツ改善 → SEO評価 の順で実行 実際: 簡単なフィードバックだけで終了 CLAUDE.md が無視されるケース CLAUDE.md に詳細なワークフローを書いても、同様の問題が起きます。 # CLAUDE.md ## レビューワークフロー 記事のレビューを依頼された場合は、以下の順序で実行してください: 1. technical-accuracy-reviewer でセキュリティチェック 2. content-reviewer でコンテンツ品質評価 3. blog-reviewer でSEO評価とタイトル生成 問題点 : CLAUDE.md は常時読み込まれるが、長くなると相対的に優先度が下がる 「レビューして」という曖昧な指示では、このワークフローが適用されない モデルの判断に依存するため、 確実性がない 技術的な背景: 読み込みタイミングの違い なぜこのような問題が起きるのか、読み込みタイミングの観点から説明します。 機能 読み込みタイミング 確実性 CLAUDE.md セッション開始時に全文 △ 埋もれる可能性 Skills メタデータのみ → マッチ時に本文 △ マッチ判断はモデル依存 Slash Commands ユーザーが /command 入力時 ◎ 100%確実 Slash Commands は ユーザーが明示的に呼び出す ため、読み込みタイミングに曖昧さがありません。 /review と入力すれば、 必ず review.md の内容が読み込まれます。 解決策: Slash Commands Slash Commands とは Slash Commands は、 .claude/commands/ ディレクトリに配置した Markdown ファイルを、 /コマンド名 で呼び出す機能です。 .claude/commands/ ├── review.md → /review で呼び出し ├── research.md → /research で呼び出し └── plan.md → /plan で呼び出し なぜ「確実に発火する」のか Slash Commands が確実な理由は単純です: ユーザーが明示的に入力 : /review と入力 = 意図が明確 即座に読み込み : コマンドファイルの内容が即座にプロンプトに追加 モデル判断なし : Skills のような「使うかどうか」の判断がない Skills の場合: ユーザー入力 → モデルが判断 → Skill を使う/使わない Slash Commands の場合: ユーザー入力 /review → review.md を読み込み → 実行 Slash Commands のファイル構造 --- description: コマンドの説明(/help で表示される) allowed-tools: Read, Task, AskUserQuestion argument-hint: [ファイルパス] --- # コマンドの指示内容 ここに Claude への指示を記述します。 $ARGUMENTS で引数を受け取れます。 YAML Frontmatter のフィールド : フィールド 必須 説明 description 任意 /help で表示される説明 allowed-tools 任意 使用を許可するツール argument-hint 任意 引数のヒント model 任意 使用するモデル(haiku, sonnet など) 移行事例 実際に僕が Skills/CLAUDE.md から Slash Commands に移行した事例を紹介します。 事例1: CLAUDE.md → /review Before: CLAUDE.md にワークフロー記載 # CLAUDE.md ## レビューワークフロー 記事のレビューを依頼された場合は、以下のエージェントを使い分けてください: 1. technical-accuracy-reviewer: 技術的正確性とセキュリティ 2. content-reviewer: コンテンツ品質の反復改善 3. blog-reviewer: 公開前の包括的評価 4. seo-title-generator: タイトルとメタディスクリプション ### 推奨フロー 1. まず technical-accuracy-reviewer で技術チェック 2. content-reviewer で品質改善(必要に応じて複数回) 3. blog-reviewer で最終確認 問題点 : 「レビューして」と言っても、このフローが適用されない エージェント名を明示しないと使われない 複数エージェントの連携が実行されない After: /review コマンド --- description: ブログ記事のレビューを実施。技術的正確性チェック、コンテンツ品質改善、SEO最適化、タイトル生成を支援します。 allowed-tools: Read, Task, AskUserQuestion --- # Article Review Command ブログ記事のレビューを実施します。ユーザーの目的や状況に応じて、最適なエージェントを選択・実行します。 ## Usage /review [ファイルパス] ## Available Review Agents ### 1. technical-accuracy-reviewer **特化領域**: 技術的正確性 + セキュリティ **こんな時に使う**: - 初稿が完成した時 - 技術的な内容が正しいか心配 - セキュリティリスクがないか確認したい ### 2. content-reviewer **特化領域**: コンテンツ品質(反復改善用) **こんな時に使う**: - 執筆中で何度も改善したい - 可読性を向上させたい ### 3. blog-reviewer **特化領域**: 包括的評価(最終確認用) **こんな時に使う**: - 公開前の最終確認 - コンテンツとSEOの両方を評価したい ## Execution Flow ### Step 1: 記事ファイルの確認 ユーザーがファイルパスを提供している場合、Read ツールで記事内容を確認。 ### Step 2: ユーザーの意図判断 AskUserQuestion ツールを使用して、ユーザーに選択肢を提示。 ### Step 3: エージェントの実行 選択に基づいて、適切なエージェントを Task ツールで実行。 改善点 : /review と入力すれば 確実に このワークフローが開始 AskUserQuestion でユーザーの意図を確認 複数エージェントの連携が保証される 事例2: Skills → /research Before: Skills として登録 # .claude/skills/research.md --- name: research description: Web調査を実施し、技術トピックについて調査します。 --- ## When to Use - ユーザーが「調べて」「調査して」と依頼した場合 - 技術トピックについて情報収集が必要な場合 ## Commands WebSearch と WebFetch を使用して調査を実施します。 問題点 : 「調べて」と言っても、簡易検索で終わることがある 調査深度の確認なしに実行される 調査結果の保存形式が統一されない After: /research コマンド --- description: Web調査を実施し、結果を docs/research に保存。技術トピック、公式ドキュメント、最新動向などを調査します。 argument-hint: [調査トピック] allowed-tools: WebSearch, WebFetch, Read, Write, AskUserQuestion --- # Research Command ## Workflow ### Step 1: Clarify Research Scope Before starting research, use AskUserQuestion to clarify: - 調査の深さ(クイック概要 / 標準調査 / ディープダイブ) - 情報源の信頼性要件(高:公式のみ / 中:推奨 / 低:幅広く) ### Step 2: Conduct Research Use WebSearch and WebFetch to gather information. ### Step 3: Save Results Save the research document to docs/research/ with format: YYYY-MM-DD-{topic-slug}.md 改善点 : /research トピック と入力すれば 確実に スコープ確認から開始 調査深度をユーザーが選択できる 結果が統一されたフォーマットで保存される 各要素の住み分け ここまでの内容を踏まえて、Claude Code の各拡張機能の住み分けを整理します。 呼び出し方式による分類 呼び出し方式 機能 確実性 適したユースケース イベント駆動 Hooks ◎ 100% 決定的処理(フォーマット、権限制御) ユーザー明示的 Slash Commands ◎ 100% 確実に発火させたいワークフロー モデル自動判定 Skills, Agents △ 不確実 自動適用してほしい知識・処理 常時読み込み CLAUDE.md △ 埋もれる プロジェクト全体の指針 選択フローチャート タスクを自動化したい │ ├── LLMに依存しない決定的処理? │ └── Yes → Hooks │ ├── ツール実行前後 → PreToolUse / PostToolUse │ └── 権限制御 → PermissionRequest │ ├── 確実に発火させたい? │ └── Yes → Slash Commands │ └── /review, /research など │ ├── 自動で判断して適用してほしい? │ └── Yes → Skills / Agents │ └── トリガーワードで自動認識 │ └── プロジェクト全体に適用? └── Yes → CLAUDE.md └── 開発ガイドライン、アーキテクチャ情報 具体的な使い分け例 ユースケース 推奨機能 理由 記事レビュー /review 複雑なワークフロー、確実に実行したい Web調査 /research スコープ確認が必須、結果を統一フォーマットで保存 ブログスクレイピング Skills URL を渡せば自動で判断してほしい 自動フォーマット Hooks (PostToolUse) ファイル編集後に必ず実行 コーディング規約 CLAUDE.md 常に意識してほしい全体ルール ベストプラクティス 1. 「確実性」が必要かで判断する Slash Commands を選ぶべきケース : 複数ステップのワークフロー ユーザーへの確認が必須のプロセス 結果のフォーマットを統一したい処理 「毎回同じように実行してほしい」処理 Skills のままでよいケース : 単純なツール呼び出し トリガーワードが明確で誤認識がない 「自動で判断してくれればOK」な処理 2. AskUserQuestion を活用する Slash Commands では、AskUserQuestion ツールを使ってユーザーの意図を確認できます。 ## Step 1: ユーザーの意図確認 AskUserQuestion を使用して、以下を確認してください: - 記事の現在の状態(初稿/執筆中/公開前) - 実行したいレビュー項目(技術チェック/コンテンツ/SEO) これにより、 曖昧な指示でも適切な処理を実行 できます。 3. allowed-tools で安全性を確保 --- allowed-tools: Read, Task, AskUserQuestion --- コマンドで使用するツールを制限することで、意図しない操作を防げます。 4. 段階的に移行する 一度にすべてを移行する必要はありません: まず 問題が起きているワークフロー を Slash Commands に移行 効果を確認してから、他のワークフローも検討 Skills で問題なく動いているものは、そのまま まとめ この記事では、Claude Code Skills の「発火しない」問題と、その解決策としての Slash Commands を紹介しました。 結論: 確実性で選ぶ 確実性 機能 使いどころ ◎ 100% Hooks 決定的処理(フォーマット等) ◎ 100% Slash Commands 確実に発火させたいワークフロー △ 不確実 Skills / Agents 自動判断でOKな処理 △ 埋もれる CLAUDE.md プロジェクト全体の指針 前回記事との関係 前回 : CLAUDE.md → Skills への移行で「自動認識」を実現 今回 : Skills → Slash Commands への移行で「確実な発火」を実現 どちらが優れているという話ではなく、 適材適所で使い分ける ことが重要です。 次のステップ 「発火しない」問題が起きているワークフローを特定 そのワークフローを Slash Commands に移行 効果を確認し、必要に応じて他も移行 参考リンク 公式ドキュメント Claude Code Slash Commands Claude Code Skills Claude Code Hooks Claude Code Sub-agents 関連記事 Claude Code Skills 実装ガイド:ローカルツールをスムーズに統合する方法 ここまで読んでいただき、ありがとうございました! Skills と Slash Commands、それぞれの特性を理解して使い分けることで、Claude Code との協業がさらにスムーズになります。ぜひ、この記事を参考に、あなたのプロジェクトでも実践してみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【Claude】「Skillsが発火しない」を解決:Slash Commandsで確実なワークフロー構築 first appeared on SIOS Tech Lab .
アバター
こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 株式会社 ROUTE06 が、プログラミング不要で直感的に AI アプリを構築できるプラットフォーム「Giselle(ジゼル)」を、オープンソースとして正式リリースしました。 誰でも直感的にAIアプリを作れる時代へ。ビジュアルAIアプリビルダー『Giselle(ジゼル)』を全世界に向けてオープンソースで正式リリース https://prtimes.jp/main/html/rd/p/000000050.000056964.html Red Hat は 2026 年後半を目標に、NVIDIA の次世代 AI 基盤「Vera Rubin」向けに RHEL のサポートを開始すると発表しました。 2026年後半、NVIDIA Vera Rubin向けにRed Hat Enterprise Linuxサポート開始へ https://enterprisezine.jp/news/detail/23528 Microsoft Copilot セッションに侵入し機密データを盗む攻撃「Reprompt」が発見されました。 Copilot Attack that Silently Steals Your Personal Data https://www.varonis.com/blog/reprompt ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2026年1月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech Lab .
アバター
今号では、複数のファイルをまとめたり、バックアップを取る際によく利用される tar コマンドについて説明します! tar とは tar とは、複数のファイルを 1つのファイル (アーカイブファイル) にまとめたり、まとめたファイルを元に戻す (展開) ための仕組みです。 本来は「まとめる」だけでありファイルの圧縮は行われませんが、オプションを組み合わせることで gzip などの圧縮も同時に行うのが一般的です (tar.gz 形式など)。 基本の書式 アーカイブファイルを作成 tar [オプション] アーカイブファイル名 アーカイブ対象のファイル・ディレクトリ の書式で実行します。 ディレクトリを指定した場合、ひとつのアーカイブファイルにまとめられます。 例: $ tar -cf data.tar /tmp/data/ $ ※各オプションの意味については後述します。 -v オプションを付与することによって、アーカイブされたファイルが表示されるようになります。 例: $ tar -cvf data.tar /tmp/data/ /tmp/data/ /tmp/data/log.1 /tmp/data/log.2 /tmp/data/log.3 /tmp/data/log.4 /tmp/data/log.5 $ アーカイブファイルを展開 tar [オプション] アーカイブファイル名 の書式で実行します。 例: $ tar -xf data.tar $ アーカイブファイルの作成と同様に -v オプションを付与することによって、展開されたファイルが表示されるようになります。 例: $ tar -xvf data.tar /tmp/data/ /tmp/data/log.1 /tmp/data/log.2 /tmp/data/log.3 /tmp/data/log.4 /tmp/data/log.5 $ 展開した後、カレントディレクトリに tmp ディレクトリが表示されていれば成功です。 $ ls data.tar tmp $ ls tmp/data/ log.1 log.2 log.3 log.4 log.5 tar コマンドのオプション tar コマンド の基本的なオプションをご説明します。 ※すべてのオプションはご紹介せず、よく使用されると考えられるものを抜粋しています。 -c アーカイブファイルを作成します。 ※-f オプション (アーカイブファイルを指定) と同時に使用する必要があります。 $ tar -cf data.tar /tmp/data/ -x アーカイブファイルを展開します。 ※-f オプション (アーカイブファイルを指定) と同時に使用する必要があります。 $ tar -xf data.tar -v アーカイブ、もしくは展開されたファイルの一覧など、実行時の詳細な情報を表示します。 -z gzip 形式でアーカイブ、もしくは展開します。 ファイルが圧縮されるため、ファイルサイズを小さくしたい場合に有効です。 アーカイブ時の拡張子は、tar.gz にするのが一般的です。 $ tar -czvf data.tar.gz /tmp/data/ /tmp/data/ /tmp/data/log.1 /tmp/data/log.2 /tmp/data/log.3 /tmp/data/log.4 /tmp/data/log.5 $ $ tar -xzvf data.tar.gz /tmp/data/ /tmp/data/log.1 /tmp/data/log.2 /tmp/data/log.3 /tmp/data/log.4 /tmp/data/log.5 $ アーカイブ後のファイルサイズを確認すると、tar.gz 形式のファイルの方がサイズが小さくなっていることが分かります。 $ ls -l data.* -rw-r--r--. 1 user1 user1 201 1月 13 00:21 data.tar.gz -rw-r--r--. 1 user1 user1 10240 1月 13 00:21 data.tar 補足1:なぜ -f オプションが必須なのか? 上で記載の通り、 -f オプション はアーカイブファイルを指定するオプションですが、なぜこのオプションが必要なのか?について説明します。 tar コマンドのマニュアルを確認すると、-f オプションに関する箇所に下記の記述があります。 -f, --file=ARCHIVE Use archive file or device ARCHIVE. If this option is not given, tar will first examine the environment variable `TAPE'. If it is set, its value will be used as the archive name. Otherwise, tar will assume the compiled-in default. The default value can be inspected either using the --show-defaults option, or at the end of the tar --help output. 上記によると、-f オプションが指定されていない場合、最初に TAPE 変数を参照、次にコンパイル時に読み込まれたデフォルトのデバイスを参照しに行きます。 つまり、-f オプションで明示的にファイルを指定しなければ意図しないファイルやデバイスを参照してしまうことになります。 このような誤動作を避けるために -f オプションが必要となります。 補足2:アーカイブする場合の拡張子は何でも良いか? コマンドの仕組み上、tar -cf や tar -czf でファイルをアーカイブする際のファイル名に決まりはなく、どんな名前 (拡張子) にしても良いです。 しかしながら、 ユーザがアーカイブファイルとひと目で分かるように .tar や .tar.gz としておくのが一般的 であり、推奨されます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 知っておくとちょっと便利!tar コマンドを使ったファイルのアーカイブ・展開 first appeared on SIOS Tech Lab .
アバター
こんにちは。サイオステクノロジーの和田です。前回は こちら でアウトボックスパターンという設計パターンを紹介しましたが、今回はその設計パターンを実現できる River というライブラリを使ってみたので紹介したいと思います。それではいきましょう。 River とは River は Go 言語で書かれた PostgreSQL 専用のジョブキューライブラリです。PostgreSQL をバックエンドとして使用することで、アウトボックスパターンを簡単に実装できます。主な特徴として、Redis や RabbitMQ などの外部ジョブキューを必要とせず River 単体でジョブキューを管理することができます。 ディレクトリ構成 今回作るサンプルアプリは river_examples 配下に、以下のような構成で配置します。 river_examples ├── db │ └── init.sql ├── docker-compose.yml ├── go.mod ├── go.sum ├── handlers │ └── user.go ├── jobs │ └── send_email.go └── main.go 実装 まず、必要なパッケージを 公式 の手順に従ってインストールします。 go get github.com/riverqueue/river go get github.com/riverqueue/river/riverdriver/riverpgxv5 go mod tidy River を動かすためには PostgreSQL が必須なので、Docker Compose で DB を作っていきます。 ここでは、River 本体が使うテーブルのマイグレーションと、今回サンプルで作成するアプリケーションで使うテーブルのマイグレーションを行います。 まず最初にアプリケーションで使うユーザーテーブルを作成するための SQL を作ります。 -- filepath: db/init.sql CREATE TABLE IF NOT EXISTS users ( id BIGSERIAL PRIMARY KEY, email TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); 次に、postgres 本体とマイグレーション用のコンテナを Docker Compose で作ります。 River にはマイグレーション用の go コマンドがあるので、そちらを利用してマイグレーションを行っています。 # filepath: docker-compose.yml services: db: image: postgres:16-alpine environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: mydb ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data - ./db/init.sql:/docker-entrypoint-initdb.d/001-init.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d mydb"] interval: 2s timeout: 5s retries: 30 river-migrate: image: golang:1.24 depends_on: db: condition: service_healthy environment: DATABASE_URL: postgres://user:password@db:5432/mydb?sslmode=disable command: - bash - -c - | set -euo pipefail go install github.com/riverqueue/river/cmd/river@v0.28.0 /go/bin/river migrate-up --line main --database-url "$$DATABASE_URL" restart: "no" volumes: pgdata: 以下のコマンドで作成します。 cd river_examples docker compose up -d db docker compose run --rm river-migrate 1. ジョブの定義 続いて、メール送信ジョブを定義します // filepath: jobs/send_email.go package jobs import ( "context" "fmt" "log" "github.com/riverqueue/river" ) // SendEmailArgs はメール送信ジョブの引数 type SendEmailArgs struct { UserID int64 `json:"user_id"` Email string `json:"email"` Subject string `json:"subject"` Body string `json:"body"` } // Kind はジョブの種類を識別する名前を返す func (SendEmailArgs) Kind() string { return "send_email" } // SendEmailWorker はメール送信を実行するワーカー type SendEmailWorker struct { river.WorkerDefaults[SendEmailArgs] } // Work は実際のメール送信処理を実行 func (w *SendEmailWorker) Work(ctx context.Context, job *river.Job[SendEmailArgs]) error { log.Printf("Sending email to %s (UserID: %d)", job.Args.Email, job.Args.UserID) log.Printf("Subject: %s", job.Args.Subject) // ここで実際のメール送信処理を行う // 例:外部のメール配信サービスAPIを呼び出す err := sendEmailViaSMTP(job.Args.Email, job.Args.Subject, job.Args.Body) if err != nil { return fmt.Errorf("failed to send email: %w", err) } log.Printf("Email sent successfully to %s", job.Args.Email) return nil } func sendEmailViaSMTP(email, subject, body string) error { // 実際のメール送信ロジック // ここでは簡略化のため省略 return nil } 2. メイン処理 メイン処理では主に以下を行います。 River クライアントの初期化 River ワーカーの登録 ユーザー登録処理 // filepath: main.go package main import ( "context" "log" "time" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/riverqueue/river" "github.com/riverqueue/river/riverdriver/riverpgxv5" "river_examples/handlers" "river_examples/jobs" ) func setupRiver(ctx context.Context, dbPool *pgxpool.Pool) (*river.Client[pgx.Tx], error) { workers := river.NewWorkers() // メール送信ワーカーを登録 river.AddWorker(workers, &jobs.SendEmailWorker{}) riverClient, err := river.NewClient(riverpgxv5.New(dbPool), &river.Config{ Queues: map[string]river.QueueConfig{ river.QueueDefault: {MaxWorkers: 100}, }, Workers: workers, }) if err != nil { return nil, err } return riverClient, nil } func main() { ctx := context.Background() // PostgreSQL接続プールの作成 dbPool, err := pgxpool.New(ctx, "postgres://user:password@localhost:5432/mydb?sslmode=disable") if err != nil { log.Fatal(err) } defer dbPool.Close() // Riverクライアントのセットアップ riverClient, err := setupRiver(ctx, dbPool) if err != nil { log.Fatal(err) } // Riverワーカーを起動 if err := riverClient.Start(ctx); err != nil { log.Fatal(err) } defer riverClient.Stop(ctx) log.Println("River worker started") // アプリケーションのメイン処理 userHandler := handlers.NewUserHandler(dbPool, riverClient) if err := userHandler.RegisterUser(ctx, "test@example.com", "password"); err != nil { log.Fatal(err) } // 動作確認用(ジョブが処理されるまで少し待つ) time.Sleep(2 * time.Second) } 3. ユーザー登録処理 ユーザー登録時に、DB への書き込みとジョブの投入を同じトランザクションで行います // filepath: handlers/user.go package handlers import ( "context" "fmt" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/riverqueue/river" "river_examples/jobs" ) type UserHandler struct { dbPool *pgxpool.Pool riverClient *river.Client[pgx.Tx] } func NewUserHandler(dbPool *pgxpool.Pool, riverClient *river.Client[pgx.Tx]) *UserHandler { return &UserHandler{ dbPool: dbPool, riverClient: riverClient, } } func (h *UserHandler) RegisterUser(ctx context.Context, email, password string) error { // トランザクション開始 tx, err := h.dbPool.Begin(ctx) if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } defer tx.Rollback(ctx) // 1. ユーザーテーブルに挿入 var userID int64 err = tx.QueryRow(ctx, ` INSERT INTO users (email, password_hash, created_at) VALUES ($1, $2, NOW()) RETURNING id `, email, hashPassword(password)).Scan(&userID) if err != nil { return fmt.Errorf("failed to insert user: %w", err) } // 2. メール送信ジョブをエンキュー(同じトランザクション内) _, err = h.riverClient.InsertTx(ctx, tx, jobs.SendEmailArgs{ UserID: userID, Email: email, Subject: "Welcome to Our Service!", Body: "Thank you for registering. Please verify your email...", }, nil) if err != nil { return fmt.Errorf("failed to enqueue email job: %w", err) } // 3. トランザクションをコミット if err := tx.Commit(ctx); err != nil { return fmt.Errorf("failed to commit transaction: %w", err) } return nil } func hashPassword(password string) string { // パスワードハッシュ化(今回はそのまま登録) return password } サンプルでは UserHandler を main から呼び出す形にしていて、実行すると users への INSERT と River のジョブテーブルへの INSERT が同一トランザクションで行われ、ワーカーがジョブを処理します。 動作の流れ 実際の処理の流れは以下のようになります。 ユーザー登録リクエストが来る トランザクション開始 ユーザーテーブルに挿入(INSERT) River のジョブテーブルに挿入(InsertTx) トランザクションコミット River ワーカーがジョブテーブルを監視 メール送信ジョブを実行 これにより、ユーザー登録が成功した場合のみメール送信ジョブが確実に実行され、前回説明したアウトボックスパターンが実現できます。 まとめ 今回は、River を使ったサンプルアプリを作ってみました。River を使うことで、 PostgreSQL のトランザクション機能を活用し、アウトボックスパターンを簡単に実装できます。データベースへの書き込みとジョブの投入を単一のトランザクションで行えるため、データの整合性を保ちながら非同期処理を実現できます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Goのジョブキューライブラリ River 使ってみた first appeared on SIOS Tech Lab .
アバター
はじめに 皆さん、こんにちは!PS-SLの織田です。2025年最後のブログ投稿になります。今回は、『 Java言語で学ぶデザインパターン入門 』の第3章を読んだ感想をまとめていきたいと思います。第2章ではAdapterパターンを扱いましたが、第3章ではTemplate Methodパターンについて書かれています。第2章のブログは コチラ からご覧ください。それでは詳しく見ていきましょう! Template Methodパターンとは Template Methodパターンとは「処理の枠組み(テンプレート)を親クラスで定義し、具体的な処理内容はサブクラスに実装させる」パターンです。文字で説明しても何のこっちゃという感じなので、具体的なコードとともに説明していきます。 処理の枠組みを定義する:AbstractDisplay.java public abstract class AbstractDisplay { // open, print, closeはサブクラスに実装をまかせる抽象メソッド public abstract void open(); public abstract void print(); public abstract void close(); // displayはAbstractDisplayで実装してるメソッド public final void display() { open(); for (int i = 0; i < 5; i++) { print(); } close(); } } このクラスはTemplate Methodパターンの核心部分です。全体のおおまかな流れをここで定義しています。一方で、細かな処理については記述されていません。ここで注目すべきはdisplay()メソッドです。このメソッドは次のような処理の流れを定義しています: 1. open()で開始処理を実行 2. print()を5回繰り返し実行 3. close()で終了処理を実行 重要なのは、display()メソッドがfinal宣言されている点です。これにより、サブクラスがこの処理の流れを変更できないようにしています。一方、open()、print()、close()は抽象メソッドとして宣言されており、具体的な処理内容はサブクラスに委ねています。 具体的な実装例1:CharDisplay.java public class CharDisplay extends AbstractDisplay { private char ch; // 表示すべき文字 // コンストラクタ public CharDisplay(char ch) { this.ch = ch; } @Override public void open() { // 開始文字列として"<<"を表示する System.out.print("<<"); } @Override public void print() { // フィールドに保存しておいた文字を1回表示する System.out.print(ch); } @Override public void close() { // 終了文字列として">>"を表示する System.out.println(">>"); } } AbstractDisplayクラスで記述しなかった細かい処理を記述していきます。CharDisplayクラスは、文字を括弧で囲んで表示する実装です。open()で<<を表示し、print()で指定された文字を表示し、close()で>>を表示します。 実行すると次のような出力になります: <<HHHHH>> 具体的な実装例2:StringDisplay.java public class StringDisplay extends AbstractDisplay { private String string; // 表示すべき文字列 private int width; // 文字列の表示幅 // コンストラクタ public StringDisplay(String string) { this.string = string; this.width = string.length(); } @Override public void open() { printLine(); } @Override public void print() { System.out.println("|" + string + "|"); } @Override public void close() { printLine(); } // openとcloseから呼び出されて"+----+"という文字列を表示するメソッド private void printLine() { System.out.print("+"); for (int i = 0; i < width; i++) { System.out.print("-"); } System.out.println("+"); } } おまけでもう1個処理のバリエーションを増やします。StringDisplayクラスは、文字列を罫線で囲んで表示する実装です。printLine()という独自のヘルパーメソッドを使用して、開始と終了時に罫線を表示します。 実行すると次のような出力になります: +-------------+ |Hello, world.| |Hello, world.| |Hello, world.| |Hello, world.| |Hello, world.| +-------------+ 利用例:Main.java public class Main { public static void main(String[] args) { // 'H'を持ったCharDisplayのインスタンスを1個作る AbstractDisplay d1 = new CharDisplay('H'); // "Hello, world."を持ったStringDisplayのインスタンスを1個作る AbstractDisplay d2 = new StringDisplay("Hello, world."); // d1,d2とも、すべて同じAbstractDisplayのサブクラスのインスタンスだから // 継承したdisplayメソッドを呼び出すことができる // 実際の動作は個々のクラスCharDisplayやStringDisplayで定まる d1.display(); d2.display(); } } このクラスはTemplate Methodパターンを利用するクライアント側の実装例です。重要なポイントは、AbstractDisplay型の変数を宣言し、CharDisplayやStringDisplayのインスタンスを代入している点です。 どちらのインスタンスも同じdisplay()メソッドを呼び出していますが、実際の動作(open()、print()、close()の処理内容)は各サブクラスの実装によって異なります。 Template Methodパターンで嬉しいこと 「わざわざ抽象クラスを作る必要があるの?」と思う人がいるかもしれません。CharDisplayやStringDisplayに必要な処理を書けば、たしかにAbstractDisplayは削ることができます。しかし、このパターンを使うことで受けられる恩恵があります。例えば、処理の流れを変更したくなったとします。 ケース1:表示回数を変更したい Template Methodパターンあり: public abstract class AbstractDisplay { // 略 // 表示回数を3回に変更したい public final void display() { open(); for (int i = 0; i < 3; i++) { // この1行だけ変更すれば済む print(); } close(); } } Template Methodパターンなし: public class CharDisplay { // 略 public void display() { System.out.print("<<"); for (int i = 0; i < 3; i++) { // すべてのクラスで変更が必要 System.out.print(ch); } System.out.println(">>"); } } public class StringDisplay { // 略 public void display() { printLine(); for (int i = 0; i < 3; i++) { // こっちのクラスでも変更が必要;; System.out.println("|" + string + "|"); } printLine(); } } Template Methodパターンあり:親クラスの1箇所を修正するだけで、すべてのサブクラスの動作が変わる Template Methodパターンなし:すべてのクラスで同じ修正を繰り返す必要がある ケース2:処理の前後にログを追加したい また、もっと複雑な処理をする際にはより重宝します。例えば、処理の開始と終了時にログを出力したくなったとします。 Template Methodパターンあり: public abstract class AbstractDisplay { // 略 public final void display() { System.out.println("[LOG] 処理開始"); // ログ追加 open(); for (int i = 0; i < 5; i++) { print(); } close(); System.out.println("[LOG] 処理終了"); // ログ追加 } } Template Methodパターンなし: public class CharDisplay { public void display() { System.out.println("[LOG] 処理開始"); // すべてのクラスに追加が必要 System.out.print("<<"); for (int i = 0; i < 5; i++) { System.out.print(ch); } System.out.println(">>"); System.out.println("[LOG] 処理終了"); // すべてのクラスに追加が必要 } } public class StringDisplay { public void display() { System.out.println("[LOG] 処理開始"); // こっちのクラスにも追加が必要 printLine(); for (int i = 0; i < 5; i++) { System.out.println("|" + string + "|"); } printLine(); System.out.println("[LOG] 処理終了"); // こっちのクラスにも追加が必要 } } Template Methodパターンありの場合: ケース1と同様に修正が必要最小限に留まっています。AbstractDisplayにログ出力の処理を追記するだけで済みました。 Template Methodパターンなしの場合:ケース1と同様に、処理の流れが各クラスに分散しているため、同じような修正をすべてのクラスで実施する必要があります。そのため、修正漏れやバグの混入リスクが高まってしまいます 。 ケース3:新しい表示方法を追加したい さらに、新しい表示方法を追加したい場合を考えてみましょう。例えば、XMLタグで囲んで表示するクラスを追加したいとします。 Template Methodパターンあり: public class XmlDisplay extends AbstractDisplay { private String content; private String tagName; public XmlDisplay(String content, String tagName) { this.content = content; this.tagName = tagName; } @Override public void open() { System.out.print("<" + tagName + ">"); } @Override public void print() { System.out.print(content); } @Override public void close() { System.out.println("</" + tagName + ">"); } } Template Methodパターンなし: public class XmlDisplay { private String content; private String tagName; public XmlDisplay(String content, String tagName) { this.content = content; this.tagName = tagName; } public void display() { // 処理の流れを毎回ゼロから実装する必要がある // もし他のクラスと処理の流れを変えたい場合、それも可能になってしまう(一貫性が失われる) System.out.print("<" + tagName + ">"); for (int i = 0; i < 5; i++) { System.out.print(content); } System.out.println("</" + tagName + ">"); } } Template Methodパターンありの場合: 新しいクラスを追加するだけで、既存のコードを全く変更することなく、新しい表示方法を実装できます。しかも、処理の流れ(open() → 5回print() → close())は自動的に継承されるため、一貫性が保たれます。 Template Methodパターンなしの場合:新しいクラスを追加するたびに処理の流れをゼロから実装する必要があり、一貫性を保つのが開発者の責任になってしまいます。 まとめ Template Methodパターンの本質は、「処理の流れの統一」と「変更の容易さ」の実現にあります。処理の枠組みを親クラスで一元管理することで、共通の処理フローを保証しつつ、具体的な実装の詳細は各サブクラスに委ねることができます。 特に重要なのは、以下の3つの利点です: Template Methodパターンの本質は、「処理の流れの統一」と「変更の容易さ」の実現にあります。処理の枠組みを親クラスで一元管理することで、共通の処理フローを保証しつつ、具体的な実装の詳細は各サブクラスに委ねることができます。 特に重要なのは、以下の3つの利点です: 1. 一箇所の変更で全体に影響 :処理の流れを変更したい場合、親クラスの1箇所を修正するだけで、すべてのサブクラスの動作が変わる 2. 一貫性の保証 :すべてのサブクラスが同じ処理の流れを持つことが保証される 3. 拡張の容易さ :新しいサブクラスを追加する際、処理の流れを意識する必要がない 実際の開発では、「処理の流れは共通だが、詳細な処理内容だけが異なる」という場面が発生するかと思います。そんな時、Template Methodパターンはコードの重複を避け、保守性を向上させ、将来の拡張性も確保するというメリットをもたらしてくれます。 それではこの辺りで2025年最後のブログを締めたいと思います。個人的に大変学びの多い一年でした。来年も引き続きデザインパターンをはじめ多くのことを学んでいきたいと思います。それでは、よいお年を! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post デザインパターンのすゝめ ~Template Method~ first appeared on SIOS Tech Lab .
アバター
初めに メリークリスマス!!ども!龍ちゃんです。 いや~クリスマスですね。年末ですし、そろそろいろいろな締め作業がありますね。 実は弊社では、裏でこっそりアドベントカレンダーもどきをやっていました。アドベントカレンダーもどきってのは、アドベントカレンダーって「テーマ」があるはずなんですけど、弊社のブログとエンジニアの特徴上、ネタの一貫性を持たせるのが大変だからって理由だったので「フリーテーマ」ですね。というわけで 12 月は毎日投稿されていたって感じです。この時期で投稿記事が爆増えして、ブログの企画をやっている側としてはにっこにこです。 ざっくりと紹介とまとめを書いていこうと思います。ぜひ興味ある記事を見つけてみてね! AI・機械学習関連 12 月は AI 活用の記事が盛りだくさんでした。Azure OpenAI からローカル LLM、エージェント連携まで幅広くカバーしています。 Azure OpenAI 入門:モデルのデプロイと python から API を実行 Azure OpenAI を初めて触る方向けの入門記事です。Azure ポータルでのリソース作成から、モデルデプロイ、Python での API 呼び出しまでを丁寧に解説しています。デプロイの種別(グローバル/リージョン、Standard/バッチ)や TPM、動的クォータといった概念もわかりやすく説明されており、これから Azure OpenAI を始めたい方の最初の一歩に最適です。 AzureOpenAI 入門:JSON 形式のデータを出力させる 前回の続編として、LLM に JSON 形式でデータを出力させる方法を解説しています。「JSON モード」と「構造化出力(Structured Outputs)」の 2 つの方法を比較し、構造化出力がなぜキーを保証できるのか、制約つきデコードという技術まで踏み込んで解説しています。アプリケーションに LLM を組み込む際に必須の知識です。 【v0.4】Ragas の最新アップデート情報と Azure OpenAI GPT-5 での評価方法【2025 年 12 月】 RAG 評価フレームワーク「Ragas」の v0.4.0 アップデート情報と、GPT-5 を使った評価方法を紹介しています。GPT-5 の reasoning_effort パラメータを「minimal」と「high」に変えた場合の評価結果比較も実施。faithfulness スコアに差が出ることが確認でき、用途に応じた使い分け指針が示されています。 【LangChain】SQL Agent で RAG に集計・統計機能を追加する方法 セマンティック検索は「完了率を教えて」「担当者ごとの件数は?」といった集計・統計の質問が苦手です。この記事では、LangChain の SQL Agent を組み合わせてこの限界を突破するハイブリッドアーキテクチャを提案しています。LLM がクエリの意図を判断して適切なツールを選択する実装例も紹介されています。 ノート PC で動くローカル LLM 完全ガイド【2025 年 12 月版】 2025 年 12 月時点でノート PC で動作する主要なローカル LLM を徹底比較した保存版記事です。Gemma 3、Phi-4、Qwen2.5、Llama 3.1、DeepSeek-R1 など各モデルのスペック・特徴・日本語性能を公式ソースに基づいて整理。Ollama などの実行環境や、量子化・メモリ使用量などの導入時注意点まで網羅しています。 【FastAPI】SSE で AI の回答をリアルタイムストリーミングする ChatGPT のように文字が順次表示されるストリーミング体験を FastAPI で実現する方法を解説しています。SSE と WebSocket の違いから始まり、sse-starlette を使った実装、LangGraph からのイベント変換、フロントエンド(React)での受信処理まで、実用的なコード例とともに紹介されています。 もう AI に振り回されない!OpenSpec で実現する予測可能な AI 開発 「Vibe コーディング」の問題点と、その解決策である「仕様駆動開発(SDD)」について詳しく解説した力作記事です。CLAUDE.md の限界から始まり、OpenSpec、Kiro、Spec Kit といった主要 SDD ツールの比較、実際の使い方までを網羅しています。AI に振り回されず、予測可能な開発を実現したい方必読です。 A2A(Agent2Agent)プロトコル入門| MCP との違いと活用メリット Google が発表した AI エージェント間通信プロトコル「A2A」の入門記事です。異なるフレームワークで作られた AI エージェント同士が連携できるようになる仕組みで、MCP との違い(MCP はツール接続、A2A はエージェント間連携)も明確に解説されています。マルチエージェントシステムに興味がある方におすすめです。 Claude Code 関連 Claude Code の機能を深掘りした記事と、AI 開発の新しいパラダイムについて考察した記事が揃っています。 Claude Code Hooks ガイド:AI コーディングを自動化・カスタマイズする方法 Claude Code の「Hooks」機能を詳しく解説した記事です。Hooks は、ツール実行の前後に設定したシェルコマンドを自動実行する機能で、LLM の判断に依存せず確実に実行されるのが特徴です。PreToolUse、PostToolUse など 9 種類のイベント、設定ファイルの優先度、マッチャーの正規表現パターン、そして実践的な設定例(自動フォーマット、センシティブファイル保護、Bash コマンドのロギング)まで網羅しています。 Claude Code Skills の使い方と汎用テンプレート公開 Claude Code に特定タスクの実行方法を教える「Skills」機能のガイドです。Skills は「新しいチームメンバーに渡すオンボーディング資料」のようなもので、プログレッシブ・ディスクロージャーにより必要な情報だけを段階的に読み込みます。description の書き方が成否の 9 割を決めるという重要なポイントも解説されています。Web 開発向けの汎用 Skills テンプレートも公開されています。 GitHub Spec Kit 入門| AI コーディングエージェントで仕様駆動開発を実践する GitHub がオープンソースで公開した「Spec Kit」を実際に Todo アプリで試した体験記です。Specify(仕様作成)→ Plan(技術計画)→ Tasks(タスク分解)→ Implement(実装)の 4 フェーズワークフローを採用し、各フェーズにゲートがあることで品質を担保します。Claude Code、GitHub Copilot、Cursor など 15 以上の AI エージェントに対応しており、「思ってたのと違う」を減らしたい方に最適です。 これからの「バイブコーディング」の話をしよう AI 開発時代における原則の再定義を試みた考察記事です。コードレビュー、DRY 原則、可読性、保守性といった従来の「正しい」原則は、すべて「人間がコードを読み、人間が修正する」という前提から生まれています。AI がコードを書き直す時代には、「入出力が正しければ内部実装は問わない」「一貫性は不要、重複も OK」「保守しない、作り直す」という新しい原則が成立するのでは、という刺激的な提言がされています。 Three.js の Vibe Coding でビジュアルイメージを検討する Gemini と Copilot を使って three.js で Web ビジュアルを作成した実践記事です。「アスタリスクの 3D 版」「ゴリッと拡大したい」といった雰囲気ベースのプロンプトで AI と対話しながら、数ステップでイメージに近いビジュアルを実装していく過程が紹介されています。完成した three.js コード(コピペで動作可能)も公開されており、バイブコーディングの具体的な成功事例として参考になります。 Kubernetes・インフラ関連 Kubernetes のバックアップ・運用に関する記事が充実しています。Velero シリーズは特に読み応えがあります。 初めての Kubernetes バージョンアップ:Kubernetes におけるバックアップの必要性とデータ管理の課題 Kubernetes のバックアップがなぜ必要なのかを解説した入門記事です。バージョンアップ時に失われる可能性のある要素として「クラスターリソースの設計図(Deployment、Service など)」と「アプリケーションデータ(DB 内のデータなど)」の 2 つを挙げ、etcd と PV/PVC の二軸でバックアップを行う重要性を説明しています。Blue/Green デプロイにおけるデータ移行の課題も詳しく解説されています。 Kubernetes バックアップツール「Velero」の概要 Kubernetes のリソースと永続ボリュームを包括的にバックアップできる「Velero」の概要記事です。PV のバックアップ方式(ボリュームスナップショット、ファイルシステムバックアップ、CSI スナップショットデータムーバー)、アーキテクチャ、バックアップ/リストアのワークフロー、そしてデータベースの整合性を確保する Hook 機能について解説されています。他のエンタープライズバックアップソリューション(Cohesity、Commvault、Rubrik)との比較もあります。 Velero のインストールと基本設定 前回の概要編に続き、実際に Velero を導入する手順を解説した実践記事です。学習用環境として Minikube を使用し、バックアップ先に S3 互換ストレージである MinIO を構築します。Velero CLI のインストール、VolumeSnapshotClass の設定、Helm を使った Velero 本体のインストールまで、コマンドと YAML ファイルを交えて丁寧に説明されています。 GitOps だけじゃない!新たな選択肢「HelmOps」とは? Kubernetes へのアプリケーション自動デプロイ手段として、GitOps に代わる「HelmOps」を解説した記事です。GitOps が Git リポジトリを信頼できる情報源とするのに対し、HelmOps は Helm レジストリを信頼できる情報源として扱います。CD プロセスで Git を介さずにアプリケーション更新ができるためシンプルな構成になる反面、環境ごとのカスタマイズが難しいというトレードオフがあります。 【Kong 初心者向け】Canary Release Plugin の使い方 API Gateway の Kong を使って、一部ユーザーにのみ新サービスを公開するカナリアリリースを実現する手順を解説しています。Kong Manager での workspace 作成、service/route 設定、Key Auth・ACL plugin の設定、そして Canary Release Plugin の設定まで、スクリーンショット付きで丁寧に説明されています。Enterprise 機能ですが、Kong Academy の virtual lab で試すことができます。 フロントエンド・開発ツール 初心者向けの入門記事から、実践的な CI/CD 構築まで幅広いトピックが揃っています。 Next.js + Storybook + Playwright を Chromatic でビジュアルテスト自動化する Next.js 14 プロジェクトに Storybook と Playwright E2E テストを導入し、Chromatic でビジュアルテストを自動化する方法を詳しく解説した実践記事です。Storybook のセットアップ、各コンポーネントの Stories 作成例(Button、MessageList、ImportProgress)、Playwright E2E テストの Chromatic 対応、GitHub Actions での自動化設定まで網羅しています。ハマりポイントと解決策も記載されており、導入時に役立ちます。 チンパンジーでもわかる Git/Github【初心者向け】 「サルでもわかる git」がわからなかった筆者が、当時の自分を救うべく書いた超初心者向け Git 入門記事です。グループでレポートを書く例え話から始まり、リポジトリ、クローン、ブランチ、コミット、プッシュ、プルリクエスト、マージといった用語を、大学のグループ課題に例えて説明しています。Git と GitHub の違いも明確に解説されており、これから Git を学ぶ方の最初の一歩に最適です。 UI 基礎:選択式入力の使い分け 入力フォームにおける「ラジオボタン」「チェックボックス」「セレクト」などの選択式 UI コンポーネントの使い分けを整理した記事です。基本ルール(1 件選択で 2〜5 件ならラジオボタン、5 件以上ならセレクト、複数選択ならチェックボックス)から始まり、トグルスイッチ、コンボボックス、デイトピッカーなどの発展的なコンポーネントまで解説。性別、生年月日、都道府県など具体的な事例での使い分けも紹介されています。 Hardhat 3 と Dev Container で Solidity の開発 VS Code の Dev Container を使って Solidity 開発環境を構築し、Hardhat 3 で SmartContract を動かすまでを解説した記事です。devcontainer.json の設定、Nomic Foundation の Solidity 拡張のインストール、Hardhat 3 の初期化、ローカルネットワークでの Contract 実行、Sepolia テストネットへのデプロイまでを順を追って説明しています。Hardhat 3 の keystore 機能を使った秘密鍵の安全な管理方法も紹介されています。 デザインパターン・設計 設計パターンを学ぶシリーズ記事と、マイクロサービスで役立つパターンの解説です。 デザインパターンのすゝめ ~ Iterator パターン編~ 『Java 言語で学ぶデザインパターン入門』第 1 章を読んだ感想をまとめた記事です。Iterator パターンは集合要素を順に指していき処理を繰り返し実行するパターンで、本棚(BookShelf)と本(Book)を例に解説されています。配列から ArrayList への変更時も、Iterator パターンを使っていれば BookShelf クラスだけの修正で済み、Main クラスは変更不要という具体例が示されています。 デザインパターンのすゝめ ~ Adapter パターン編~ Iterator パターン編の続編として、Adapter パターンを解説しています。「すでに提供されているもの」と「本当に必要なもの」のズレを埋めるパターンで、既存クラス(Banner)を新しいインターフェース(Print)で使えるように変換する PrintBanner クラスを例に説明されています。HTML 出力への切り替えなど、将来の拡張でもクライアントコードの修正を最小限に抑えられる利点が紹介されています。 アウトボックスパターンとはなにか マイクロサービスアーキテクチャにおいて、データベースの更新とイベント発行を矛盾なく行うためのアウトボックスパターンを解説しています。ユーザー登録サービスを例に、「DB 書き込み成功・メッセージ送信失敗」「DB 書き込み失敗・メッセージ送信成功」といった不整合が発生するケースを示し、Outbox テーブルを使った解決策を紹介しています。メッセージリレーによる送信と冪等性の考慮についても解説されています。 その他 プロジェクトマネジメント、資格取得、キャリア、コミュニティ運営など、技術以外のトピックも充実しています。 ラスト 1 か月を炎上させないためのプロジェクトマネジメント 初めて PM を担当した筆者が、プロジェクト終盤で多くのバグが発生した経験から学んだ教訓をまとめた記事です。「ウォーキングスケルトン」(フロント・バック・DB が繋がった最小限の動く骨組み)を早期に作ること、「フェイルファスト」の考え方で小さく早く失敗すること、CI/CD と「触れる環境」を早期に整えることの重要性が解説されています。 LT は怖くない!(怖がらない!)LT 実践の心得 5 選 これから LT(ライトニングトーク)で登壇したい方向けの心得を紹介した記事です。「登壇すると決める」「何を伝えるかを決める」「しゃべりすぎない」「スライドに書いていないことはあまりしゃべらない」「楽しむ」の 5 つを中心に、自己紹介は短く、デモは避ける、AI でスライド作成を楽にするなど具体的なコツも紹介されています。 プロジェクト管理入門 – WBS・スケジュール作成 WBS(Work Breakdown Structure)の作成方法からスケジュール作成のポイントまでを解説した記事です。成果物の洗い出し、タスクの分解(1〜5 人日程度の粒度)、依存関係の定義(FS/SS/FF/SF)、バッファ設定、営業日を考慮したスケジュール作成、ガントチャート可視化まで網羅しています。Jira と Notion の比較も掲載されています。 Exchange Online のメール自動転送を制限する Exchange Online でメールの自動転送を制限し、情報漏洩リスクを軽減する方法を解説した記事です。Microsoft 365 Defender ポータルでのアウトバウンドスパムフィルターポリシー設定、特定ドメインのユーザーに対する自動転送完全禁止、または社内ドメインのみへの自動転送許可(リモートドメイン設定)の 2 つのパターンを、スクリーンショット付きで説明しています。 自宅にデジタルサイネージを導入しました Raspberry Pi と MagicMirror2 を使って自宅にデジタルサイネージを導入した体験記です。時計、祝日カレンダー、天気予報、ニュースヘッドライン、YouTube ライブ動画を 1 画面で表示し、さらに洗濯物の取り込みタイミングを判断するための「直近の雨予報モジュール」を Vibe Coding で自作しています。実用的かつ楽しい作品です。 AZ-104 合格体験記:効果的な学習法と予想問題集の活用戦略 Azure Administrator Associate(AZ-104)に合格した筆者が、効果的だった学習方法を紹介した記事です。Udemy の予想問題集を中心に学習すること、試験中に MS Learn を参照できる特性を活かして「調べ方」を鍛えること、間違った問題を徹底的に深掘りすること、比較表や図を自作することなど、具体的なアドバイスが満載です。 地方で IT 技術コミュニティを 1 年間運営して得たもの JAZUG(Japan Azure User Group)静岡支部を立ち上げ、1 年間運営してきた経験をまとめた記事です。「ないなら自分でやってしまえばいい」という発想から始まり、集客の苦労、「現地開催のみ」へのこだわり、運営で得られた技術的視野の広がりやコネクション、「場づくり」スキルの重要性について語られています。 基礎知識ゼロから新卒 1 年|仕事としての技術とマインド 機械工学専攻から未経験で IT エンジニアになった新卒 1 年目の振り返り記事です。学生と社会人のマインドセットの違い、「分からない」を認める勇気、暗記ではなく「調べ方」を知ること、「雑談・相談」の重要性、とにかく手を動かして作りながら学ぶことなど、未経験からエンジニアを目指す方への励みになる内容です。 OSS 鳥観図ワーキングループの活動紹介 OSS 推進フォーラムの「鳥観図ワーキンググループ」の活動を紹介した記事です。OSS 鳥観図は、複雑多岐にわたる OSS を視覚的に俯瞰できるようにまとめたもので、2014 年から毎年更新されています。新規追加・削除・カテゴリ変更の議論プロセスや、OSC・Open Source Summit での宣伝活動、参加方法も紹介されています。 まとめ いかがでしたか?12 月は本当にたくさんの記事が公開されて、企画している側としてはとても嬉しい限りです。 AI・機械学習から Kubernetes、デザインパターン、プロジェクトマネジメントまで、幅広いトピックが揃いました。ぜひ気になる記事があったら読んでみてくださいね! 来年も SIOS Tech Lab をよろしくお願いします! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SIOS Tech Lab アドベントカレンダー2025まとめ|全34記事を一挙紹介 first appeared on SIOS Tech Lab .
アバター
サイオステクノロジーのひろです。今回はAzure OpenAIでスキーマに沿ったJSON形式データを出力することをゴールに、以下の目次で解説していきます。 前回の記事はこちら Azure OpenAI入門:モデルのデプロイとpythonからAPIを実行 LLMの構造化データ出力 LLMは流暢で自然な文章を出力することが可能です。学習した膨大なテキスト情報を使い、ユーザの入力(プロンプト)に沿った文章を出力してくれます。 例えばAzure OpenAIモデルに「こんにちは」というプロンプトを渡すと以下のように返してくれました。 「こんにちは!どのようにお手伝いできますか?」 自然な文章だと思います。 しかしLLMはこのような自然な文章を生成するだけでなく、JSON形式でテキストを出力することができます。 JSON形式で出力させることで、アプリケーションのシステムの一部として組み込むことが容易になります。 AzureOpenAIで可能な出力方法 試しにプロンプトのみでJSON形式で出力してもらいました。 messageは以下の通りです。 python messages=[ { "role": "system", "content": "あなたは優秀なアシスタントAIです。JSON形式で出力してください。", }, {"role": "user", "content": "こんにちは"}, ], 実行結果(返答)はこちらです。 { "message": "こんにちは!何かお手伝いできることがありますか?" } JSON形式でレスポンスをくれました。 この例のようにJSON形式で返してくれる場合もありますが、プロンプトエンジニアリングだけでは確実性に欠けるもので、崩れたJSON形式であったり、JSONの前に「JSON形式で回答します。」という文章が出力されることがあります。 そのためアプリケーションに組み込むにはリスクがあります。 そこで、この次の章ではAzure OpenAIモデルでJSON形式でレスポンスを取得できる2種類の方法をご紹介します。 1つ目:JSONモード Azure OpenAIにはJSONモードが存在します。 JSONモードを使用することで、JSON形式で返答されることが保証されます。 JSONモードを使用するには、AzureOpenAIへのリクエストの中に以下のパラメータを追加し、プロンプトでJSON形式で出力してください等という文章を追加します。 python response_format: { type: "json_object" } これによりJSONモードを使用できます。 注意点 JSONモードを使用するときは、systemプロンプトにJSON形式で出力してください等の文言を入れてください。JSONという文字が含まれない場合、エラーが出ます。 以下はサンプルコードと実行結果です。今回はpythonで用意しています。 また、スキーマを用意し、プロンプトに含めることでスキーマに沿った内容を出力させようとしています。 サンプルコード python import os import json from openai import AzureOpenAI from dotenv import load_dotenv from test_schemas import TestSchemas # .envファイルから環境変数を読み込み load_dotenv() api_key = os.getenv("AZURE_OPENAI_API_KEY") endpoint = os.getenv("AZURE_OPENAI_ENDPOINT") api_version = os.getenv("AZURE_OPENAI_API_VERSION") deployment = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME") # Azure OpenAIクライアントの作成 client = AzureOpenAI( api_version=api_version, azure_endpoint=endpoint, api_key=api_key, ) # スキーマのJSON表現を取得 schema_string = json.dumps( TestSchemas.model_json_schema(), indent=2, ensure_ascii=False ) prompt = f""" 以下の文章を分析し、指定されたスキーマに従ってJSON形式で出力してください。 文章: '''私は今週末のテストに備えて早く寝ることにしました。''' スキーマ: '''{schema_string}''' """ response = client.chat.completions.create( messages=[ { "role": "system", "content": "あなたは優秀なアシスタントAIです。日本語でJSON形式に合わせて回答してください。", }, {"role": "user", "content": prompt}, ], response_format={"type": "json_object"}, max_tokens=1000, temperature=0.7, model=deployment, ) print(response.choices[0].message.content) TestSchemasクラス python from pydantic import BaseModel, Field class TestSchemas(BaseModel): title: str = Field(description="文章のタイトル") content: str = Field(description="文章の内容") importance: int = Field( ge=1, le=5, description="文章の重要度を1から5の範囲で評価(5が最も重要)" ) 実行結果 { "title": "テスト準備", "content": "私は今週末のテストに備えて早く寝ることにしました。", "importance": 4 } スキーマに沿ったJSON形式のレスポンスが返ってきていることが確認できました。 ただ、これは成功例で、スキーマに沿ったキーでレスポンスをくれない場合もあります。 このJSONモードはJSON形式であることは保証してくれますが、どんなキーが含まれるかまでは保証してくれません。 プロンプトのみでJSONを指定した場合に比べると形式が保証されているという良い点がありますが、キーが変わる場合があるとなるとアプリケーションに組み込むにはリスクがあります。 この問題を解決するのがもう一つの方法である構造化出力(Structured Outputs)です。 2つ目:構造化出力(Structured Outputs) 構造化出力はJSONモードより後に追加された機能で、JSONモードを強化したバージョンといえると思います。 JSONモードと何が違うかというと、JSONモードではどんなキーが含まれるかという点は保証してくれませんでした。しかし、この構造化出力は指定したスキーマに準拠した回答をさせることが可能です。 JSONモードではプロンプトにスキーマを入力していましたが、response_formatにスキーマを指定することができます。 以下はサンプルコードです。 スキーマはJSONモードのサンプルコードで使用したTestSchemasを使用しています。 python import os import json from openai import AzureOpenAI from dotenv import load_dotenv from test_schemas import TestSchemas # .envファイルから環境変数を読み込み load_dotenv() api_key = os.getenv("AZURE_OPENAI_API_KEY") endpoint = os.getenv("AZURE_OPENAI_ENDPOINT") api_version = os.getenv("AZURE_OPENAI_API_VERSION") deployment = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME") client = AzureOpenAI( api_version=api_version, azure_endpoint=endpoint, api_key=api_key, ) schema_string = json.dumps( TestSchemas.model_json_schema(), indent=2, ensure_ascii=False ) prompt = """ 以下の文章を分析し、指定されたスキーマに従ってJSON形式で出力してください。 文章: '''私は今週末のテストに備えて早く寝ることにしました。''' """ response = client.chat.completions.parse( messages=[ { "role": "system", "content": "あなたは優秀なアシスタントAIです。日本語でJSON形式に合わせて回答してください。", }, {"role": "user", "content": prompt}, ], response_format=TestSchemas,#スキーマを指定 max_tokens=1000, temperature=0.7, model=deployment, ) print(response.choices[0].message.content) 実行結果 {"title":"テストに備えるための早寝","content":"私は今週末のテストに備えて早く寝ることにしました。","importance":3} スキーマに沿ったJSON形式で出力されていることが確認できました。 制約つきデコード なぜ構造化出力でキーを保証できるんだろうという点に疑問を持ったので調べてみました。 どうやら制約付きデコードと呼ばれる技術が用いられているようです。 ここでLLMが文章を生成する方法についておさらいしましょう。 LLMは学習したパターンに基づいて、プロンプトに沿った内容の文章を生成してくれます。 まず、文脈に沿った次に来る確率が高い言葉をリストアップし、その中から確率で次の言葉を決定し、これを繰り返すことで文章を生成しています。 以下の図の例で見ますと、「今日は」に続いて、「いい」、「天気」、「寒い」という言葉がリストアップされており、それぞれに確率が存在します。次の単語が「いい」の確率は60%、「天気」の確率は30%、「寒い」の確率は10%という具合です。例では「いい」が選ばれていますね。この選択を繰り返すことで文章を生成しています。 制約つきデコードとは何かというと、リストアップされた言葉のうち、指定された種類の言葉以外が選ばれる確率を制限するというものです。 以下の例では、response_formatとして、titleとcontentというfieldのみ存在するスキーマを渡したとします。 制約付きデコードがない場合は。「{」に続いて、「title」が60%、「key」が30%、「name」が10%という具合で、title以外のキーが選ばれる可能性があります。 制約付きデコードがあれば、「title」以外の言葉の確率が0になるようマスキングされ、titleが選ばれるようになります。 このように制約付きデコーディングが使用されることで、構造化出力で指定されたスキーマのキーが保証されるようになります。 まとめ 今回はAzureOpenAIを使用してJSON形式のデータを出力させる方法についてまとめました。 方法は2種類あり、JSONモードではJSON形式の出力は保証されますが、どんなキーが含まれるかについては保証されません。 対して構造化出力(Structured Outputs)を使用することでキーについても保証されるようになります。 JSON形式で出力させることでアプリケーションに生成AIを組み込みやすくなります。是非活用してみてはいかがでしょうか。 次回はAzure OpenAIのFunctionCallingについて解説します。 参考文献 https://learn.microsoft.com/ja-jp/azure/ai-foundry/openai/how-to/json-mode?view=foundry-classic&tabs=python https://learn.microsoft.com/ja-jp/azure/ai-foundry/openai/how-to/structured-outputs?view=foundry-classic&tabs=python-secure%2Cdotnet-entra-id&pivots=programming-language-python https://openai.com/ja-JP/index/introducing-structured-outputs-in-the-api ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AzureOpenAI入門:JSON形式のデータを出力させる first appeared on SIOS Tech Lab .
アバター
こんにちは、サイオステクノロジーの遠藤です。 前回のブログ「 A2A(Agent2Agent)プロトコル入門|MCPとの違いと活用メリット 」では、A2Aプロトコルの概要を解説しました。 今回は、 実際にA2Aプロトコルを使ってマルチエージェントアプリを作ってみた ので、その実装を紹介します。 5秒でわかる:この記事の内容 項目 内容 やったこと A2Aプロトコルで「ライター×校閲者」マルチエージェントアプリを構築 得られるもの A2Aエージェントの実装パターン、Python SDKの使い方 対象読者 A2Aを実際に試したい人、マルチエージェント開発に興味がある人 関連記事:より深く理解するために A2A自体について理解したい方は、前回のブログを先に読むことをおすすめします。 前回ブログ: A2A(Agent2Agent)プロトコル入門|MCPとの違いと活用メリット TL;DR 「ライターエージェント」と「校閲者エージェント」をA2Aで連携させるデモを実装 Python SDK( a2a-sdk )を使えば、数十行でA2Aサーバーが構築可能 Azure OpenAI(または他のLLM)と組み合わせて、実用的なワークフローを構築 こんな人に読んでほしい A2Aプロトコルを実際に動かしてみたい人 マルチエージェントアプリの実装パターンを知りたい人 Python + Azure OpenAIでAIアプリを作っている人 「エージェント間連携って実際どう実装するの?」と思っている人 作るもの:編集部ワークフロー 今回作るのは、 ブログ記事の執筆→校閲を自動化するワークフロー です。 オーケストレーター がライターエージェントにテーマを送信 ライターエージェント がAzure OpenAIを使って初稿を生成 オーケストレーター が初稿を受け取り、校閲者エージェントに送信 校閲者エージェント が誤字脱字・技術的正確性をチェックし、修正案を返す 実装の全体像 Step 1: 環境セットアップ 前提条件 このデモでは uv (Pythonパッケージマネージャー)を使用します。uvの導入がまだの方は、以下の記事を参考にセットアップしてください。 参考: 【Python】uv入門 – pipより高速なパッケージ管理ツール 依存関係のインストール # pyproject.toml [project] name = "a2a-demo" version = "0.1.0" requires-python = ">=3.12" dependencies = [ "a2a-sdk[http-server]>=0.3.0", "openai>=1.0.0", "httpx>=0.28.0", "uvicorn>=0.34.0", "python-dotenv>=1.0.0", ] 環境変数の設定 AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/ AZURE_OPENAI_API_KEY=your-api-key AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o AZURE_OPENAI_API_VERSION=2024-02-15-preview Step 2: ライターエージェントの実装 agent.py – LLM呼び出しロジック import os from typing import Literal from openai import AzureOpenAI from pydantic import BaseModel class WriterResponse(BaseModel): """ライターエージェントのレスポンス形式""" status: Literal["input_required", "completed", "error"] = "input_required" content: str class WriterAgent: """ブログ記事の初稿を書くエージェント""" SYSTEM_PROMPT = """あなたは技術ブログのライターです。 指定されたテーマについて、読みやすく分かりやすいブログ記事の初稿を書いてください。 ## 記事の構成 1. 導入(テーマの背景と記事の目的) 2. 本文(技術的な説明、具体例) 3. まとめ(要点の整理) ## 注意事項 - 技術的に正確な内容を心がける - 初心者にも分かりやすい表現を使う - 適切な見出しを付ける - 500〜800文字程度で簡潔にまとめる""" def __init__(self): self.client = AzureOpenAI( azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"], api_key=os.environ["AZURE_OPENAI_API_KEY"], api_version=os.environ.get("AZURE_OPENAI_API_VERSION", "2024-02-15-preview"), ) self.deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"] async def invoke(self, theme: str) -> WriterResponse: """テーマに基づいてブログ記事の初稿を生成する""" if not theme or theme.strip() == "": return WriterResponse( status="input_required", content="記事のテーマを指定してください。", ) response = self.client.chat.completions.create( model=self.deployment_name, messages=[ {"role": "system", "content": self.SYSTEM_PROMPT}, {"role": "user", "content": f"テーマ: {theme}"}, ], temperature=0.7, max_tokens=2000, ) return WriterResponse( status="completed", content=response.choices[0].message.content, ) agent_executor.py – A2Aエグゼキューター ここがA2Aプロトコルの核心部分です。 AgentExecutor を継承して、 execute メソッドを実装します。 """Writer Agent Executor - A2Aプロトコル用のエグゼキューター""" from a2a.server.agent_execution import AgentExecutor, RequestContext from a2a.server.events import EventQueue from a2a.server.tasks import TaskUpdater from a2a.types import Part, TaskState, TextPart from a2a.utils import new_agent_text_message, new_task from writer_agent.agent import WriterAgent class WriterAgentExecutor(AgentExecutor): """ライターエージェントのA2Aエグゼキューター""" def __init__(self): self.agent = WriterAgent() async def execute( self, context: RequestContext, event_queue: EventQueue, ) -> None: query = context.get_user_input() task = context.current_task if not task: task = new_task(context.message) await event_queue.enqueue_event(task) updater = TaskUpdater(event_queue, task.id, task.context_id) # 処理中ステータスを送信 await updater.update_status( TaskState.working, new_agent_text_message("記事を執筆中です...", task.context_id, task.id), ) # ライターエージェントを実行 result = await self.agent.invoke(query) if result.status == "completed": # 成果物として記事を追加 await updater.add_artifact( [Part(root=TextPart(text=result.content))], name="draft_article", ) await updater.complete() else: await updater.update_status( TaskState.input_required, new_agent_text_message(result.content, task.context_id, task.id), final=True, ) ポイント : RequestContext からユーザー入力を取得 TaskUpdater でタスクの状態を更新 結果は Artifact として返す main .py – サーバー起動 """Writer Agent Server - ライターエージェントのA2Aサーバー""" import uvicorn from dotenv import load_dotenv from a2a.server.apps import A2AStarletteApplication from a2a.server.request_handlers import DefaultRequestHandler from a2a.server.tasks import InMemoryTaskStore from a2a.types import AgentCapabilities, AgentCard, AgentSkill from writer_agent.agent import WriterAgent from writer_agent.agent_executor import WriterAgentExecutor load_dotenv() def main(): skill = AgentSkill( id="write_article", name="ブログ記事ライター", description="指定されたテーマでブログ記事の初稿を執筆します", tags=["blog", "writing", "article"], examples=[ "Pythonの非同期処理について記事を書いて", "Dockerの基本概念を解説する記事を書いて", ], ) agent_card = AgentCard( name="Writer Agent", description="技術ブログの初稿を執筆するエージェント", url="http://localhost:10001/", version="1.0.0", default_input_modes=WriterAgent.SUPPORTED_CONTENT_TYPES, default_output_modes=WriterAgent.SUPPORTED_CONTENT_TYPES, capabilities=AgentCapabilities(streaming=False), skills=[skill], ) request_handler = DefaultRequestHandler( agent_executor=WriterAgentExecutor(), task_store=InMemoryTaskStore(), ) server = A2AStarletteApplication( agent_card=agent_card, http_handler=request_handler, ) print("Starting Writer Agent on http://localhost:10001") uvicorn.run(server.build(), host="0.0.0.0", port=10001) if __name__ == "__main__": main() ポイント : AgentSkill でエージェントの能力を定義 AgentCard でメタデータを公開 A2AStarletteApplication でHTTPサーバーを構築 Step 3: 校閲者エージェントの実装 校閲者エージェントも同様の構造です。違いはシステムプロンプトと出力形式です。 agent.py(抜粋) class ReviewerAgent: """ブログ記事を校閲するエージェント""" SYSTEM_PROMPT = """あなたは技術ブログの校閲者です。 与えられた記事を以下の観点でチェックし、修正案を提示してください。 ## チェック項目 1. **誤字脱字**: タイポや文法ミスがないか 2. **技術的正確性**: 技術的な説明が正確か 3. **読みやすさ**: 文章が分かりやすいか 4. **トーン&マナー**: 技術ブログとして適切なトーンか ## 出力形式(JSON) { "issues": ["問題点1", "問題点2", ...], "suggestions": ["改善提案1", "改善提案2", ...], "corrected_article": "修正後の記事全文" }""" 校閲者はJSONで構造化された結果を返し、問題点・改善提案・修正後の記事を明確に分離しています。 Step 4: オーケストレーターの実装 オーケストレーターは、A2Aクライアントとして両エージェントを呼び出します。 """Orchestrator - ライターと校閲者エージェントを連携させるクライアント""" import asyncio from uuid import uuid4 import httpx from a2a.client import A2ACardResolver, A2AClient from a2a.types import MessageSendParams, SendMessageRequest async def get_agent_client(base_url: str) -> tuple[A2AClient, httpx.AsyncClient]: """エージェントのA2Aクライアントを取得する""" httpx_client = httpx.AsyncClient(timeout=httpx.Timeout(120.0)) resolver = A2ACardResolver(httpx_client=httpx_client, base_url=base_url) agent_card = await resolver.get_agent_card() client = A2AClient(httpx_client=httpx_client, agent_card=agent_card) return client, httpx_client async def send_message(client: A2AClient, message: str) -> str: """エージェントにメッセージを送信して結果を取得する""" payload = { "message": { "role": "user", "parts": [{"kind": "text", "text": message}], "messageId": uuid4().hex, }, } request = SendMessageRequest( id=str(uuid4()), params=MessageSendParams(**payload) ) response = await client.send_message(request) return extract_result_text(response) async def run_editorial_workflow(theme: str): """編集ワークフローを実行する""" print(f"テーマ: {theme}") # Step 1: ライターエージェントに接続 writer_client, writer_http = await get_agent_client("http://localhost:10001") # Step 2: ライターに記事を依頼 draft_article = await send_message(writer_client, theme) print("--- 初稿 ---") print(draft_article) # Step 3: 校閲者エージェントに接続 reviewer_client, reviewer_http = await get_agent_client("http://localhost:10002") # Step 4: 校閲者に記事をレビュー依頼 review_result = await send_message(reviewer_client, draft_article) print("--- 校閲結果 ---") print(review_result) # クリーンアップ await writer_http.aclose() await reviewer_http.aclose() ポイント : A2ACardResolver でAgent Cardを取得 A2AClient でメッセージを送信 結果は Artifact から抽出 Step 5: 実行してみる エージェントを起動(ターミナル2つ) # ターミナル1: ライターエージェント cd demo PYTHONPATH=. uv run python -m writer_agent # ターミナル2: 校閲者エージェント cd demo PYTHONPATH=. uv run python -m reviewer_agent オーケストレーターを実行 uv run python orchestrator/main.py "grpcとはなにか" 実行結果 ============================================================ A2A Protocol Demo: ライター × 校閲者 ワークフロー ============================================================ テーマ: grpcとはなにか [Step 1] ライターエージェントに接続中... ✓ ライターエージェントに接続しました [Step 2] 記事の初稿を依頼中... ✓ 初稿を受け取りました --- 初稿(抜粋) --- # gRPCとはなにか?初心者でもわかる解説 ## 導入:gRPCの背景とこの記事の目的 近年、マイクロサービスやクラウドアプリケーションの普及に伴い、 サービス間の通信技術がますます重要になっています。 そんな中で注目されているのが「gRPC」という通信プロトコルです。 gRPCはGoogleが開発した高速で効率的なRPCフレームワークで、 多くの企業や開発者に支持されています。 ### 双方向ストリーミング gRPCは一方向または双方向のストリーミング通信もサポート。 これにより、リアルタイムのデータ送受信や大容量データの分割送信が可能です。 --- 初稿ここまで --- [Step 3] 校閲者エージェントに接続中... ✓ 校閲者エージェントに接続しました [Step 4] 記事の校閲を依頼中... ✓ 校閲結果を受け取りました --- 校閲結果 --- 【発見した問題点】 1. gRPCはGoogleが開発したオープンソースであることを明記したほうが良い 2. 「gRPCは一方向または双方向のストリーミング通信もサポート」の文が やや簡潔すぎて意味が取りづらい 3. 対応言語をもう少し具体的に挙げると親切 4. 全体的に文章は読みやすいが、技術用語の説明がもう少し丁寧だと初心者に親切 【改善提案】 1. gRPCがオープンソースとして広く利用されていることを明示する 2. ストリーミング通信の種類(クライアント/サーバー/双方向)を 具体的に説明し、用途例を簡単に示す 3. C#, Node.js, PHPなどの対応言語も補足する 4. 専門用語には簡単な注釈を加え、初心者が理解しやすいようにする 【修正後の記事(抜粋)】 ### ストリーミング通信 gRPCは以下の3種類のストリーミング通信をサポートしています。 - クライアントストリーミング:クライアントからサーバーへ連続したデータを送信 - サーバーストリーミング:サーバーからクライアントへ連続したデータを送信 - 双方向ストリーミング:クライアントとサーバーが同時にデータを送受信 これにより、リアルタイムのデータ送受信や大容量データの分割送信が可能になります。 --- 校閲結果ここまで --- ============================================================ ワークフロー完了! ============================================================ 校閲者エージェントが初稿の曖昧な表現を検出し、より具体的な説明に改善してくれました。特に「ストリーミング通信」のセクションでは、3種類のストリーミングを箇条書きで明確に説明する形に修正されています。 Agent Cardを確認してみる 各エージェントのAgent Cardは、以下のURLで確認できます: # ライターエージェント curl http://localhost:10001/.well-known/agent.json | jq # 校閲者エージェント curl http://localhost:10002/.well-known/agent.json | jq { "name": "Writer Agent", "description": "技術ブログの初稿を執筆するエージェント", "url": "http://localhost:10001/", "version": "1.0.0", "skills": [ { "id": "write_article", "name": "ブログ記事ライター", "description": "指定されたテーマでブログ記事の初稿を執筆します" } ], "capabilities": { "streaming": false } } これがA2Aの「発見性」です。クライアントはこのAgent Cardを取得することで、エージェントの能力を動的に把握できます。 まとめ この記事で作ったもの コンポーネント 役割 ライターエージェント テーマを受け取り、ブログ記事の初稿を生成 校閲者エージェント 記事を受け取り、問題点・改善案・修正版を返す オーケストレーター 両エージェントを連携させてワークフローを実行 A2Aの実装パターン エージェントロジック(agent.py) : LLM呼び出しなどのビジネスロジック エグゼキューター(agent_executor.py) : A2Aプロトコルとの橋渡し サーバー(main.py) : Agent CardとHTTPサーバーの定義 まとめ A2Aプロトコルは「エージェントのマイクロサービス化」を実現する有力なアプローチです。MCPでツールを接続し、A2Aでエージェントを連携させる。この組み合わせで、より複雑で柔軟なAIシステムが構築できます。 ぜひ皆さんも試してみてください! 参考リンク 公式ドキュメント A2A Protocol Official Documentation A2A Python SDK A2A Samples ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post A2Aプロトコルでマルチエージェントアプリを作ってみた|ライター×校閲者ワークフロー first appeared on SIOS Tech Lab .
アバター