AIでデバッグ機能を爆速生成し、開発・検証の「面倒」を根こそぎ削る

本記事は TVer Advent Calendar 2025 16日目の記事です。
15日目の記事は @entaku0818 さんによる「iOS 26のAlarmKit APIでアプリからアラームを鳴らす」でした。

qiita.com

はじめに

TVerAndroidエンジニアをしている石井です。

開発・検証プロセスにおいて、特定のデータや環境を操作・確認できるデバッグ機能が不可欠となります。実装自体は容易にできますが、簡易的なUIでも0から作るのは面倒で、日々の業務の中で後回しになりがちです。なのでAIに作らせましょう。

AIに作らせるメリット

デバッグ機能は通常のユーザー向け機能と異なり、品質要件やデザイン要件が緩和されるため、AIによる実装と非常に相性が良いという特性があります。

品質を大きく気にしない、実装の容易さ

デバッグ機能は、一般のユーザーではなく、開発者やテスターが使用する前提で作られます。 そのためレイアウトや操作感に洗練されたUI/UXは求められません。 加えてAndroidではビルドタイプを設定することができ、デバッグ機能をデバッグビルドに限定することによってユーザー影響を一切考えずに実装することが可能になります。
AIがコードを生成した場合、通常は細かい調整が必要になりますが、デバッグ機能においてはそこまでの品質を求めていないため、生成コードをほぼそのまま利用でき、実装工数を大幅に削減できます。

仕様がシンプルで伝達漏れが少ない

デバッグ機能は、1機能が1つの目的に特化して作られ、開発者やテスターが利用するシンプルな構成になります。このシンプルさにより、仕様が複雑になりにくく、伝達漏れや考慮漏れ等の不具合が大幅に減ります。そのため、複雑な設計や詳細な仕様詰めに工数を掛けることなく、検証に必要な機能を即座に開発環境に組み込むことが可能です。

機能の洗い出し

機能の洗い出しは、エンジニア組織内にとどめず、サービス開発に携わる非エンジニア(ディレクター、デザイナー、QAなど)を巻き込むことが重要です。他メンバーの視点を取り込むことで、調査に必要な機能を網羅できます。開発組織全体のSlackチャンネルなどで意見を募るといった方法で、必要なデバッグ機能を効率よく収集しています。

デバッグ機能の一例

実際に実装したデバッグ機能の一例です。

機能名 概要 活用シーン
コンテンツ詳細画面への遷移 コンテンツIDを入力して、その詳細画面へ直接遷移する 特定コンテンツでのみ発生する不具合などの調査・検証に活用
利用者の環境表示 APIの疎通先やアプリバイナリのバージョンなど、利用者がどの環境でアプリを使用しているかなどを表示する 不具合報告に合わせて環境情報をいただくことで原因調査に役立てる
A/Bテストなどのローカル強制切り替え 本来、サーバ側で割り振られるA/Bテストのパターンをフロント側で強制上書きして動作確認できるようにする 特定パターンでの動作検証やテストをする際に活用
導線がない画面への遷移 新規で開発していて導線がまだない画面や特定条件下でのみ遷移できる画面などの遷移をデバッグ画面に用意しておく ディレクターやデザイナーなどの非エンジニアが確認する際に活用

実際のデバッグメニュー

まとめ

デバッグ機能は開発・検証プロセスにおいて重要な役割を担っていますが、UIを0から作る必要があり手間がかかります。 そのためAIに作らせることで迅速に実装してくれます。実際これらの機能を実装するのに数分で完了しています。

今は非エンジニアの方に欲しい機能をヒアリングして追加実装を少しずつ行っていたりしますが、エンジニアが間に入らない自動化を目指しています。 今後の展望として、Issue起票を軸にActionsを発火させ、生成AIがPRを作成し、エンジニアがレビューするフローを作れないかなど、検討中です。

dbt Platform による TVer 広告データの分析基盤構築

はじめに

こちらは TVer Advent Calendar 2025 16日目の記事です。15日目は @ko-ya346 さんの「TVer の分析業務について」でした。

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

今回は、TVer 広告のデータサイエンティストが直面する集計業務におけるつらみを解消すべく、dbt Platform を用いてデータ分析基盤を構築している最前線をご紹介します。

広告領域におけるデータ集計依頼

TVer 広告のデータサイエンティストは少数精鋭で日々の業務を遂行しています。分析業務と並行して、営業チームからのデータ集計依頼にも対応しています。例えば以下のような依頼です。

  • 都道府県別・デバイス別の配信実績を出してほしい」
  • 「このキャンペーンのユーザー属性別ユニークユーザー数を教えてほしい」
  • 「クリエイティブ別の視聴完了率は?」

このような多岐にわたる依頼に対して、色々な配信ログを直接参照するような集計 SQL を都度書いて対応していました(現在も一部対応中ですが...)。

サービスのグロースに伴う課題

TVer の広告事業が急成長する中で、以下のような問題が顕在化しました。

依頼の増加と多様化

  • キャンペーン数の増加に伴い、配信実績確認の依頼が激増
  • 集計粒度の多様化
    • 「日次」「週次」といった、様々な時間粒度での集計依頼
    • 広告代理店・広告主・キャンペーン・クリエイティブといった、様々な粒度での集計依頼

再現性と効率の問題

  • 似たような集計を何度も書き直している
  • 人によってデータに対する理解度が異なり、集計作業ですら属人化してしまう

結果として、本来注力すべき分析業務ではなく、集計作業に時間を取られる状況に陥っていました(今も改善中ですが...)。

dbt Platform でデータ分析基盤を整備

このような課題を解決するため、事前に最適な粒度で集計したデータマートを構築し、迅速かつ正確に集計結果を提供する必要があると考えました。 データ分析基盤の構築には dbt Platform を採用し、ベストプラクティスに倣って 3 層構造のデータモデルを構築しています。

  1. Staging 層
    • 生ログからの軽い加工を担当。NULL の COALESCE 処理、エイリアス名の統一など後続処理で扱いやすい形への整形を行う
  2. Intermediate 層
  3. Mart 層
    • 分析・可視化用の最終テーブル。営業チームが直接参照するキャンペーン別配信実績サマリや、BI ツール接続用の集計済みテーブルを配置

結果として、136 個の SQL モデル 57 個の YAML 定義ファイルで構成される基盤が稼働しており、現在も拡張中です。

dbt Platform を選定した理由

スクラップ&ビルドのしやすさ

TVer の広告事業は急成長中のため、レポート要件の追加や集計粒度の多様化、季節性イベントに伴う分析ニーズの変化など、変化が激しい状況です。dbt は SQL ベースでモデルを定義するため、不要になったモデルの削除や新規モデルの追加が容易なことから、このような変化にも柔軟に対応できます。また、YAMLスキーマを定義し、モデル間の依存関係を ref() 関数で明示することで、変更の影響範囲も把握しやすくなっています。

データエンジニアが不在でもメンテナンス可能

専任データエンジニアがいない中で少数のデータサイエンティストが様々な依頼に対応しているため、以下の点でもメリットがあります。

  • ワークフローツールの管理運用が不要なため、SQL によるロジック記述に集中できる
  • スケジューリングが標準機能として搭載されているため、簡単にジョブ実行頻度を制御できる
  • ドキュメントが自動生成されるため、新規にジョインしたメンバーのモデル理解が容易になる

BigQuery との親和性

TVer ではデータ基盤に BigQuery を採用しています。dbt は BigQuery 固有の機能との親和性が高く、日々の運用で恩恵を受けています。

例えば広告配信では、毎日大量のレコードが発生するため、スキャン量の最適化が不可欠です。dbt では SQL モデル内の config() ブロックで partition_bycluster_by を指定するだけで、パーティションクラスタリングを適用したテーブルを作成できます。

また、BigQuery 向けのインクリメンタルマテリアライゼーションでは、merge 戦略(MERGE 文による upsert)と insert_overwrite 戦略(パーティション単位の置き換え)を選択できます。配信ログの特性に応じてこれらを使い分けることで、フルスキャンを回避しビルド時間とコストを削減しています。

エコシステムとコミュニティの充実

BigQuery をデータ基盤として採用している以上、Google Cloud ネイティブの Dataform も選択肢でした。しかし dbt はユーザー数が圧倒的に多く、実務での Tips やトラブルシューティング事例が豊富に蓄積されています。少人数チームで運用する我々にとって、「困ったときに検索すれば先人の知見が見つかる」安心感は大きな決め手でした。

また、dbt_utilselementary といったパッケージのエコシステムが充実しており、汎用的なユーティリティや異常検知の仕組みをすぐに導入できる点も魅力です。

データ品質の担保

dbt の標準テスト機能とカスタムテストを組み合わせ、データ品質を多層的にチェックしています。

標準テストでは not_nulluniqueaccepted_valuesrelationships などを活用し、主キーの一意性制約や外部キーの参照整合性、カラム値の妥当性を担保しています。

加えて、データパイプライン固有の問題を検知するためカスタムテストを実装しています。具体的には、直近 N 時間分のレコードが想定どおり存在するかを検証するテストを作成し、上流のデータ取込遅延やジョブ失敗を早期に検知できる仕組みを整えました。

テスト失敗時は Slack 通知が飛ぶようにしており、多方面へ影響が出る前に対処できる体制を構築しています。

現状の運用

現在はチームメンバーが dbt に慣れることを優先し、依頼ベースで必要なデータマートを都度構築しています。「完璧なデータモデルを最初から設計する」のではなく、まずは動くものを作り、運用しながら改善するアプローチを取っています。活用が進み、データモデルが増えてきた現在、次のフェーズとして以下の整備を進めています。

  • 類似モデルの統合、不要になったモデルの廃止
  • ディメンションテーブルの共通化促進
  • モデル命名規則やドキュメント記載ルールの標準化

今後の展望

セマンティックレイヤーの活用拡大

dbt Platform の セマンティックレイヤー(Semantic Layer) 機能を導入し、広告ビジネス指標の定義の一元管理を目指しています。一部データモデルでは既にこれを導入しており、Google スプレッドシートの dbt Semantic Layer アドオンを使って、定義されたメトリクスに従った数値をスプレッドシート上で直接取得できるようにしています(下図)。

Google スプレッドシートから dbt Semantic Layer を使う

セマンティックレイヤーの導入により、「インプレッション数」や「ユニークユーザー数」といった指標の計算ロジックを YAML で一元定義し、どのツールから参照しても同じ結果が得られる Single Source of Truth が実現可能になります。SQL を書くことなく、デバイス別・日付別など任意のディメンションで指標を参照できるよう整備中です。今後は対象モデルを拡大し、より多くの指標をセルフサービスで取得できる環境を目指していきます。

MCP を活用した自然言語でのデータアクセス

さらなるデータの民主化を目指し、Model Context Protocol(MCP)を活用した自然言語によるデータ分析基盤へのアクセスを検討しています。

dbt Labs が公開している dbt MCP Server を利用することで、LLM がセマンティックレイヤーで定義されたメトリクスやディメンションの情報を参照し、ユーザーの自然言語による問い合わせを適切な Semantic Layer API 呼び出しに変換できます。現在 PoC を進めており、「先週のデバイス別視聴完了率を教えて」といった問い合わせに対して正しい結果を返せることを確認しています。

Claude Desktop から MCP で dbt Semantic Layer を使う(勝手に pivot してくれている)

今まで我々のチームに依頼していた内容をそのまま自然言語で問い合わせられる環境を整備し、データリテラシーに依存しない情報アクセスを実現したいと考えています。

終わりに

TVer では、広告事業の成長を支えるデータ基盤の構築・運用に一緒に取り組んでくれる仲間を募集しています。

  • ビジネス価値を引き出すデータモデリングに興味がある方
  • dbt や BigQuery を使ったモダンなデータ基盤に挑戦したい方
  • 「分析のための分析」ではなく、事業成長に直結するデータ活用を実現したい方

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

https://herp.careers/v1/tver/ARm9gwwiv3zS


明日の記事は @NagaiKoki さんの、「Vitestは本当に早いのか? Vitestでテストを高速化するアプローチについて」です。お楽しみに!

TVer の分析業務について

こんにちは、TVer のデータ分析をしている高橋です。
こちらは TVer Advent Calendar 2025 の15日目の記事です。

採用面接やカジュアル面談をしていると、TVer の分析業務についてあまり認知されていないという実感があります。
そこでこの記事では、「よく聞かれる質問」ベースで、実際どのように働いているのかをまとめてみました。

組織について

私は現在、TVer とビデオリサーチによる合弁会社である TVer Data Marketing(以下 TDM) のデータシステム部に所属しています。
元々TVer内にあったデータシステム周りを担当する部署が、今年の4月にまるごとTDM に移った形になります。
データシステム部ですが現在6名(プロパーのみ、マネージャー含む)、データエンジニアなども所属しています。
そのうち分析担当メンバーは、

  • プロパー: 1名
  • 業務委託: 3 名

の少数精鋭チームで動いており、主に TVer の事業部全体の分析支援を依頼ベースで担っています。

データ分析支援の依頼について

どこから依頼が来るか

事業部での施策推進においてデータが必要になる場面は多いため、依頼元は多岐に渡ります。

役割 主な依頼内容
PdM 新機能の評価、仮説検証 UI変更の効果測定
ディレクター ログ設計、基礎分析 新機能の計測用ログ設計、各種機能の利用状況把握
マーケティングCRM キャンペーン施策、Push 通知施策の評価 Push・メルマガ配信セグメントの提案
事業戦略 KPI設計 次期KPI策定に向けた基礎調査、KPIツリー提案
放送局 キャンペーン施策評価 SNS施策のコンバージョン計測

単発依頼のものもあれば、長期的に施策をフォローするものもあります。
Push 配信施策については、ツール導入初期から評価設計やデータ連携の整備に継続的に関わっています。

TVer では分析作業が分析チームに閉じておらず、ビジネス側も SQL や Redash を使って自ら分析するような対応が広まってきています。
なので社内で発生する分析業務を全て担っているわけではなく、

  • 複雑なクエリを書かないと分析出来ないとき
  • 効果検証など専門性が必要なとき
  • そもそも何を分析したらいいか分からないとき

といった場面で分析チームに依頼が寄せられるように感じます。

依頼が来るタイミング

施策は次の図のようなステップに分解できます。
どのステップで相談が入るかは施策や担当者によって大きく異なります。
分析担当者は依頼を受けた段階で コントロールできる範囲 を明確にし、その中で最適なアウトプットを設計するようにしています。

分析チームで定義している施策の流れ

データの面白さ

TVer のデータはとにかくめちゃくちゃ面白いです。

行動ログの粒度が細かい

行動ログは大きく分けると 3種類あります。

ログの種類 発火タイミング
画面遷移ログ HOME 訪問、マイページ訪問など画面が切り替わるタイミング
イベントログ コンテンツのクリック、お気に入り登録など
視聴ログ 再生開始、停止、シーク移動、一時停止・再開、視聴終了など

これらを組み合わせることで例えば、

  • マイページの絞り込み機能の利用状況と、利用時のエピソード到達率
  • HOME から再生までのファネル分析
  • おすすめ欄経由再生のプリロール突破率(広告視聴体験の分析)

などユーザーの行動を非常に高い解像度で追うことができます。

自社開発ログで突合しやすく、分析しやすい

ログは全て自社で設計・開発しています。
そのため、

  • ログ仕様が統制されている
  • 各種テーブルのスキーマ構造が統一され、横断的に扱いやすい
  • 画面遷移ログ × イベントログ × 視聴ログをきれいに突合できる

といった特徴があります。
結果として、前述のような分析をシンプルなクエリで素早く行えることが可能になっています。

自社開発ログのポリシーについてはこちらの記事が詳しいです。

TVer におけるログ収集のポリシー (1/2) - TVer Tech Blog

TVer におけるログ収集のポリシー (2/2) - TVer Tech Blog

社会インフラ級のデータ規模

TVer は社会インフラレベルの事業規模のサービスであり、日々数十億規模のログが収集されています。

speakerdeck.com

膨大なデータと多様な切り口があるため、探索的な分析がいくらでもできます。
まだ活用しきれていない領域も多く、分析者として腕の振りどころが非常に大きい環境です。

放送 × 配信のデータを扱える

TVer では配信の視聴データだけでなく、テレビ放送の視聴データも収集しています。
そのため、

  • 放送番組の見逃し視聴の行動分析
  • 裏被りの時間帯の視聴行動パターン

など、テレビ視聴と配信視聴のクロス分析が可能です。
ここは動画配信サービスの中でもかなりユニークなポイントです。

チーム文化

分析チームは、少人数ながら以下の文化が根付いています。

相互レビューとオンボーディング

クエリ/ロジック/分析の方向性を相互にレビューし合い、どんな依頼でもアウトプットの品質を上げられるようにしています。

新しくジョインした方には、オンボーディングとしてログ仕様や BigQuery、Redash の使い方、過去の分析例などを共有しつつ、最初の分析はレビューを通じて一緒に進めています。
相互レビューを通じて SQL や分析設計のスキルが身に付くので、自然と出来ることの幅が広がっていきます。

分析定例

社内の「データ分析に携わる人」「データ分析に興味ある人」が集まり、

  • 業務で実施した分析内容の共有、相談
  • 参加したイベントの紹介
  • 最近読んでる本の紹介

など、ゆるい勉強会も兼ねて知見を共有し合っています。
現在は隔週で実施しています。

データの流れを理解する

分析チームでは、

「データ分析をするなら、データが"どこで、どう生まれ、どう流れてくるのか" を理解するべき」

という考え方を大切にしています。
ログを扱う時、

  • どの操作/どのタイミングで発火するのか
  • どのように収集されるのか
  • どのような処理が行われてテーブルに入るのか

を理解しているだけで分析の質がまったく変わります。計測ミスや解釈のズレにもすぐ気付けるようになります。
そのため分析官でもデータパイプライン構築などいわゆるデータエンジニアリング領域の業務に挑戦することが可能です。
(自分も昨年データマート基盤を開発しました

このあたりの "領域横断" な雰囲気は小規模チームならではの魅力だと思います。

おわりに

ここまで紹介したように業務の大半はアナリスト的な業務ですが、最近はデータサイエンス寄りのことも少しづつ挑戦しています。

  • Push 向けのレコメンドモデル
  • 再生回数・お気に入り数の予測モデル
  • 分析エージェント構築

これらは、事業部から「これ作って!」という明確な依頼があるわけではなく、なんとなく課題っぽいものを拾って形にしたり、完全に興味ベースで始めたプロジェクトもあります。
まだ検証段階ですが、少しずつ実用化に向けて動いているところです。
TVer は事業規模もデータの厚みも大きく、やろうと思えばもっといろんな領域に挑戦できると思います。

もしこの記事を読んで、
「こういう分析やってみたいかも」
「このチームでデータ活用を進めてみたい」
と思っていただけたら、ぜひ一度カジュアルにお話ししましょう。

まだまだやりたいことがたくさんあるので、仲間が増えると嬉しいです。

herp.careers

AWS re:Invent 2025 参加レポート

この記事は TVer Advent Calendar 2025 12日目の記事です。

こんにちは。TVerでバックエンドエンジニアをしている横尾です。

先日、ラスベガスで開催された世界最大級のカンファレンス AWS re:Invent 2025 に参加する機会をいただきました。 現地では「AI Agent」というキーワードが至る所で飛び交っており、開発者体験そのものが大きく変わろうとしている熱気を肌で感じました。

今回の記事では、現地のリアルな体験談とともに、バックエンドエンジニアの視点で感じた「AIエージェント元年」の実態と、TVerの開発に活かせる具体的な知見をご紹介します。


1. re:Invent 2025 の歩き方

会場の熱気と移動のリアル

今年も re:Invent はラスベガスで開催されました。The Venetian、MGM Grand、Mandalay Bay など巨大ホテル群が会場となり、セッション間の移動だけで1日2万歩は軽く超えます。

Keynote会場は早朝7時からEDMのDJパフォーマンスで振動し、数万人のエンジニアが一堂に会する光景は圧巻でした。この規模感こそが、世界のテックトレンドの中心にいることを実感させてくれます。

AWS re:Invent 2025 Keynote 会場

「英語の壁」を越える参加ハック

日本からの参加者にとって最大の壁は「言語」ですが、今年はテクノロジーの力でその壁が低くなっていました。

  • Google Meet のリアルタイム翻訳: 講演者の英語音声をリアルタイムで日本語字幕化。技術用語の文脈も正確に捉えてくれます。
  • Gemini による即時要約: セッション終了後、Geminiに「今の議論のポイントをまとめて」と投げるだけで、日本語の要約ノートが完成します。

Google Meet リアルタイム日本語翻訳


2. Keynote から見える「AIエージェント」へのパラダイムシフト

"Assistant" から "Agent" へ

AWS CEO Matt Garman の Keynote で繰り返されたのが、このフレーズです。

"AI assistants are starting to give way to AI agents that can perform tasks and automate on your behalf."

これまでのチャットボット(Assistant)は「質問に答える」ことが主でしたが、これからの AI Agent は「目的を与えれば、計画を立て、ツールを使い、タスクを完遂する」存在になります。

TVer の文脈で考えると

Swami Sivasubramanian VP の言葉も印象的でした。

"For the first time in history, we can describe what we want to accomplish in natural language, and agents generate the plan."

これをTVerのサービスに置き換えると、「来週のドラマ特集を組んで」と指示するだけで、過去の視聴データから番組を選定し、CMSに入稿し、編成スケジュールを組む——そんな世界が現実味を帯びてきたということです。


3. セッションレポートとTVerへの活用

ここからは、具体的なセッション内容と、それをTVerのシステムにどう活用できるかを紐解いていきます。

動画コンテンツ処理の自動化

主なトピック: From Hours to Minutes (DEV334), Amazon Nova

長時間の映像からショート動画を自動生成するパイプライン(Transcribe + Nova + Polly)の実例紹介です。マルチモーダルモデル「Amazon Nova」が、映像の文脈(シーンの意味)を理解してカット割りを行う点が革新的でした。

ショート動画生成パイプライン

💡 活用ポイント

  • ハイライト自動生成: 1時間のドラマやバラエティから「見どころ」を自動抽出するようなことができそうです。

  • 文脈理解: 単なる顔認識ではなく「盛り上がっているシーン」を抽出できるため、クリエイティブな判断の補助として活用を検討できます。

"脱・手動" レコメンドとメタデータ生成

主なトピック: Multimedia Understanding on Bedrock, Multimodal Embedding Search

「動画の中身」をAIが理解する技術です。Bedrock を通じてサムネイルや動画内容からメタデータを生成したり、マルチモーダル埋め込み(Embedding)を使って「雰囲気の似た番組」を検索したりすることが可能になります。

💡 活用ポイント

  • タグ付けの自動化: 出演者、ジャンル、雰囲気などのメタデータのタグ付与自動化が可能になりそうです。

  • 検索精度の向上: キーワード検索に加え、「このシーンのような番組」といった直感的な検索・レコメンドも検討ができそうです。

メディアワークフローを統括する「Media Agents」

主なトピック: Media Agents, Content Compliance Automation

動画分析、品質管理、コンプライアンスチェックといった個別のタスクを、Supervisor Agent(監督役エージェント) が統括して自動処理するアーキテクチャです。

コンテンツコンプライアンス自動化

💡 活用ポイント

  • コンプライアンス対応: 配信前チェックをAIエージェントが一次スクリーニング。人間は最終確認のみに集中するフローの構築などが検討できそうです。

  • 自律的な品質管理: エラーなどを検知したら、自動で再処理フローを回すような自律システムの構築も検討できそうです。

Amazon Q Developer と AWS DevOps Agent

主なトピック: Amazon Q Developer, AWS DevOps Agent, Game Day

Amazon Q は、「便利なコード補完ツール」にとどまらず、開発プロセス全体をサポートしてくれるパートナーのような存在になりえると感じました。

特に今回発表された AWS DevOps Agent は、運用のあり方を大きく変えるものです。 「Always-on incident triage(常時稼働のインシデントトリアージ)」により、障害発生時にエージェントがログを解析し、根本原因を特定し、解決策まで提示してくれます。

Game Day での実感

Game Day(ハンズオン形式の競技イベント)では、実際に Amazon Q を使い倒してその威力を体感しました。AWS Workshop Studio という環境で、リアルタイムにスコアを競い合います。

Game Day - Amazon Q による自動コード生成 (Amazon Q がインフラのエラーを確認して改善策を提案する様子)

💡 活用ポイント

  • 開発効率化: エンジニアが「コードを書く時間」を減らし、「どのような機能をユーザーに届けるか」という設計と意思決定の時間を最大化する。

  • 運用の自動化: DevOps Agent を導入し、リアクティブな障害対応(Firefighting)から、プロアクティブな運用改善へとシフトする。


4. おわりに:Renaissance Developer を目指して

AIエージェント時代に、エンジニアはどうあるべきか

今年の re:Invent のメッセージは明確でした。「AI Agent」はツールではなく、共に働くチームメイトになるということです。

AWS CTO Dr. Werner Vogels は、最後の Keynote「Renaissance Developer(ルネサンスデベロッパー)」 という概念を提唱しました。 これは、AI時代に求められるエンジニアの姿として、以下の5つの資質を持つことの重要性を説いたものです。

  1. 好奇心 (Curiosity): 新しい技術や解決策に対して常に探究心を持つ
  2. システム思考 (Systems Thinking): 部分最適ではなく、全体を俯瞰して設計する
  3. コミュニケーション (Communication): 人間ともAIとも正確に対話する能力
  4. オーナーシップ (Ownership): 自分の作ったものに責任と誇りを持つ
  5. ポリマス (Polymath): 深い専門性を持ちつつ、幅広い知識を兼ね備える

その仕事は、あなたのものです

"The work is yours, not the tool's."

この言葉は、Game Day で Amazon Q と共に課題に挑んでいたときに、私自身も強く再認識したことでもあります。

Amazon Q は正確なコードを書いてくれましたが、「どの課題を優先して解くか」「ユーザー(この場合は競技のスコア)にとって最大の価値は何か」を判断することが、今後一層求められるでしょう。

AI Agent は効率を劇的に高め、より大きな課題に挑むための道を開いてくれます。しかし、最終的な品質への責任、そして「TVerを通じてユーザーにどんな体験を届けたいか」という情熱は、AIには代替できません。

re:Invent 2025 で得た知見、そして Renaissance Developer としてのマインドセットを持ち帰り、TVerを次のステージへと進化させていけたらと思います。

AWS CodeBuild + Docker Serverによるキャッシュ永続化の恩恵と運用の課題

この記事は TVer Advent Calendar 2025 5日目の記事です。

はじめに

こんにちは。TVerでDevOpsを担当している鈴木です。

TVerのバックエンドではECSを活用しており、アプリケーションの変更にはコンテナイメージのビルドが必須です。 開発組織の拡大に伴い、1日のビルド回数が増加したことで、デプロイ待ち時間が無視できない課題となってきました。

今回は、ビルド時間を短縮するためにCodeBuildの「Docker Server」機能によるキャッシュ永続化を試みた事例を紹介します。 結果としてビルド時間を約50%ほど高速化しましたが、運用上の課題により採用を見送った経緯までを共有します。

なぜDocker Serverの導入を検討したか

従来のCodeBuildでは以下の理由からビルドごとのキャッシュ効率が悪いという課題がありました。

  • 環境のリセット: ビルドごとにビルド用環境が破棄されるため、ローカルのDockerレイヤーキャッシュが残らない
  • ネットワークコスト: --cache-from でECRからプルするには転送に時間がかかる

上記課題をできるだけ少ない工数で解消するためにCodeBuildの「Docker Server」機能を試してみることにしました。

Docker Serverはコンテナイメージのビルドをリモートホストに集中化することでビルドを高速化でき、デプロイの待ち時間を短縮することができます。 AWS CDKを利用している場合、以下のようにCodeBuildの定義に dockerServer プロパティを数行追記するだけで有効化できます。

// CodeBuildプロジェクトの定義
const cfnProject = new CfnProject(stack, 'SampleProject', {
  // ...その他設定
  environment: {
    // type, image, computeType などの他の環境設定
    dockerServer: {
      computeType: codebuild.ComputeType.X_LARGE, // Docker Serverのインスタンスタイプを指定
    },
  }
});

Docker Serverの詳細の仕様やコンソールからの有効化手順については公式のドキュメントが分かりやすいのでこちらを参照ください。 aws.amazon.com

導入効果:49%の高速化を実現

Docker Serverを有効にしたところ、ビルド時間が4分 58秒 -> 2分 31秒と大幅に短縮されました。

変更頻度の低いベースイメージの取得や go mod download がキャッシュされるようになったことで、ビルド時間を49%削減できました。

直面した「安定性」の壁

速度面では期待以上の成果が出ましたが、運用を開始してからいくつかの課題に直面しました。 今回検証したビルドプロセスは、最大10並列でのコンテナ生成に加え、単一プロジェクトで複数環境のビルドを並行処理するため、極めてリソース負荷が高い特性を持っていました。

ビルドのタイミングによってはCodeBuildとDocker Server間の一時的な通信エラーと思われる以下のような事象が発生しビルドが失敗するようになりました。

ERROR: failed to run Build function: malformed header: missing HTTP content-type
ERROR: DeadlineExceeded: context deadline exceeded
ERROR: failed to receive status: rpc error: code = Unknown desc = malformed header: missing HTTP content-type

多くのエラーは一時的なものであり、リトライで解消することもありました。しかし、中には15分以上リトライしても同じエラーが解消されないケースも発生することもありました。 リトライが発生すれば、せっかくの高速化の恩恵は帳消しになりむしろ待ち時間は増えてしまいます。

健全な開発サイクルを維持するためには、ビルド速度の短縮だけでなく、「実行結果に対する信頼性」が不可欠です。 不安定な高速化は、結果として手戻りを生み、開発効率を下げてしまうためです。

また、根本原因の特定や監視が困難であることも、採用を見送る大きな要因となりました。

多数のビルドが並列実行される環境下では、Docker Server側のCPUやメモリリソースが逼迫している可能性を疑いました。 しかし、CodeBuildの管理コンソール上にはDocker Server固有のメトリクスが見当たらなかったため、AWSサポートへ問い合わせたところ「現時点ではDocker Serverの内部状況を確認できるメトリクスなどは提供されていない」との回答をいただきました。

上記からビルド時間の短縮とビルドの安定性の天秤にかけた結果、今回はDocker Serverの導入を見送ることとしました。

まとめ

今回検証したDocker Server機能についても、詳細なチューニングを行えば安定化の余地はあったかもしれません。 しかし、今回は「少ない工数で迅速に成果を出すこと」を重視したため、導入を見送る判断に至りました。

もちろん、手段はこれに限りません。 今後はDocker Build CloudなどのSaaS活用も含めより幅広い選択肢を検証していく予定です。

より良い開発者体験を提供するために、これからもインフラ改善に取り組んでいきたいと思います。

TVerインフラアーキテクチャの現在地(2025年)

TVerインフラアーキテクチャの現在地

TVerクラウドインフラチームでインフラ周りを担当しています西尾です。 前回までは直近で行っていた施策をご紹介していましたが、今回はもっと根本的なTVerの動画配信のインフラについてどうしようとしているかについて書いていければと思っています。

現在のTVerインフラアーキテクチャについて

現在の動画配信については今までに何度かその構成について触れましたが、主にAWS上でALB・ECSを主軸としたサービスを利用して稼働しています。 この構成についてはこれから移行する次世代構成との説明をわかりやすく区別するために、ここからはTVerアーキ1.0と仮称します。

現在のTVerの構成(TVer1.0)

では何故今のこのTVerアーキ1.0の構成からわざわざ変えるのかというと現在の構成では幾つかの問題を抱えていました。

サービス拡大により顕在化した問題

お陰様でTVerを皆様に提供し始めて今年で10周年となりその間に視聴ユーザーも右肩上がりで増えていきました。 その中でシステム構成や運用上で幾つかの問題点が積み上がって来ました。

  • Prewarmingの問題(事前暖気)
  • 急激な地上波からの流入によるトラフィック増(枠切れ問題)
  • リリース方式、カナリアリリースの簡略化
  • 開発環境の増加による運用コスト、費用の増加問題(多面化多すぎる問題、新規環境構築の高速化)

など主に上記のような問題が出てきました。 ではこれらについては一つ一つ説明して行きます。

Prewarming(事前暖気)に関連する問題

これについては過去に取り上げています。 今年の春にLCUの一般提供を開始したタイミングでALBのPrewarming費用が急激に増えた事が発端となりました。 それまでALBのLCUを一時的に増やすことで予見される急激なトラフィック増に対応していました。 これに関しては事前暖気が必要で人的な運用コストの問題でなんとかしようと考えていましたが、なかなか手が付かない状態でしたが、費用問題が新しく出たことで本腰を入れて対応が必要になりました。 この発端により運用コストと費用を下げるためにNLBを選択する流れとなりました。 ここではその内容について詳しくは触れませんが、ALBをNLBとNginx Routerに移行することで事前暖気の運用を無くし、そのタイミングで必要な数のLCUでスケールが行われることで費用を抑えることを目的とした構成変更を行いました。 そしてこの取り組みは既存の構成から移行したアーキになりましたのでTVerアーキ1.5と呼ぶことにしました。

NLB構成による変更箇所(TVer1.5)

このTVerアーキ1.5構成は既存の問題に対しての段階的なリアーキとなり、その他課題になっていた問題をまとめて解決出来るものではありませんでした。 ただNginxを挟んだことで別ラインで行っていたTVer落ちないプロジェクトをここで取り組むことが出来ました。

TVer落ちないプロジェクト(補足)

これは事の発端が前回の話で上がりましたDBメンテナンスによりサービス断が発生するので、それに対して根本的な取り組みをしようというのがこのプロジェクトの主旨になります。 DBにアクセス出来ない場合はアプリケーション側でどうにかするのが手段としてありますが、ただ今回の場合は各アプリケーションにフォールバックの変更を入れるのでは無く、また要件として一律に対応できる部分もありましたので、このプロジェクトではDBアクセス出来ない場合は個別にアプリケーションで対応せずにインフラ側でどうにかするという選択になりました。 要件として一律に対応とありますが、これは下記のように許容出来る部分がありました。

  • 全てのAPIエンドポイントが対象では無く、TVerの配信サービスを提供続けるために必要となるコアな機能をターゲットとする
  • DBに接続できない場合、その取得するレコード情報は少し前の内容を返してもOK

そのため、これを実現するためにNginx + Lua + Redis構成を取ることでDBが落ちた場合でも少し古い情報ですが返す事ができるようになったのでサービスを継続的に提供出来るようになりました。 ただこの構成はまだQAテストが十分ではないので現段階ではまだ本番運用に入っていません。 しかし来年初めには本番運用を行う事ができると思いますので、皆様により安定したサービス提供を行えるようになるのではないかと期待しています。

新しいインフラアーキテクチャへの道

これまでにTVerアーキ1.0/1.5の構成について取り上げましたが、ここからは来年から順次実施されるリアーキについて話をして行きます。 これはPrewarming以外の問題点についても真剣に取り組み問題点を解決することを目指した新しいインフラ環境になりこれがTVerアーキ2.0環境と呼ばれるものになります。 TVerアーキ2.0の説明に入る前に先程の現状の問題点で取り上げていない部分について説明して行きます。

急激な地上波からの流入によるトラフィック増(枠切れ問題)

これはTVerのサービスでずっと課題となっていました問題になります。 地上波コンテンツの放送終了に伴い、TVer側に一気にユーザーが来ることで急激に負荷が上がることがあります。 今年で現在までで一番インパクトがあった枠切れは、それまでの視聴ユーザーが短時間(1分以内)に15倍ぐらいまで増えたコンテンツがありました。 現在までこのような枠切れにどのように対応しているかと言いますと、人気で枠切れの可能性があるコンテンツに関してはコンテンツの配信チームから情報をインフラ側に提供してもらい、その見積もりユーザー数から事前にインフラリソースをスケールすることで対応してきました。 これに関しては費用もかかりますが、何よりも人的な事前のスケーリング作業を行う必要があり、運用コストがかかっていました。

*事前のスケール作業の効率化は日々取り組みとしてやっており、一から全てのリソースをぽちぽち実施するということは流石にありません。またここで増やすリソースはLBのLCU以外のコンテナサービスやDBのレプリカの追加を対象としています。

そのため、このような事前作業を無くし運用負荷を下げるための施策が求められていました。

リリース方式、カナリアリリースの簡略化

大きな修正が入ったリリースを安定的に実施したいので、カナリアリリースについては弊社でも行っていました。 ただこのカナリアリリースについてはそこまで簡略化がされていなく、しかもこのリリースはALBの機能を利用して実現していましたのでNLB移行した事で部分的に出来なくなってしまいました。 そのためカナリアリリース出来るようにNginx側で実装することで一応それらしいリリースは出来るようにしましたがこの方式には問題点もありました。 それはこの方式のカナリアリリースの割合調整を行う場合は動的に実施することができず、Nginx Routerの入れ替えが必要になり、また実際リリースを行う開発者の体験が悪くこの方式はいつまでも取り入れる方式では無いと最初から分かっていました。

開発環境の増加による運用コスト、費用の増加問題(多面化多すぎる問題、新規環境構築の高速化)

複数の開発環境があることは珍しく無いと思いますが、弊社でも開発環境は複数存在しDevXX系と呼ばれて同時進行で機能開発を進めるために必須となっています。 ただこれに関しては、丸々環境が存在するので費用もかかり、まただからと言って必要な時に必要な環境を直ぐに作れるかというとそうでもなかったりします。 インフラに関してはTVerのサービスはCDKを利用しているのでコード化はしていますが、それはあくまで一つの機能の中で個別に定義している形となります。 そしてTVerのサービスに関しては複数のコンポーネントが協調して動いていますが、ただそれらはコードのレポジトリやCDKのスタックも違ったりして1箇所で集権的に管理されておらず、その上全てが自動的に協調してdeployできる状態にもなっていません。 そのため新規の環境構築するために自動化を一時期取り組んでいましたが、全ての自動化が難しく手作業も混在して環境構築に現状時間がかかっています。

*それでも昔は1週間とか1環境の追加にかかっていましたが、1.5日ぐらいに短縮はされています。

またTVerサービスをちゃんと動かすためには複数のコンポーネントが必要であり、それが問題を複雑化しています。

新環境の要件

上記のように複数の課題があり、それを踏まえてTVerアーキ2.0ではこれだけは譲れない解決すべき問題と目指すべきスケール目標を設定しました。

  • LB・コンテナのスケールの短縮(1分以内) Must
  • 限定的なリソースの事前増強 Must
  • 多面化環境構築の高速化 Should
  • 選択的なリリース方式 Should

EKS周りの構成(TVer2.0)

それでは上記について一つ一つ取り上げて行きたいと思います。

LB・コンテナのスケールの短縮(1分以内)

地上波からの流入は短時間(1分以内)にそれまでの何倍もの流入があります。 この時間はとても重要でアクセス出来ないユーザーが発生しますと、せっかく続きをTVerで視聴しようとしたのに見れないと大きな失望を与えてしまいます。 そのため現在は事前に枠切れがわかるものに関しましては、リソースを事前に増やすことでその問題に対応しています。 しかし、全ての枠切れで大きなアクセスが来るかは不明確な部分もあり、リソースを適切に運用できているというと必ずしもそうではありません。 また枠切れ以外の急激なトラフィック増、例えば近年ではリアルタイムでネットでバズる事で意図しない短時間のユーザー増も考えられます。 それらに対応するために、LBは短時間でスケール出来るNLBを選び、その後ろにあるサービス群(コンテナサービス)に関しても1分以内に起動からサービス提供まで行える状態になることを譲れない要件としました。 現在のTVerアーキ1.0/1.5ではECSのfargateを利用していますが、これをEKS(Auto Mode)に移行することにしました。 当初はEKSにすることで実際この要件を満たすかどうか半信半疑でしたが、POCや負荷試験を通してバルーンPodなどと組み合わせれば1分以内に起動することが出来るということがわかり、本格採用に至りました。

  • TVerアーキ1.0/1.5 ECS(fargate) Taskの起動から、runningになりアプリケーションの初期化、リッスン状態になるまでにおおよそ1〜2分の時間を要する

  • TVerアーキ2.0 EKS(Auto Mode) Podの確保、立ち上げからのアプリケーションの初期化、リッスン状態になるまでにおおよそ50秒〜60秒に収まる

ただしこの比較はあまりフェアじゃ無いものであり、ECSであれば最近出ましたECS マネージドインスタンスで比較した方がより速い起動になると思います。 ただ今回に関しては、NLB構成にしたことでNginxと協調出来るルーティング構成がよくEKSの場合Ingress controllerでその機能を補えるということで当初のままで行くことにしました。

*ただここからその後、NGINX Ingress Controller以外の他の選択をする必要に迫られると思いませんでした。 ただ今回に関してはまだ次の移行先はまだ未定なのでNGINX Ingress Controllerのままで構成は説明して行きます。

限定的なリソースの事前増強

現在まで実施しているリソースの事前スケールが全てEKSを採用することで無くなるということは実は期待していません。 ただ事前に増やす必要がある規模は通常時のリソースの2倍にすることが最も多く、その増強運用のオペレーションが無くなるだけでかなり運用負荷が下がることを想定しています。 そのため、ものすごいアクセス増が見込まれるコンテンツに関しては心理的な安全も確保したいので手動でリソース増強を今まで通りに実施しようと思っています(この場合通常時のリソースの4〜10倍の間)。 ただこの頻度に関しては年に数回とかに収まると想定しています。

多面化環境構築の高速化

現在開発環境はECSのクラスターを含め、その開発面と同じ数のセットで倍増しています。 EKSにすることで、開発は同じEKSクラスターに共有して存在しその中でサービスとして分離された状態にすることでリソースの管理をしやすく、コストも抑えるようにします。 ただしセキュリティーやリソースの分離を鑑みて、またあまりクラスターが多すぎるとkubernetesの更新作業も面倒になるので下記のように環境を分けなるべく運用負荷を上げないようにしました。

環境別EKSクラスタ

選択的なリリース方式

カナリアリリースなどを実施する上でそれを実際に行うのは開発者側であり、開発者がいつでもリリースしやすい体験で行えるのが望ましいです。 今回のEKS環境のリソースデリバリーはArgoを採用していますので、Argo Rolloutsを利用することでカナリアリリースは実現できます。 それは現在のNginxでやっている加重方式よりはやりやすくなると期待しています。

*Argo以外の製品もありますが、Istioなどのサービスメッシュを必要とするのでまだ弊社ではそれには手を出していないので選択外となりました。

また当初はArgo Rolloutsに関してはLBなどとは連携せずに、純粋にPod数単位でユーザートラフィックを分散させようと思っています。 これは相乗りで動くことでLB IngressとArgo Rolloutsとの対応が1対1になるか不明なのもあります。

まとめ

まだこのTVerアーキ2.0構成に関しては走り始めたばかりです。 開発環境でECSからEKSにサービスを移して機能試験や負荷試験を実施した段階なので、まだまだやることは山積しています。 その上Ingressの移行問題も出てきたのでやることはさらに増えてはいますし、またこのリアーキに関してはコンテナオーケストレーションなどの製品の選定で終わるものでもなく更に裏にあるDBなども対象に含んでいます。 ではそれでも前に進んでやるかと問われますと、増え続けるユーザーに安定的にサービスを提供し、落ちないTVerを目指すために必要な過程だと捉えています。

ストレスフリーで高速なCIテストのために工夫したこと

この記事はTVer Advent Calendar 2025 10日目の記事です。9日目の記事はta9tさんの「toC×エンタメPMとして「欲しい」を理解し続ける」でした。

はじめに

こんにちは、Backend Enabling Teamの伊藤(@sou_world) です。

TVerのバックエンドはGoで書かれておりGitHubのPRを利用して開発をしています。PRはコードレビューだけでなくテストやlint、labelチェックなどの様々なCIを通すことで初めてマージできます。

ここ1年の開発チームの拡大と開発速度の上昇に伴い、CI実行時間が徐々に増加し開発体験に影響が出始めてきました。なかでもテスト実行がボトルネックで、去年比で2倍以上遅くなっておりcommitごとに15分以上実行がかかる状態になっていました。

開発組織の拡大は良いことですが、その結果個々人の開発サイクルが遅くなってしまっては本末転倒です。なんとか速くしたいです。

今回はGitHub Actions上で実行しているGoのテストを高速化するために工夫したことについて紹介します。

改善前のCIテストについて

実行環境と所要時間

GitHub Hosted Runner (Linux x64, 2 CPU, 7 GB RAM) を使用。

  • キャッシュなし: 約15-20分
  • キャッシュあり: 約8-10分

実行フロー

  1. PRのopen/commit/mergeが実行されるとgo test用のCIが発火される
  2. GOCACHEおよびGOMODCACHEをCommit単位で取得しに行く
  3. go test -race ./... を実行する

また、最新のmainを取り込めていないとマージできない制約をGitHubの設定で行っていました。そのためmainへのマージタイミングがメンバー間で重なると、マージできるまで何度も実行し続けなければならない状況でした。

改善のためにやったこと

merge queueの導入

何よりもストレスだったのがmainへの取り込みです。 mainへのマージは最新のmainが取り込まれていないと実行できないように設定されています。

最新のmainを取り込んでCIが終わるまで10分以上待ってその後マージボタンを押します。この3ステップを全て手動で実行しなければいけません。この時点でもちょっと嫌な雰囲気が出ています。

このCI実行中に別のPRがマージされる場合はもっと大変です。 再び最新のmainを取り込んでCIの完了を待ってマージをしなければなりません。1回でも苦痛ですが、さらに運が悪いとこれが数回起こる可能性もあります。最悪の開発者体験です。

これを解決すべくmerge queueを導入しました。各開発者は従来の面倒な作業の代わりにボタンを一個押すだけで済むようになりました。

-raceフラグによるオーバーヘッドの解消

Goのテストでは-raceフラグを使用することで、データ競合を検出できます。これは並行処理のバグの早期発見に有用な機能ですが、テスト実行時間を増加させる要因となります。

TVerではCIテストの構築時はすべてのテスト実行で-raceを有効にしていました。当時はコードが小さく実行時間も十分許容でき、全てのテスト実行で -race をつけることの利益の方が高かったためです。 しかしながら開発組織の拡大に伴い -race は大きなボトルネックとなりました。

現在はmerge queueとmainへのマージ時のみ-raceを有効にしています。開発の中心であるPRへのcommitではCI速度を優先し、mainへのマージ前後では品質の担保を優先する形にしました。

これにより約30%の短縮を実現でき15-20分から10-15分の実行に短縮できました。

キャッシュ戦略の最適化

GitHub Actionsでは10GBまでキャッシュを利用できます。GOCACHEはPRの各commit単位で作成していましたが、10GBを数GB超過している状態でした。 そのためGOCACHEをPR単位で作成する形へ変更し、キャッシュを10GB以内に収めました。

これによってキャッシュが各PRで確実に利用できるようになり、各PRの2回目以降のCI実行時間の確実な短縮を実現できました。

ActionsのRunnerのスペックを上げる

Private RepositoryでGitHub Actionsを利用する場合、デフォルトでは2CPUのRunnerまでしか利用できません。

TVerのバックエンドではリアーキテクチャを進めており新旧アーキテクチャが混在している状況で、かなりのpackageが存在している状態です。 go test ./...の各パッケージのテストを同時にたくさん実行できれば、より実行時間を短縮できます。そこでRunnerのスペックを上げることを検討しました。

Self-hosted RunnerやSaaSを利用する選択肢もありましたが、今回はGitHubが提供しているLarge runnerを採用しました。 DevOpsは現状2人で取り組んでおり利用したいCIも1つだったため、導入と管理が簡単であることを最優先としたためです。

現在は8CPUのRunnerを利用していますが、これによって実行時間は50%改善できました。結局スペックは正義ですね。

改善後のCIテストについて

実行環境と所要時間

GitHub Hosted Runner (Linux x64, 8 CPU, 32 GB RAM) を使用。

  • キャッシュなし: 約5-8分 (改善前: 15-20分 → 約60-70%短縮)
  • キャッシュあり: 約2-4分 (改善前: 8-10分 → 約60-75%短縮)

実行フロー

PRのopen/commitの場合

  1. go test用のCIが発火される
  2. GOCACHEおよびGOMODCACHEをPR単位で取得しに行く
  3. go test ./... を実行する

PRのmergeの場合

  1. go test用のCIが発火される
  2. go test -race ./... を実行する

merge queueを利用しており、各開発者はボタンを1回押せばPRのマージ作業が完了できるようになりました。

終わりに

今回のCIテストの改善ではテスト品質を維持しながら開発体験を向上させることを目指しました。 GitHubが提供している機能の活用、ビルドキャッシュの最適化、マシンスペックの変更など基本を抑えることで速度と開発者体験を向上させられます。

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

明日は西尾さんの「TVerインフラアーキテクチャの現在地」です。