
個人開発や副業でWebサイトを運営していると、「手を動かして改修したのに、本当に数字が動いたのか分からない…」って悩むこと、多いよね。
今回は、毎週アクセス解析の画面を睨みつけるのをやめて、事前登録ルールとGitHub Actionsで分析から判定までを全自動化した運用の裏側を紹介するよ!
現在実際に稼働しているアーキテクチャの全容をまとめたから、ぜひ読んでみてね!
個人で運営しているWebサイトを、少しでも成果が出るように改善したい。 ただ、副業や個人開発でサイト改善に充てられる時間は、せいぜい週に数時間しかありません。
この限られたリソースの中で一番困るのが、加えた改修によって本当に数字が動いたのか判断できないことです。
そこで今回、打った施策が改善につながったのかを客観的に検証できる自動化パイプラインを構築しました。
この記事は、現在実際に稼働しているシステムアーキテクチャと運用フローを解説する【実践・システム設計編】です。
ここに至るまでに直面した統計の壁(MDE)や、数字を見てからルールを後出ししてしまう人間の自分への甘さ、設計の挫折については以下の【試行錯誤・落とし穴編】で詳しく振り返っています。
1. 課題と運用サイクル
画面監視に奪われていた時間
サイトに少し手を入れてみる。ボタンの文言を変えたり、トップページに新しい導線を追加したり。 そして週末、まとまった開発時間が取れたタイミングでアクセス解析を開きます。
当時、効果を確かめるために毎回開いていたのは以下の画面でした。
- GA4の探索レポート: 対象ページの表示回数やエンゲージメント時間、ボタンクリックやモーダル開封といったカスタムイベントの発生数を、改修前後の期間を指定して手動集計
- Search Consoleの検索パフォーマンス: 改修したページのクリック数や平均掲載順位が動いていないか、検索クエリごとの推移を確認
- GitHubのコミットログやメモ帳: 「そもそもこの改修をデプロイしたのは何日の何時だっけ?」と過去の記録を掘り返す作業
この確認作業が、想像以上に個人の開発リソースをすり減らしていました。
GA4の管理画面で毎回期間比較を手動設定し、関係のない参照元を除外するフィルタを当てるだけで20〜30分が溶けます。 さらに2つのツールを行き来していると、GA4のPVは微増しているのにSearch Consoleのクリック数は横ばいだったり、週末のアクセス変動なのか改修の効果なのか判断がつかなかったりと、数字を前に延々と悩み続けることになります。
成果が分からないまま次の開発に進むと何が起きるか。 手応えのない施策に何週間も貴重な時間を注ぎ続けてしまったり、逆に良い改善だったはずのものを、たまたま全体のアクセスが落ちた週の数字を見て失敗と判断し、元に戻してしまったりします。

▲ GA4の画面監視を全廃し、結果を受けた意思決定に集中するアプローチへの転換
副業や個人開発で確保できる時間は、週にせいぜい数時間しかありません。 その貴重な時間の半分を、GA4とSearch Consoleの画面を行き来して一喜一憂する時間に奪われていたのは、最大の損失でした。
目指したのは、定点観測と集計・判定は機械に任せ、人間は届いた結果を受けて次に何を打つかの判断だけに集中する運用です。
5つの自律運用サイクル
試行錯誤の末、最終的にたどり着いた運用サイクルは以下の5つのステップです。
① 決める 数字を見る前に、狙い・測る指標・分岐ルールを定義する(人間)
② 打つ 改修コードを書き、施策ログを同じコミットに入れる(人間 + AI)
③ 待つ 42日間じっと待つ。この時間は縮められない(待機)
④ 測る 改善 / 悪化 / 判定不能 の3値で自動判定する(機械・週次)
⑤ 読む 次の1手を決める。見立てが外れたら記録を残す(人間・隔週)
└→ ①へ戻る

▲ 事前登録ルールと不可分コミットによる5ステップ運用サイクル
なぜこの運用サイクルに行き着いたのか、現在のシステム構成と設計原則を解説します。
2. システムの全体構成
パイプラインの実行フロー
現在、このサイトで毎週自走している自動化パイプラインの全体像がこちらです。

▲ 事前登録ルールとGitHub Actionsによる完全自律パイプライン構成図
パイプラインは以下の流れで自律的に動作します。
- 日曜 9:00(GitHub Actions
observe.yml):test_common.pyやcheck_initiatives.pyによる台帳の整合性チェック(記述漏れやパス重複のブロック)- GA4 Data API・Search Console APIから実績数値を自動取得
- 週次レポート(
.md/.json)の生成とリポジトリへの自動コミット - 隔週で同一のGitHub Issueを更新し、判定結果とアラートを集約
- 日曜 11:00(クラウドタスク
OODA Decide):- 生成された最新レポートを読み込み、事前登録された分岐ルールと数値を照合
- 次に採択すべきバックログ候補をAIが抽出・提示
- 人間 + AI(判断と実装):
- 提示された候補をレビューし、次の一手を決定
- 改修コードと施策記録(
experiments/log.yml)を同一コミットでコミット&デプロイ
- 月曜 8:00(
ga4-tracking-audit.yml):- イベント欠損や計測外れのサイレント障害を自動監査
運用を支える3つの設計原則
このアーキテクチャが破綻せずに自走し続けている理由は、3つの設計原則にあります。

▲ 4段階の運用サイクルと、3つのタイムスケール・人間と機械の役割境界線
1. 3つの異なるタイムスケール
この仕組みの中では、3つの異なる時間が流れています。
- 14日(判断の周期): 次に何を改修するかを人間が決めるスプリント
- 28日(基準値の窓): 直近のベースライン指標を評価する集計区間
- 42日(評価の窓): 1つの改修成果を客観的に判定できる最短期間
42日待つ必要があるからといって、その間開発の手を止めるわけではありません。 改修を打つたびに42日のタイマーが個別に走り出し、人間は14日ごとに次の改修を進めていきます。
並行して改修が重なった場合は効果の切り分けが難しくなりますが、最終的な合否は売上件数で判断するため、並行改修自体は禁止せず警告を出す運用にとどめています。
2. 施策と改修の2階建て構造
台帳は施策(数ヶ月単位の大きな狙い)と改修(デプロイごとの具体的な一手)の2階建てになっています。
施策どうしは互いに独立していなければなりません。複数の施策が同じページを同時に触ってしまうと、どちらの変更が数字を動かしたのか完全に分からなくなってしまうためです。
人間の注意深さだけに頼るのは無理があるため、CI(check_initiatives.py)がページの重複を検知して自動でブロックするようにしています。
3. 機械と人間の境界線
| 役割 | 担当 | 具体的な内容 |
|---|---|---|
| データ収集 | 機械(GitHub Actions) | APIから数値を収集し、MarkdownとJSONを生成 |
| ルール照合 | 機械(クラウドタスク) | 事前登録された分岐条件に数値を当てはめる |
| 期日督促 | 機械(GitHub Actions) | 未判定のまま放置されている施策にアラートを出す |
| 詰まり箇所の洞察 | 人間 | ボトルネックが入口にあるのか中身にあるのかを読み解く |
| 次の打ち手の決定 | 人間 | バックログから次の改修を選択して合意する |
| 対象面の選定 | 人間 | どのページに開発リソースを投じるかを決める |
機械に任せる範囲は、データ収集、事前ルールの照合、期限切れの督促に絞っています。 ボトルネックの分析や次の施策選定といった判断は、完全に人間に委ねるように境界線を引きました。
3. 実装ルール
件数で白黒をつけ、率は安全装置にする
自動判定の肝となるのが、指標の評価基準です。
小規模なサイトでは比率(CV率など)の変化を追うのが統計的に難しいため、合否判定(KGI)は必ず件数で定義するルールにしています。
kgi:
name: 販売本数
unit: 件/月 # 比率での指定はCIエラーで弾く
baseline: 0
target: 3
率は42日待っても判定不能になりがちですが、件数なら数えるだけです。 今月3件売れたかどうか。これなら統計検定など不要で、誰が見ても一瞬で白黒がつきます。
一方、因果推論の差分の差分法(DiD)は、改善判定ではなくガードレール(安全装置)として活用しています。 改修によってサイトが壊れ、数値が暴落した際に即座に検知する役割です。
効果量 R = (改修した対象群の変化率) / (改修していない対照群の変化率)
サイト破損時は数値が急落するため、微細な有意差を見る必要がなく、安全装置として確実に機能してくれます。

▲ 評価設計の転換:合否は件数で即決し、比率はサイト破損の安全装置に限定
次の一手を導く事前登録バックログ
測定結果を受けて次にどう動くかも、コード化されています。
施策台帳(initiatives.yml)にあらかじめ条件に応じたバックログの採択ルールを記述しておきます。
decide:
review_at: 2026-10-04 # 判断期日。過ぎると未判定アラートが出る
rules:
- written_at: 2026-08-30 # 記述日の入力を強制(CI検証)
when:
- {kpi: モーダル開封数, op: ">=", value: 30}
- {kpi: 開封クリック率, op: "==", value: 0}
then: modal-content # 採択するバックログID
note: 入口は足りている。ボトルネックは中身にある
backlog:
- id: modal-content
name: モーダルのコピーとボタン配置を再設計
why: 開封に対してクリックが0件
機械は事前に書かれたルールを照合するだけ。 その場の思いつきで案を作らせず、人間の思考をあらかじめコード化しておくアプローチです。
また、すべての分岐ルールに記述日(written_at)の入力を強制し、観測開始日より後に追記されたルールにはレポート上で警告を出すことで、後出しのカンニング仮説を防いでいます。
改修コードと台帳の不可分コミット
運用において最も徹底しているのが、改修コードとログファイルを必ず同一コミットに入れることです。
git commit -m "CTAの文言を変更"
├─ src/components/Modal.tsx ← 改修コード
└─ experiments/log.yml ← その記録
- id: 2026-08-29-cta-redesign
deployed_at: 2026-08-29T14:35:00+09:00
target_pages: [/features/lead-capture] # 改修の影響を受けるページ
control_pages: [/features/docs-overview] # 改修しないページ(対照群)
hypothesis: モーダルの文言短縮によりCV率が向上する
primary_metric: engagement_rate
guardrail: [engagement_rate]
evaluate_after_days: 42
コミットを分けてしまうと、あとでまとめて書こうとして確実に忘れてしまいます。 記録から漏れた改修は二度と評価パイプラインに載りません。記録漏れを防ぐには、コミットレベルで不可分にするのが最も確実でした。
まとめ
この自動化パイプラインが稼働したことで、日々の開発体験は大きく変わりました。
- アクセス解析を見る時間がゼロになった
毎週のグラフに一喜一憂する無駄がなくなり、通知が届いた時だけ15分で判断すればよくなりました。 - 手応えのない施策を延々と引きずらなくなった
42日経過時点で改善・悪化・判定不能の白黒がつくため、次の手へ迷わず移行できます。 - 限られた個人リソースを開発そのものに注げるようになった
観測と判定の規準をコードで固めたことで、安心して新しい機能開発や記事執筆に時間を投下できています。
このアーキテクチャは最初から綺麗に作れたわけではありません。 実際には、小規模サイト特有の統計の限界にぶつかり、自分自身の意志の弱さでルールを破りながら、3回設計を根本から作り直しています。
その試行錯誤のプロセスと泥臭い失敗談については、ぜひ【試行錯誤・落とし穴編】をご覧ください。

最後まで読んでくれてありがとう!
画面とにらめっこする時間を減らして、届いた結果から「次の一手をどう打つか」に集中できると、個人開発がぐっと楽しくなるよね!
気になった人は、ぜひ【試行錯誤編】の失敗談もあわせて覗いてみてね!またねー!


