TVerにおけるテスト自動化の歩み

こんにちは。TVerのAutomationチームで、テストや開発業務の効率化・自動化を担当している城間です。

TVerの開発組織では、2025年からリリースサイクルの短縮に取り組み、リリーストレイン(複数チームが同期して決められたサイクルでリリースを行う運用)を導入しています。
いま現在、Web、iOS、Androidの各プラットフォームはおおむね隔週でのリリースを実現できており、その背景や経緯の詳細は弊社の「計測から始める品質とスピードの両立 - TVerの開発組織改革2年間の記録」で紹介しています。

techblog.tver.co.jp

リリースサイクルを短縮するためには、リリースのたびに行うリグレッションテストを短時間かつ確実に回せる仕組みが重要になります。

しかしながら、2025年の春先まで、TVerのリグレッションテストはすべて手動で行われていました。 リリースサイクルを短縮しようとすればするほど、テスト工数が線形に積み上がっていく構造で、これを解消しない限りリリーストレインの持続的な運用はできません。

リリーストレインの運用をはじめるにあたり、迅速かつ安定して検証ができる自動テスト基盤を構築することは、私たちAutomationチームの重大なミッションでした。

本稿では、私たちが約1年間、戦略策定から運用に至るまで、段階を踏んでテストの自動化を進めてきた過程とその取り組みを紹介したいと思います。

抱えていた課題

2025年の初頭、リリース前に実施していたリグレッションテストの所要工数は、概算で以下のとおりでした。

プラットフォーム リグレッションテストの所要工数
Web 約8.6人日
iOS 約4.9人日
Android 約5.1人日

これは、UIのリグレッションや、動画・ライブの目視確認、広告配信の検証など、複数のテストスイートにまたがる総工数の見積もりです。 継続的な機能改善とリリースを必要とするTVerサービスにおいて、毎回リリース前に数日分の検証工数を割き続ける運用には、いくつかの構造的な限界がありました。

  • テストの実行に一定の工数を要し、短サイクルでのリリース対応が困難
  • テスト実行の一部が属人化しており、チーム全体の生産性に波が出やすい
  • 人的ミスによる軽微な不具合の取りこぼしが発生しうる

また、TVerのテストには「動いて見える」だけでは検証できない領域があります。

ユーザーの操作の裏で送信されるTVerタグ(行動ログ)視聴データの計測用ビーコン広告に関連するURLパラメータ置換処理といったログ系の整合性確認です。
これらはTVerの主要KPI、ひいては放送局・広告主に対する説明責任に直結する重要な検証項目ですが、マニュアルではHTTPプロキシで通信ログを目視確認するしかなく、QAチームへの負荷も再現性も大きな課題でした。

戦略の策定から始める

私たちはテストの自動化を導入するにあたり、フレームワークの選定よりも前に、まずリグレッションテストの戦略を明文化することから始めました。
自動テストを持続可能なものにするためには、何を、どこまで、どのように自動化するのかを最初に定義しておく必要があります。

スコープの定義

戦略ドキュメントでは、テストピラミッドの考え方を参考に、リグレッションテストを正常系のユーザーシナリオに絞ることに決めました。
細かな分岐や例外は単体・結合テストに任せ、リグレッションテストでは主要導線がend-to-endで機能していること、ユーザー操作によって生じるCRUD処理(作成・読み取り・更新・削除)が正しく動くことを確認する。ピラミッドの頂点に置くべき範囲に限定する、という方針です。

加えて、前述したログ系の整合性確認も、主要KPIへの影響度が高いことからリグレッションテストのスコープに含めました。
ユーザー操作の裏で送信されるログまで含めて回帰を担保する、TVerのサービス特性を反映した判断です。

実行契機の整理

次に自動テストを「いつ、どのトリガーで、何のために回すか」を整理しました。 いまは主に次の3つの実行契機で回しています。

# 実行契機 目的 トリガー
1 mainブランチの変更 マージした変更のデグレードを早く検知し、不具合を溜め込まない mainブランチへのpush
2 リリース前検証 リリースコードの品質を確認し、リリース可否の判断材料とする releaseブランチへのpush
3 テスト環境のデイリーチェック 見逃した不具合や環境・依存の変化による不具合を早期に検知する CI日次実行

自動テストを導入する目的は単一ではなく、同じテストアセットでも、走らせるタイミングを変えれば狙えるリスクが変わります。
この前提を最初に揃えることで、後から個別の運用設計をブレずに進められました。

E2Eテスト環境を独立して用意する

戦略の次に着手したのは、E2Eテスト専用の検証環境を各プラットフォームで揃えて用意することでした。

通常の開発環境やステージング環境を流用すると、開発作業や手動テストの副作用が自動テストの結果に影響してしまい、再現性が大きく損なわれます。 テストごとに「いまの環境はどんな状態か」を気にしないと結果を信頼できない状況は、自動化の前提を崩します。

私たちはWeb/iOS/AndroidのそれぞれのOSで、E2Eテスト専用の環境を共通で見るようにしました。実装方法はOSごとに異なりますが、テストが実行されるバックエンドは同じ独立した環境を指しています。

データの独立性とテストの再現性、この2つを早い段階で担保することが、後の運用フェーズで「テストを信じてリリース判断する」という文化を作るうえで重要でした。

E2Eテスト専用の検証環境

リグレッションテストそのものを見直す

戦略と環境が用意できた後、私たちは自動化の実装に進む前に、もうひとつ大きな工程を挟みました。 既存のリグレッションテスト自体の作り直しです。

既存のリグレッションテストは、長らく画面の要素単位で書かれていました。
たとえば「シリーズ名が表示されていること」「エピソード名が表示されていること」「制作局が表示されていること」「配信終了日時が表示されていること」のように、画面のパーツがひとつずつ列挙され、それぞれを確認していくテストです。

このスタイルは、確認漏れを防ぐという観点では一定の意味がありましたが、自動化を視野に入れると、以下のような問題が見えてきました。

  • テストの単位がユーザーの目的と乖離している:「要素Aの表示確認」「要素Bの表示確認」と並んでいても、それが何のユーザーシナリオを担保しているのかが不明瞭
  • 項目数が膨らみやすい:同じ画面の要素を画面ごとに繰り返し確認することになり、機械的な確認項目が無限に増えていく
  • 自動化したときの価値が見えにくい:1要素1アサーションのテストを大量に走らせても、ユーザー体験のリスクをどこまで担保できているかが定量化しにくい

そこで私たちは、リグレッションテストをユーザーシナリオに沿ったend-to-endのテストに書き直しました。
「ユーザーが何をしようとしていて、そのために画面をどう操作し、結果として何が起きるべきか」を一つのシナリオにまとめ、その流れの中で要素の表示や挙動を検証する形に変えていきました。

書き直しに合わせて、テストスイートそのものの最適化も同時に進めました。
検証デバイスの精査、テストファイルの命名規則の整理、テストデータの記述ルール化、不具合があっても次回対応となるケースの除外といった、自動化と独立しても価値のある手動テストの整理も、自動化準備と並行して進めました。

テストケースの書き直しと最適化による効果は2つありました。

  1. テストの意義そのものが明確になった:1つのテストケースが「ユーザーがこれを達成できる」という保証単位になり、優先度づけやスコープの取捨選択が判断しやすくなった
  2. 自動化との相性が大幅に上がった:E2Eテストフレームワークは、もともとユーザー操作を起点としたシナリオの記述に最適化されており、書き直し後のテストはほぼそのまま自動化のテンプレートに乗せられる形になった

「既存のテストをそのまま自動化する」のではなく、自動化を視野に入れてテストそのものを再設計する。 この順序が、その後の実装フェーズの速度と質を大きく押し上げました。

ツールの選定

自動化ツールには、大きく分けてコード型OSS(Playwright/Cypress/Seleniumなど)ローコードSaaS(Autify/MagicPod/mablなど)の2系統があります。 私たちは双方を比較したうえで、最終的にコード型OSS(Web: Playwright、iOS: XCUITest、Android: Espresso)を選定しました。

選定にあたって特に重視したのは、プロダクトの開発サイクルとの親和性メンテナンス性です。

  • ランニングコストを抑えられる:実行回数やシナリオ数に制限がなく、追加コストなしでスケールできる
  • プロダクトの開発プロセスに乗せやすい:各プラットフォームの開発言語と同じ言語でテストを書ける。Page ObjectモデルやCI/CDへの組み込みも、エンジニアが普段使うワークフローに載せやすい
  • 柔軟性が高い:HTTPリクエストの傍受やフィクスチャの差し替えなど、TVer特有の検証要件にあわせて拡張できる

SaaSにはレコーディングによるテスト量産しやすさという強みがある一方、メンテナンス性や実行制限、ランニングコストの面で、私たちが向かいたい方向とはトレードオフが大きいと判断しました。

設計上の工夫

工夫① 「テストの安定性を最優先し、メンテナンスコストを最小限に抑える」

実装方針として最初に掲げたのが、この一文です。E2Eテストは作るより維持するほうがはるかにコストがかかるため、設計のすべての判断をこの軸で評価することにしました。具体的な設計は以下のとおりです。

Page Object Model

「画面」を1つのクラスに抽象化し、テストはそのメソッドを呼び出すだけにすることで、UI変更の影響範囲をクラス1つに閉じ込めます。 さらに、3つのOSでPage Objectのファイル名を揃えるルールを徹底しました。

Web:     e2e/pages/EpisodePage.ts
iOS:     TVerLibrary/UITests/PageObjects/EpisodePage.swift
Android: app/src/androidTest/.../e2e/pages/EpisodePage.kt

同じ「エピソード詳細画面」を扱うクラスは、どのOSでもEpisodePageという名前を持ちます。
これにより、新しいテストを書くエンジニアがどのOSでも同じ感覚で実装でき、レビュー時にも他OSとの比較がしやすくなりました。

画面遷移を戻り値の型で表現する

Page Objectのメソッドは、画面遷移を伴う場合に遷移先のPage Objectを返す設計にしています。 これによって、テストコードが「画面A → 画面B → 画面C」というユーザー操作の流れをそのまま読み下せるようになります。

// iOSのPage Object設計(一部抜粋)
struct SettingsPage: PageObject {
    let app: XCUIApplication

    init(app: XCUIApplication) throws {
        self.app = app
        try waitForPageToLoad()
    }

    func tapNotificationButton() throws -> NotificationPage {
        notificationButton.waitAndTap()
        return try NotificationPage(app: app)
    }

    private func waitForPageToLoad() throws {
        try settingsTitle.waitForExistenceOrThrow(timeout: 10)
    }
}

フェイルファストで余計な待機を消す

iOSではPage Objectのinit内で前提となる要素の待機を行い、見つからなかった場合はthrowsで即座にテストを中断します。 途中の画面遷移に失敗したテストが、その後の操作で何度もタイムアウトを待つ、という典型的な無駄を排除する設計です。

sleepを書かない

固定のsleepはflakyの温床になるため、ヘルパー関数で待機を抽象化しています。
iOSではwaitAndTap() / waitAndType()、AndroidではwaitAndClickById() / waitAndClickByText()のような形で、すべての操作に「要素が利用可能になるまで待つ」処理を組み込んでいます。

工夫② APIでテストの冪等性を担保する

E2Eテストには、前回の実行が次の実行を壊す順序依存の問題がついて回ります。
「お気に入り登録できる」テストを2回連続で実行すれば、2回目は「すでに登録済み」状態となって挙動が変わってしまう、という類のものです。

私たちはテストごとに、必要な前提状態をAPIで直接揃えるアプローチを採用しています。

  • テスト前: 「あとで見る」をクリア、視聴履歴を消去、お気に入りを全削除する
  • テスト中: UIではなくAPIでテストデータを生成する(テスト観点に直接関係しない手順を省略)
  • テスト後: 状態をリセットして副作用を残さない

UI経由でこれらを行うよりも圧倒的に高速で、テストが何を前提にしているかがコードから明示的に読み取れるという副次的なメリットもあります。

同様の発想で、Feature flagのような実行時に変わりうる外部設定もテスト用の値に固定しています。
テスト中に配信内容が切り替わると結果がぶれるため、E2Eテスト側で取得処理を差し替えて外部依存を切り離し、再現性を保っています。

工夫③ テストを並列で動かして実行時間を抑える

E2Eテストはもともと実行コスト・メンテナンスコストの大きいテストです。ケース数が増えれば実行時間もメンテナンス負荷も膨らみ、開発のフィードバックループを遅くする要因になりかねません。
カバレッジの広さもテストにとっては重要ですが、それと引き換えにフィードバックの遅さを受け入れてしまうと、自動化の効果が損なわれていきます。

このトレードオフを抑えるために、複数のレイヤーで並列性を確保する設計にしています。

テストレベルの並列化 WebではPlaywrightの fullyParallel を有効化し、テストごとの独立性を前提に、複数ワーカーで同時実行しています。冪等性を担保したことが、そのまま並列実行の前提条件として効いています。

CIランナーレベルの分散実行 iOS/AndroidではCIワークフローのmatrixを使い、shard単位でテストを並列に分散実行しています。Androidではさらにphone/tabletのデバイス軸 × shard軸の二次元matrixを組んで、CI全体の所要時間を短縮しています。

実行環境の高速化 WebではAWS CodeBuildのカスタムランナーを採用し、CI実行時のリソース確保と起動時間の安定化を図っています。Playwrightブラウザのキャッシュも併用し、依存物のダウンロードコストを削減しています。

これらを組み合わせた結果、Webでは300をこえるテストケースが20分前後で完走できるところまで高速化できました。 リリース前検証も、main/releaseブランチへのpush起点のCIも、開発者の手を止めない時間内に収まる現実的なフィードバックループとして機能しています。 速度改善は単独の工夫ではなく、冪等性の担保や環境分離といった設計判断の上に積み上がっているものでもあります。

約350件のテストが18分で完走しています

工夫④ ログそのものをE2Eテストで検証する

冒頭で述べたとおり、TVerのテストには「画面が表示された」だけでは不十分な領域があります。 ユーザーの操作の裏で送信されるログの整合性確認は、サービスの根幹に直結する検証項目です。

これらは画面操作の自動化だけでは検証できません。WebではPlaywrightのpage.on('request')、iOS/AndroidではHTTPAssertionライブラリでHTTPレイヤを傍受し、期待のログが期待のパラメータで送信されたかまでを確認しています。

たとえば計測用ビーコンでは、ログイン状態やプライバシー設定の組み合わせごとに、再生時に送るパラメータが異なるため、検証パターンが必然的に多くなります。
サービス根幹に関わる領域なので確実に見たい一方、マニュアルでは網羅しにくい組み合わせですが、テストの自動化を進めることによって網羅的な検証が可能になりました。
「動画を再生したらビーコンが飛んだ」で終わらず、そのときのプライバシー設定が正しくフラグに反映されているかまで踏み込んで検証する。組み合わせ網羅が必須でありながら手動では担保しにくい領域を、率先して自動テストに置き換えていきました。

工夫⑤ AllureレポートでFail調査のリードタイムを縮める

CIでE2Eを回し始めると、すぐに直面するのが「失敗したテストの原因が、ログだけでは追えない」問題です。 Stack Traceは得られても、どの画面で、何が表示されていて、どのHTTPリクエストが飛んでいたか、これらが分からない限り、実行結果の深掘りに時間がかかります。

そこで、Web/iOS/AndroidのすべてでAllure Reportを導入しました。

Web E2Eテストの実行結果レポート

各OSで生成されたAllureレポートはすべてS3にアップロードし、共通の独自ドメインから配信しています。
Slack通知には毎回レポートURLを貼っており、「落ちた → URLクリック → スクリーンショット・動画・通信ログを確認」という流れが1アクションで完結します。

工夫⑥ マルチブラウザ・マルチデバイスに、必要な分だけ対応する

TVerはWebで複数の主要ブラウザに対応し、iOS/Androidはスマートフォンとタブレットの両方をサポートしています。E2Eテストでこれらを全件 × 全環境で回すと実行時間が膨大になるため、テストの性質に応じて環境を絞る工夫をしています。

WebではPlaywrightのプロジェクト機能を使い、メインスイートはChromiumで、ブラウザ固有挙動が出やすいテストだけをFirefoxやEdgeに振り分けています。 Androidでもアノテーションで「タブレットでも実行するテスト」を明示する仕組みを用意し、CI側でデバイスごとに並列分散しています。

すべてのテストを全環境で走らせるのではなく、必要な検証を必要な環境にだけ届けるという設計判断を行いました。

TVer QA Suite:自動テストでの主な使い方

TVerでは、テスト用の内製ツールTVer QA Suiteを運用しています。 2025年末に公開したukitakaの記事では、Proxyを使ったログ収集と自動検証の仕組みを紹介しましたが、いまは横断的なツール群として実装され、機能拡張が続いています。

仕組みとしては、

  • アプリが叩く外部サーバのURLを、QA SuiteのProxy経由に書き換える
  • リクエスト/レスポンスをS3に記録する
  • 検証ルールをWebUIから登録できる

という構成ですが、自動テストの文脈で現在もっとも活用しているのは、広告サーバーのプロキシ機能です。
QA SuiteのProxyは、テストごとに配信される広告テンプレート(VMAP/VAST)を差し替えることができます。

通常、広告は本物の広告サーバーから配信されるため、テストのたびに広告内容が変わってしまい、E2Eでは再現性のある検証が困難です。QA Suiteを経由させることで、

  • 「このシナリオではCompanion広告を含むパターン」
  • 「このシナリオではVAST Wrapperを経由するパターン」
  • 「このシナリオでは広告なしのパターン」

といったように、再生中の広告挙動をテスト側から制御可能になります。
これにより、本物の広告配信では再現性を担保することが難しかったケースでも、E2Eテストでは同じ条件を繰り返し検証できるようになりました。

取り組みの結果

各プラットフォームの定量的な成果

テスト自動化による成果は、プラットフォームごとに以下の通りです。

プラットフォーム 初期工数 自動化後の工数 削減幅
Web 約8.6人日 3.0人日 約65%
iOS 約4.9人日 2.0人日 約59%
Android 約5.1人日 2.1人日 約59%

TVerという動画配信プラットフォームの性質上、動画再生やライブ配信、UI/UXの体感など、どうしても目視確認を残さざるをえない領域があり、すべてを自動化して実施工数をゼロにすることはできませんでした。

それでも、自動化可能な範囲においては、Web/iOS/Androidのいずれも、リリース前のリグレッションテストの工数を約59〜65%削減し、2〜3人日程度まで抑えられました。
3プラットフォーム合計では約18.6人日から約7.1人日(約62%削減)となり、リリースのたびに約11人日分の工数を他の業務に充てられるようになっています。

リグレッションテストの工数推移

組織全体への波及効果

自動テスト単体の成果だけでなく、組織全体の品質・スピード指標にも変化が出ました。2025年度を通じて、

  • インシデントの発生件数: 約7分の1に減少(昨年比 -86%)
  • リリース頻度: 約2倍に増加(昨年比 194%)

という結果につながっています。もちろんこれはAutomationチーム単独の成果ではなく、全プロダクトチームの取り組みの総体ですが、自動テストによる品質担保とリードタイム短縮の両面から、こうした全社的な改善に貢献できた手応えがあります。

特にリリース頻度の倍増は、冒頭で触れたリリーストレイン運用と表裏一体です。
リリーストレインで「決まった周期に必ずリリースする」運用を成立させるには、毎リリース前のリグレッションテストが短時間で確実に回せることが前提条件になります。
自動化の整備はリリーストレインを下支えするインフラそのものであり、リリースサイクル短縮の実現には欠かせない取り組みでした。

質的な変化

数値以上に大きかったのは、「自動化によって、QAチームの活動そのものが変わった」という質的な変化です。
これまでリリース前の手動検証に多くの工数を割いていましたが、その役割をE2Eテストが肩代わりするようになりました。
これによりQAチームは新規機能のテスト戦略やリスクベースの探索的テストに集中できるようになり、「同じ確認を繰り返す役割」から、「どこに品質リスクがあるかを見極め、よりよい検証戦略を設計する役割」へと変わりました。

これから

私たちが今期より取り組んでいることは、以下の方向性です。

  • CTV(Connected TV)への展開: Linux CTV、ATV/FTVなど、これまで自動化が及んでいなかった領域の自動テスト導入
  • マニュアルテスト工数のさらなる削減: 既存自動テストの安定運用とカバレッジ拡大
  • 業務効率化ツールの内製: 自動化・効率化のための社内ツールを継続的に作成

そして、特に注力しているのが、AIを活用した自動テスト運用です。
E2Eテストは一度導入したらそのまま自走するわけではなく、新たに追加された機能のテスト実装や、テストが落ちたときの一次切り分け、その後の修正対応に依然として人手のコストがかかります。私たちはこの領域をAIで軽減する取り組みを、2つの方向で試験運用しています。

1. Claude Codeによるテストの自動化

E2Eテストの実装には、Claude Codeを使ったAIによる自動テストの実装を検証しています。
自然言語で書かれたテストケースを受け取ったAIが、TVerのドメイン知識やテスト設計手法・技術の知識を持つQAエンジニアスキルと、Page ObjectやE2E環境での実行手順を押さえたE2E実装スキルを併用し、テストコードを実装します。
実装後はテストを実際に動かして動作を確認し、Failするようであれば原因を分析して修正、問題がなければ自動でPR作成まで行います。
自動テストの新規実装はAIに任せ、人間はレビューに集中できる状態を目指しています。

2. Claude Managed AgentによるE2E実行結果の自動切り分けと修正PR作成

また、実行結果の確認、修正などの運用面の自動化を目指して、Claude Platform上で動くAIエージェント、E2E Failure Analyzer & PR Fixerを構築しました。

AIによる実行結果分析と修正

SlackのE2E通知チャンネルを監視し、失敗通知を検知すると、GitHub Actionsのジョブログから失敗テストを特定し、直近のPR・コミット・関連Slackスレッドを横断的に調査して、根本原因を4種類(flaky / 環境問題 / 実装との乖離 / 本物のバグ)に分類します。
修正可能な内容であればDraft PRを自動作成し、元のSlackスレッドに調査結果とPRリンクを返信します。 「Slack通知を見る → 原因を切り分ける → 修正PRを作る」までを、人手を介さずに走らせる仕組みです。

いずれも試験運用フェーズですが、Agentic codingによる開発速度の高速化についていくためには、こうしたAI活用を進めていく必要があると考えています。

まとめ

本稿では、自動化を進めてきた過程と取り組みを紹介させていただきました。
振り返ると、まず戦略の策定・専用環境の整備・既存テストケースの見直しといった準備工程を先に整えてから実装に入ったことが、短期間での大きな工数削減とリリース頻度の改善につながったと感じています。

とはいえ、現状はまだ自動テストの運用を人間が支えているフェーズです。 次のステップとして、その運用までをAIに任せていく「自動テストの自動化」を目指していきます。

最後までお読みいただきありがとうございました。私たちと一緒に「品質と開発スピードを両立する開発組織」を作っていきたい方がいれば、ぜひ採用ページもご覧ください。

TVer Tech Talk(T3)第22回 開催レポート

こんにちは。TVerのサービスプロダクト本部フロントエンド開発部の黒田です。

TVerでは毎月、社内勉強会を開催しています。広告、データ、プロダクト、デザインなど垣根を超えて多くのメンバーが集まります。

TVer Tech Talkを略してT3と呼ばれており、今月も2026年3月27日に第22回が開催されました。

今回もワイワイとした雰囲気の中、各チームの近況共有とテックな発表が行われましたので、その様子をレポートします。

TVer Tech Talk(T3)とは

T3では、サービスプロダクト本部・広告プロダクト本部・プラットフォーム本部・TVer Data Marketingの開発メンバーが一堂に会し、技術・デザイン・プロダクトなど様々なテーマをシェアします。

組織を横断したコミュニケーションを図る取り組みで、普段関わらないチームのことを深く知り、ナレッジも共有できる機会になっています。

サービスプロダクト本部:TVerのtoC向けサービス開発を担当
プラットフォーム本部:配信基盤やID基盤などの開発を担当
広告プロダクト本部:TVer広告システムの開発を担当
TVer Data Marketing データシステム部:データ基盤の開発を担当

毎回運営メンバーがお菓子を用意してくれて、堅苦しくなく気軽に話せる雰囲気を作ってくれています。

T3の様子

今回のスイーツ

第22回のスイーツは 赤坂・浅田家 の和菓子を用意してくれました!
110年以上続く老舗の名店で、評判の品は夕方にはほとんど売り切れてしまうほどの人気ぶり。
餡・餅・豆などがやさしく混ざり合う「豆大福」はファンも多く、この日も大好評でした。

赤坂 浅田家の豆大福

赤坂浅田家 - visit-minato-city.tokyo

各チームの近況トピック

各部門から今月の取り組みの共有や、新メンバーの紹介などが行われます。

サービスプロダクト本部

FY26のミッションとして、
「品質!品質!品質!」「スピード!スピード!スピード!」「洗練!洗練!洗練!」
を掲げています。
FY25から「品質」と「スピード」は引き続き大切にしつつ、今期は新たに「洗練」が加わり、よりプロダクトを磨き込んでいくテーマになっています。

この日は検証環境のアップデートや、各施策のリリース状況、社内で利用しているAI botツールの紹介がありました。

また、開発ディレクション部からは、TVerにおける「当たり前の品質」に基づいてエージェントが自動でコードレビューを行うGitHub Appを実装・運用開始したという紹介がありました。

バックエンド開発部の発表
フロントエンド開発部の発表
開発ディレクション部の発表

広告プロダクト本部

広告プロダクト本部からは、TVer 広告の機能のアップデートなど、リリース情報の共有がありました。

T3の様子

TVer Data Marketing(TDM)データシステム部

TVer Data Marketing(TDM)データシステム部からは、コスト削減への取り組みや、多岐にわたる分析業務の進捗共有がありました。

T3の様子

発表セッション

「データシステム運用の面倒なこと」

TDM データシステム部からの発表でした。
データシステムの日常的な運用で発生する課題や、それに対する取り組みについて紹介いただきました。

TDMの発表

「デザインにおけるAI活用」

サービス事業本部 サービス推進部からの発表でした。
デザイン領域でのAI活用事例や、実際の業務でどのように取り入れているかを具体的に紹介いただきました。

デザイナーチームの発表

おわりに

T3は毎月開催しており、組織横断でエンジニアやデザイナーがフラットに話せる場として定着してきています。
お菓子をつまみながらワイワイと情報交換できるこの時間が、チームの垣根を越えたつながりを生んでいると感じています。
TVerの開発現場の雰囲気が少しでも伝わっていれば嬉しいです。次回もお楽しみに!

Regional Scrum Gathering Tokyo 2026 参加レポート

はじめに

サービスプロダクト本部フロントエンド開発部に所属している中谷です。スクラム・アジャイル開発のカンファレンス「Regional Scrum Gathering Tokyo (RSGT) 2026」に参加してきました。テーマはスクラムですが、エンジニアリング全般に通じる視点や学びを多くのセッションから得ることができました。印象に残ったセッションの内容とそこから得た学びを、当日のメモをもとにレポートします。

キーノートセッション

An introduction to Beyond Budgeting – Business agility in practice

脱予算経営に関する発表で、かつて発明された予算管理を慣習のまま使い続けていることへの問題提起でした。

従来の予算管理が抱える問題

従来型のマネジメントは人は信用できない、人と未来をコントロールできるという前提に基づいていますが、これは幻想です。

マネジメントと呼ばれるもののほとんどは、人々の仕事をしにくくするものである ── ピーター・ドラッカー

従来の予算策定がもたらす弊害は深刻です。

  • 策定コスト:策定自体に膨大な時間がかかる
  • 前提の陳腐化:1年前の前提は現時点と異なる
  • 非倫理行動の誘発:目標の低設定、リソースの囲い込み
  • 意思決定タイミングの悪さ:遅すぎる、あるいは早すぎる
  • 使わなければ損という意識の発生
  • パフォーマンスの誤解:予算達成=良い業績という短絡的な評価

信号機 vs ラウンドアバウト

こちらの比喩が秀逸でした。

観点 信号機(従来型) ラウンドアバウト(脱予算型)
コントロール 過去にプログラムした人 運転しているドライバー
情報 過去データ 今この瞬間の情報
前提 ドライバーを信頼せず、ルールで縛る ドライバー同士を信頼し、協調して意思決定する

脱予算経営の実践事例

  • Handelsbanken(銀行):財務的な予算・目標を外し、支店の自律性を優先。個人ボーナスを廃止し支店ボーナスに変更。指標は「他の銀行よりも良いこと」
  • Roche(製薬):出張費を予算なしで運用。同僚の出張情報(行き先、宿泊先、食事等)をすべて透明化。結果として出張費用は下がった
  • Miles:PC・カンファレンス・トレーニングの予算をなくし、何を学んだか・何に使ったかの投稿を義務化。透明性をコントロールとして活用

なぜ予算を立てるのかに立ち戻ることも含め、エンジニアリング組織にも通じる示唆に富んだ内容でした。「変化をいきなり全部する(ルールをなくす)のではなく、ルールを減らすことが最初の一歩」という言葉が印象的でした。

From Frameworks to Substrate: Rewilding Agile to Work at Scale - フレームワークから土壌へ:アジャイルを野生に戻して大規模で機能させる

アジャイルの「家畜化」が弱体化をもたらしたと指摘するセッションでした。内容は難解でしたが、複雑性への対応に関するアプローチが発表されていました。

本来のアジャイルは高い弾力性を持ち環境に適応するものでしたが、現代のアジャイルは「創始者の経験に基づく構造化されたレシピの集合体」になってしまっています。

家畜化がもたらした弊害

  • レシピ本の信者:シェフにならず、レシピ本だけを欲する
  • 認定ビジネスの蔓延:10年かかるクラフトマンシップが軽視され、短期間でマスターを乱発
  • 成功の安易な模倣:有名なモデルの表面だけを真似するが、出発点が違うため機能しない
  • 相関と因果の混同:チョコレートの消費量とノーベル賞の受賞数には相関があるが因果はない。アジャイルの成功事例も同様

非注意性盲目の実験

放射線科医にX線写真の異常を見つけるよう依頼する実験で、写真に紛れ込ませたゴリラの画像に83%の医師が気づかなかったという結果が紹介されました。人は予期しないものを見ないようにできています。正しい情報と正しい判断材料を与えても、正しい判断ができるとは限りません。

クネビンフレームワークとスクラムの限界

スクラムは本質的に、ジャングル(complex)を整地された公園(complicated)のように構造化して管理しようとするアプローチです。しかしcomplexの因果関係は後からしかわからず、成功事例は無数の可能性から生まれた偶然の産物の一つに過ぎません。学ぶべきは成功事例ではなく、失敗の中にある学びの物語だという言葉が刺さりました。

  • 犬:秩序を好み、従順
  • 猫:複雑性を理解し、暖かさと食べ物を受け入れても、自由は決して手放さない

みなさん自由は決して手放さない猫になりましょう!

登壇資料

https://speakerdeck.com/julesyim/rsgt2026-dave-snowden-keynote

トークセッション

デイリースクラム DeepDive

デイリースクラムについて改めて整理するセッションでした。

デイリースクラムは朝会ではありません。 スプリントゴールに向けた検査をする場であり、オーナーシップは開発者にあります。

重要なポイント:

  • スプリントゴールこそがスプリントの唯一の目的であり、最大の関心事は「スプリントゴールを達成できるか?」だけ
  • タイムボックス(15分)は必ず守る。終わらないのはやり方が悪い
  • 問題の存在確認と方針に留め、詳細はデイリースクラムの外で話す

やり方としては3つの型が紹介されました。

  1. 古典的な3つの質問(ゴール達成への言及がないため構造上問題がある)
  2. PBI by PBI:プロダクトバックログアイテムを1つずつ眺め、進捗・障害を共有する
  3. スプリントゴールチェックイン:「このままいけば達成できそうか?」と問いかけ、懸念があれば次の24時間のアクションを話す

登壇資料

https://slide.meguro.ryuzee.com/slides/132

よくわからないことが多い場合の計画づくりのコツ

不確実性が高い状況での計画づくりについてのセッションです。

わからないには種類があるという整理がされました。既知の既知、既知の未知、未知の未知。そして大切なのは以下のマインドセットです。

  • 最初から完璧なものは無理と認識する
  • 計画通りではない場合、計画が間違っていただけ
  • 計画通りが良いとは限らない
  • わかったふりをしない

計画では、ゴール、マイルストーン、想定しやすい短い期間(1〜2週間)の詳細な計画を立てます。計画することでわからなかったものがわかるようになり、小さく少しずつアップデートしながら継続的に計画し続けることが重要です。この辺りは何となく進めてきた経験があり、今後は意識して取り組みたいと思いました。

登壇資料

https://www.docswell.com/s/yohhatu/KN9YYL-2026-01-07-084924

EBM実践のカタ —— 実践とゴールと計測を結びつけるアジャイルのありたい姿へ

EBM(Evidence-Based Management)は、不確実な状況下で価値を提供し続けるためのフレームワークで、スクラム同様、透明性・検査・適応のサイクルで実行します。

  • 3つのゴール:戦略的ゴール・中間ゴール・即時戦略ゴール
  • 計測:市場価値と組織的な能力(反応性・効果性)の2種類のアウトカムを確認
  • 実験:短期のゴールに集中し、計画を実験に置き換え、常に仮説を検証

EBMの原則は明快です。

  • 小さく投資し、損失を回避
  • 実験は包括的な計画に勝る
  • 一度に作るものを少なくし、フィードバックを早く得る
  • 顧客価値の最大化を第一とする

登壇資料

https://www.docswell.com/s/nagasawa/59MXXJ-EBM-practical-kata

自己管理型チームの一員となるためのセルフマネジメント:モチベーション編

スクラムチームは自己管理型であり、誰が・いつ・どのように行うかをチームで決定します。そしてモチベーションが自律と行動を生みます。

自分のモチベーションの源泉を理解するためのフレームワークが紹介されました。

<自分のRole・役割>として、<キャリア・タスク(what)>を達成したい。それは<自分にとっての価値(why)>のためだ

適切なモチベーションの引き出し方は人それぞれ(挑戦・報酬・達成・貢献など)であり、ゴールとの関係性で働きかけを変えるべきだという内容でした。また、モチベーションを失ったときには物理的・認知的・心理的フリクション(ステップが多い作業、Slackの通知音、不安感など)と向き合うことが大切だという点も非常に参考になりました。

登壇資料

https://speakerdeck.com/kakehashi/management-yourself-and-your-team

QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する

コード変更からリリースまでが最短12日かかっていたという課題に対して、QAフローを見直した実践事例です。

取り組みのポイント:

  1. 事業コア価値を理解して達成したい品質水準を決める
  2. 開発フローの制約条件を理解する
  3. 上記を満たすQAフローを設計する
  4. QAと一緒にリグレッションテストケースを決め直す
  5. 移行計画を作り、移行していく

結果として、障害件数は変わらずリリース期間を12日から6日に短縮し、QA負荷も削減できたとのことでした。品質を落とさずにスピードを上げた好事例でした。

登壇資料

https://speakerdeck.com/shibayu36/optimize-qa-workflow

ワークショップ

「ふりかえり手法を試そう!」で始める3桁人のギャザリング体験~初めましての人あつまれ!~

チームをシャッフルしながら、4つの振り返り手法を体験するワークショップでした。

私が体験した手法:

  • +/Δ(プラス・デルタ)
  • 闇鍋
  • 象 死んだ魚 嘔吐
  • 露天風呂

さまざまなバックグラウンドを持つ方々と振り返りを実践できたのは貴重な経験でした。

さっそく実務での振り返りで、共有いただいたふりかえりカタログにあるセレブレーショングリッドという手法を取り入れてみました。これは縦軸に「成功/失敗」、横軸に「実験/ベストプラクティス」を取り、取り組みを4象限にマッピングする手法です。普段の振り返りでは良かったこと、改善点という二軸で考えがちですが、この手法では実験的に動いたのか・すでに知っていたことなのかから、どうだったのかまで掘り下げられるのが新鮮でした。

セレブレーショングリッドによる振り返り

チームからもいつもの固定した振り返りの観点とは違う個々の振り返りにフォーカスして書くことができたという意見がありました。固定の振り返り手法を使い続けるのではなく、状況やチームの状態に合わせて手法を変えてみるのも効果的だと実感したので、今後も積極的に活用していきたいです。

まとめ

RSGT 2026を通じて得た学びを振り返ると、共通して以下の点がありました。

  1. 信頼と自律:根底にあるのは「人を信頼し、自律を促す」という考え方
  2. レシピではなくシェフになれ:フレームワークやプラクティスをそのまま適用するのではなく、文脈を理解して適応させる
  3. 失敗から学ぶ:成功事例の模倣ではなく、失敗の中にある学びの物語から進化する
  4. 継続的な実験と適応:完璧な計画を立てるのではなく、小さく実験し、フィードバックから学び続ける
  5. 透明性がコントロールに代わる:ルールで縛るのではなく、透明性を高めることで自己調整を促す

スクラムやアジャイルに限らず、ソフトウェア開発組織のマネジメント全般に適用できる示唆に富んだカンファレンスでした。来年もぜひ参加したいと思います。

エージェンティック広告が変える広告の未来 - 技術標準と実装事例から見る業界変革

はじめに

こんにちは。広告プロダクト担当の大野です。

去年あたりから、アドテク界隈でエージェンティック広告(Agentic Advertising)に関する話題が急速に盛り上がっています。IAB Tech LabがAAMP(Agentic Ad Management Protocols)という包括的なイニシアチブのもと、ARTF(Agentic Real Time Framework)などの業界標準仕様の策定を進めているほか、Amazon AdsGoogle AdsがMCP(Model Context Protocol)を活用したAIエージェント機能の提供を開始するなど、広告の新しいトレンドとして注目を集めています。

毎週のように様々なエージェンティック広告に関するアップデートがあるので、現状の動向の個人的な整理をかねて、この記事を書くことにしました。

エージェンティック広告がここまで盛り上がっているのは、当然ながら昨今のLLMの進化と、それによる技術革新が、様々な分野において、AIが人間の業務を代替できるという実績がでてきているからです。 広告業界においても広告運用やメディアプランニング、見積もりなどの作業は労働集約的な要素がまだ多く残っている状況です。

私も長年プログラマティック広告などの運用型広告に関連した仕事に携わっており、常々労働集約的な部分、専門性が高い部分の効率化や品質の再現性をどうするかというところは課題感をもっていました。

そんな中、AI技術の進化により、エージェンティック広告という新しいアプローチが、広告の運用や広告の未来を大きく変えそうな雰囲気をビシビシ感じています。

前置きが長くなりましたが、この記事では、AgenticAdvertising.orgによるAdCP(Ad Context Protocol)や、IAB Tech LabによるAAMPなどのエージェンティック広告を支える技術標準や最新事例を交えながら、エージェンティック広告の技術的なアーキテクチャ、従来手法との違い、現状の活用トレンド、今後の展望について解説したいと思います。

エージェンティック広告とは

エージェンティック広告(Agentic Advertising)とは、AIエージェントが広告のプランニング、バイイング、クリエイティブ最適化、効果測定といった一連の業務を自律的に判断・実行するアプローチを指します。ここでいう「エージェント(Agent)」は、単なる自動化ツールではなく、目標を与えられたら自ら状況を分析し、最適な行動を選択・実行できるAIシステムを意味します。この辺りがこれまでの人の作業のルール化を中心とした自動化と大きく異なります。

従来の自動化との違い

これまでも広告業界では、様々な自動化手法が取り入れられてきましたが、従来の自動化手法とエージェンティック広告には明確な違いがあります。

従来の自動化アプローチ: - ルールベース自動化: 人間が事前に設定したルール(例:「CTRが1%以下なら入札停止」)に従って機械的に実行 - 機械学習ベース最適化: 過去データから学習し、予測モデルに基づいて入札額やターゲティングを調整

エージェンティック広告の特徴

  • 自律的な判断: 状況に応じてAIが柔軟に判断
  • マルチステップの実行: 単一タスクではなく、複数の業務プロセスを連携して実行
  • 自然言語での指示:「新製品の認知度を高めたい」といった抽象的な目標から、具体的な施策を設計
  • 継続的な学習と改善: 実行結果をフィードバックし、次の判断に活かす

例えば、従来の自動入札では「CVRを最大化する」という目標に対して入札額を調整するだけです。一方、エージェンティック広告では「新製品の認知拡大」という目標に対し、ターゲット設定、メディア選定、クリエイティブ案の提示、配信スケジュール最適化まで一貫して提案・実行できます。特に後述するMCPやAdCPなどの登場により、AIエージェントが複数のメディアの情報を横断的に取得し、プランニングをするなど、これまで人間が担っていた業務をAIが自律的に行うことが可能になってきています。

広告領域での位置づけ

エージェンティック広告は、広告業務の以下の領域で活用が進んでいます:

  • プランニング: キャンペーン設計、メディアプラン策定、予算配分
  • バイイング: 媒体選定、入札戦略、在庫管理
  • クリエイティブ最適化: 広告素材の生成、A/Bテスト設計、パーソナライゼーション
  • 効果測定と分析: アトリビューション分析、レポート作成、改善提案

広告技術仕様を策定しているIAB Tech Labは、これらの領域における標準化や、既存の広告配信システム(DSP、SSP、DMPなど)とのスムーズな連携を可能にする技術仕様の策定を進めています。

技術的アーキテクチャ

エージェンティック広告は、複数の技術要素が組み合わさることで実現されています。ここでは、主要な技術要素について解説します。

主要な技術要素

1. LLMベースの意思決定エンジンとMCP統合

大規模言語モデル(LLM)を活用することで、自然言語での指示を理解し、複雑な広告戦略に変換します。GoogleやAmazonは、MCP(Model Context Protocol)を採用し、LLMやAIエージェントと広告APIをシームレスに統合する仕組みを提供しています。

Google Ads MCP: - Google Ads APIとLLM/エージェントを統合 - 自然言語でのキャンペーン情報取得や設定変更が可能 - GitHubでオープンソースとして公開され、開発者が自由に活用可能

Amazon Ads MCP: - Amazon Advertising APIへのプログラムアクセスを提供 - LLM/AIエージェントと広告APIの統合を実現 - オープンベータ版として提供開始

2. マルチエージェント協調

単一のAIエージェントではなく、複数の専門エージェントが協調して動作する仕組みが採用されています。

エージェント 役割
プランニングエージェント キャンペーン全体の戦略を設計
クリエイティブエージェント 広告素材の生成と最適化
バイイングエージェント 入札戦略の実行と調整
アナリティクスエージェント 効果測定と改善提案

3. 既存システムとの連携

エージェンティック広告は、既存の広告配信エコシステムと統合される形で実装されています。IAB Tech Labは、OpenRTB(リアルタイム入札)、AdCOM(広告コモンオブジェクトモデル)、OpenDirect(予約型広告取引)といった既存の広告取引標準と、MCP、Agent2Agent(A2A)、gRPCなどの現代的なプロトコルを統合する仕様を策定しています。

これにより、エージェンティック広告は以下のような既存システムとシームレスな連携が可能になります: - プログラマティック広告の入札・配信プラットフォーム - オーディエンスデータ管理システム - 広告効果測定ツール - クリエイティブ管理システム

4. AdCP(Ad Context Protocol)

Ad Context Protocol(AdCP)は、AgenticAdvertising.orgが策定するオープンスタンダード(Apache 2.0ライセンス)で、AIエージェントが複数の広告プラットフォームを横断して、キャンペーン管理・クリエイティブ生成・オーディエンス活用を単一インターフェースで実行できるようにするためのプロトコルです。IAB Tech LabのAAMPとは別のイニシアチブですが、いずれもエージェンティック広告のエコシステムを支える標準として相互補完的な関係にあります。

主な役割

機能 説明
コンテキスト情報の標準化 ページコンテンツ、ユーザー行動、配信環境などの情報を標準フォーマットで提供
リアルタイム情報交換 AIエージェント間でコンテキスト情報を迅速に共有
プライバシー配慮 ユーザープライバシーを保護しながら、必要な情報のみを提供

AdCPにより、AIエージェントは配信先の文脈を深く理解し、より適切な広告配信判断が可能になります。例えば、ニュース記事のトーン、動画コンテンツのジャンル、ユーザーの関心領域などを考慮した配信最適化が実現します。

IAB Tech Labによる標準化の動き:AAMPイニシアチブ

エージェンティック広告の普及、課題解決のため、IAB Tech Labは、AAMP(Agentic Ad Management Protocols)という包括的なイニシアチブを立ち上げました。

AAMPは単一の仕様ではなく、エージェンティック広告のエコシステムを支える以下の「3つの柱」で構成されています。

1. 実行基盤(Delivery and Execution control plane)

AIエージェントが広告システム内で安全かつ確実、そして高速に動作するための実行環境を定義します。

  • ARTF(Agentic Real Time Framework):
    • コンテナベースのエージェント実行環境を定義
    • リアルタイム入札(RTB)環境での遅延を大幅に削減(最大90%削減)
    • MCP(Model Context Protocol)インターフェースを内蔵し、本番環境での実行能力を確保

2. 管理プロトコル(Agentic Protocols)

エージェント間や広告主・各プラットフォーム間での交渉、取引、情報交換のためのスキーマやツールを定義します。

  • Agentic Audiences (旧 User Context Protocol): リアルタイムの意図信号とアイデンティティ情報の交換標準
  • Agentic Direct: 予約型広告取引(OpenDirectベース)のエージェント対応
  • Agentic Mobile: モバイルアプリエコシステムにおけるエージェントワークフロー
  • Agentic Ad Objects: 広告共通オブジェクトモデル(AdCOM)から派生したエージェント用オブジェクト定義

また、エージェント間の直接通信を可能にするAgent2Agent(A2A)プロトコルなどもこのレイヤーに含まれます。

3. 信頼と透明性:Agent Registry

エージェントの中立的な透明性と説明責任を確保するための基盤です。

  • Tech Lab Agent Registry: エージェントのアイデンティティ、検証結果、情報の開示状況などを登録・公開する仕組み。これにより、取引相手が「誰(あるいは何)」であるかを確実に把握できるようになります。

これらの3つの柱は、相互に補完し合うように設計されています。実行基盤がなければスケールせず、共有標準がなければ実行基盤は意味をなさず、そして信頼がなければエコシステム全体が不透明なものになってしまうからです。

従来の広告配信システムとの違い

従来のプログラマティック広告では、人間が戦略を立て、システムが実行するという役割分担でした。一方、エージェンティック広告では、AIエージェントが戦略立案から実行、検証、改善までを一貫して担います。

項目 従来のアプローチ エージェンティックアプローチ
戦略立案 人間が担当 AIエージェントが担当
実行 システムが自動実行 AIエージェントが自律実行
分析 人間が分析 AIエージェントが分析
改善 人間が改善策を検討 AIエージェントが改善策を実行
人間の主な役割 オペレーター(戦略立案・分析・改善) 監督者・意思決定者(目標設定・承認・監督)

人間の役割は、オペレーターから監督者・意思決定者へとシフトします。

現状の活用事例とトレンド

エージェンティック広告の具体的な活用例として、クロスメディアプランニングの領域での実装が進んでいます。

AdCPを活用したクロスメディアプランニング

Ad Context Protocol(AdCP)への対応が、Yahoo、PubMatic、Magniteなどの主要プラットフォームや、Scope3、Samba TVなどのデータプロバイダーを含む複数のベンダーで進んでいます。これらは、AdCPを通じて各メディアのコンテキスト情報を統合的に把握し、最適な広告配信戦略を自動で立案します。

主な機能

  • 予算配分の最適化: テレビ(地上波・CTV)、デジタル(ディスプレイ・動画・SNS)間での最適な予算配分を、コンテキスト情報に基づいて自動計算
  • リーチ重複の排除: 複数メディアでの重複リーチを考慮し、効率的なフリークエンシー管理
  • コンテキスト連動配信: 各メディアのコンテンツ特性に応じた最適なクリエイティブとタイミングで配信
  • アトリビューション分析: 各メディアの貢献度を測定し、次回キャンペーンの戦略に反映

従来、広告代理店の担当者がExcelで手作業で行っていたメディアプランニング業務が、AdCPによるコンテキスト情報の自動収集・分析により、スピーディーに完了するようになってきています。

IAB Tech LabのARTF(Agentic Real Time Framework)

ARTF(Agentic Real Time Framework)は、前述のAAMPイニシアチブの実行基盤として策定が進められています。現在想定される主な活用領域は以下の通りです。

活用領域: - アイデンティティ解決(Identity Resolution) - ディール活性化(Deal Activation) - セグメンテーション - インプレッション前の不正検知

ARTFは2026年1月に公開コメント期間を終了し、現在最終化の準備が進められています。バージョン2.0の開発も既に進行しており、エージェンティック広告のインフラとして業界標準となることが期待されています。ご興味のある方はARTFのページをご確認ください。

NBCUniversalのプレミアム動画買付自動化

NBCUniversalは、RPA、FreeWheel、Newton Researchとのパートナーシップにより、エージェンティックAIを使用したプレミアム動画買付の革新的なアプローチを導入しました。

主な特徴

  • リニア・デジタル統合買付: リニアテレビとデジタルプラットフォーム全体にわたり、秒単位でプレミアム動画に投資し最適化
  • ライブスポーツへの適用: 2026年Q1のライブフットボールプレーオフゲームなどのプレミアム枠を対象に実装
  • 業界初の取り組み: AIエージェントがリニアテレビ上でライブスポーツインベントリを自動化するのは初めての事例

この取り組みが今年のCESで発表されたことが、個人的にはエージェンティック広告への興味を引くきっかけになったほど、大きなインパクトがありました。

従来の広告運用との比較

エージェンティック広告は、従来の広告運用と比較して多くのメリットをもたらす一方で、新たな課題も生じています。

観点 従来の広告運用 エージェンティック広告
最適化作業 担当者が手動で入札調整・A/Bテスト・レポート作成 AIが自動実行。大規模運用でも高い一貫性を維持
意思決定スピード 日次・週次でデータ確認後、人間が判断・設定変更 24時間365日リアルタイムに監視・最適化
担当者の役割 定型業務(入札・レポート)中心。戦略業務は一部 監督・承認・戦略業務が中心。定型業務は一部
最終意思決定 人間がすべての判断を担当 大規模予算変更・ブランド判断など重要事項は人間が承認必須
データ依存度 担当者の経験・判断でカバー可能 データ品質に大きく依存。ガバナンス整備が必要
判断の透明性 担当者の意図・根拠が明確 ブラックボックス化リスクあり。可視化・監査機能の整備が必要
導入コスト 既存スキルで運用可能 プロンプト設計・AI監督など新スキル習得が必要

今後の展望と課題

エージェンティック広告は発展途上の技術領域であり、今後数年で大きく進化すると予想されます。

短期的な展望(1-2年)

Google、Amazon、Metaなどの主要プラットフォームでエージェント機能や様々なAI機能の統合が進み、中小規模の広告主でも専門知識なしに高度な広告運用が可能になっていくでしょう。 特に、メディアプランニング、運用、レポーティングなど定型的な業務プロセスでの自動化が加速し、広告代理店の役割で運用代行部分のウェイトが減り、戦略コンサルティングなどの部分に役割のウェイトがシフトしていくことが予想されます。

中長期的な展望(3-5年)

テレビ(地上波・CTV)、デジタル、OOHなどあらゆるメディアを統合したクロスメディアプランニングや広告運用の自動化、クリエイティブ制作の自動化が進展すると予想されます。動画広告の自動生成やブランドトーンの学習による一貫性のある広告制作が実現し、AIによる映像認識技術を活用したショッパブル広告、インタラクティブ広告などの新フォーマットが普及するでしょう。

業界全体への影響

スキルセットの変化

広告運用担当者に求められるスキルが、プラットフォーム操作やデータ集計から、AIエージェントへの適切な指示設計(プロンプトエンジニアリング)、戦略立案、AIの判断監督・評価へと変化します。AIエージェント監督者やエージェント戦略設計者など、新しい職種が登場する可能性もあります。

ガバナンスの重要性

AIエージェントが自律的に広告配信を行う環境では、AIの判断根拠の可視化、バイアス排除、プライバシー保護、監査体制の確立など、透明性と説明責任の確保が不可欠です。IAB Tech Labの標準化やガバナンスフレームワークが、業界共通の指針として重要な役割を果たすことが期待されます。

エージェンティック広告への対応

広告プラットフォームやメディアはエージェンティックAIへの対応をしないと、広告プランニングに入らないというような状況が生まれる可能性もあります。

まとめ

エージェンティック広告は、AIエージェントが広告のプランニングから配信、最適化、分析までを自律的に実行する新しいアプローチです。IAB Tech Labによる標準化の推進や、Google、Amazonなどの主要プラットフォームでの実装により、業界全体での普及が進んでいます。

従来のルールベースやデータドリブンな自動化とは異なり、エージェンティック広告では、AIが状況に応じて柔軟に判断し、複数の業務プロセスを統合的に実行できる点が大きな特徴です。これにより、広告運用の複雑化へ対応しつつ、人間はより戦略的・クリエイティブな業務に集中できるようになります。

一方で、AIの判断に対する透明性の確保、プライバシー保護、人間による適切な監督など、解決すべき課題も残されています。IAB Tech LabのガバナンスフレームワークやAPI標準化の取り組みや、国内においてもエージェンティック広告に関するルールづくりの整備は今後徐々に進んでいくと思います。

なお、まだ部分的な利用が多いですが、TVerでの広告開発や運用業務において、AIを活用したことによる恩恵を日々実感しています。(Claude Codeとの対話時間が爆増しています) TVerとしても、広告運用の効率化や高度化、広告価値向上において、MCPやA2Aなどを活用したエージェンティック広告の可能性を探っていく価値があると考えています。特にプランニング、運用、レポーティングなど、人がやるとどうしても煩雑になりがちな業務においては、AIエージェントの導入は有力な選択肢となると考えています。少しずつですが、出来る部分から検討を進めています。

またNBCUniversalから発表された内容のように、放送と配信の広告をAI技術の活用により、再構築していくことを目指しているところは、TVerの広告にとっても考えていくべきだと感じています。

エージェンティック広告は、まだ発展途上の技術領域ですが、今後数年で広告業界の標準的な手法となる可能性が高いと感じています。業界全体としても、技術の進化を注視しつつ、透明性とガバナンスを確保した形での導入を進めることが重要だと言えます。

そんな変化の激しい広告業界ですが、TVerの広告プロダクト開発チームでは一緒に広告プロダクトを開発するメンバーを絶賛募集中です。もちろん広告以外のエンジニアポジションも募集中です。AIなどの新しい技術を活用した広告プロダクト開発に興味のある方は、是非ご検討ください。

ご興味のある方は、是非弊社採用サイトをご確認ください。

前提知識ゼロでもAIで乗り切った!大規模プロジェクトでのClaude Code活用術

こんにちは、TVerでiOSエンジニアを担当している福島(@mantaroufire)です。

今回は、ある大規模プロジェクトにおいて、前提知識がほぼない状態から途中参画し、AIを活用してバグ修正を効率的に進めた経験についてご紹介します。

大規模プロジェクトへの途中参画

TVerでは、ボリュームの大きな機能の開発プロジェクトが進行していました。私が参画したのは、一通りの実装が完了し、不具合解消フェーズに入ったタイミングでした。

つまり、プロジェクト固有の要件・仕様や、細かい実装アプローチをほとんど把握していない状態からのスタートです。

通常であれば、まずコードを読み込んでキャッチアップに時間をかけるところですが、リリースまでの時間は限られています。そこで活用したのが、Claude Codeスキルでした。

Claude Codeのスキルとは

Claude Codeには、特定のタスクに特化した「スキル」を自作できる機能があります。プロジェクト固有の作業手順をスキルとして定義しておくことで、誰でも同じ品質・同じ手順で作業を進められるようになります。

今回のプロジェクトでは、以下の3つのスキルを順番に使うワークフローが活躍しました。

/analyze-and-create-issues → /implement-issue → /create-pr

不具合の分析からPR作成まで、一連の流れをスキルで標準化しています。

TVerでは不具合管理にGitHub Issueを活用しています。Claude Codeはターミナル操作も自律的に行えるため、GitHub Issueを中心としたワークフローとの相性が良く、ghコマンド(GitHub CLI)を使ったIssue作成・PR作成や、他リポジトリの探索も実行してくれます。これにより、調査から実装・PR作成までをシームレスに進められます。もちろん実行前に承認を求めてくれるので、内容を確認しながら対話的に進められます。

各スキルの紹介

1. /analyze-and-create-issues - 不具合の分析とIssue作成

QAチームから報告された不具合Issueをインプットとして、以下を自動で行います。

実行内容

  • 不具合Issueの内容を読み取り、問題を分析
  • 現在のソースコードを調査し、原因を特定
  • 調査結果と修正方針をまとめたIssueを作成

対話例

👤:

/analyze-and-create-issues

🤖:

案件分析を開始します。まず、インプット情報を収集させてください。

issueのURLまたは番号を教えてください

👤:

QAから報告されたこのIssueを見て(不具合IssueのURLを共有)

🤖:

不具合Issueを確認しました。特集画面で一部エリアのレイアウトが崩れている問題ですね。

調査の参考になる補足情報があれば教えてください。(任意・スキップ可)

例:実装対象のファイルパス、参考にすべき既存実装、その他の補足情報など

👤:

Androidではどう実装されているか確認してほしい

🤖:

承知しました。Androidリポジトリも含めて調査します。(ソースコード・Androidリポジトリを調査)

調査が完了しました。XXXXXViewでアイコンの表示条件に問題がありそうです。

Android側と比較したところ、iOS側のフィルタリング条件が仕様と異なっていました。Android実装に合わせる形で修正するのが良さそうです。

以下のIssue分割案で進めてよろしいですか?

👤:

OK、Android比較の結果もIssueに含めて作成して

🤖:

承知しました。Android実装との比較を含めたIssueを作成します。(Issueを作成)

Issue #7017 を作成しました。


作成されるIssueの例:

Issueには、概要・背景・調査結果・影響範囲・参考コード・関連リンクなどが詳細に記載されます。

このように、スキルが対話形式で情報を収集してくれるので、途中で「Androidの実装を確認して」といった追加の依頼を挟みながら、より精度の高いアウトプットを得ることができます。

2. /implement-issue - Issueに基づく実装

前のスキルで作成したIssueをインプットとして、実装を行います。

実行内容

  • Issueの調査結果や方針を読み取り、具体的な実装方針を策定
  • 採用アーキテクチャに沿った設計で実装
  • ビルド確認
  • コミット作成

対話例

👤:

/implement-issue #7017

🤖:

Issue #7017 の内容を確認し、実装を進めます。

(実装を進める)

実装が完了しました。ビルドも通っています。


Issueに「影響範囲」「参考コード」が詳細に記載されているため、AIはそれをもとに実装方針を固めて進められます。実装後はセルフレビューを行い、違和感があれば対話で修正します。

3. /create-pr - PR作成

実装が完了したら、PRを作成します。

実行内容

  • 変更内容の分析
  • Android実装との比較表の作成
  • Before/Afterの整理
  • PR本文の生成

対話例

👤:

/create-pr

🤖:

PRを作成します。Android実装との比較表も含めます。(PRを作成)

PR #7021 を作成しました。


作成されるPRの例:

このように、レビュワーが「なぜこの修正が正しいのか」を判断できる情報がPRに詰め込まれています。特にAndroid実装との比較表があることで、修正の妥当性を客観的に確認できます。

バグ修正とAIの相性の良さ

今回の経験を通じて、バグ修正はAI活用と非常に相性が良いと感じました。その理由は以下の通りです。

1. 期待値が明確

新機能開発と異なり、バグ修正には「正しい動作」という明確なゴールがあります。仕様書、Android実装など、参照できる情報源が多いため、AIが判断に迷う余地が少ないです。

2. スコープが限定的

バグ修正は影響範囲が比較的小さく、1つのPRで完結することが多いです。AIにとって扱いやすいタスクサイズです。

3. 調査の自動化

人間が複数のリポジトリやドキュメントを行き来して調査するのは時間がかかりますが、AIなら高速に横断的な調査ができます。

プロンプトの工夫

スキルを作成する際に工夫した点をいくつかご紹介します。

1. 対話形式での情報収集

必要な情報を一度に全て聞くのではなく、1つずつ質問して回答を得てから次へ進む設計にしました。これにより、ユーザーが何を入力すればいいか迷わずに済みます。また、やりとりの粒度を小さくすることで、AIが情報を見落としにくくなる効果もあります。

2. 段階的なアプローチ

Issue分割案を提示する際は、まず概要を提示して承認を得てから詳細を出力するようにしました。これにより、方向性の確認が早い段階でできるため、手戻りを防止できます。

3. 補足情報の任意収集

ファイルパスや用語説明など、調査を効率化するための補足情報を任意で収集するステップを設けました。人間側が持っている情報をAIに渡すことで、調査精度が上がります。

まとめ

私と同様に途中からプロジェクトに参画したメンバーにも、これらのスキルを使ってもらいました。

前提知識がない状態でプロジェクトに途中参画するのは不安なものですが、スキルで作業手順を標準化しておくことで、キャッチアップの時間を大幅に短縮できました。「どこまで調査すればいいか」「PRにはどんな情報を含めるべきか」といった属人的なノウハウがスキルに集約されているため、プロジェクトの背景を知らなくても一定品質のアウトプットを出せます。

結果として、無事にプロジェクトのリリースを迎えることができました


さいごに

TVerでは一緒に働く仲間を募集しています。AIを活用した開発や、大規模プロジェクトへの対応など、チャレンジングな環境で一緒に働きませんか?

カジュアル面談も受け付けていますので、少しでも気になった方はお気軽にご連絡ください!

recruit.tver.co.jp

混合負の二項分布による広告フリークエンシー分布の推定

こんにちは。TVer の広告事業領域でデータサイエンティストをしている川井です。普段は TVer 広告の配信システムの開発や、広告効果分析、データ基盤構築などを担当しています。

ストリーミング広告の配信において、「誰に何回広告が届いたか」を把握することは非常に重要です。同じユーザーに繰り返し広告が届くよりも、まだ届いていないユーザーに届けたい——そうしたニーズに応えるには、広告接触回数の分布構造を理解する必要があります。

以前の記事「負の二項分布でストリーミング広告のリーチを予測してみた」では、リーチカーブに直接フィットさせるアプローチを紹介しました。今回は別のアプローチとして、フリークエンシー分布(広告接触回数の分布)そのものを混合モデルで分解する手法を紹介します。単一の負の二項分布では「ユーザー全体の異質性」を 1 つのパラメータに集約しますが、混合モデルを使うと「ライト層が○%、ヘビー層が○%」といったユーザー構造を可視化できます。フリークエンシー分布の「なぜこの形になるのか」を解釈しやすくなる点が利点です。

フリークエンシー分布とは

「各ユーザーが何回広告に接触したか」という分布をフリークエンシー (frequency; FQ) 分布といいます。典型的なフリークエンシー分布には以下の特徴があります。

  •  0 が非常に多い
    • 母集団の大半は広告に接触しない
  • 急激に減衰
    • 広告に  1 回だけ接触したユーザー( FQ=1)が最も多く、 FQ=2 以降のユーザー数は急激に減衰する
  • 右に裾が長い
    • ごく少数のユーザーが非常に多くの回数接触する場合がある

この分布を統計モデルで表現できれば、「あと○○万回配信できたら何人リーチが増える」といった予測が可能になります。

シミュレーションデータの生成

フリークエンシー分布を推定するため、シミュレーションデータで検証してみましょう。以下のような 3 タイプのユーザーが混在する母集団(100万人)を想定します(ユーザータイプ・構成比・パラメータの数値は全て仮定です)。

フリークエンシー分布は過分散(分散が平均より大きい)を示すことが多く、ポアソン分布では表現できません。負の二項分布はこの過分散を扱えるため、広告接触回数のモデリングに適しています。負の二項分布のパラメータには  \mu \theta があり、 \mu は平均、 \theta は過分散を制御するパラメータです。 \theta が小さいほど分散が大きくなり、 \theta \longrightarrow \inftyポアソン分布に収束します。

ユーザータイプ 構成比  \mu  \theta 特徴
ライト 60% 0.1 0.5 広告にほとんど接触しない
レギュラー 30% 1.0 0.5 平均 1 回程度接触する
ヘビー 10% 3.0 0.5 頻繁に広告に接触する

負の二項分布の分散は  \mu + \frac{\mu^{2}}{\theta} で計算されるため、 \theta が小さいほど分散が大きくなります。今回は簡単のため、全てのユーザータイプで  \theta は一律  0.5 としました。

なお、私は最近 R にハマっているので、以降は全て R を用いて実験をしています。

Code

set.seed(42)

n_population <- 1000000

# 真のパラメータ
true_params <- tribble(
  ~component, ~prior,  ~mu, ~theta,
  "ライト",     0.60,  0.1,    0.5,
  "レギュラー", 0.30,  1.0,    0.5,
  "ヘビー",     0.10,  3.0,    0.5,
)

sim_data <- true_params |>
  slice_sample(n = n_population, weight_by = prior, replace = TRUE) |>
  mutate(
    user_id = row_number(),
    imp = rnbinom(n(), mu = mu, size = theta)
  )

成分ごとの統計量を確認します。avg_fq は理論上の  \mu に、variance \mu + \frac{\mu^{2}}{\theta} に近い値となるはずです。

Code

sim_data |>
  summarise(
    each_uu = n(),
    each_imp = sum(imp),
    reach_uu = sum(imp > 0),
    avg_fq = each_imp / each_uu,
    variance = var(imp),
    landing_fq = each_imp / reach_uu,
    .by = component
  ) |>
  arrange(each_imp) |>
  gt::gt() |>
  gt::fmt_integer(columns = 2:4) |>
  gt::fmt_number(columns = 5:7, decimals = 2)

component each_uu each_imp reach_uu avg_fq variance landing_fq
ライト 600,076 59,908 52,227 0.10 0.12 1.15
レギュラー 300,033 300,699 127,029 1.00 3.01 2.37
ヘビー 99,891 300,734 62,062 3.01 21.35 4.85

可視化してみましょう。接触回数が  0 回のユーザーがほとんどなため、可視化からは除外し、縦軸を対数表記にしています。

Code

sim_data |>
  filter(imp > 0) |>
  mutate(component = factor(component, levels = c("ライト", "レギュラー", "ヘビー"))) |>
  bind_rows(
    sim_data |> filter(imp > 0) |> mutate(component = "全体")
  ) |>
  mutate(component = factor(component, levels = c("全体", "ライト", "レギュラー", "ヘビー"))) |>
  ggplot(aes(x = imp, fill = component)) +
  geom_histogram(binwidth = 1, alpha = 0.5) +
  scale_x_continuous(breaks = scales::breaks_width(10)) +
  scale_y_log10(labels = scales::comma) +
  facet_wrap(~ component, ncol = 1) +
  labs(x = "接触回数", y = "人数")

全体としては右に裾の長いフリークエンシー分布になっています。ライト層は数回の広告接触に留まるのに対し、ヘビー層には広告にたくさん接触しているユーザーが存在することがわかります。なんとなくそれっぽいデータが生成されましたね。

全体の統計量についても確認します。今回はシミュレーションデータなので上記のように内訳がわかりますが、実際の広告配信後に得られるデータは以下のようなものになります。

Code

sim_data |>
  summarise(
    total_uu = n(),
    total_imp = sum(imp),
    reach_uu = sum(imp > 0),
    avg_fq = total_imp / total_uu,
    variance = var(imp),
    landing_fq = total_imp / reach_uu,
    max_fq = max(imp)
  ) |>
  gt::gt() |>
  gt::fmt_integer(columns = 1:3) |>
  gt::fmt_number(columns = 4:6, decimals = 2)

total_uu total_imp reach_uu avg_fq variance landing_fq max_fq
1,000,000 661,341 241,318 0.66 3.88 2.74 79

つまり、母集団サイズ、総インプレッション、リーチ人数、そしてフリークエンシー分布(接触回数ごとの人数)です。この情報だけから、背後にあるユーザー構造(ライト・レギュラー・ヘビー)とその構成比を推定できるでしょうか。

単一の負の二項分布によるフィッティング

まず、単一の負の二項分布でフリークエンシー分布をモデリングしてみます。

ここでは glmmTMB パッケージを使用します。 glmmTMB は一般化線形混合モデル(GLMM)をフィッティングするためのパッケージで、負の二項分布を含む様々な分布族をサポートしています。今回は混合効果を使わないシンプルなケースですが、weights 引数で集計データを扱える点が便利です。weights = cnt とすることで、「接触回数 imp のユーザーが cnt 人いる」という集計データをそのまま渡せます。 実務では、ベイズモデリングを使うと推定の不確実性を信用区間で表現できて有用なことが多いですが、今回は真のパラメータがわかっているシミュレーションなので、計算の速い頻度論的アプローチで進めます。

Code

freq_dist <- sim_data |> count(imp, name = "cnt")

fit_single <- glmmTMB::glmmTMB(
  data = freq_dist,
  formula = imp ~ 1,
  family = glmmTMB::nbinom2,
  weights = cnt
)

summary(fit_single)

 Family: nbinom2  ( log )
Formula:          imp ~ 1
Data: freq_dist
Weights: cnt

      AIC       BIC    logLik -2*log(L)  df.resid
1941961.4 1941965.5 -970978.7 1941957.4        57


Dispersion parameter for nbinom2 family (): 0.174

Conditional model:
             Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.413487   0.002695  -153.4   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

モデルは正常に収束しました。推定されたパラメータを確認します。

Code

single_params <- get_parameters(fit_single) |>
  mutate(value = exp(Estimate)) |>
  select(Component, value) |>
  pivot_wider(names_from = Component, values_from = value) |>
  rename(mu = conditional, theta = dispersion)

single_params |>
  gt::gt() |>
  gt::fmt_number(decimals = 2)

mu theta
0.66 0.17
  •  \mu の推定値

    • 母集団平均は約  0.66 なので、正しく捉えられています。
  •  \theta の推定値

    • 真の  \theta は成分ごとに  0.5, 0.5, 0.5 ですが、推定値は  0.17 でした。

    • 単一分布で混合分布の過分散を表現しようとした結果、 \theta が不自然に小さくなってしまいました。

このパラメータを使って、推定されたフリークエンシー分布と実際の分布を比較してみましょう。

Code

freq_dist |>
  mutate(
    total_cnt = sum(cnt),
    expected = total_cnt * dnbinom(imp, mu = single_params$mu, size = single_params$theta),
    residual = cnt - expected
  ) |>
  filter(imp <= 20) |>
  ggplot(aes(x = imp, y = residual)) +
  geom_col(fill = "steelblue") +
  geom_hline(yintercept = 0, color = "coral") +
  scale_x_continuous(breaks = scales::breaks_width(1)) +
  scale_y_continuous(labels = scales::comma) +
  labs(x = "接触回数", y = "残差(実測 - 推定)")

接触回数が 1 回の部分で大きな残差が生じており、単一の負の二項分布ではフリークエンシー分布の構造を十分に捉えられていないことがわかります。

混合負の二項分布によるフィッティング

単一の負の二項分布では残差が大きく、フリークエンシー分布の構造を十分に捉えられていませんでした。ここでは、複数の負の二項分布を混合したモデルを試してみます。混合負の二項分布のフィッティングには、flexmixパッケージを使用します。flexmix は有限混合モデルをフィッティングするためのパッケージで、countreg パッケージの FLXMRnegbin と組み合わせることで混合負の二項分布を推定できます。

成分数を 2〜4 で試し、BIC で比較します。BICベイズ情報量規準)はモデルの当てはまりと複雑さのバランスを評価する指標で、値が小さいほど良いモデルとされます。

stepFlexmix の主な引数は以下の通りです。

  • k: 試す成分数。ベクトルで複数指定可能。

  • model: 各成分の分布。FLXMRnegbin() で負の二項分布を指定。

  • weights: 集計データの頻度ウェイト

  • nrep: 初期値を変えて繰り返す回数。EMアルゴリズムは初期値依存なので、複数回試行して最良の結果を採用

  • control: minprior は成分の最小構成比。これを下回る成分は除外される

Code

tidy_flexmix <- function(fit) {
   flexmix::parameters(fit) |>
    t() |>
    as_tibble() |>
    rename(log_mu = `coef.(Intercept)`) |>
    mutate(
      component = row_number(),
      prior = flexmix::prior(fit),
      mu = exp(log_mu),
      .before = 1
    )
}

set.seed(42)

fit_mix <- flexmix::stepFlexmix(
  data = freq_dist,
  formula = imp ~ 1,
  k = 2:4,
  model = countreg::FLXMRnegbin(),
  weights = ~ cnt,
  control = list(iter.max = 500, minprior = 0.01),
  nrep = 20,
  verbose = FALSE
)

tibble(
  k = 2:4,
  BIC = sapply(fit_mix@models, BIC)
) |>
  gt::gt() |>
  gt::fmt_integer()

k BIC
2 1,936,738
3 1,936,448
4 1,936,502

 k=3BIC が最小となっています。 k=4 では改善せずむしろ悪化しており、3 成分が最適であることを示しています。今回のシミュレーションでは真の成分数が 3 だったので、正しく特定できています。 BIC が最小だった、 k=3 のモデルのパラメータを確認します。

Code

fit_best <- flexmix::getModel(fit_mix, which = "BIC")
mix_params <- tidy_flexmix(fit_best)
mix_params |>
  gt::gt() |>
  gt::fmt_number(columns = 2:5, decimals = 2)

component prior mu log_mu theta
1 0.12 2.67 0.98 0.46
2 0.20 1.22 0.20 0.66
3 0.67 0.12 −2.12 0.40

真のパラメータと比較したのが以下です。

真の成分 構成比  \mu  \theta 推定 構成比  \mu  \theta
ライト 0.60 0.1 0.50 Comp3 0.67 0.12 0.40
レギュラー 0.30 1.0 0.50 Comp2 0.20 1.22 0.66
ヘビー 0.10 3.0 0.50 Comp1 0.12 2.67 0.46

完全には一致しませんでしたが、構造の傾向は捉えられています。 \mu の大小関係(ライト < レギュラー < ヘビー)は正しく識別されており、構成比もライト層が多数を占めるという特徴を反映しています。ただし、レギュラー層の構成比が過小推定され、その分ライト層に吸収されています。中間的な成分は境界が曖昧になりやすく、隣接成分と混同されやすい傾向があります。

混合負の二項分布の残差確認

推定されたパラメータを使って、フリークエンシー分布の残差を確認します。

Code

freq_dist |>
  crossing(mix_params) |>
  mutate(prob = prior * dnbinom(imp, mu = mu, size = theta)) |>
  summarise(cnt = max(cnt), prob = sum(prob), .by = imp) |>
  mutate(
    total_cnt = sum(cnt),
    expected = total_cnt * prob,
    residual = cnt - expected
  ) |>
  filter(imp <= 20) |>
  ggplot(aes(x = imp, y = residual)) +
  geom_col(fill = "steelblue") +
  geom_hline(yintercept = 0, color = "coral") +
  scale_x_continuous(breaks = scales::breaks_width(1)) +
  scale_y_continuous(labels = scales::comma) +
  labs(x = "接触回数", y = "残差(実測 - 推定)")

単一の負の二項分布と比較して、残差が大幅に改善されています。 FQ=1 付近の大きなズレが解消され、全体的に残差が小さくなっています。 FQ=3, FQ=4 で若干の過大推定がありますが、母集団 100 万人に対して誤差 200 ~300 人程度なので実用上は問題ないレベルです。

リーチ予測への応用

推定したパラメータを使って、任意のインプレッション数に対するリーチを予測できます。混合負の二項分布では、リーチ率(1人以上に接触する確率)は以下のように計算されます。

 \displaystyle
        \text{リーチ率} = 1 - \sum_{i} \pi_i \cdot P(X=0 | \mu_i, \theta_i)

ここで  \pi_i は各成分の構成比、 P(X=0) は負の二項分布で接触回数が  0 となる確率です。

インプレッション数を変化させたときのリーチ予測を行うには  \mu をスケーリングします。配信量が 2 倍になれば、各ユーザーへの接触機会も2倍になると仮定し、 \mu を比例させてリーチカーブを描いてみました。

Code

calc_reach <- function(target_imp, params_df, total_uu, actual_imp) {
  scale <- target_imp / actual_imp

  params_df |>
    mutate(
      scaled_mu = mu * scale,
      p_zero = prior * dnbinom(0, mu = scaled_mu, size = theta)
    ) |>
    summarise(p_zero = sum(p_zero)) |>
    pull(p_zero) |>
    {\(p) total_uu * (1 - p)}()
}

freq_dist |>
  summarise(
    actual_imp = sum(imp * cnt),
    actual_reach = sum(cnt[imp > 0]),
    total_uu = sum(cnt)
  ) |>
  crossing(target_imp = seq(10000, 1000000, by = 10000)) |>
  mutate(
    predicted_reach = pmap_dbl(
      list(target_imp, total_uu, actual_imp),
      \(target_imp, total_uu, actual_imp) calc_reach(target_imp, mix_params, total_uu, actual_imp)
    ),
    reach_rate = predicted_reach / total_uu
  ) |>
  ggplot(aes(x = target_imp, y = predicted_reach)) +
  geom_line(color = "steelblue") +
  geom_point(aes(x = actual_imp, y = actual_reach), color = "coral", size = 3) +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::comma) +
  labs(x = "インプレッション数", y = "リーチ人数")

点は実測値(約66万 imp → 約24万リーチ)で、予測カーブが実測値を通過しており、モデルの妥当性が確認できます。また、カーブの形状からリーチの逓減効果も見て取れます。 インプレッション数を増やしても、リーチの伸びは徐々に緩やかになります。これは一部のヘビー層が繰り返しインプレッションを吸収するためで、混合モデルがこの構造を捉えていることを示しています。

このように、パラメータさえ推定できれば「○○万 imp でリーチ何人?」という問いに即答できるようになります。

まとめ

今回は、フリークエンシー分布を混合負の二項分布でモデリングする手法を紹介しました。シミュレーションを通じて、以下のことが確認できました。

  • 単一の負の二項分布では、異なるユーザー層が混在するフリークエンシー分布を十分に表現できない
  • 混合負の二項分布を用いることで、ライト・レギュラー・ヘビーといったユーザー構造を識別できる
  • 推定したパラメータから、任意のインプレッション数に対するリーチ予測が可能になる

この手法を実データに応用することで、リーチ予測やユーザー構造の定量的な比較が可能になるほか、ターゲティング戦略やフリークエンシーキャップ設定の検討に活用できそうです。

なお、今回はシミュレーションデータを使用しましたが、実際のキャンペーンデータに適用する際には、配信期間やターゲティング条件によるパラメータの変動など、より突っ込んだ検討が必要になります。

We’re Hiring!

TVer では、データサイエンスの力で広告事業の成長を支えるメンバーを募集しています。今回紹介したようなリーチ予測モデルの構築・改善や、広告配信の最適化など、チャレンジングな課題に取り組んでいます。 また、広告データ基盤も現在絶賛整備中のため、データエンジニアの募集も行っています。

ご興味のある方は、ぜひカジュアル面談からでも気軽にお話しましょう!

計測から始める品質とスピードの両立 - TVerの開発組織改革2年間の記録

この記事は Tverアドベントカレンダー2025 25日目の記事です。24日目の記事は @tomat_oooさんのTVerでテレビの体験をつくる!5つの壁とUIデザインの工夫でした。

サービスプロダクト本部 本部長の脇阪(@tohaechan)です。

techblog.tver.co.jp

1年前に上記のような記事を書きました。

当時は技術統括(TVerサービス開発部門内のVPoEみたいなポジション)として、主に技術戦略や組織マネジメントに責任を持っていました。 そこからPdMやデザイナーも含めた開発組織の本部長となったこともあり、これまでの仕事に加えてプロダクト成長にもより強くコミットすることとなりました。 そこで本記事では、プロダクト成長のためにどのような組織戦略、技術戦略を立てて実現したのかを共有したいと思います。

品質とスピード

FY25の注力ポイント
まず今年度サービスプロダクト本部の方針として掲げたのが 品質とスピードの両立 です。

昨年末の記事でも課題を書きましたが、機能開発のスピードは期待するほどのスピードが出ず、品質に関しても様々なトラブルが発生しその解消に追われて開発が後手後手に回るという状況でした。

一部の開発チームでは変更障害率の計測をしていたのですが、その数字はよくありませんでした。 実際、年末年始は怒涛のhotfixリリースをして胃が痛かったです…。しかも特定の領域で多く発生しているというようなことはなく、iOS, Android, Web, バックエンド、インフラとまんべんなく問題が発生していました。 体感3割くらいは緊急の不具合対応に追われており、当初予定していたリリーススケジュールがずるずる遅延していくという悪循環です。

このころ組織の人数としては約1年で2倍になり、育ってきた環境が異なるメンバーが増え、TVerというプロダクトや組織の課題感の認識もバラバラという課題感もありました。

「クソコードすぎるから事故るんだ!リアーキテクチャだ!!!(意訳)」「開発のスピードが遅すぎる!!!(意訳)」「まずは落ちまくるインフラの品質を担保すべき(意訳)」

ざっくりわかりやすく意訳すると上記のような感じで、人によってバラバラです。 それぞれの課題感が間違っているわけではないものの、人によって課題感が異なるので優先順位付けの際に揉めたり話が噛み合わなかったりします。 まずは開発組織全員の認識を揃え、同じ方向を向かせたい。そしてある程度覚えやすく認知しやすい方針にしたい。その思いから「品質とスピード」をスローガンに掲げることにしました。 品質とスピードはトレードオフの関係にあると考えられがちですが、品質を高めることで結果としてスピードを上げることができると考え、このようなメッセージにしました。

品質とスピードの両立の実現に向けて

これまでも品質とスピードの向上は各チームで取り組んではいましたが、 一方で「目指すべき理想形の状態」を定量的に示せていないことで認識のズレが起こっていました。

「インシデントが多い」「開発がなんとなく遅い」「リリース回数が少ない」といった定性的な課題感はあるものの、具体的にどの程度の問題なのか、改善が進んでいるのかを判断できない状態でした。 各チームの取り組みで改善できることには限界があり、組織全体でプロセスや手段を変えていく必要があるとも感じていました。

そこで品質とスピードのスローガンとともに、定量目標を設定しました。

  • インシデント発生件数
    • インシデントレベルを定義し、レベルごとの発生件数をn件以内にする
  • 平均修復時間
    • ポストモーテムで平均修復時間を計測し、平均修復時間をn時間以内にする
  • リリース頻度
    • 各デバイスごとの一ヶ月以内のリリース頻度を定義し、それ以上のリリースを行う
  • リードタイム短縮
    • FY25はまずは計測から始める

このように各指標の定義を明確にして、計測することから始めました。

課題と対策1: インシデント管理 && 平均修復時間の改善

まずはインシデントについて。インシデント管理において大きく3つの課題がありました。

  1. インシデント定義が曖昧
    • インシデントの重大度の判断が、人やチームによって異なる
    • インシデント改善タスクの優先度を決められない(あるいは、誤った優先度を設定している)
  2. インシデント対応を各チームバラバラに実施
    • 他のチームでどのようなインシデント対策を行っているのか知らない
    • インシデントが発生したことすら知らない
    • チーム横断的に対応した方がよいインシデントもあるが、対応できていない場合がある
  3. 再発防止&恒久対応をやりきっていない
    • 暫定対応や緩和措置の一時的な止血対応が、そのまま再発防止&恒久対応になっている
    • いつかちゃんとやろうと思っていても、機能追加に追われたり新しいインシデントへの対応でしっかりとした再発防止&恒久対応ができずに埋もれていく

こういった課題を解決するため、インシデント管理委員会を設立し、全チームから1人ずつ集めてインシデントの管理について話し合いを進めました。 全チームを呼んだのは全チームが自分事とし、現実的な管理ができるよう議論してもらうためです。

1のインシデント定義が曖昧だったところに対しては、本部全体で統一的なインシデントレベルを定義します。 過去1年のインシデントを手作業で洗い出し(各チームのポストモーテムであったり、Slackの障害報告であったりを地道にサルベージしました)、 インシデントを「アプリ」、「広告」、「ログ計測」などのカテゴリに分類しました。 このカテゴリ別にレベルを分類していくのですが、例えばアプリであれば、影響ユーザー数と機能重要度の掛け算でレベルを決めることにしました。もう少し具体的に言うと「コンテンツを再生できないユーザー数がxx万以上」であればインシデントレベルSというような形です。

このような定義を行い、本部目標として「インシデントレベルSを0件、Aをn件以内に抑える」ということを通期の目標として追っていくこととしました(件数に関しては前年発生件数から現実的な目標を算出)

許容できるリスクの明確化と段階的ロールアウト

あらゆるインシデントを起こさないのが理想的ではありますが、ソフトウェア開発でそれは不可能に近いです。テストに多くの時間を割けば限りなく少なくすることはできるかもしれませんが、スピードとの両立は難しくなります。

そこで重要になるのが、インシデントレベルに影響ユーザー数を含めることで許容できるリスクが明確になったことです。 例えば「影響ユーザー数が1000人未満ならインシデントレベルB」という定義があれば、新機能のリリース時に「まずは1000人未満に開放してフィードバックを得る」という判断ができるようになります。

この明確な基準により、過度に品質を作り込むことが無くなりました。 従来は「万が一何か起きたら大変だ」という心理的安全性の欠如から、リリース前に完璧を目指して長時間のテストや検証を行っていました。しかしインシデントレベルの定義により「このレベルなら許容できる」という共通認識が生まれ、スピードを上げることができるようになったのです。

具体的には、Feature Flagを使用して段階的にロールアウトしていく方法を全デバイスで標準化しました。

昨年のiOSDCでiOSの事例を発表していますが、Android、Web、コネクテッドTV、バックエンドの全てでこの考え方を適用させています。

バックエンドの事例に関してはこちらの登壇資料もご確認ください。

運用としては、数%ずつの段階開放を行い、クラッシュ数やサーバのエラー数、事業KPIへの影響などを観測します。 さらに、仮に問題が発生したとしてもインシデントレベルがB未満に収まるように開放率をコントロールする運用を心がけていました。 これにより、許容できるリスクの範囲内で新機能をリリースし、実ユーザーの反応を早期に確認できるようになりました。

この手法により、仮に何か問題が発生したとしてもすぐ0%に切り戻せる運用が確立し、実際に途中で切り戻して事なきを得たケースも何度かありました。 また、影響範囲を小さくしてリリースすることで、実ユーザーから早期にフィードバックをもらえるようになり、プロダクトの改善サイクルも大幅に向上しています。

今ではほとんどの機能リリースが段階的ロールアウトすることが当たり前になっており、品質とスピードの両立を実現する重要な仕組みとなりました。

インシデント情報の共有と透明性の向上

2のインシデント対応の課題に関しては、まずは本部全体でポストモーテムのテンプレートを作成し、一箇所に集約しました。

合わせて目標の一つである平均修復時間を計測できるように、「平均検出時間(MTTD)」「平均認知時間(MTTA)」「平均原因特定時間(MTTK)」「平均修正時間(MTTF)」「平均確認時間(MTTV)」をポストモーテムに含めることとします。

続いてインシデントが発生したことや、どのようなインシデント対策が行われているかを知らないという課題に対し、本部の正社員が全員いるチャンネルにSlackワークフローを2つ作成しました。

1つ目は「インシデント疑い報告」で、インシデントかどうかはわからないが、何らか調査を始めたときにこのワークフローを呼び出し、実際調査に当たってるチャンネルやスレッドを共有し全員が認知できるようにしました。

2つ目は「ポストモーテム作成報告」で前述のポストモーテムを作成したら共有するためのものです。 これに加えて本部の毎月の定例で、ポストモーテムとして良かった事例をインシデント管理委員会から共有し、本部全体に対してポストモーテムの重要性や対応してくれた人に感謝を示す場を設けて運用しています。

再発防止の徹底

3の再発防止&恒久対応をやりきっていない課題に関しては、ポストモーテムが整備されたことで管理しやすくなったため、開発ディレクターを中心にタスク管理を行うことでカバーしています。

課題と対策2: リードタイムの短縮 && リリース頻度

こちらの課題もまずは計測から始めました。

note.com

こちらの記事でも少しだけ触れていますが、バリューストリームマッピングを実施し エンジニア、QA、PdM、デザイナー、ディレクターそれぞれの視点で、リリースまでにどういうプロセスがあり、そこにどれだけの時間がかかっているかをMiroで可視化していきました。 各視点でおおよそ2時間強かかるなかなか重い作業ではありましたが、開発プロセスが可視化できて非常に意味のある取り組みだったかと思います。

それぞれの視点で見ていくと、大きくコストがかかっていたのは各職種間での連携です。

チーム固定化による品質と生産性の向上

これまでのチームビルディングはプロジェクトごとに人員がアサインされる方式でした。この方式には以下のような課題がありました:

  1. チームが成熟しにくく、内部品質が悪化する

    • プロジェクト都度でメンバーが入れ替わるため、未成熟なチームワークのまま開発が行われる
    • チーム内でのコードレビューやナレッジ共有が十分に機能せず、内部品質が悪化しやすい
    • プロジェクトごとにチームビルディングをやり直すコストが発生
  2. 同時並行プロジェクトによる認知負荷の高さ

    • リーダーが横断的に複数プロジェクトの詳細を把握する必要があり、認知負荷が高すぎる
    • メンバーも複数のプロジェクトに跨って参加することが多く、コンテキストスイッチのコストが大きい
    • 同時並行で動くプロジェクト数が多すぎることが、品質や生産性を下げる大きな要因となっていた

これらの課題に対し、職能別の組織をクロスファンクショナルなチームにして固定化することで解決を図ります。

チーム固定化により以下のような効果を狙いました: - チームメンバーが固定されることで、チームが成熟しやすい環境をつくる - 同時並行で動くプロジェクト数を制限し、認知負荷を下げる - 基本的にはチーム内のみ詳細を見ておけば良い状態を目指し、横断的な把握の負担を減らす

実はチーム固定化自体は2024年の早い段階から実施したかったのですが、人が十分に採用できていないことや、既存プロジェクトがありなかなかタイミングが合わず実現できてませんでした。 しかしエンジニアも増え、PdMやデザイナーも含めて同じ組織になるこのタイミングで実行するしかないとなり、ついに実現できました。 上記の決起会の記事にも「長年の悲願だった固定スクワッドチーム体制への変更が本運用開始〜」とあるように、マネージャー目線では悲願of悲願で、決起会やその後の本部の定例などでスクワッドチームの代表者が一丸となったチームの成果を発表する姿を見ると、マネージャー陣はうれしくてニヤニヤしてしまうというのが最近の恒例だったりしますw

チームの固定化でコミュニケーションの質を上げリードタイムの短縮は着実に改善されていったわけですが、各チームでの開発がそれぞれ進むとチーム間でどう連携をしてリリースしていくかという次の悩みが生まれることが予想されました。 これに関してはリリーストレインで解決することを事前に決めていました。

リリーストレイン(Release Train)とは、アジャイル開発において、複数の開発チームが連携し、電車のように決まったスケジュール(頻度)で定期的にソフトウェアをリリースする仕組みです メルカリなどで導入され、リリース遅延の防止、チーム間の同期、品質の安定化、ビジネス部門との連携強化などを目的とし、間に合わなかった機能は次の「列車」に乗せる(先送りする)イメージです。 (Geminiによる概要)

スクワッドチームは3チームあるのですが、隔週でリリースするという決め事の中で、間に合わなかったものは次のリリースに回すという運用をすることにしました。 この結果、安定して月に2回以上の機能リリースを実現できるようになりました。

このようにアウトプットが加速すると、今度はQAのリソースが不足する懸念が生まれてきました。 生産性が高まったからこそ生まれたうれしい悲鳴ではあるのですが、QAがボトルネックになってリリースができないという事態は避けなければなりません。

テスト自動化によるQAの効率化

これに関しては先ほどのバリューストリームマッピングの結果や不具合分析から改善点を抽出し、「SET(Software Engineering Test)チームによるテスト自動化の文化づくり」により改善していくこととなります。 リグレッションテストに大きな工数がかかっていることがわかったため、SETチームを組成しまずはWebとiOSからE2Eテストを開発していきました。QAやSETだけがテストをするというのではなく、各エンジニアがユニットテストを書くような文化づくりも行ってもらいました。 その結果大幅にテスト工程を削減でき、品質とスピードの両立に大きく貢献しています。

課題と対策3: 生成AIの活用

生成AIの活用に関してはあくまで手段であって目的ではないのですが、年初から他社での活用事例が多く出てきており、ある程度トップダウンで方向性を示さなければあっという間に周回遅れになりそうな危機感があり、期初の戦略に含め活用を推進してきました。 春先からClaudeやDevinの活用を始め、6月には生成AIをテーマにした開発合宿を実施、その結果プロダクトへの生成AIの適用なども順次始まっています。 今回のアドベントカレンダーでも多くのAI活用事例が書かれていますが、エンジニアだけでなくPdMやデザイナーも多くがAIを中心とした開発を進めています。 しかし、まだまだAI活用が他社よりリードできているとは全く思ってません。むしろ少し遅れてるくらいの認識でいます。 来年はAIエージェントの開発も含め、AIを活用しより品質とスピードを高めていきたいと考えています。

まとめ: 品質とスピードのその先、アウトプットからアウトカムへ

これらの課題を解決した結果、期初に立てた本部目標は概ね達成できており、着実に品質とスピードが上がってきているのを実感しています。 しかし、プロダクト開発において重要なのはアウトプットではなくアウトカムだともよく言われます。 アウトプットを高めることに費やした約2年間で、ようやく競合他社と比較しても目劣りしないレベルのアウトプットを出せる開発組織になったと自負していますが、ここからはアウトカムを得るフェーズになったと思っています。 PdMやデザイナーを含めたスクワッドチームは、このアウトカムを全員で得るために様々な創意工夫を行える体制でもあります。 実際、今年はショート動画のリリースや、各種出面のパーソナライズなど、プロダクト開発でのKPIへの寄与が着実にできた一年でもあります。 来年はさらなる飛躍の年にしていくので、みなさまTVerをこれからもよろしくお願いいたします。年末年始はTVerで動画をお楽しみください。 良いお年を!