📝

GitHub Copilot で検証記録を Zenn 記事に変換する — カスタム エージェントによるコンテンツ パイプライン

に公開

はじめに

第一弾の記事で紹介した通り、セキュリティラボ環境での検証作業を GitHub Copilot Agent モードに任せています。検証を実行すると、その結果は LabNote リポジトリに検証記事として記録されます。

しかし、LabNote の検証記事はあくまで内部向けの作業記録です。ラボ固有の VM 名・IP アドレス・ドメイン名が散りばめられており、そのままでは外部に公開できません。Zenn の記事として公開するには、以下のような作業が必要です。

  • ラボ固有の情報(VM 名、IP、ドメイン名、テナント ID 等)を一般化する
  • 内部メモ的な記述を読者向けの説明に書き換える
  • 記事の構成を Zenn のフォーマットに合わせる
  • 画像パスを変換する
  • 公式ドキュメントと検証結果の区別を明確にする

この変換作業を毎回手作業でやるのは面倒です。そこで、GitHub Copilot のカスタム エージェントを使って、検証記録から Zenn 記事への変換パイプラインを構築しました。

この記事では、LabNote(検証記録リポジトリ)と ZennDoc(Zenn 記事リポジトリ)にそれぞれどんなカスタマイズを施しているか、そしてその間をどうつないでいるかを紹介します。

全体像

検証から記事公開までの流れは以下の通りです。

ポイントは 2 つのリポジトリにそれぞれカスタム エージェントを配置していることです。

リポジトリ エージェント 役割
LabNote verification 検証の計画・実行・結果記録
ZennDoc zenn-writer 検証記事の Zenn 記事への変換・校正

それぞれのリポジトリの .github/ 配下に、エージェント定義・Instructions・Prompts を配置しています。

LabNote 側の構成

.github/ のディレクトリ構成

LabNote/.github/
├── copilot-instructions.md       # リポジトリ全体のルール
├── agents/
│   ├── verification.agent.md     # 検証エージェント
│   ├── labops.agent.md           # ラボ操作エージェント
│   └── ...
├── instructions/
│   ├── verification.instructions.md  # 検証記事の規約
│   ├── scripts.instructions.md       # Python スクリプトの規約
│   └── ...
└── prompts/
    ├── new-verification.prompt.md    # 新規検証記事作成
    └── ...

copilot-instructions.md — リポジトリのルールブック

第一弾の記事でも触れましたが、copilot-instructions.md にはリポジトリ全体のルールを定義しています。ディレクトリ構成、命名規則、VM 接続情報、機密情報の取り扱いなど、Copilot が検証作業を行う上で必要なコンテキストをすべて書いています。

verification エージェント — 検証の一気通貫

verification エージェントは、検証テーマを受け取って 計画 → 実行 → 記録 を一貫して行います。

.github/agents/verification.agent.md(抜粋)
---
name: verification
description: "検証の計画・実行・結果分析・記事作成を一貫して行うセキュリティ検証エージェント"
tools: [read, edit, execute, search, todo, web, mcp]
---

エージェント定義には以下を含めています。

  • ラボ環境の接続情報: VM 一覧、接続方法(PowerShell Direct / SSH)、既存スクリプトの一覧
  • ワークフロー: Plan → Execute → Analyze & Document の 3 Phase
  • 記事の作成ルール: テンプレート構造、ステータス管理、journal / TODO の更新ルール

たとえば「Entra ID の条件付きアクセスを検証して」と指示すると、エージェントは以下を自動的に行います。

  1. verification/_template.md をベースに記事ファイルを作成
  2. Azure CLI / Graph API で設定を確認・変更
  3. テスト用アカウントでサインインを試行し、結果を記録
  4. Sentinel でサインインログを確認
  5. 結果と考察を記事に記入
  6. journal/YYYY-MM.md に作業ログを追記

instructions — ファイルパターン別のルール

.github/instructions/ には、ファイルの種類ごとの詳細ルールを定義しています。

.github/instructions/verification.instructions.md(抜粋)
---
applyTo: "verification/**/*.md"
---

applyTo でファイルパターンを指定すると、そのパターンに一致するファイルを編集する際に自動的にルールが適用されます。検証記事の場合、テンプレート構造、ステータス表記、画像の配置ルール、HTML コメントマーカーの使い方などを定義しています。

prompts — ワンクリックで記事作成

.github/prompts/new-verification.prompt.md は、検証テーマを入力するだけで新規記事を作成する再利用プロンプトです。

.github/prompts/new-verification.prompt.md
---
agent: verification
description: "新しい検証記事を作成して関連ファイルを更新する"
---

以下のテーマで新しい検証記事を作成してください。

**検証テーマ**: ${input:検証テーマを記述してください}

VS Code のコマンド パレットから選択し、テーマを入力するだけで、テンプレートの展開、journal の更新、TODO の追加まで自動で実行されます。

検証記事の例

LabNote の検証記事は参考までに以下のような構造です(内部向けの筆者にわかれば OK なドキュメント)。

# 検証: Entra ID 条件付きアクセス — デバイスフィルター動作検証

| 項目 | 値 |
|------|-----|
| 日付 | 2026-04-01 |
| ステータス | 完了 |
| カテゴリ | Entra ID |
| 関連サービス | Microsoft Entra ID Conditional Access |
| 関連 VM | MainLab-Win11-24H2-JP-01, MainLab-WinSrv2025-DC-01 |

## 目的
(...)

## 検証手順
### 1. 条件付きアクセスポリシーの作成
(Azure CLI や Graph API のコマンドが、ラボ固有の値で記載されている)

## 結果
(...)

この記事には MainLab-Win11-24H2-JP-01 のような VM 名や、sample-mura.com のようなドメイン名が含まれています。検証で得た知見を Zenn の公開記事にするには、これらを一般化する必要があります。

ZennDoc 側の構成

.github/ のディレクトリ構成

ZennDoc/.github/
├── agents/
│   └── zenn-writer.agent.md          # Zenn 記事執筆エージェント
└── instructions/
    └── zenn-articles.instructions.md  # Zenn 記事の編集ルール

zenn-writer エージェント — 記事の執筆と変換

zenn-writer エージェントは、Zenn 記事の作成・校正・構成提案を行います。特に重要なのが、LabNote からの変換パイプラインの定義です。

変換フローの定義

エージェント定義に、LabNote の検証記事を Zenn 記事に変換する際のルールを含めています。

.github/agents/zenn-writer.agent.md(抜粋)
## LabNote 検証記事からの変換パイプライン

### 変換フロー

1. LabNote の検証記事を読み込む
2. ラボ固有情報をサニタイズする
3. Zenn の記事構成に再構成する:
   - LabNote の「目的」→ Zenn の「はじめに」
   - LabNote の「前提条件」→ Zenn の「前提・環境」(一般化)
   - LabNote の「検証手順」+「結果」→ Zenn の本文セクション
   - LabNote の「考察・所見」→ Zenn の「まとめ」に統合
   - LabNote の「参考資料」→ Zenn の「参考」
4. 画像パスを変換する
5. HTML コメントマーカーを除去する
6. フロントマターを付与する

構成のマッピングが定義されているので、エージェントに「この検証記事を Zenn 記事にして」と伝えるだけで、適切な構成に再構成してくれます。

サニタイズルール

エージェント定義にラボ固有情報のサニタイズルールを含めています。

固有情報の種類 変換ルール
VM 名 役割名に置換(「DC」「CA サーバー」「攻撃端末」等)
IP アドレス 省略またはプレースホルダー
ドメイン名 contoso.com 等の例示ドメインに置換
ユーザーアカウント 汎用名に置換
テナント ID / サブスクリプション ID プレースホルダーまたは省略

さらに、最終確認用のチェックリストも定義しています。エージェントは記事の生成後にこのチェックリストを実行し、ラボ固有情報の残存を検出します。

情報ソースの明確化

技術記事で特に重要なのが、公式情報と検証結果の区別です。zenn-writer エージェントには、情報の出所によって書き分けるルールを定義しています。

情報の種類 書き方
公式ドキュメントに記載あり 「Microsoft Learn によると、〜です」
筆者の検証結果 「筆者の検証環境では〜という結果になりました」
検証結果からの推測 「〜と考えられます」「〜の可能性があります」
未ドキュメントの動作 「公式ドキュメントには明記されていませんが〜」

これにより、読者が「この情報はどこまで信頼できるか」を判断できるようになります。Microsoft Learn に書かれていることと、筆者が試してみて分かったことは、明確に区別されるべきです。

instructions — 記事編集時の自動適用ルール

.github/instructions/zenn-articles.instructions.md(抜粋)
---
applyTo: "articles/**/*.md"
---

articles/ 配下の Markdown を編集する際に自動で適用されるルールです。フロントマターの規約、文体、Zenn の記載方法や、画像配置、サニタイズルールの簡潔版を含めています。エージェントを明示的に呼び出さなくても、記事ファイルを編集するだけでこれらのルールが適用されます。

実際の変換フロー

具体的にどう使っているかを紹介します。

手順 1: LabNote で検証を実行

LabNote リポジトリで verification エージェントに検証を依頼します。検証が完了すると、verification/YYYY-MM/YYYYMMDD-slug.md に結果が記録されます。

手順 2: zenn-writer エージェントに変換を依頼

ZennDoc リポジトリに切り替え、zenn-writer エージェントに LabNote の検証記事を渡します。

@zenn-writer LabNote の検証記事 verification/2026-04/20260401-conditional-access-device-filter.md の検証結果から
Zenn 記事を作成してください。

エージェントは以下を自動的に行います。

  1. LabNote の検証記事を読み込む
  2. slug 名を提案する
  3. フロントマターを生成する
  4. LabNote の構成を Zenn の構成にマッピングする
  5. ラボ固有情報をサニタイズする
  6. 画像パスを変換し、コピー先を案内する
  7. 情報ソースの書き分けを適用する
  8. サニタイズチェックリストを実行する

手順 3: 人間によるレビューと調整

ここが重要なポイントですが、エージェントが生成した記事をそのまま公開することはありません。必ず人間がレビューし、以下のような調整を行います。

  • 技術的な正確性の確認: エージェントが変換時に誤解釈していないか、検証結果の記述が正確か
  • 文章の推敲: 表現の微調整、読みやすさの改善、文脈に合わない言い回しの修正
  • サニタイズの最終確認: ラボ固有情報が残っていないか、目視でもチェック
  • 追加説明の加筆: 読者に伝わりにくい箇所に補足を追加
  • 構成の見直し: セクションの順番や粒度の調整

エージェントは「たたき台の生成」と「定型的な変換作業の自動化」を担っており、最終的な品質は人間が担保します。Copilot に修正を指示することもあれば、自分で直接編集することもあります。

まとめ

  • LabNote(検証記録)と ZennDoc(Zenn 記事)の 2 つのリポジトリに、それぞれカスタム エージェントを配置してコンテンツ パイプラインを構築しています
  • LabNote の verification エージェントが検証の実行と記録を担い、ZennDoc の zenn-writer エージェントが記事の変換・サニタイズ・校正を担います
  • ラボ固有情報(VM 名、IP アドレス、ドメイン名等)のサニタイズルールと確認チェックリストをエージェント定義に含めることで、公開前の漏れを防いでいます
  • 公式ドキュメントと検証結果の書き分けルールを定義し、読者が情報の信頼性を判断できるようにしています
  • .github/ 配下の copilot-instructions.mdagents/instructions/prompts/ を組み合わせることで、検証から記事公開までの一連のフローを効率化できます
  • 最終的な記事の品質は人間がレビュー・推敲して担保します。エージェントはたたき台の生成と定型作業の自動化を担い、人間は内容の正確性と読みやすさに集中します

このパイプラインを構築したことで、検証から情報発信までのリードタイムが大幅に短縮されました。以前は検証が終わっても「記事にまとめるのが面倒だな」と後回しにしがちでしたが、今は検証記事がすでに LabNote にあるので、Zenn 向けの変換・サニタイズ・校正を経て公開するまでのハードルが格段に下がっています。

せっかくラボ環境で面白い検証結果が得られても、自分の中だけに留めておくのはもったいないです。このパイプラインを活かして、今後も面白いと思った検証結果をどんどん記事にして公開していきたいと思います。

Microsoft (有志)

Discussion