ヘルプページをAIと共同運用する 〜 Notion→Git移行と自動更新システムの構築

こんにちは、SRE2年生が終わろうとしている墨(YOUTRUST/X)です!

昨今AIの台頭によりリリース頻度が高くなっていく中でヘルプページの更新がリリースに追いつかないなどの課題をお持ちではないでしょうか?
今回は、NotionからGitベースのヘルプページへ移行し、さらにAIによる自動更新システムを構築した事例をご紹介します。
非エンジニアメンバーが簡単に運用できる仕組みを作ることで、運用工数を大幅に削減しつつ、品質管理を向上させた取り組みです。

YOUTRUST ヘルプページ

プロジェクト概要

YOUTRUSTでは、ユーザー向け(to C)と公式リクルーター向け(to B)の2つのヘルプページを提供しています。

※ 以降ユーザー向け(to C)をSNS、公式リクルーター向け(to B)を採用管理画面と呼称します。

項目 詳細
対象サイト https://help.youtrust.jp/
利用者 一般ユーザー(SNS) + 公式リクルーター(採用管理画面)
記事数 160記事以上
更新頻度 プロダクト更新に応じて随時
技術スタック Material for MkDocs + Vercel + GitHub Actions
コスト 月約$20(Vercel pro + GitHub Actions利用料)

なぜNotionからの移行が必要だったのか

移行前の課題

従来のNotion版ヘルプページには、いくつかの運用課題がありました。

1. リリース情報の分断

最も大きな課題は、ヘルプページを運用する非エンジニアメンバー(マーケティング・CS担当)に、プロダクトのリリース情報が届かないことでした。

  • エンジニアのPRマージ → プロダクト反映
  • しかし、その情報が非エンジニアメンバーに漏れることがある
  • 結果、ヘルプページの更新漏れが発生

ユーザーからの問い合わせで初めて、仕様変更への対応漏れに気づくこともありました。

2. 変更管理の弱さ

  • Notionの履歴機能はあるが、コードレビューのようなワークフローが存在しない
  • 誰が何を変更したのか追跡しづらい

3. 手動運用の手間

  • 編集→公開を手動で行う必要があり、レビューフローも未整備
  • プレビュー機能がないため、公開してから「イメージと違った」となることも

4. AI連携の困難さ

  • Notionのデータ構造は外部システムとの連携が難しい
  • 将来的なAI活用を見据えると、Markdown管理が望ましい

目指したゴール

これらの課題を解決するため、「Docs as Code」の思想に基づいた移行を決定しました。

  • AIによるリリース監視: 日々のPRを自動監視し、ヘルプ更新が必要かAIが判定
  • 非エンジニアメンバーでも簡単に運用: Slackボタンだけでマージ・デプロイできる仕組み
  • Gitでのバージョン管理: 全変更履歴を完全管理
  • PRベースのレビューフロー: マージ前にプレビュー確認が可能
  • 自動デプロイ: mainブランチへのマージで即座に反映

技術選定のポイント

ホスティング:Vercel を選択

当初はGitHub Pagesを検討していましたが、最終的にVercelを採用しました。

候補 判定 理由
GitHub Pages 不採用 現在のTeamプランではpublicリポジトリでしか使えない
Vercel 採用 privateリポジトリ対応、Serverless Functions でSlack連携が可能

GitHub Pagesを断念した理由は、現在のGitHub Teamプランでは、publicリポジトリでしかGitHub Pagesを運用できないためです。ヘルプページのソースコードには内部情報が含まれる可能性があるため、リポジトリをpublicにすることはできませんでした。

Vercelであれば、privateリポジトリでもホスティング可能で、さらにServerless Functionsを使ったSlack連携も実現できました。

静的サイトジェネレータ:Material for MkDocs

候補 判定 理由
MkDocs + Material 採用 学習コスト低、ドキュメント特化、日本語検索対応
Docusaurus 不採用 高機能だがReact知識必要、初期設定が複雑
Hugo 不採用 汎用的だがドキュメント特化ではない
Next.js (Nextra) 不採用 React/Next.js 知識必要、オーバースペック

Material for MkDocsは、ドキュメント作成に特化したフレームワークで、学習コストが非常に低いのが特徴です。Markdown記法さえ知っていれば、非エンジニアメンバーでもすぐに編集できます。

AIエージェント

候補 判定 理由
GitHub Actions ai-inference 採用 無料枠があり、Actionsからの呼び出しに最適
Gemini 不採用 実績はあったが、より安いai-inferenceを採用
Claude API 不採用 動作安定せず、システムに組み込むのは難しいと判断

アーキテクチャ全体像

システム全体は、大きく3つのコンポーネントで構成されています。

  • ドキュメント管理(Material for MkDocs)
    - docs/user/       (一般ユーザー向け)          
    - docs/recruiter/  (公式リクルーター向け)       
    - mkdocs.yml       (ナビゲーション設定)         
  • CI/CD(GitHub Actions)
    - deploy.yml              (デプロイ+Slack通知)
    - check-help-updates.yml  (AI自動更新)        
    - pr-diff-summary.yml     (PR差分サマリー)    
  • ホスティング+API(Vercel)
    - site/           (MkDocsビルド出力)           
    - api/slack/      (Slack連携 Serverless API) 

AI自動更新システムの仕組み

ここからが本記事のメインテーマです。プロダクトのmainブランチへのPRマージに連動して、ヘルプページの更新が必要かをAIが自動判定し、更新PRを作成するシステムを構築しました。

システムの全体フロー

毎朝9:00 JST
  ↓
GitHub Actions が起動
  ↓
webapp / nativeapp の過去24時間のマージ済みPRを取得
  ↓
5件ずつバッチ処理で GPT-4.1 に分析依頼
  ↓
「追加」「更新」「削除」のいずれかを判定
  ↓
必要に応じてMarkdownファイルを自動生成・更新・削除
  ↓
mkdocs.yml のナビゲーションを自動更新
  ↓
SNS用 /採用管理画面用の2つのPRを自動作成
  ↓
Slackに通知(ボタンでマージ・クローズ可能)

ステージ1:PR収集とバッチ処理

まず、対象リポジトリ(youtrust-webapp(Webアプリ)youtrust-nativeapp(モバイルアプリ))から、過去24時間にマージされたPRを取得します。
取得したPRは、5件ずつのバッチに分割します。これはGitHub Models APIのレート制限対策と、分析精度を保つためです。

ステージ2:GPT-4.1による影響判定

各バッチに対して、GitHub Models API(GPT-4.1)を使って分析します。
ポイントは、判定基準を明文化したプロンプトファイル.github/prompts/help-criteria.md)を用意していることです。

含めるべき変更の例

  • ユーザー向け機能の追加・変更(UIの大幅な変更を含む)
  • 機能の廃止・削除
  • 全ユーザーに公開された新機能
  • ユーザーが画面上から判断可能な情報のみに限定

除外すべき変更の例

  • プレリリース機能
  • A/Bテストやロールアウト中の機能
  • 見た目の微調整(色、フォント、余白など)
  • リファクタリング
  • 管理画面・内部ツールの変更
  • ドキュメントやテストの追加、修正

GPT-4.1は、以下のようなJSON形式で応答します。

{
  "action": "add",
  "target_path": "user/account/login-settings.md",
  "target_section": "一般ユーザー向け",
  "reason": "新しいログイン方法が追加されたため",
  "requires_image": true
}

リトライ機能も実装しており、API呼び出しが失敗した場合は指数バックオフで3回まで再試行します。

ステージ3:コンテンツ生成

判定結果が「追加」または「更新」の場合、GPT-4.1に再度依頼してMarkdownコンテンツを生成します。

生成時の制約条件

生成時の制約条件は、プロンプトに埋め込んでいます。

  • リリース告知は書かない(「〜されました」という表現は禁止)
  • 現在ある機能として説明する(「〜できます」「〜されます」)
  • 日付や時期は書かない
  • Material for MkDocsのアイコン記法を使う:material-xxx:
  • 画像は含めない(テキストのみで説明)

ステージ4:ナビゲーション自動更新

生成されたMarkdownファイルを配置するだけでなく、mkdocs.yml のナビゲーション構造も自動更新します。

これにはPythonスクリプトを使用し、YAMLの階層構造を維持しながら新しいエントリを追加します。

import yaml

with open('mkdocs.yml', 'r', encoding='utf-8') as f:
    config = yaml.safe_load(f)

# 新しいページをナビゲーションに追加
nav_entry = {
    '新機能の使い方': 'user/account/login-settings.md'
}

for section in config['nav']:
    if '一般ユーザー向け' in section:
        account_section = next(
            (item for item in section['一般ユーザー向け']
             if 'アカウント設定' in item),
            None
        )
        if account_section:
            account_section['アカウント設定'].append(nav_entry)

with open('mkdocs.yml', 'w', encoding='utf-8') as f:
    yaml.dump(config, f, allow_unicode=True)

ステージ5:PR自動作成とSlack通知

最後に、SNS用と採用管理画面用で別々のPRを作成します。これは、それぞれ担当チームが異なるためです。

  • SNS用:マーケティングチーム担当
  • 採用管理画面用:CSチーム担当

PR作成後、Slackに通知を送ります。この通知には、インタラクティブなボタンが含まれています。

  • 👀 PRを見る(GitHubへのリンク)
  • ✅ マージ(確認ダイアログ付き)
  • ❌ クローズ(確認ダイアログ付き)

Slack通知は最低限とし具体的な内容はPRに記載してあります。
スレッドにプレビュー用のURLリンクが挿入されるため担当者は現在との差分を実際に確認し、マージ・修正・クローズを判断します。

Slack通知例

Vercel Serverless Functions によるSlack連携

非エンジニアメンバーでも簡単に運用できるようにするという要件を満たすため、Slackボタンのクリックだけでマージ・クローズができる仕組みを実装しました。

API設計

エンドポイントは /api/slack/merge で、以下のフローで動作します。

Slackボタンクリック
  ↓
POST /api/slack/merge
  ↓
署名検証(HMAC-SHA256)
  ↓
即座に200 OKを返す(Slackの3秒タイムアウト回避)
  ↓
バックグラウンドで処理
  ├─ Slackメッセージを「🕐 処理中...」に更新
  ├─ GitHub API で PR をマージ/クローズ
  ├─ PR にコメント追加(実行者名を記録)
  └─ Slackメッセージを最終結果に更新

セキュリティ対策

Slackからのリクエストが正規のものであることを確認するため、署名検証を実装しています。

import crypto from 'crypto';

function verifySlackRequest(
  body: string,
  timestamp: string,
  signature: string,
  secret: string
): boolean {
  // 5分以上古いリクエストは拒否
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) {
    return false;
  }

  // HMAC-SHA256で署名を検証
  const sigBasestring = `v0:${timestamp}:${body}`;
  const mySignature = 'v0=' + crypto
    .createHmac('sha256', secret)
    .update(sigBasestring)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(mySignature),
    Buffer.from(signature)
  );
}

GitHub API連携

PRのマージには、Octokitを使用します。マージ前に mergeable ステータスをチェックし、コンフリクトがある場合はエラーを返します。

// マージ可能かチェック
const { data: pr } = await octokit.pulls.get({
  owner: 'team-youtrust',
  repo: 'youtrust-help-page',
  pull_number: prNumber,
});

if (pr.mergeable_state === 'dirty') {
  throw new Error('❌ コンフリクトがあるためマージできません');
}

if (pr.state !== 'open') {
  throw new Error('❌ このPRは既にクローズされています');
}

// マージ実行
await octokit.pulls.merge({
  owner: 'team-youtrust',
  repo: 'youtrust-help-page',
  pull_number: prNumber,
  merge_method: 'squash',
});

// コメント追加
await octokit.issues.createComment({
  owner: 'team-youtrust',
  repo: 'youtrust-help-page',
  issue_number: prNumber,
  body: `✅ Slackから @${slackUserName} によってマージされました`,
});

これにより、非エンジニアメンバーはGitHubを開くことなく、Slackだけでヘルプページの更新ができるようになりました。

デプロイフローの自動化

PRがマージされると、deploy.yml ワークフローが起動します。

ビルドとデプロイ

- name: Setup Python
  uses: actions/setup-python@v5
  with:
    python-version: '3.12'

- name: Install MkDocs
  run: pip install -r requirements.txt

- name: Build site
  run: mkdocs build

- name: Deploy to Vercel
  run: |
    vercel deploy --prod --token=${{ secrets.VERCEL_TOKEN }}

重要なのは、Vercel側ではビルドを行わないという設計です。vercel.jsonbuildCommand は空文字列にしており、GitHub Actions側で mkdocs build を実行しています。

これにより、ビルドログがGitHub Actionsに集約され、トラブルシューティングが容易になります。

プレビューデプロイとSlack連携

PRブランチへのプッシュ時は、プレビューデプロイを作成し、そのURLをSlackスレッドに投稿します。

- name: Deploy preview to Vercel
  id: deploy
  run: |
    URL=$(vercel deploy --token=${{ secrets.VERCEL_TOKEN }})
    echo "url=$URL" >> $GITHUB_OUTPUT

- name: Post preview URL to Slack thread
  if: contains(github.event.head_commit.message, 'slack_thread:')
  run: |
    # コミットメッセージから slack_thread:CHANNEL:TIMESTAMP を抽出
    THREAD_INFO=$(echo "${{ github.event.head_commit.message }}" | grep -o 'slack_thread:[^:]*:[0-9.]*')
    CHANNEL=$(echo "$THREAD_INFO" | cut -d: -f2)
    TS=$(echo "$THREAD_INFO" | cut -d: -f3)

    # Slackスレッドに投稿
    curl -X POST https://slack.com/api/chat.postMessage \
      -H "Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}" \
      -d "channel=$CHANNEL" \
      -d "thread_ts=$TS" \
      -d "text=プレビューデプロイ: ${{ steps.deploy.outputs.url }}"

このとき、PR作成時にコミットメッセージに slack_thread:CHANNEL_ID:MESSAGE_TS というメタデータを埋め込んでおくことで、元のSlack通知のスレッドに返信する形でプレビューURLを投稿できます。

これにより、非エンジニアメンバーはSlackスレッド内で全ての情報(更新内容、プレビューURL、マージボタン)にアクセスできます。

運用フローの確立

日々の運用(非エンジニアメンバー向け)

  1. 毎朝9:00に自動実行(またはエンジニアが手動実行)
  2. Slackに通知が届く
  3. 担当者(非エンジニアメンバー)がPRの内容を確認
  4. 必要に応じて修正・画像追加(後述)
  5. Slackボタンで「✅ マージ」または「❌ クローズ」をクリック
  6. マージされると自動的に本番反映

ポイント:GitHubを開く必要がない

非エンジニアメンバーはGitHubのアカウントを持っていなくても、Slackだけで全ての操作が完結します。

修正や画像が必要な場合の対応

AIは requires_image: true を判定しますが、画像の生成・挿入は人間(またはDevin)が行います。

Slackスレッド内でDevinを呼び出し、スクリーンショット撮影と画像挿入を依頼します。 画像挿入後、再度プレビューURLがSlackスレッドに投稿されるので、確認してからマージします。

効果測定

工数削減

作業項目 移行前(Notion) 移行後(Git + AI)
リリース情報の把握 手動で各チームに確認(見落としあり) AI自動監視(24時間以内に検知)
ヘルプ更新の判断 手動(担当者の判断に依存) AI自動判定(基準を明文化)
コンテンツ作成 手動(30分〜1時間/記事) AI下書き + 人間レビュー(10分/記事)
デプロイ 手動公開ボタン Slackボタン1クリック
レビュー なし PRベース(プレビュー確認可能)

概算で、1記事あたりの作業時間が1/3以下になりました。

品質向上

  • リリース情報の見落としがゼロに: AIが24時間以内に全PRをチェック
  • 変更履歴がGitで完全管理される: いつ、誰が、何を変更したか全て記録
  • PRプレビューで公開前に見た目を確認可能: 公開後の修正が不要に
  • レビューフローにより誤字脱字が減少: AI生成でも人間がチェック
  • 統一された文体・スタイル: AIプロンプトで制御

非エンジニアメンバーの負担軽減

  • GitHubの知識不要: Slackだけで操作完結
  • リリース情報の追跡不要: AIが自動検知してSlackに通知
  • プレビュー確認が簡単: SlackスレッドにURLが投稿される
  • マージ操作が簡単: ボタン1クリックで完了

学びと今後の展開

技術的な学び

1. AIに任せる範囲の見極めが重要

当初はAIに全て任せようとしましたが、以下は人間の判断が必要でした。

  • 画像の選定と挿入
  • 微妙なニュアンスの調整
  • ユーザー目線での分かりやすさ

AIは「下書き」を作る役割と割り切ることで、うまく協業できるようになりました。

2. プロンプトエンジニアリングの重要性

判定精度を上げるため、help-criteria.md を何度も改善しました。

  • 具体例を豊富に含める
  • 除外条件を明確にする
  • 出力フォーマットを厳密に指定する

特に「プレリリース機能は除外」「A/Bテストは除外」など、除外条件を明確にすることが精度向上のカギでした。

3. 非エンジニアメンバー向けのUX設計

「GitHubを開かなくても運用できる」という要件は、技術的には簡単ですが、UX設計が重要でした。

  • Slackボタンの配置
  • 確認ダイアログの文言
  • プレビューURLの投稿タイミング
  • エラーメッセージの分かりやすさ

実際に非エンジニアメンバーにテストしてもらい、フィードバックを反映しました。

まとめ

Notion→Git移行とAI自動更新システムの構築により、以下を実現しました。

  • リリース情報の見落としゼロ: AIが24時間以内に全PRを監視
  • 運用工数を1/3以下に削減: AI下書き + Slackボタンマージ
  • 非エンジニアメンバーでも簡単に運用: GitHubの知識不要
  • PRベースのレビューフローで品質向上: プレビュー確認 + 変更履歴管理

「Docs as Code」の思想と、AIの活用、そして非エンジニアメンバーでも使いやすいUX設計により、ドキュメント運用の新しい形が見えてきました。

今後はヘルプコンテンツをベースに、Slackで動作するAI問い合わせエージェントを開発し、CX業務など他領域の効率化も目指していきます!

同じような課題を抱えているチームの参考になれば幸いです。

We're hiring!

YOUTRUSTではエンジニアを積極募集中です! 仕事専用SNSを一緒に作りましょう!