TECH PLAY

タイミー

タイミー の技術ブログ

264

はじめに こんにちは。プラットフォームエンジニアリングチームに所属している徳富( @yannKazu1 )です。 先日、本番環境でドキュメントの大規模更新を行った際にCPUが100%に張り付く事象が発生しました。検証環境で同じ更新処理を試しても再現せず、原因がわからない。そこで「そもそも自分、Elasticsearchの中で何が起きてるかちゃんと理解してないな」と気づき、インデキシングから検索までの仕組みを一から整理してみました。 同じように「なんでこうなるの?」と悩んでいる方の助けになれば嬉しいです。 前提知識 本記事では、Shard内部の動作にフォーカスして説明していきます。「そもそもShardって?Segmentって?」という方は、 メルカリさんのこちらの記事 がとてもわかりやすいので、先に読んでおくことをおすすめします。 全体の流れ まず、大枠の流れを押さえておきます。 インデキシング開始 — ドキュメントがメモリバッファに蓄積される Refresh — メモリバッファの内容からセグメントが作られ、検索可能になる 検索 — すべてのセグメントを対象に検索が実行される セグメントマージ — 小さなセグメントが統合され、削除済みデータも物理削除される シンプルに書くとこれだけなんですが、それぞれの段階で「何が起きているのか」「どんな時に負荷が上がるのか」を知っておくと、トラブル時の原因切り分けがしやすくなります。 では、各ステップを詳しく見ていきましょう。 1. インデキシング開始 ドキュメントがインデキシングされると、まずメモリバッファに蓄積されます。同時に、各シャードの Transaction Log(translog) にも操作が記録されます。 Lucene commitは変更のたびに実行するとコストが高すぎるため、その役割をtranslogが担います。万が一プロセスの終了やハードウェア障害が発生しても、translogから操作を再生することでデータを復旧できます。 なお、デフォルト設定( index.translog.durability: request )では、各リクエストごとにtranslogへのfsyncが発生するため、ディスクI/Oが完全にゼロというわけではありません。 参考ドキュメント: Near real-time search | Elastic Docs Translog settings | Reference 2. Refreshによるセグメント生成 デフォルトでは 1秒ごと にRefresh処理が走ります。この処理で、メモリバッファの内容がファイルシステムキャッシュに書き込まれ、 immutable(不変)なセグメント が新たに作られます。ここで初めて、そのデータが検索可能になります。 RefreshとFlush、何が違うの? ここで似た名前の処理が出てくるので、先に整理しておきます。この2つ、最初は「同じようなもの?」と思っていたんですが、実は 全く別の操作 です。 操作 やっていること 重さ 目的 Refresh メモリバッファ → メモリ内セグメント作成(ファイルシステムキャッシュ経由) 軽め 検索できるようにする Flush Lucene commit + translogクリア(ディスクに永続化) 重い データを永続化する 重要なのは、 検索可能にするのはRefreshだけ ということです。Flushは永続化のための処理であり、検索可能性には影響しません。検索はメモリ内のセグメントに対して行われるため、Refreshでセグメントが作られて初めて検索できるようになります。 Flushは、translogが一定サイズに達した時や、一定時間が経過した時に発生します。 Search Idleルール ここで重要なルールがあります。自動Refreshは、過去30秒以内に検索リクエストがあったインデックスだけが対象です(厳密にはシャード単位で管理されます)。つまり、検索トラフィックがあるシャードには定期的なRefresh(デフォルト1秒ごと)が走りますが、検索されていないシャードはバックグラウンドRefreshがスキップされ、リソースが節約される仕組みになっています。これはバルクインデックス時のパフォーマンス最適化を目的とした機能です。 「Refreshがスキップされている間に追加されたデータはどうなるのか」と疑問に思われるかもしれませんが、心配は不要です。アイドル状態のシャードに検索リクエストが来ると、その検索操作の一部としてRefreshがトリガーされ、完了してから検索結果が返されます。つまり、データ自体は問題なく検索できます。ただし、アイドル状態からの最初の検索はRefresh完了を待つ分、レスポンスが遅くなる可能性がある点には注意が必要です。 とはいえ、本番環境と検証環境では動きが変わってくる可能性がある点がポイントです。本番では常にユーザーが検索しているので定期Refreshが走ります。しかし検証環境では誰も検索していない場合、シャードがアイドル状態になり、検索時に初めてRefreshが走ります。同じ更新処理でも、裏側で起きていることがまったく異なる場合があります。 Refresh間隔は調整できます index.refresh_interval で設定可能です。大量データを投入する時は、この値を大きくしておくとセグメント数を減らすことができます。なお、アイドル判定の時間は index.search.idle.after (デフォルト30秒)で変更できます。 PUT /my-index/_settings { "index" : { "refresh_interval" : "30s" } } 参考ドキュメント: Near real-time search | Elastic Docs - Refreshの仕組み、ファイルシステムキャッシュ経由でのセグメント生成 Refresh API | Elasticsearch Guide - Refresh APIの詳細、30秒ルール Translog settings | Elastic Docs - FlushとTranslogの関係、Lucene commitの説明 General index settings | Elastic Docs - index.search.idle.after 設定、Search Idle機能の詳細 短期間に大量更新すると何が起きるか さて、ここからが本題です。短期間に大量の更新が発生すると、Refreshのたびに 小さなセグメントがどんどん作られていきます 。 セグメントはimmutableなので、「既存のセグメントにちょっと追加」ということができないんです。更新のたびに新しいセグメントを作るしかない。結果として、細かいセグメントが山のように溜まっていきます。 これが引き起こす問題 セグメントが増えると検索が遅くなる ファイルディスクリプタをたくさん消費する 後で説明するマージ処理の負荷が大きくなる 対策 大量にインデックスする時は refresh_interval を -1 (無効)にしておいて、終わったら手動でRefreshする。これだけでだいぶ違います。 参考ドキュメント: Tune for indexing speed | Elastic Docs 削除処理の仕組み ドキュメントを削除する時、実際にデータを消しているわけではありません。セグメントがimmutableである以上、「この部分だけ消す」ができないんです。 じゃあどうするかというと、 削除フラグ(tombstone)を付けて「削除済み」とマークする だけ。いわゆる論理削除ですね。 実際の流れ 削除リクエストが来る 対象ドキュメントに削除フラグを付ける 検索時はフラグ付きのドキュメントを結果から除外する 後でセグメントマージが走った時に、やっと物理的に削除される つまり、削除したつもりでも マージが完了するまでディスク容量は減らない んです。「削除したのに容量減らないな...」と思ったことがある方、これが原因かもしれません。 参考ドキュメント: Force merge API | Elasticsearch Docs 3. 検索時に何が起きているか 検索処理では、 すべてのセグメントに対して検索が実行されます 。各セグメントの結果をマージして、最終的な検索結果ができあがります。 ここで「セグメントが増えると検索が遅くなる」理由がわかりますよね。検索対象が増えれば増えるほど、当然時間がかかります。 キャッシュの話も重要です Elasticsearchには主に2種類のキャッシュがあるんですが、どちらもセグメントの変更に影響を受けます。 キャッシュ 単位 いつ無効化される? Node query cache セグメント単位 セグメントがマージされた時 Shard request cache シャード単位 シャードがリフレッシュされた時 新しいセグメントにはまだキャッシュがないので、最初のクエリは必ずキャッシュミスになります。しかもマージが走るとせっかく溜めたキャッシュも消えてしまう。 セグメントが頻繁に作られたりマージされたりする環境では、キャッシュがなかなか効かなくなります。 参考ドキュメント: Tune for search speed | Elastic Docs Node query cache settings | Reference 4. セグメントマージ — 重い処理 バックグラウンドで定期的にセグメントのマージ処理が走ります。小さなセグメントをまとめて大きなセグメントにする処理です。この際、転置インデックスの再構築が行われるため、CPUとI/Oを大量に消費します。 マージがもたらすメリット 細かいセグメントが大きなセグメントに統合されます 削除フラグ付きのドキュメントが物理削除されます セグメント数が減るため、検索が高速化します ただし、マージ中は重い マージ自体はとても重い処理です。マージが走っている間は、検索もインデキシングも影響を受けます。 ElasticsearchにはAuto-throttling(自動スロットリング)という仕組みがあり、マージがインデキシングに追いつけなくなると、インデキシング自体にブレーキがかかります。これは「セグメント爆発」を防ぐための安全装置です。 セグメントマージがどんな感じで進むのか、視覚的に理解したい方は こちらの記事 がおすすめです。 参考ドキュメント: Merge settings | Reference Force merge API | Elasticsearch Docs まとめ 長くなりましたが、ここまで読んでいただきありがとうございます。 今回学んだことで特に大事だなと思ったのは、この3つです。 セグメントはimmutable — 更新・削除のたびに新しいセグメントができる Refreshの30秒ルール — 検索がないシャードはRefreshがスキップされる マージは重い — CPU・I/Oを大量に使い、キャッシュも無効化される 本番環境で「なんか重いな」と思った時は、セグメントの状態やマージの発生状況も見てみてください。きっと何かヒントが見つかるはずです。 もし同じような問題で悩んでいる方がいたら、この記事が少しでも参考になれば嬉しいです。 ちなみに、今回の調査をきっかけに、チームメンバーがElasticsearchの詳細な状況を収集できる仕組みを整えてくれました。実際のデータをもとにした分析や考察、情報収集するための観点や方法については、そのメンバーが続編で紹介してくれるかもしれません。お楽しみに!
アバター
タイミーのプロダクトマネージャーの飯田です。 今回は、12/4に開催された プロダクトマネージャーカンファレンス (以下pmconf)に参加してきました。このイベントを通じて非常に有意義な学びを得られたため、タイミーのプロダクトマネージャー(柿谷、小宮山、鈴木、小西、佐々木、楠本、飯田)から、各セッションから学んだ内容を、全3回の記事で紹介します。 (本記事は、全3回のうち、Part3です。) ▪️Part1・Part2はこちら pmconf2025に参加してきました part1 pmconf2025に参加してきました part2 マルチプロダクトのカオスを制す。「プロダクトディシジョンレコード」で実現するチーム横断のアラインメント戦略 登壇者: 株式会社エス・エム・エス / プロダクト推進本部 アーキテクト プロダクトマネージャー 三浦 玄 氏 登壇資料: speakerdeck.com 株式会社エス・エム・エスで「カイポケ」のリニューアル責任者を務める三浦氏による、不確実性の高いマルチプロダクト開発における意思決定プロセス「プロダクトディシジョンレコード(PDR)」についてのセッションをレポートします。 ■ マルチプロダクトにおける「不確実性」の正体 カイポケは40以上のサービス・プロダクトを展開する巨大なバーティカルSaaSで、業務×業態の掛け合わせによる複雑性(カオス)を抱えています。複数のプロダクト連携を前提とした「カイポケコネクト」の開発では、将来の予測の将来予測の困難さ(環境の不確実性)や、誰に何を聞けばよいか分からないこと(通信の不確実性)が課題となり、「誰が決めるのか?」「もう決まったのか?」といった混乱が生じていました。 ■ 意思決定のプロトコル「プロダクトディシジョンレコード」 この不確実性の中で意思決定を機能させるプロトコルとして設計されたのが「プロダクトディシジョンレコード(PDR)」です。元々はエンジニアリングの文脈であるArchitecture Decision Record(ADR)をベースにしており、決定内容だけでなく、「なぜその決定に至ったのか」という背景や文脈(コンテキスト)を残すことを重視しています。 テンプレートには以下の項目が含まれます: イシューとコンテキスト : 白黒ついていない問題と、なぜ今それを解決するのか。 クリティカルユーザージャーニー : 影響を受けるUX/CUJ。 オプションと評価軸 : 選択肢のメリット・デメリットと、判断のためのトレードオフ基準。 決定と理由 : 最終的な結論と、その選択理由。 ■ 運用と定着のポイント PDRは単なるドキュメントではなく、会議体のアジェンダと連動させ、Slackへのプッシュやロードマップへの反映を行うサイクルで運用されています。特に「影響範囲が広く不可逆な決定」や「重要なリリース前の意思決定」において、WIP(書き途中)の段階から透明性を確保しながら合意形成を図る点が重要です。 ■ 参加して感じたこと 「決定をデータベース化し、一覧性の高い形で見える化する」というアプローチは、シンプルながらも実行難易度が高い取り組みだと感じました。 しかし、不確実性が高い環境だからこそ、当時の意思決定の背景(コンテキスト)が資産として残ることの価値は計り知れません。小規模なチームから大規模・部署横断のプロジェクトまで、規模を問わず汎用的に活用できるフレームワークであり、自組織でも取り入れていきたいと感じました。 (執筆:楠元久貴) 元経営企画CSO(戦略責任者)のPMが語る「プロダクトが創る事業戦略」のリアル  〜PLに振り回されず、価値から逆算する事業貢献の最大化〜 登壇者: キャディ株式会社 / VPoPS(Product Strategy) 岸本 裕史 氏 登壇資料: speakerdeck.com いわゆる「ビジネス価値と顧客価値のトレードオフ」や「よりビジネス観点を持ちたい」という課題感からこちらのセッションに参加しました。 PMを苦しめる「PL責任論」 PMの現場では、往々にして以下の対立構造が生まれます。 PMの想い : 「ユーザーのために価値あるプロダクトを作りたい(中長期視点)」 経営・事業側の要求 : 「今月の売上はどうするんだ(短期視点)」 この板挟みになり、PL達成のために本質的でない機能開発に追われてしまうのが「PMあるある」です。岸本さんはこれを、単なるコミュニケーション不足ではなく、 見ている指標と時間軸のズレ による構造的な問題だと指摘しました。 視点を変える3つのポイント 1. 売上は「遅効性指標」である 経営企画や経営陣にとって、売上などの財務数値はあくまで「結果(遅効性指標)」に過ぎません。 経営者が真に見極めたいのは、すでに起きた結果ではなく、「隠れた未来(先行指標)」です。 プロダクトが本質的な価値を提供できているかどうかが、将来の売上を作る先行指標となり得ます。 2. 指標を見る「順序」を変える 「売上を作るためにプロダクトを作る」のではなく、「市場(TAM/SAM/SOM)という大きなポテンシャルから逆算し、価値提供の進捗を確認する」というアプローチへの転換が提案されました。 TAM/SAM/SOMを見据える : まず自分たちが戦っている市場の全体像とポテンシャルを定義する。 価値の開拓スピードを確認する : その巨大な市場に対して、プロダクトがどの程度のスピードで価値を届けられているかを測定する。 結果として売上を見る : 上記の結果としてついてくる数字として売上を捉える。 この順序でロジックを組むことで、「短期的な売上」という小さな枠組みではなく、「巨大な市場を取りに行くための投資」という文脈でプロダクト開発を語れるようになります。 3. 事業戦略とは「価値から逆算すること」 キャディ社の事例(製造業2,000兆円市場への挑戦)を挙げながら、産業全体の課題(Issue)からTAMを規定し、そこから逆算して現在のプロダクト戦略を描く重要性が語られました。 PLに振り回されるのではなく、 PL(結果)をコントロールするための変数が「プロダクト価値」である と定義し直すことが、戦略的PMへの第一歩とのことです。 感想 「売上は遅効指標でプロダクト価値がその土台である」というのは、言われてみれば当たり前のことです。一方で、実務でその考え方に基づいた判断ができていたかというと、そうではなかったと感じました。 PLを意識して小手先の取り組みに終始したことがある反省があります。 それを踏まえて今後は市場と顧客を深く理解し、価値をベースにプロダクトの展望を大きくかつ根拠を持って語れるようにしていかねばと思いました。 (執筆:小西 裕真) 「PMが未来に挑む、って何?──変化の時代に“対話”で未来を描く」 登壇者(インナーサークル): 株式会社TVer / サービスプロダクト本部プロダクト推進部部長 松岡 綾乃 BASE株式会社 / 執行役員 BASE BANK 事業 事業責任者 柳川 慶太 PM Jam / プロダクトマネージャー 飯沼 亜紀 ファシリテーター: Product People Inc. / 提携プロダクトコーチ 広瀬 丈 氏 「PdMの未来」を問う、熱気ある1時間45分 〜フィッシュボウル形式で議論された「PM不要論」と「本質的な役割」〜 OSTの裏側では、「PMの未来」をテーマに、参加者同士が対話を行う「フィッシュボウル」形式でのディスカッションを実施していました。 ■ 議論のテーマと形式 当初のテーマは「PMの未来」でしたが、議論は「そもそもPMはいらないのでは?」という、より根源的かつ挑発的な問いからスタートしました。フィッシュボウルという発散型の大規模対話手法を用いることで、予定されていた1時間45分は、フェーズや立場の異なる参加者たちによる濃密な議論の場となりました。 ■ さまざまなトピック 議論の中では、プロダクトマネジメントの役割の曖昧さや多面性について、以下のような視点が飛び交いました。 事業フェーズによるPMの役割変遷 経営層と現場をつなぐ「結節点」としての機能 「なぜビジネスサイドでは代替できないのか?」という問い 経営者・事業責任者とPdMの境界線 ■ 印象的な議論:「ロードマップを書いて捨てる!」 その中でも印象に残ったトピックの一つが、「ロードマップは書いて捨てる!」という一言から始まった、不確実性の高い現代におけるロードマップのあり方です。 議論の中では、不確実性の高い時代において「固定化はリスクである」という認識のもと、状況に合わせて適切にロードマップを書き換え、何が最善かを考え抜くことの重要性が語られました。 しかし、単に書き換えるだけでは短期的な施策に終始してしまう懸念もあります。そのため、2-3年後を意識し現在地を把握しながら、今の状況に必要な意思決定をしていく視座が求められます。 これには、PMには計画策定能力だけでなく、状況に応じた意思決定力や、ステークホルダーへの説明責任、適切なコミュニケーションなどの総合的なスキルが求められると気付きました。 単に「PMとは何か」を定義するのではなく、変化の激しい時代において「どのような視座でプロダクトや組織に向き合うべきか」を再考させられる、非常に示唆に富んだセッションとなりました。 (執筆:飯田 咲紀) おわりに 全3回にわたり、pmconf2025のセッションレポートをお届けしました。 計7名のPMで参加した今回のカンファレンス。各セッションを通じてさまざまな学びが得られました。 「売上はプロダクト価値の遅効指標である」という言葉の通り、私たちが向き合うべきは常に「ユーザーのペイン」と、その先にある「市場への価値提供」です。 今回得た熱量と知見を日々の開発に還元し、タイミーはこれからも「はたらく」のインフラとして、ユーザーの皆様に驚きと信頼を届けるプロダクトをつくり続けていきます。 さいごに、pmconfではブースも出展していましたが、タイミーでは、共に「はたらく」の未来をつくる仲間も募集しています。興味を持っていただいた方は、ぜひカジュアルにお話ししましょう! (執筆:飯田 咲紀・タイミーPM一同)
アバター
タイミーのプロダクトマネージャーの飯田です。 今回は、12/4に開催された プロダクトマネージャーカンファレンス (以下pmconf)に参加してきました。このイベントを通じて非常に有意義な学びを得られたため、タイミーのプロダクトマネージャー(柿谷、小宮山、鈴木、小西、佐々木、楠本、飯田)から、各セッションから学んだ内容を、全3回の記事で紹介します。 (本記事は、全3回のうち、Part1です。) ▪️Part1・Part3はこちら pmconf2025に参加してきました part1 pmconf2025に参加してきました part3 「語られた戦略」を「語れる戦略」へ──共通言語をつくるPdMの試み 登壇者: 株式会社コドモン / 開発本部プロダクト企画部長 重山 由香梨 氏 登壇資料: speakerdeck.com 戦略の「ズレ」を「納得感」に変える。コドモンが実践する「戦略の再編集」というアプローチ 「経営と現場の距離が埋まらない」「戦略を共有したはずなのに、メンバーの動きがバラバラ」。 組織が成長する過程で必ずと言っていいほど直面するこの課題に対し、株式会社コドモンが実践している「戦略を再編集するプロセス」についてのセッションをレポートします。 ■ そもそも「戦略のズレ」はなぜ起きるのか? セッションの中で印象的だったのは、「ズレが生じるのは当然のことであり、むしろ土台として避けられない」という前提です。同じ戦略を語っていても、立場によって見ている景色が全く異なるからです。 事業・経営: 事業成長、収益性、社会的インパクト プロダクトマネージャー(PdM): 価値の体系化、ユーザー体験のロジック 開発: 実現可能性、負荷、品質、安全性 どれも正解であり、正しい視点です。しかし、同じ言葉を使っていても、立場に加えて在籍歴や背景知識の違いによって解釈の「ゆがみ」が生じます。その結果、現場のモヤモヤとして蓄積されてしまいます。 ■ 解決策は「ズレ」を材料にした「再編集」 登壇では、このズレを「埋める」のではなく「ズレを材料にして戦略をアップデート(再編集)する」というアプローチを紹介されていました。 特に興味深かったのが、「メンバー自身が話者になる想定で読み合わせる」というプロセスです。 人は「聞く立場」にいる限り、受動的・批判的になりがち。 しかし、自分が誰かに説明する「話者」の視点に立つことで、「どこが曖昧か」「どこが説明しにくいか」がメタ認知され、自分自身の理解不足(ズレの正体)が手元でクリアになる。 このプロセスを経ることで、トップダウンの戦略が、 現場の言葉を内包した「ボトムアップ的な戦略」へと再編集されていきます。 人に説明しながら理解を深める、いわゆるファインマンテクニックに近い進め方で、そこで生まれた認知のズレを材料に共通認識を再構築していく点が、とても興味深かったです。。 ■ なぜ、ここまで「対話」にコストをかけるのか? 「なぜそんなに時間をかけるのか?」という問いに対し、登壇者の方は「戦略は仲間のためでもあるから」と語られていました。 ズレを放置することは、組織の中に「負の遺産」を積み重ねるのと同じです。戦略を自分事化し、自分の言葉で語れる状態にすることは、メンバーが誠実に仕事に向き合うための前提条件となります。お話を伺う中で、色々過去に色々なズレで悩んだ経験がフラッシュバックしてきました。 ■ 参加して感じたこと:開発チームへの応用 このセッションを聴いて、これは組織戦略だけでなく、 開発チームで新しい技術的挑戦やプロセス改善を行う際にも非常に有効 だと感じました。 心理的安全性を確保しながら「なぜこれをやるのか」というモヤモヤを出し切る メンバー自身が「他チームに説明するなら?」という視点でワークを行う 出た違和感を反映して、取り組みの進め方を再編集する 「ズレ」を否定せず、それをより良い形にするための「インプット」として捉える。そんなしなやかな組織運営のヒントをいただいたセッションでした。 (執筆:柿谷樹) "主観で終わらせない"定性データ活用 ― プロダクトディスカバリーを加速させるインサイトマネジメント 登壇者: 株式会社カミナシ / プロダクト本部 プロダクトマネージャー 右田 涼 氏 登壇資料: speakerdeck.com このセッションでは、 定性データを「感想」で終わらせず、プロダクトの意思決定につなげるための考え方と実践 が、体系的に整理されていました。 ユーザーインタビューや現場ヒアリングは、多くのプロダクトチームで行われていますが、 解釈が個人に閉じてしまう チームに共有されず、再利用されない 「いい話だった」で終わってしまう といった課題を抱えやすい領域でもあります。本セッションは、そうした定性データ活用のつまずきどころを明確に言語化していた点が印象的でした。 ■ なぜ定性データは「主観」で終わってしまうのか? セッションで語られていたのは、定性データの問題は「質」ではなく、 扱い方の構造にある という視点です。 事実(ユーザーの発話・行動) そこから得た気づきや仮説 意思決定に使われるインサイト これらが混ざったまま扱われることで、 「誰の解釈なのか分からない」「再検証できない」状態が生まれてしまう、という指摘には強く納得感がありました。 ■ 解決策は「インサイトマネジメント」 この課題に対し紹介されていたのが、 事実 → 解釈 → インサイトを明確に分離し、インサイトをチームの資産として管理する という「インサイトマネジメント」の考え方です。 単発のインタビュー結果を結論にするのではなく、 複数の事実を束ね、再現性のある形で整理することで、 初めてプロダクトディスカバリーのスピードと質が上がる、というメッセージが一貫して語られていました。 ■ 参加して感じたこと 「定性データは感想ではなく、意思決定の材料である」という言葉が特に印象に残りました。 インタビューを実施すること自体が目的化しがちな中で、 どうすればチームで使える知見に昇華できるのか を改めて考えさせられる内容でした。 日々ユーザーの声に触れているPdMにとって、 定性データ活用を一段引き上げるためのヒントが詰まったセッションだったと思います。 (執筆:小宮山貴大) なぜ使われないのか?──定量×定性で見極める本当のボトルネック 登壇者: 株式会社カケハシ / AI在庫管理 プロダクトマネージャー 梶村 直人 氏 speakerdeck.com 本セッションでは、 「なぜ使われないのか?」というPdMであれば一度は直面する問いに対し、 定量データと定性データを組み合わせて真のボトルネックを見極める考え方 が整理されていました。 ファネルや利用率などの定量データを見ることで、 「どこで使われていないか」は把握できます。一方で、その背景にあるユーザーの判断や迷い、業務上の前提は、数字だけでは捉えきれません。本セッションでは、そうした 定量だけ・定性だけでは見えない課題 に正面から向き合っていた点が印象的でした。 ■ 「使いやすい」と「使われる」は別物 特に印象に残ったのは、 「“使いやすい”(迷わず操作できる)と“使われる”(安心して業務を任せられる)は別物である」 という指摘です。 操作性を高めることで「使える」状態は作れても、それだけで業務を任せてもらえるとは限りません。業務を任せるという行為は、業務上のリスクを引き受けることや、これまでの判断基準・やり方を手放すことを意味します。そのため、操作性とは異なる次元のハードルが存在するという整理に強い納得感がありました。 ■ 定量×定性で、N1の判断構造を捉える 本セッションでは、 定量であたりをつけ、定性でN1(個別ユーザー)の判断背景を深掘る というアプローチが紹介されていました。 ユーザーに直接理由を聞くだけでは表面的な回答に留まりがちな中で、 事前に定量・定性の両面から仮説を立てた上でヒアリングに臨むことで、 ユーザー自身も言語化できていなかった前提や、店舗属性ごとの運用の違いが見えてくる、という話が印象的でした。 ■ 参加して感じたこと 「使われない理由」を機能やUIの問題に矮小化せず、 ユーザーがどんな判断をし、何に不安を感じているのか まで踏み込んで理解することの重要性を改めて感じました。 定量・定性を往復しながらN1を丁寧に見る姿勢は、 プロダクトディスカバリーの質を大きく左右するのだと思います。 日々データを扱うPdMにとって、自分の分析スタンスを見直すきっかけになるセッションでした。 (執筆:小宮山貴大) Part3に続く。 ▪️Part1・Part3はこちら pmconf2025に参加してきました part1 pmconf2025に参加してきました part3
アバター
タイミーのプロダクトマネージャーの飯田です。 今回は、12/4に開催された プロダクトマネージャーカンファレンス (以下pmconf)に参加してきました。このイベントを通じて非常に有意義な学びを得られたため、タイミーのプロダクトマネージャー(柿谷、小宮山、鈴木、小西、佐々木、楠本、飯田)から、各セッションから学んだ内容を、全3回の記事で紹介します。 (本記事は、全3回のうち、Part1です。) ▪️Part2・Part3はこちら pmconf2025に参加してきました part2 pmconf2025に参加してきました part3 どんなPMに機会が与えられるか?与えるべきか? 登壇者: Product People株式会社 / 代表取締役 プロダクトコーチ  横道 稔 氏 株式会社SmartHR / プロダクトマネジメント統括本部 タレントマネジメントプロダクト本部 本部長 松栄 友希 氏 横道さんと松栄さんによるセッションを聴講しました。組織の中で、マネージャーは誰に、どの程度の難易度の機会を渡すのか?その意思決定の裏側にある「アサインの論理」が語られました。 特に印象に残ったのは、機会を引き寄せる要素として挙げられた以下の3点です。 突撃力というコミットメント わからないことがあれば「初めまして!」と飛び込み、20人にヒアリングできるような行動力。「わからないことを、わからないと聞きに来られる人」これは単なる元気の良さではなく、不確実な状況でも「何とかする」という高いコミットメントの証明であり、マネージャーがアサインする上での重要な要素である。 思考力とは「言葉の精度」 よく「地頭が良い」と表現されるが、これは先天的なIQの話だけではなく、「言葉を曖昧に使わず、前提を揃える力」と定義されていた。認識のズレが命取りになるPdMだからこそ、論理的かつ構造的に言葉を扱える能力が不可欠である。 「経験」ではなく「ペイン」に向き合う 「新規事業を経験したい」という自分主語の動機だけでは機会は巡ってこない。「このユーザーのこのペインを解消したい」という課題への執着心があるか。そして、その挑戦が本人のスキルに対して「パニックゾーン」に入りすぎていないか(現実的に遂行可能か)という冷静な判断のもとで機会は与えられる。 感想 自身の転職活動中も「地頭」という言葉を頻繁に耳にし、どこか先天的な才能のように感じて不安になることがありました。しかし、本セッションで「思考力とは、言葉の定義にこだわり後天的に磨けるスキルである」と定義されたことに、非常に勇気をもらいました。 ただ「やりたい」と手を挙げるだけでなく、曖昧さを排除して解像度高く仕事に向き合う姿勢や、不明確な事象・状況でも物怖じしない姿勢こそが、次の仕事の機会を引き寄せるのだと感じました。 (執筆:鈴木亜由子) 海外SaaSに学ぶプロダクト成長の新しい指標 - Product Engagement Score- 登壇者: Pendo.io Japan株式会社 / Technical Account Services PdM Consultant 若松 研二朗 氏 Pendo.io Japan株式会社によるセッションを聴講しました。内容が非常に示唆に富んでいたため、レポートとして整理します。特に、タイミーが今後「事業者の業務深層に入り込むソリューション提供」へ拡張していく上で参考になると感じました。 Pendo.io(ペンド)社について Pendoは、2013年に米国で設立された、プロダクトマネージャー(PdM)のためのオールインワン・プラットフォームを提供する企業です。 「ユーザーがプロダクトをどのように使い、何を求めているか」を可視化・分析し、コードを書かずにアプリ内ガイドなどを実装することで、プロダクトを通じたユーザー体験の最適化(Product-Led Growth)を支援しています。Fortune 500に名を連ねる企業から成長著しいスタートアップまで、世界中で利用されています。 PES(Product Engagement Score)とは PESは、プロダクトの「 真の健康状態 」を測定するための複合指標で、以下の3つの重要指標の平均値で算出されます。 Adoption(採用率) :全ユーザーのうち、コア機能を使いこなしているユーザーの割合 Stickiness(継続性) :ユーザーが毎日、あるいは毎週継続的に戻ってきている頻度 Growth(成長率) :新規・既存ユーザーの増加スピード 【なぜPESが主流になっているのか】 従来の「DAU/MAU(アクティブユーザー数)」などの指標だけでは、「ログインはしているが活用はしていない」というユーザーを見抜くことが困難でした。SaaS市場が成熟する中、単なる集客ではなく「機能の深い活用」が解約防止やLTV向上に直結するため、多角的にエングージメントを測るPESが世界的な標準指標となりつつあります。 海外SaaSにおける導入事例: ① Okta :Adoptionの低い特定の重要機能を特定。Pendoのインアプリガイドを活用してユーザーを誘導した結果、プロダクト採用率25pt向上。 ② Adobe :新機能リリース後のGrowthとAdoptionをPESで常時モニタリング・機能案内を自動化することで新機能が「標準」として使われるまでの期間を大幅に短縮化。 タイミーにおけるPES活用の可能性 今後タイミーが長期アルバイト採用や特定領域のJOBタスク化へとソリューションを広げるにあたり、特定タスクの習熟度などの「Adoption(活用度)」を可視化することで、クライアントの事業成長への寄与を定量化できる可能性があります。 また、業界特有のフローに合わせた操作支援をプロダクト内で完結させれば、CSM(カスタマーサクセスマネージャー)によるサポートに頼りすぎず、レバレッジの効いた事業スケールが可能になると思いました。 (執筆:佐々木富美) 絶対に失敗しない。toB領域プロダクトのGTM戦略フレーム 登壇者: 株式会社estie / 執行役員 マーケットリサーチ事業本部 本部長 久保 拓也 氏 登壇資料: speakerdeck.com 株式会社estie(エスティ)について オフィス不動産データ分析プラットフォーム「estie(エスティ)」、賃貸管理システム「estie 管理」などの開発・運営。 日本最大級のオフィス不動産データ基盤を保有し、不動産業界(デベロッパー、アセットマネジメント会社等)のDXを推進するバーティカルSaaS企業です。 本セッションでは、PMFを「Product × Market × GTM」の掛け合わせととして再定義し、販売チャネル(GTM)まで含めて設計・検証することの重要性が説かれていました。特に、単一プロダクトの成功に留まらず、複数のプロダクトを戦略的に組み合わせる「プロダクトポートフォリオ」の視点が非常に参考になりました。 GTMまで含めたPMFの設計 一般的にGTMは「作った後にどう売るか」という後工程の戦略と捉えられがちですが、本セッションでは「GTMまで含めて設計されて初めてPMFが成立する」という点が強調されました。 プロダクト単体の機能だけでなく、既存資産を活かしていかに効率よく市場へ届けられるかという「勝ち筋」をセットでアセスメントする必要性を強く認識しました。 マルチプロダクトによるWhole Product(ホールプロダクト)の実現 タイミーにとって、圧倒的な集客力を誇る「スポットワーク求人」は、クライアントがタイミーの価値を即座に体感し、プラットフォームへ定着するための「エントリープロダクト」としての役割を果たしていると考えています。 estie社の事例のように、この起点で得たデータを活かし、周辺課題を解決するプロダクトを順次投入して「Whole Product」として顧客価値を最大化させる考え方は、今後の長期アルバイト採用や正社員採用への拡張戦略において不可欠な視点だと感じました。 (執筆:佐々木富美) Part2に続く。 ▪️Part2・Part3はこちら pmconf2025に参加してきました part2 pmconf2025に参加してきました part3
アバター
こんにちは、タイミーでエンジニアをしている徳富( @yannKazu1 )です。 前回の記事では、 EKS 上に self-hosted GitHub Actions Runner 基盤を構築した話 をご紹介しました。 ▼ 前回の記事 https://tech.timee.co.jp/entry/2025/09/22/122415 ありがたいことに、この取り組みは AWS さんの公式ブログでもご紹介いただきました 。 👉 AWS ブログ https://aws.amazon.com/jp/blogs/news/timee-amazon-eks-auto-mode/ 今回はその続編として、 EKS のクラスターバージョンアップを、どうやって安全に自動化したか についてお話しします。 EKS のクラスターバージョンアップ、地味につらい EKS を運用していると、どうしても避けて通れないのが 定期的なクラスターバージョンアップ です。 Kubernetes のマイナーバージョンは定期的に EOL が来る 放置するとサポート切れになる とはいえ、毎回人が確認して手動で上げるのは正直しんどい 「これ、もう少し楽にできないか?」 そう思ったのが、今回の仕組みを考え始めたきっかけでした。 今回の前提:EKS Auto Mode を使っている 今回運用している EKS では、 EKS Auto Mode を採用しています。 EKS Auto Mode では、 ノード管理 主要な Add-on 管理(VPC CNI / AWS Load Balancer Controller など) を AWS 側で管理しており、運用負荷を軽減できます。 そのため、クラスターバージョンアップの流れは比較的シンプルです。 マニフェストで 非推奨 API を使っていないか確認 する 問題なければ クラスターバージョンをアップ する ノードや主要 Add-on は AWS が自動で追従 する さらに EKS には Upgrade Insights という便利な仕組みがあります。 非推奨 API の使用状況 バージョンアップ時に問題になりそうな点 を事前にチェックできるため、 「このバージョンに上げて大丈夫か?」をかなり楽に判断できます。 自動化の方針 とはいえ、いきなり本番クラスターバージョンを自動で上げるのは、さすがに怖い。 そこで、次の方針で仕組みを作りました。 1. 本番とは別にテスト用クラスターを用意する Self-hosted Runner 用の main クラスターとは別に、 検証専用の test クラスター を用意しています。 コストを抑えるため Spot インスタンスを使用 する 最小構成で test-runner のみを起動 する インフラは次のように管理しています。 クラスターや AWS リソース: Terraform ARC Controller などの Helm リソース: Terraform その他の Kubernetes リソース: マニフェスト(Kustomize) この構成にしていることで、 test / main クラスターに ほぼ同じ設定をそのまま適用 できる runner の 台数やサイズだけを環境ごとに切り替え られる といったことが簡単にできます。 結果として、 コントローラや設定は本番と同一 リソース(インスタンスサイズ・台数)を最小構成にした test-runner という、「本番に限りなく近いが、低コストなコピー環境」を作れています。 2. テストクラスターで先にバージョンアップする テストクラスターでは、次の条件を満たした場合のみ 自動でバージョンアップを行います。 ① リリースから 1 か月以上経過したバージョンであること aws eks describe-cluster-versions \ --include-all \ --query 'clusterVersions[?versionStatus==`STANDARD_SUPPORT`].{version: clusterVersion, releaseDate: releaseDate}' \ --output json 取得した結果を jq で加工し、 「リリースから 1 か月以上経過しているバージョン」のみを対象にします。 ② Upgrade Insights がすべて PASS していること INSIGHTS_JSON=$(aws eks list-insights \ --cluster-name ${{ inputs.cluster-name }} \ --output json) ERROR_COUNT=$(echo "$INSIGHTS_JSON" | jq '[.insights[] | select(.category=="UPGRADE_READINESS" and .insightStatus.status=="ERROR")] | length') WARNING_COUNT=$(echo "$INSIGHTS_JSON" | jq '[.insights[] | select(.category=="UPGRADE_READINESS" and .insightStatus.status=="WARNING")] | length') ERROR / WARNING があればブロックする UNKNOWN は未使用機能なので許容する これらの条件をすべて満たしている場合のみ、毎朝 7 時に GitHub Actions から aws eks update-cluster-version を実行します。 3. test クラスターの結果を cluster_version.txt の PR として残す 本番クラスターのバージョンアップは、 cluster_version.txt に書かれたバージョンへ更新する という前提で設計しています。 そのため、 本番をいつ上げるかだけは人が判断できるように cluster_version.txt の更新は必ず PR 経由にしています。 test クラスターバージョンアップが正常に完了すると、 実際に上がった EKS バージョンを そのまま cluster_version.txt に書き込み 自動で PR を作成 します。 # **cluster_version.txt** 1.34 この PR をマージすると、 その日の深夜に 本番クラスターバージョンアップが実行されます。 検証は自動で完了済み 本番反映の日付だけ人が判断する というバランスに落ち着きました。 本番クラスターバージョンアップフロー 本番クラスターバージョンアップは、 毎日 深夜 2 時 に GitHub Actions から定期実行しています。 流れは次のとおりです。 1. cluster_version.txt との差分を確認 cluster_version.txt のバージョン 現在の本番クラスターのバージョン を比較し、差分がなければここで終了します。 差分がある場合のみ、以降のチェックに進みます。 2. Upgrade Insights が PASS していることを確認 INSIGHTS_JSON=$(aws eks list-insights \ --cluster-name ${{ inputs.cluster-name }} \ --output json) ERROR_COUNT=$(echo "$INSIGHTS_JSON" | jq '[.insights[] | select(.category=="UPGRADE_READINESS" and .insightStatus.status=="ERROR")] | length') WARNING_COUNT=$(echo "$INSIGHTS_JSON" | jq '[.insights[] | select(.category=="UPGRADE_READINESS" and .insightStatus.status=="WARNING")] | length') 3. test-runner のヘルスチェックを実行 本番アップグレード前に、 test クラスター上の Self-hosted Runner が正常に動くか を確認します。 簡単な workflow_dispatch のワークフローを用意しています。 name: Test Runner Health Check on: workflow_dispatch jobs: health-check: runs-on: test-runner # testクラスター上のtest-runnerを指定する timeout-minutes: 10 steps: - run: | echo "✅ test-runner is healthy!" hostname date このワークフローを gh コマンドで起動し、 10 分以内に success すること を確認します。 (ポーリング処理は省略していますが、実装上は完了を待っています) 4. 問題なければ本番クラスターバージョンアップ aws eks update-cluster-version \ --name ${{ env.MAIN_CLUSTER_NAME }} \ --kubernetes-version "$TARGET_VERSION" 流れを図で表すと、以下のとおりです。 なぜ深夜 2 時に「自動で」上げるのか? 「本番反映の日付は人が制御」と書きましたが、厳密には PR をマージした日の深夜 2 時に自動でクラスターバージョンアップが走る 仕組みです。 つまり、人が決めるのは 「いつの深夜にクラスターバージョンアップを実行するか」 だけ。 この設計にしている理由は 2 つあります。 1. 深夜ならデプロイと競合しない デプロイが走っていない時間帯である ノード更新時に Pod が退避しても影響が出にくい デプロイ途中で Pod が落ちる事故を防げる 2. 問題が起きても業務開始後に対処できる Self-hosted Runner の利用箇所では、Organization variablesを使って runner を指定しています。 runs-on : ${{ vars.RUNNER_AMD64_STANDARD }} もしクラスターバージョンアップ後に問題が発覚しても、この変数の値を ubuntu-latest などに変更するだけで、全リポジトリのワークフローが GitHub-hosted runner で動くようになります。 コードを一切変更せずにフォールバックできるため、 業務開始後に気づいてからの対応でも十分間に合います 。 このフォールバック手段があるからこそ、 深夜に自動でクラスターバージョンアップを実行 人は「日付を決める」だけ という運用が成り立っています。 Terraform 管理との付き合い方 インフラは Terraform で管理していますが、 EKS のクラスターバージョンだけは Terraform 管理外 にしています。 cluster_version に ignore_changes を設定している バージョンアップは CLI で実施している これにより、 CLI で上げても Terraform 差分が出ない IaC と運用の責務をきれいに分離できる というメリットがあります。 まとめ この仕組みを導入したことで、 クラスターバージョンアップの toil を大幅に削減できた 「test → 本番」の安心できるフローを自動化できた Self-hosted Runner が壊れないことを事前に保証できるようになった という成果が得られました。 EKS Auto Mode の特性を活かすことで、 「人が気合で回す運用」から一段階進められたかなと思っています。 同じように EKS を運用している方の参考になれば嬉しいです 🙌
アバター
こんにちは、DevPFチームの菅原です。 現在、弊社のアプリケーション基盤(ECS on Fargate)では、コンテナログの収集・転送に FireLens を採用し、 Datadog Logs へ集約しています。FireLensはタスク定義に数行記述するだけでログ基盤が整う非常に便利な機能です。一方で裏側では、 Fluent Bit がサイドカーとして動作し、複雑なパイプラインを処理しています。 「ログなんて標準出力に出せば、あとは勝手に届くもの」 そう思われがちですが、実際にはアプリケーションコンテナからDatadog Logsのexplorerに表示されるまでには、いくつもの難所が存在します。今回は、ログがDatadogに到達するまでのアーキテクチャを紐解きながら、ログが「どこで」「なぜ」欠損するのかを解説します。 ログ転送のアーキテクチャ概要 まずは現在の構成のおさらいです。 基盤 : AWS ECS on Fargate(v1.4) ログ収集 : FireLens (実体はFluentdまたはFluent Bitサイドカー。弊社ではFluent Bitを採用) 送信先 : Datadog Logs アプリケーションが出力したログは、大まかに以下の経路を辿ります。 Appコンテナ : stdout/stderrへログを書き込む shim logger プラグイン : containerd-shimのロガープラグイン。shim loggerが各コンテナのstdout/stderrをパイプ経由で定期的に読み込み、サイドカーのFluent Bitに転送。 Log router (Fluent Bit)コンテナ : ログを受け取り、バッファリング・加工を行う Network : Datadog APIへHTTPSで送信 Datadog : Ingest(取り込み)・Indexing(インデックス化) 一見シンプルですが、この経路には大きく分けて4つの「欠損リスク」が潜んでいます。 アプリケーション 〜 Fluent Bit間のバックプレッシャー 最初の難関は、ログがサイドカーに渡る瞬間です。 仕組み FireLensを使用する場合、Fargate (v1.4) の内部では shim-loggers-for-containerd が使用されます。 アプリケーションが出力したログは、この shim logによってパイプ経由で読み取られ、Unix Socketを経由して Fluentd Forward Protocol でサイドカーのFluent Bitに転送されます。 ここで何が起きるか? Fluent Bitで処理が詰まったりしてバッファがいっぱいになると、Fluent BitはInputを一時停止します。その間、アプリケーションが出力し続けるログはどうなるでしょうか? Fluent BitがInputを停止している間に出力されたログは、Fargate基盤側のshim logger内のメモリバッファやその前段のパイプのバッファに溜まります。しかし、このバッファも有限です。よってFluent Bitが復帰して再開したときには、その間のログは闇に消えている可能性があります。 application-to-sidecar 対策 出来るだけ処理が詰まらないようにする、可能な範囲でバッファを大きくすることが対策となると考えます。例えば次のようなことができるでしょう。 不要なログを出力しない log-driver-buffer-limit オプションでのshim loggerレイヤのチューニング log_routerのバッファサイズ、retryの上限設定等のチューニング Outputの失敗と道連れ欠損 Fluent Bitがログを受け取った後、Datadogへ送信するフェーズです。 仕組み Fluent Bitはログを1件ずつ送るのではなく、効率化のために複数のログをまとめてChunkにし、一定サイズまたは一定時間ごとに送信します。 ここで何が起きるか? Outputの失敗は、「インフラ起因」と「ログ内容起因」の2つのパターンに分けられると考えます。それぞれの挙動とリスクを見ていきましょう。 インフラ起因:ネットワークや転送先の障害 インターネット接続の問題や、Datadog API側の一時的な障害、あるいはAPIキー等の設定ミスなどがこれに該当します。 Fluent Bitは送信に失敗すると、設定された回数( Retry_Limit 設定)だけ再送を試みます。しかし、障害が長時間続いてリトライ回数を使い切ると、そのChunkは破棄されます。 欠損を防ぐためにリトライを無限に設定することも可能ですが、送信できないログがFluent Bitのバッファに滞留し続けることになります。これが解消されないとバッファが埋まったままになり、結果として前述のインプットの一時停止を引き起こし、新たなログの取り込み自体が止まってしまいます。 https://docs.fluentbit.io/manual/data-pipeline/buffering#per-input-settings 特定ログ起因: 不正なログによる巻き添え欠損 これが厄介なケースです。インフラは正常でも、アプリケーションが出力した「特定のログ」が原因で発生することがあります。 Datadog Logs APIには、「ペイロードあたり最大コンテンツサイズ(非圧縮): 5MB」という制限があります。 例えば、Base64エンコードされた画像やPDFデータを含む 数MBの巨大なログ が1件出力されたとします。Fluent Bitはこの巨大ログと、同じタイミングで出力された正常な小さいログをまとめて1つのChunkにしてしまいます。Fluent Bitのdatadog output pluginはChunk単位でログを送信します。このChunkを送信しようとすると、サイズ制限超過によりDatadogから 413 Payload Too Large エラーが返されたり、接続がリセットされたりします。 重要なのは、 問題のある巨大ログだけでなく、同じChunkに含まれていた正常なログもまとめて拒否されてしまう 点です。たった1行の行儀の悪いログのせいで、周囲の無実なログまで道連れにして消えてしまう可能性があるのです。 Fluent Bitのメモリバッファのサイズ制限を設ければいいのでは?と思われるかもしれません。しかし、該当する mem_buf_limit 設定は ソフトリミット として実装されているようです。読み解いたソースコードレベルの挙動としては、「書き込み前に空き容量をチェックする」のではなく、「書き込んだ後に上限を超えていないかチェックする」という動きで、一時的に上限を超過することは許容されているようでした。 mem_buffer_limit = 5MBの時に巨大なログが来た場合の挙動 対策 方向性は大きくアプリケーション層での予防的設計と、転送層でのフィルタリング・バッファ制御が考えられます。いずれもトレードオフを伴うため、システムの特性に応じたバランスが求められます。 アプリケーション側で長大なログを出力しないよう制限する アプリケーションまたはfluent bitレイヤで一定サイズを超えるログフィールドを自動的に切り捨てるようにする 特定パターンのログを除外または置換する mem_chunk_size , flush_interval を短くして巻き添え欠損の影響範囲を小さくする メモリバッファの消失 Fargateのようなコンテナ環境特有のリスクです。 仕組み Fluent Bitのバッファ設定をデフォルトの memory にしている場合、ログは送信完了までメモリ上にしか存在しません。 ここで何が起きるか? コンテナが予期せず停止した場合、メモリ上の未送信ログは消滅します。これは異常時だけでなく、通常のデプロイフローでも発生し得ます。 ECSタスク停止時、コンテナにはSIGTERMが送られます。 タスク定義の stopTimeout (デフォルト30秒)以内に終了しない場合、SIGKILLで強制終了されます。 Fluent Bit側にもシャットダウン時の待機設定( Grace )がありますが、これらが噛み合わず、バッファをFlushしきる前にプロセスが強制停止されるとログは欠損します。 引用: 「ECS のアプリケーションを正常にシャットダウンする方法」, Amazon Web Services ブログ, https://aws.amazon.com/jp/blogs/news/graceful-shutdowns-with-ecs/ 対策 バッファのストレージタイプを filesystem に変更し永続化する。ただしECS Fargateの場合、現実的に使えるのがEFSくらいで永続化ストレージの利用に制限があるためトレードオフの検討が必要です。 stopTimeout と Grace の値を適切に調整し、シャットダウン時にFlush完了までの十分な猶予時間を確保する。 flush_interval を短く設定し、バッファに溜まるログの量を減らすことで、シャットダウン時の欠損リスクを最小化する。ただし、ネットワーク負荷とのバランスを考慮する必要があります。 Datadog側の制限 無事にインターネットを越えてDatadogに届いても、最後の難所があります。 ここで何が起きるか? Datadog側にも厳格な受入ルール があり、これに違反すると取り込み後に削除、または切り捨てられます。 日次クォータ超過 : コスト管理のために設定したインデックスの上限を超えた場合、インデックスには保存されません(アーカイブ設定があればS3には残ります)。 タイムスタンプ : ログの日時が「18時間以上過去」の場合、取り込み対象外となり削除されます。 サイズ制限 : 単一ログが1MBを超える場合、Datadogによって切り捨て(Truncate)が行われます。 前述の通り、APIへの送信ペイロード全体(非圧縮)が5MBを超えると、そもそも受け入れられずエラーとなります。 対策 日次クォータの監視アラートを設定する 前述の通り、アプリケーション側とFluent Bit側で対策を行い、Datadog側の制限に引っかからないようにする。 retry間隔がタイムスタンプの制限を超えないように再送の設計をする まとめ ログ基盤の信頼性を高めるためには、これらの欠損ポイントを理解した上での設計・運用が必要です。 Input : Fluent Bitが詰まるとその前段でログが溢れ欠損しうる。 Output : Chunk単位で処理されるため、異常なログが正常なログを巻き込むことがある。送信リトライはトレードオフがある。 Buffer : メモリバッファは揮発しうる。 Ingest : Datadog側のクォータやサイズ制限も意識する。 ログが欠損しているという事象に直面したとき、アプリケーションコードだけでなく、この険しい道のりのどこで詰まっているのかを想像できると、調査の解像度がぐっと上がるはずです。 参考資料 Amazon Web Services,2025,「詳細: Fargate データプレーン」,AWS ブログ,(2026年2月2日, https://aws.amazon.com/jp/blogs/news/under-the-hood-fargate-data-plane/ ). Amazon Web Services,2025,「Send Amazon ECS logs to an AWS service or AWS Partner」,Amazon ECS Developer Guide,(2026年2月2日, https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_firelens.html ). Amazon Web Services,2025,「ECS のアプリケーションを正常にシャットダウンする方法」,AWS ブログ,(2026年2月2日, https://aws.amazon.com/jp/blogs/news/graceful-shutdowns-with-ecs/ ). Fluent Bit,2025,「Buffering and Storage」,Fluent Bit Manual,(2026年2月2日, https://docs.fluentbit.io/manual/administration/buffering-and-storage ). Fluent Bit,2025,「Backpressure」,Fluent Bit Manual,(2026年2月2日, https://docs.fluentbit.io/manual/administration/backpressure ). Datadog,2025,「ログのトラブルシューティング」,Datadog Docs,(2026年2月2日, https://docs.datadoghq.com/ja/logs/troubleshooting/ ).
アバター
株式会社タイミーのshihorinです。 1月7〜9日に開催された「Regional Scrum Gathering Tokyo 2026(RSGT2026)」に参加してきました。 RSGTに参加するのは、昨年に続き2回目です。昨年11月に「DevEnable室(プロダクト組織運営や技術広報を担うチーム)」に異動したため、今回は組織運営や文化醸成の観点を特に意識して参加しました。 特に印象的だったセッションやOSTで得られた学び・感想を、このブログでアウトプットしてみます。 🪴 コミュニティ文化を組織に根付かせる〜推進者とバトンを受け取った実践者が語るコミュニティの価値と持続可能性への道筋〜 speakerdeck.com 株式会社ログラスの飯田さん・永井さんによるセッションです。 コミュニティに参加し始め、コミュニティに助けられた個人の経験を起点に、社内でコミュニティ文化を根付かせ、持続させるまでの実践的な取り組みが、ストーリーに沿って語られるセッションでした。1人で始めたことが会社から認められるようになり、やがて共に推進してくれる仲間にバトンを繋げられた、素敵なストーリーだなと思いました。 このセッションを聞いて、重要だと思った要素はこの2つです。 自分がやってみて、周りに広める 「なんだか怖い」と思っても、きっかけを逃さず飛び込んでみる。そこで得られたものを周りに広める。 自分がやることで、活動の価値を語れるようになる。 継続が大事 継続することで複利的に価値が上がる。 維持する努力を続けなければ維持できない。1人の強いパワーだけでも続かない。複数の小さなモメンタムを生むきっかけ作りと、維持するための後押しを根気よく行う。 これらはコミュニティ活動に限らず、カルチャーをつくる・広める上で共通する考え方ではないでしょうか。 最近私は「発信文化を継続的に育てる」という業務に取り組み始めました。自分自身が「発信活動の価値」を語れるようになるために、今年はどこかのカンファレンスにプロポーザルを出してみようと思います……! そしてこのセッションは、自分自身のコミュニティ活動に関するこれまでと現在地を振り返るふりかえるきっかけにもなりました。 私はタイミー入社前まで、気が向いた時にごく稀にconnpassでイベントを見つけて参加するくらいでした。入社後は、周りのメンバーがカンファレンスやイベントに積極的に参加しているのを知り、私も同様に足を運ぶようになりました。大きな進歩ではあると思いますが、「その場に行くだけで満足してしまっているのかも」と、セッションを通して気づきました。今こそ、努力の方向性を変えるタイミングなのかもしれません。今後は「小さくても良いので自分がその場に何らか貢献する」を意識してコミュニティ参加できるようになりたいと思います。 🔥 自己管理型チームと個人のセルフマネジメント speakerdeck.com 株式会社カケハシの小田中さんによるセッションです。 自己管理型チームであるために大切なことを語られていました。 一人ひとりのセルフマネジメントが必要。セルフマネジメントの土台には「モチベーションマネジメント」があり、モチベーションの源泉(心の着火点)は人によっても時にもよって変化する。 メンバーのタイプによって、マッチするモチベーションの引き出し方(目標設定やマネージャーの働きかけ方)がある。 欲求(ERG理論でいう「成長」「関係」「存在」)が損なわれると摩擦が起きる。アルバート・エリスのABC理論を用いて内省し、摩擦を乗り越えられるように行動する。 そして最後は、「自分が何にモチベーションを感じるかを明確にし、まずは自分からセルフマネジメントしてモチベーションを引き出していくことにぜひトライしてください」というメッセージで締められていました。 ※ERG理論: 「成長」「関係」「存在」の3つの欲求で構成されるモチベーション理論のこと ※ABC理論: 発生した出来事に対し、信念が影響を起こし、感情を引き起こす、という理論 私が所属しているチームは、以前は各自の守備範囲に集中するスタイルでしたが、今はお互いに越境し支え合う姿を目指しています。まさにこのセッションで語られていた「自己管理型チーム」だと気づきました。 私はついチームのプロセスに焦点を当てがちで、メンバー一人ひとり(自分も含めて)の内面に目を向けることが疎かになっていたように思います。まずは自分、そして周りのメンバーのモチベーションの源泉に思いを馳せ、心の火を燃やし続けられるよう支援していきたいです🔥 Day3のOST 16トラック x 4枠(1枠30分)のテーマが起票されていました。ずらりとテーマが並んだボードは圧巻でした! どれにするか迷いつつ、今取り組んでいる業務に関連しそうなテーマを選んで参加してきました。 その内2つについて書いてみます。 テーマ:今日の学びを少しずつ、ほんの少しずつ、チームや組織の共通知に変える仕組み タイミーのプロダクト組織では、業務時間内にカンファレンスに参加した場合、社外発信レポートの執筆もしくは登壇をお願いしています。一方で「レポート執筆・登壇以外にも学びを広める手段は様々あるはずで、もっと試せないだろうか」と個人的に課題感を持っていたため、このテーマに参加しました。 このテーマを起票した方のお話を深掘りしていくと、 会社からRSGTに参加しているメンバーが少数。RSGT、アジャイル、スクラムに興味を持っている人が現時点では限られている。 ドキュメントにまとめて渡しても、分量が多いと受け取りづらいことがある。重たいと感じられているのではないかと考えている。 学んできたことを熱心に話しても、人によって反応の温度差がある。 という背景があると分かりました。 学んできた側の心の火は燃え上がっていても、受け取る側の準備ができていない状態のように見えます。 ディスカッションで出た「学びを100そのままぶつけるのではなく、相手が受け取れるタイミングで届けられるよう見極めることが大事なのでは」というアイデアは、特に納得感があり、記憶に残りました。「今がそのタイミングだ!」と気づいた時にすぐ取り出せるように、学んだことの言語化・体系化もセットで必要そうですね。 DevEnable室が策定している「発信にまつわるガイドライン」では、「自身の知見を形式知に変換できること」を発信活動の1つの目的として記載しています。そこに、「時が来た時にすぐ取り出して使える」という具体的な利用シーンを補足することを検討したいと思います。 テーマ:パックマンルール、どうしてる? 先日行われた社内懇親会で、参加者にパックマンルールへのご協力をお願いしました。ですが、知っている人同士で固まってしまいがちでした。 「パックマンルールへの協力をお願いするだけでは足りない」とチーム内で話していたため、ヒントを得ようとこのテーマに参加しました。 ディスカッションしながら自分たちでパックマンルールを試した結果、2つのコツが分かってきました。 今後懇親会などでパックマンルールを使う時は、説明スライドの中にこれらを入れてみようと思います。 パックマン側から「食いにいく」:パックマンを形成している人たちは、近くを歩いている人を見つけたら招き入れる(目を合わせる、手招きする、スペースを開ける)。 パックマンに自ら「食われにいく」:「今どんな話をしているんですか?」というフレーズを使えば途中からでも入っていける。話しかけられてOK感を自分から演出する(例:「話したい」意思表示シールを貼る)。 運営の立場だと、「人が集まれる場所を用意すること」も1つの工夫として実践できそうです。 例えば、壁際に椅子を並べてみると、3人並んで座ってもグループが閉じた状態にならないので、4人目が入りやすいですよね。 終わりに 前回のRSGTは新設チームのスクラムマスターとして参加していましたが、今回は違う立場での参加でした。 セッションやOSTの選び方はもちろん、スポンサーブースや廊下での会話内容も前回とは変化があり、新鮮な気持ちで参加できました。 今回得られた学びは、言語化・反芻して、時が来た時にすぐ扱えるように準備したいと思います。 そして最後に宣伝です! タイミーでは現在、一緒にはたらく仲間を募集中です。 学習と実践のサイクルをまわしながらプロダクト開発に取り組みたい方、ご興味があればぜひお話ししましょう! プロダクト採用サイトTOP カジュアル面談申込はこちら
アバター
今回は、タイミーの「 Kaigi Pass 」制度を利用して、12/4に開催のされたプロダクトマネージャーカンファレンス(以下、pmconf)に参加してきました。 この制度を通じて、非常に有意義な学びを得ることができましたので、その内容を共有します。 参加セッション 「メルカリのデータ分析AIエージェント『Socrates(ソクラテス)』と、それを支えるデータ整備」 登壇者:株式会社メルカリ データアナリティクスチーム セッション詳細・学び 1. 背景と課題 (As-is) メルカリでは専任のデータアナリストのリソースが潤沢ではなく、アナリストがいないチーム(0名のチームも存在)では、PdMが自らが分析を行う必要がありました。 部門を超えたインサイト収集の困難さ: 自分の担当外の領域(例:メルカリ担当がメルペイのデータを見る等)は分析のハードルが高く、工数を要するため、複合的な意思決定が困難でした。 リソースの壁: 「分析キャパシティ」がボトルネックとなり、問いの量と質が制限されていました。 2. 解決策:AIエージェント「Socrates」 (To-be) 自然言語で対話可能な分析エージェントを導入することで、以下の状態を実現しています。 未知の領域にも対応: 「メルペイの預金残高の使い道内訳」のような、ドメイン知識がない領域でも、エージェントがデータを探し出して集計・可視化してくれます。 並列思考: 複数の観点(Parallel Agent)でブレストを行い、仮説出しから検証までを一気通貫で実行します。 問いの量と質の向上: リソース制約を気にせず貪欲に調べられるようになりることで、アウトプットの総量もが直結して向上します。 3. 実現のための土台:Basic Tables AIが正しくデータを扱える理由として、 「AI-Readableなデータ分析基盤」 の存在が強調されました。 3層構造: Raw Data Tables → Basic Tables → Analytical Tables/Views という構造を採用。 特徴: 「Basic Tables」は人間とAIの両方が分析しやすいように整理された中間テーブルであり、ここに粘り強く投資したことが勝因です。 4. 組織と運用の工夫 ツールを入れるだけでなく、それを使いこなすための組織づく作りもセットで行われています。 独立した実行組織: 企画・開発・マーケまで完結できる遊軍的な「BI Productチーム」が開発を主導。 使いこなしのルール: 気になったらまずエージェントに聞く(依頼する前に相談)。 基礎的なSQLと社内DBの理解を持ち、クエリレビューを徹底して品質を担保する。 人を動かすための活用: レポートを蓄積するだけでなく、「隙あらば分析レポートをシュッ」と提示し、ファクトをベースに組織全体を動かす文化をつく作っています。 5. 要件定義プロセスへの応用 分析だけでなく、要件定義のプロセス全体(インプット→処理→アウトプット)でにおいても活用されています。 インプット: ユーザーログ、定性調査、競合調査など。 アウトプット: ユーザーストーリー、機能仕様書、ABテスト設計書など。 これらをAIが処理することで、PdMの業務効率を飛躍的に高めています。 現場視点での気づきと、これからのアクション 今回のセッションを聞いて私たちが何を感じ、現在進めているプロジェクトをどう加速させていくのか。チームとしての「熱量」と「次の一手」をまとめました。 私たちが得た「確信」と「気づき」 ■ 「領域横断」こそが、Growthの壁を壊す スライドに映し出された「部門を超えたインサイト収集が困難」という悩みは、正直なところ「これ、今の私たちのことだ」と痛感しました。 特にGrowth領域でスピード感を持って仮説検証を回そうとすると、どうしても担当外のデータやドメイン知識の壁にぶつかります。もし「Socrates」のように社内の全データが地続きになり、AIがその文脈までを理解してくれれば、SQLを書く時間を「ユーザーに向き合って思考する時間」に変えられまする。そうしたの未来図に、強い可能性を感じました。 ■ 誰もが「迷子」にならずに意思決定できる組織へ 「意思決定の階層を減らす」という思想も、組織が急拡大している今の私たちにとって非常に重要なテーマです。 新しくジョインしたメンバーが、複雑なテーブル定義の森で迷子にならず、AIという「相棒」を通じて過去の経緯やデータに即座にアクセスできる。それが実現できれば、オンボーディングのスピードも、自走力も劇的に変わるはずです。 ■ 定性データも「資産」として使い倒す 数字(定量データ)だけでなく、商談メモや行動ログといった「定性情報」までAIに読ませるという構想にはワクワクしました。 「数字には表れないけれど、現場には落ちているヒント」をAIが拾い上げてくれれば、私たちが生み出す仮説の精度はもっと高まるはず。これを支えるための「徹底したデータ文化」や「BI Productチーム」という体制づくりも含めて、本気で真似していきたいポイントです。 これからやること(Next Actions) ■ 進行中のPoCを、さらに磨き込む 実は現在、私たちも社内で同様のデータ基盤構築に向けた取り組みを、 PoC(概念実証)としてすでに始めていますスタートさせています。 「方向性は間違っていなかった」という心強さを感じると同時に、今回のセッションは、そのPoCを成功させるための大きなヒントになりました。 具体的には、以下の動きをすぐに始めます。 「Basic Tables」の思想を、自分たちのPoCへ 今回の大きな学びである「Basic Tables(AIと人間、両方が読みやすい中間層)」の構造 を、現在私たちが進めているPoCの設計と照らし合わせてみます。 DRE (Data Reliability Engineering) チームとも連携し、「今の設計でAIが本当にデータを正しく読めるのか?」という視点でからギャップを洗い出し、PoCの設計図をブラッシュアップします。 スモールスタートで「対話」を始める 基盤整備と並行して、まずは特定のデータセットに絞った形でも「対話型インターフェース」を試せないか検討します。来週さっそくチームで集まり、具体的なロードマップを引く予定です。 メルカリさんの事例を刺激に、私たちも「未来のデータ分析体験」の実装を一気に進めていきます。 関連資料 ▼ 参照リンク(セッション内で言及・関連情報) メルカリの効率的なデータ活用を支えるデータインタフェース Basic Tables|Mercari Analytics Blog 構想1ヶ月でローンチ。メルカリの新分析ツール「Socrates」が高速で開発できた理由 | mercan
アバター
MLOpsエンジニアのtomoppiです。 データエンジニアリング部 データサイエンスグループ(以下、DSG)に所属し、ML/LLM基盤の構築・改善に取り組んでいます。 AI Security Conference に参加してきたので、そのレポート記事となります。 余談ですが、当日はまい泉のお弁当をご用意いただきました。大好きなまい泉のカツサンドが出てきて、個人的に最もテンションが上がったポイントでした。 Findy Toolsさんとスポンサーの企業様には、感謝してもしきれません。 以降、真面目にレポートしていきます。 参加動機 MLOpsエンジニアとして本カンファレンスに参加した理由は、3ラインモデルの「第1線」を担う立場として、LLM特有のリスク管理をMLOpsのサイクルに組み込む重要性を感じているからです。 現在、タイミーのMLOpsチームでは、LLM API/LLMOps基盤の開発・運用を通じ、「安心・安全な利用」を最優先事項の一つとして取り組んでいます。 これまでも、 LLMアプリケーション向けProduction Readiness Checklist の策定を通じて、セキュリティ観点の整理を進めてきました。 また社内勉強会では、 OWASP Top 10 for LLM や AI-IRS といったフレームワークを紹介するなど、社内共有も行ってきました。 今回は、これまでの知見をさらに一歩進めるべく、他社の実務に即したセキュリティ運用の事例を収集し、自社基盤へフィードバックするヒントを得る目的で参加してきました。 全体を通して 大きく分けると、テーマは次の3本立てでした。 AIガバナンス (組織としてどう決めて回すか) Security & Safety for AI (LLMを利用する際のセキュリティ対策) AI for Security (セキュリティ運用でAIをどう使うか) 各社の前提が違うぶん「唯一の正解」があるわけではなく、それぞれの現実的な落とし所が共有されていたのが良かったです。 共通していたメッセージは、次の3点だと理解しました。 セキュリティは重要だが、 ブレーキになりすぎると活用が止まる だからこそ Secure by Defaultとなるアーキテクチャとプロセス が大事 ただし各種ツールはまだ未成熟で、トレードオフの中で各社が意思決定している 印象に残ったセッション 信頼できるAIの実現に向けた東京海上グループのAIガバナンスとセキュリティ戦略(東京海上ホールディングス株式会社) このセッションは、「信頼できるAI」について、 方針→基準→運用→技術 の流れで一本の線として説明されており、全体像がつかみやすかったです。 ポイント セーフティ と セキュリティ をまず切り分けて考える セーフティ: AIが誤答や偏りで「害を出さない」ようにする(品質・倫理・説明責任) セキュリティ: 攻撃や漏洩から「守る」(プロンプトインジェクション、機密情報、権限など) そして両方を、場当たり対応ではなく ガバナンス (方針・役割・プロセス・監査)として運用する ガバナンスを 基本方針/実施基準/実施要領 の3層に分け、外向けと運用を切り分ける AIリスクの議論はまず リスクの地図 を作ってから話す(論点の漏れ・重複を防ぐ) 例: 意図しない損害、バイアス、説明責任、情報漏洩、モデル脆弱性などを上位カテゴリとして押さえる モデル検証(開発時) と ガードレール(実行時) を分けて考える 独自流ではなく、可能な限り グローバル標準の枠組み に寄せる(例: MITRE ATLAS ) ツールは黎明期なので、ツールありきではなく アーキテクチャとプロセスで統制できる型 を先に作る 感想 セーフティ/セキュリティを分けて“運用”に落とす考えは、タイミーで進めているLLM基盤設計でも活用したいと思いました。 また、グローバル企業として関連会社が多いことから、全体を束ねる AI CoE(Center of Excellence) / AI Hub の構想も語られていました。組織の大きさや、そこでガバナンスをスケールさせる難しさについて、ヒントを得られる内容でした。 freee社のAI導入とセキュリティ対策(フリー株式会社) freee社のセッションは、「AIを全社で使う」前提に立ったときに、セキュリティをブレーキではなく「前に進める仕組み」として設計していたのが印象的でした。 ポイント 主要リスクは 漏洩 ・ ハルシネーション ・ コスト (扱うデータが機微なので) 展開は 実験場 → 交通ルール → 安全装置 → 本格展開 の段階設計 「安全装置」を プロキシ(LiteLLMなど)で型化 し、ログ・機微情報遮断・出力制御を必須ライン化 市場が追いつかない領域は 小さく内製 (セキュリティレビュー/脆弱性診断の自動化など) 役割分担も、従来の CSIRT(コーポレート)/PSIRT(プロダクト) の分担を前提にしつつ、 ブルー/レッド/ホワイト/パープル の「色」で責務を切り直す 背景: プロダクト特性の変化により守る範囲が広がり、従来の分業だけだと壁ができやすい ねらい: 特に パープル でレッドとブルーの連携を促進し、スピードを落とさない 感想 freee社の発表は、セキュリティ担当部門として“何をどう守るか”が具体的で、解像度が上がりました。要素技術面に関しても、タイミーで LiteLLMを利用した基盤開発を進めて いることもあり、実際的に参考になる内容が多かったです。 まとめ 今回一番のキーメッセージだと思ったのは、「AIセキュリティはツールを揃える前に、 ガバナンスとアーキテクチャで回る型 を先に作るのが大事」という点でした。 東京海上のセッションでは、セーフティ / セキュリティを切り分けたうえで、方針→基準→運用→技術へ落としていくことで、場当たり対応を防げるという点が整理されていました。 freeeのセッションでも、段階的に展開しつつ、プロキシを「安全装置」として型化してスピードを落とさない設計が重要と語られていました。 完璧主義で全部揃えてから進むのではなく、 リスクベース で段階的に進めながら、使うだけで守られる状態(Secure by Default)に近づけていくことが、当面の目標になりそうだと思いました。 AI CoEやカラーコードのような組織設計は、いますぐ真似できるものではないですが、「活用を止めないために、どう責務とプロセスを設計するか」という観点は持っておきたいです。 タイミーでも現在、LLM基盤の構築と並行して、LLM機能の検証をいろいろ進めています。今回の学びをヒントに、取り組みを安全に加速させていきます。
アバター
1. はじめに こんにちは。株式会社タイミーのデータサイエンスグループ(以下、DSG)でグループマネージャーを務めている菊地です。 前回の記事 では、タイミーのDSGが認知負荷をコントロールするために仮想チームという形態をとり、チームトポロジーの考え方をベースに組織を運営していることをお話ししました。 その中で、MLOpsエンジニア主体のプラットフォームチームの役割を「専門性を最大化するための共通基盤を提供すること」と定義しました。現在、その基盤の上でホットなトピックとなっているのが、LLMをはじめとする基盤モデルの活用です。 昨今の基盤モデルの急速な進化に伴い、タイミーの各プロダクトチーム(チームトポロジーにおけるStream Aligned Team、以下SA Team)からも「基盤モデルを使ってユーザー体験を向上させたい」というアイデアが次々と生まれています。プロダクト内のコンテンツ生成から業務の効率化まで、基盤モデルを活用することで解決できる課題の幅は非常に多岐にわたります。 ただ、基盤モデルをプロダクトの機能として組み込むプロセスは、従来のソフトウェア開発とは異なる考慮事項も多く、不確実性も伴います。 「そもそもこの課題に基盤モデルは最適なのか?」 「精度の評価はどう客観的に行えばいいのか?」 「セキュリティやコストの管理はどうすべきか?」 これらの問いに対して、すべての案件にMLOpsエンジニアやデータサイエンティストが付きっきりで関与していると、どうしても開発のスピード感を維持するのが難しくなることもあります。DSGがボトルネックになるのではなく、SA Teamが自分たちの力で自律的に、かつ安全に基盤モデルを活用した機能をリリースできるような状態を整えていく必要があります。 そのような背景から、DSGとして「基盤モデルを用いた機能開発のガイドライン」を策定しました。 本記事では、SA Teamのセルフサービスな開発を支援し、組織全体で価値提供を加速させるためのガイドラインのエッセンスをご紹介します。 2. 開発体制パターンとDSGの関わり方 基盤モデルを活用した機能開発を進めるにあたり、まず私たちが整理したのが、開発の特性に応じた開発体制パターンです。 すべての開発を同じフローに乗せるのではなく、技術的な複雑さや求められる専門性に応じて役割分担を明確にすることで、SA Teamが迷わずに開発を開始できるようにしています。 選択の指針:スピードか専門性か これら2つのパターンのどちらを選択するかは、主に「基盤モデルの出力がそのまま価値になるか」、それとも「複雑なロジックや既存システムとの高度な統合が必要か」という観点で判断します。 パターン1. セルフサービスパターン(ガイドラインのメイン対象) SA Teamが主体となり、クラウドプロバイダーが提供するAPIを利用して開発を進めるパターンです。基盤モデル周辺の実装が比較的シンプルに完結し、プロンプトの調整や基本的なRAG(検索拡張生成)の構成で十分な価値が出せるケースを想定しています。 主なユースケース:定型文の生成、ドキュメントの要約、シンプルな分類タスクなど。 責任の所在:機能の企画、プロンプトエンジニアリング、実装、評価までをSA Teamが完結して持ちます。 DSGの役割:DSGは、API利用環境の払い出しや、セキュリティ・コストのガードレール提供、技術的な壁打ち相手としての伴走(Enabling)に徹します。 このパターンの最大のメリットは、DSGとの調整コストを最小化し、SA Teamのスピード感で価値検証のサイクルを回せることにあります。 パターン2. Complicated Subsystemパターン システムやロジック自体が高度に複雑で、運用・改善にデータサイエンティストやMLOpsエンジニアの専門知見が不可欠なケースです。例えば、基盤モデルの出力を独自の数理モデルや推薦アルゴリズムと組み合わせる場合や、ドメイン特有の複雑な評価指標が必要な場合が該当します。 主なユースケース:複雑なマッチングロジックへの組み込み、高度な推論パイプラインの構築など。 責任の所在:DSGがアルゴリズムやバックエンドの主要ロジックに責任を持ち、SA Teamと協力してプロダクトへ統合します。 DSGの役割:モデル選定からパイプライン構築、精度評価の設計までを深くリードします。 専門性が求められる部分をDSGが引き受けることで、SA Teamが基盤モデルの深い専門知識をすべて学習する負荷を下げつつ、プロダクトのコア価値を最大化します。 3. 不確実性を乗りこなす5つの開発フェーズ 基盤モデルを活用した機能開発は、従来のソフトウェア開発に比べて不確実性が高く、やってみないとわからないことが多い領域です。そのため、ウォーターフォール型で一気に作り込むのではなく、アジャイルなアプローチで段階的に仮説検証を進めることが成功の鍵となります。 ガイドラインでは、開発プロセスを以下の5つのフェーズに定義しています。ここでは、各フェーズの概要と、私たちが重視している検証のポイントを紹介します。 実際のガイドラインでは、各ステップで「どのような性質の成果物が求められるのか」を具体的に定義しています。さらに、過去の成功事例で作成したシステム構成図や、投資対効果(ROI)の判断資料、プロンプトの評価ログなどを参照できるようにしており、各ステップで目指すべきゴールを明確にイメージできるように工夫しています。 Phase 1: 計画・設計フェーズ プロジェクトの目的を定義し、ビジネス価値と技術的実現性の両面から、プロジェクトの妥当性を検証します。 検証のポイント:解決したい課題に対して基盤モデルが最適な手段であるか、成功を測るための指標(KGI/KPI)が明確か、既存システムとの安全な連携が可能か。 期待される成果物の例:成功基準を定義したドキュメント、全体的なシステム構成案、想定されるリスクと対策方針の整理。 Phase 2: PoC開発フェーズ 「この機能は本当にユーザー価値があるか?」という仮説を検証するため、最小限のコストで迅速にコア機能を構築するフェーズです。 検証のポイント:基盤モデルの応答性能が実用レベルに達しているか、提示されたユーザー体験(UX)が課題解決に繋がっているか。 期待される成果物の例:主要なプロンプトの初案、コア機能が実際に動作するプロトタイプ、コストや性能を可視化する簡易的なモニタリング環境。 Phase 3: PoC評価・本番移行計画フェーズ PoCで得られた定量的・定性的なデータに基づき、本番開発へ進むべきかを客観的に判断するフェーズです。 検証のポイント:精度、コスト、速度を総合的に評価した際に、十分な投資対効果(ROI)が見込めるか。 期待される成果物の例:本番開発への移行を判断するための意思決定ドキュメント。 意思決定のプロセス:タイミーでは、本番移行にあたって技術およびプロダクト責任者による承認を必須としており、スピードとガバナンスの両立を図っています。 Phase 4: 本番開発フェーズ 検証された価値を、全ユーザーに安定して提供できる、スケーラブルで信頼性の高い機能を構築するフェーズです。 検証のポイント:最大トラフィックに耐えうる負荷対策がなされているか、プロンプトの変更が品質劣化を招かないための評価基盤が整っているか。 期待される成果物の例:環境分離(dev/stg/prod)が徹底された本番機能、品質劣化を防ぐための自動評価(リグレッションテスト)環境、運用のための各種レポート。 Phase 5: 本番運用・継続的改善フェーズ 安定稼働を維持しつつ、収集したデータに基づいて継続的に機能を改善し、ビジネス価値を最大化するフェーズです。 検証のポイント:実際の利用データに基づき、KPIが想定通り改善されているか。 期待される成果物の例:段階的なリリース計画、インシデント発生時の対応フロー、ユーザーフィードバックの収集・分析プロセス。 継続的改善:新しいモデルの登場やモニタリング状況の変化に合わせ、迅速にプロンプトやモデルをアップデートできる体制を維持します。 4. プロダクト品質を支える技術ナレッジの体系化 開発プロセスが整っても、個々の技術的な判断基準が属人化していては、プロダクト全体の品質を一定に保つことはできません。ガイドラインでは、SA Teamが自律的に最適な意思決定を行えるよう、基盤モデル活用の勘所を技術ナレッジとして集約しています。 ここでは、私たちがガイドラインで定めている技術ナレッジの概要をいくつかご紹介します。 本当に「基盤モデル」が最適か? 基盤モデルは極めて汎用性が高いツールですが、すべての課題に対する正解ではありません。私たちは、開発を始める前に「本当にその課題を基盤モデルで解くべきか?」を立ち止まって考えることを推奨しています。 基盤モデルが得意なこと: 創造性が求められる文章生成、膨大な情報の要約、そして「文脈やニュアンス」を汲み取った高度な分類・抽出、画像や音声を統合して理解するマルチモーダルな処理。 基盤モデルが苦手なこと・適していないこと: 100%の正確性が求められる、シンプルな条件分岐で済むルールベースの処理、すでに特定のタスクに特化した専用AI APIが存在するケース。 「最新技術だから使う」のではなく、コスト・精度・安定性のバランスを鑑みて、従来通りのプログラムや専用APIの方が優れていないかを冷静に見極める眼を養うための基準を明文化しています。 素早い価値検証とデータ資産の積み上げ 一方で、基盤モデルの大きな強みは「機械学習の事前準備をショートカットできること」にあります。 従来の機械学習プロジェクトでは、特定のタスクを解くために大量の学習データを準備し、モデルをトレーニングするという数週間〜数ヶ月単位のプロセスが必要でした。基盤モデルを使えば、この重たい工程を飛び越え、プロンプトの調整だけで数日〜数週間でユーザーへの提供価値を検証できる可能性があります。 たとえ初期のAPIコストが高くついたとしても、まずは最速で「そもそもこの機能がユーザーに求められているか」という本質的な仮説に答えを出す。そして検証の過程で蓄積された「ユーザーの入力」と「フィードバック」は、将来的に専用モデルや自社独自のモデルへ移行する際の貴重な学習データとなります。 「まずは基盤モデルで素早く価値検証を行い、成功すればそのデータを基に、より最適なソリューションへ進化させていく」という、時間軸を味方につけた戦略も取りうることを明文化しています。 処理の安定性と信頼性 基盤モデルの出力をプログラムで安定して扱うためには、自由な文章ではなく、後続の処理で扱いやすい形式でデータを受け取ることが不可欠です。これは一般的に構造化出力と呼ばれていますが、私たちは構造化出力を実装における標準として定義しています。 プロンプトによる指示に加え、モデルのネイティブ機能やバリデーション用のライブラリを適切に組み合わせることで、システムの安定性を高めます。また、APIの利用制限や一時的な負荷増大によるエラーに備え、自動的な再試行や代替モデルへの切り替えといった、プロダクション環境に耐えうる信頼性設計のパターンを共通化しています。 5. おわりに 今回ご紹介したガイドラインは、一度策定して終わりではありません。現場からのフィードバックや日々進化する技術動向を取り入れながら、常にアップデートし続けるドキュメントとして運用しています。 私たちがこのガイドラインを通じて実現したかったのは、不確実性の高い、基盤モデルを活用した開発において、各プロダクトチームが余計な迷いなく自律的に動けるよう、必要な指針を示し、環境を整えることでした。 DSGがすべての案件を抱え込むのではなく、専門知見を標準化して組織全体に開放していく。このプロセスこそが、タイミーが技術の力でミッションを達成するための大きな原動力になると信じています。 We’re Hiring! タイミーでは、データサイエンティストやMLOpsエンジニアはもちろん、今回ご紹介したようなガイドラインや基盤を使い倒してプロダクトに価値を届けるエンジニア、プロダクトマネージャーなど、全方位で一緒に働くメンバーを募集しています! 最新の技術をどう社会実装するかという仕組みづくりに興味のある方は、ぜひカジュアル面談でお話ししましょう。皆さんの挑戦をお待ちしています! タイミー採用情報 - Product Team
アバター
1. はじめに こんにちは。株式会社タイミーのデータサイエンスグループ(以下、DSG)でグループマネージャーを務めている菊地です。 タイミーでは「『はたらく』を通じて人生の可能性を広げるインフラをつくる」というミッションを掲げ、日々膨大なマッチングデータや行動データを活用して、プロダクトの価値向上や意思決定の高度化に取り組んでいます。 ありがたいことに、最近は採用活動を通じて多くの方とカジュアル面談でお話しする機会が増えています。その中で、非常によくいただくのが「DSGはどのような組織体制で、どのようにコミュニケーションを取りながら組織運営しているんですか?」というご質問です。 これまでは面談の場で個別にお伝えしてきましたが、私たちの組織も拡大し、フェーズに合わせて柔軟に形を変えてきました。そこで今回、改めてタイミーDSGの現在の「組織のカタチ」を言語化し、候補者の皆さんに私たちのチームの現在地を詳しくお伝えしたいと思い、この記事を書くことにしました。 私たちの組織運営のキーワードは、「認知負荷の低減」と「自律性の最大化」です。 かつては全員で一つのスクラムを組んでいましたが、現在は「仮想チーム」という形態をとり、各チームが自律的に開発サイクルを回しています。本記事では、チームトポロジーの考え方を取り入れた組織構造から、具体的な開発フロー、そしてグループ内の文化までご紹介します。 2. 組織の変遷:なぜ「仮想チーム」へと移行したのか 全員ですべてを把握していた「単一スクラム」時代 以前、まだグループの人数が少なかった頃は、DSG全体で一つのスクラムチームとして活動していました。当時は全員がすべての取り組みの状況を把握し、毎日のデイリースクラムで情報を共有し、全員でリファインメント(バックログの精査)を行っていました。このスタイルは、情報の透明性が高く、誰が何をやっているかが一目でわかるという大きなメリットがありました。 急成長に伴う「認知負荷」の限界 しかし、タイミーというプロダクトの成長に合わせ、DSGが解決すべき課題は急速に増え、かつ多様化していきました。 担当するドメインの拡大 MLOps基盤の高度化と、それに伴う専門知識の深化 ステークホルダーの増加 こうした状況下で、一つの大きなスクラムを維持しようとすると、メンバー一人ひとりが追わなければならない情報量が爆発的に増えていきました。例えば、あるデータサイエンティストにとっては、自分が担当していない領域の細かい仕様検討を延々と聞き続けなければならず、逆にMLOpsエンジニアにとっては、すべてのモデルの数理的な背景まで深く理解し続けなければならない…といった具合です。 これが、本記事のキーワードである「認知負荷」が限界に達した瞬間でした。 「仮想チーム」とチームトポロジーの導入 この課題を解決するために私たちが取り入れたのが、実組織の中をいくつかの「仮想チーム」に分割する運用です。 「実組織」としては一つのDSGですが、日々の活動(スクラム)は各仮想チーム(Squad)単位で行います。この体制を設計する際、書籍「 チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計 」の考え方を参考にしました。 チームトポロジーとは、チームの「認知負荷」を考慮して組織とシステム構造を整合させ、高速な価値提供を目指す組織論です。私たちはこれに基づき、チームの性質を以下のように定義しました。 MLOpsエンジニア主体のチーム:プラットフォームチーム DSを中心とした多様な利用者が、ML/LLMを用いた価値提供に集中できるように、機械学習基盤やLLM基盤、CI/CD、MLミドルウェアなどの「専門性を最大化するための共通基盤」を提供する役割。 データサイエンティスト主体のチーム:コンプリケイティッド・サブシステム・チーム 推薦・マッチングやモデレーションといった特定のドメインに責任を持ち、高度なサブシステムの開発やビジネス上の複雑な課題解決を担う役割。 このように役割とチームを明確に切り分けることで、メンバーは「今自分が注力すべき領域」に認知的リソースを集中することができるようになりました。 DSG内の仮想チーム関係図 %%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': 'arial', 'primaryColor': '#ffffff', 'edgeLabelBackground':'#ffffff', 'tertiaryColor': '#f8fafc' }}}%% graph BT %% --- スタイル定義 --- classDef platform fill:#2563eb,stroke:#1e40af,stroke-width:2px,color:#ffffff,rx:10,ry:10,font-size:15px,font-weight:bold; classDef css fill:#f97316,stroke:#c2410c,stroke-width:2px,color:#ffffff,rx:10,ry:10,font-size:15px,font-weight:bold; classDef dsgContainer fill:#f1f5f9,stroke:#3b82f6,stroke-width:3px,stroke-dasharray: 6 4,color:#1e40af,font-weight:bold,font-size:16px; %% --- DSG内部の組織構造 --- subgraph DSG ["DSG (Virtual Organization Structure)"] direction BT %% 上層:価値創出の主体 CSS["コンプリケイティッド<br/>サブシステムチーム<br/>(Squads)"]:::css %% 下層:強固な基盤 MLP["ML基盤チーム<br/>(Platform Team)"]:::platform %% 供給フロー(強力な支援) MLP ====>|専門性を最大化するための共通基盤を提供| CSS end %% スタイルの適用 class DSG dsgContainer linkStyle 0 stroke:#3b82f6,stroke-width:4px; 関連記事として、データサイエンティストのストリームアラインドチームからコンプリケイティッド・サブシステムチームへの配置変更の変遷は、以下の記事をご参照いただければと思います。 tech.timee.co.jp 3. 現場の意思決定を加速させる「Squad Lead」 仮想チーム(Squad)は、特定のプロジェクトを遂行するためだけのタスクフォースではなく、担当ドメインの成果に対して中長期的に責任を持つ半永久的な組織として機能しています。 このSquadにおいて、現場の自律性を支えているのがDSG独自の役割である「Squad Lead(SL)」です。SLは、データサイエンティストやMLOpsエンジニアが本来の業務と兼務する形で担う「内部的なロール」です。 GMとSLの役割分担 私(グループマネージャー:GM)とSLは、「組織の土台作り」と「ドメインの戦略実行」という軸で役割を分担しています。 GM:採用・配置・評価・キャリア成長など、「ヒト・モノ・カネ」といった組織基盤の最適化。 SL:担当ドメインにおける「コト(プロダクト・課題)」の解決。ロードマップ策定、短期〜中期の成果創出、ステークホルダーとの合意形成に責任を持つ。 現場のコンテキストを一番理解しているメンバーがSLとして意思決定を主導し、私はそれを組織的な側面から全力でサポートする。この補完関係を築くことで、マネージャーがボトルネックにならないスピーディな開発体制を実現しています。また、あえて「仮想」という柔軟な形にしていることで、メンバーがリーダーシップを経験する機会を広げ、事業状況に合わせた機動的なチーム編成を可能にしています。 4. 専門性を最大化するプラットフォームと開発フロー では、具体的にどのようにプロダクト開発が進められているのでしょうか。ここからは、MLOpsエンジニアとデータサイエンティストの連携に焦点を当ててご紹介します。 MLOpsエンジニアが整える、専門性に集中するための共通基盤 MLOpsエンジニアは、いわゆるプラットフォームチームとして、利用者が本来の役割に集中できるよう、共通の開発環境やデプロイフローを整えています。 利用者の中心はDSですが、領域によってはデータアナリストやプロダクトエンジニアも想定ユーザーに含まれます。Google Cloudをメイン基盤とし、モノリポ構成でのディレクトリ設計やTerraformによる構成管理、CI/CDスクリプトの整備、さらにLLM基盤の構築やMLミドルウェアの導入・運用までを幅広く担当します。これにより、インフラやデプロイの複雑さを意識せずとも、安全かつ高速に価値を送り出せる仕組みが整っています。 大まかな機械学習基盤の構成は下記ページの「 Architecture 」セクションをご覧いただければと思います。 product-recruit.timee.co.jp データサイエンティストによる一気通貫の価値創出 データサイエンティストはこの基盤を使い倒し、ビジネス課題の発見から解決までを一気通貫で担います。 上流工程:課題設定、問題発見、ステークホルダーとの期待値調整。 開発・実装:分析、PoC(LLM活用含む)、本番環境へのエンジニアリング。 検証・改善:デプロイ後のABテスト、効果検証、それに基づく改善サイクルの実行。 整備されたプラットフォーム上で、Dev / Stg / Prod の各環境を使い分けながら高速にサイクルを回しています。このように、基盤を支えるスペシャリストと、事業価値を創出するスペシャリストが背中を預け合える関係性が、タイミーDSGの強みです。 5. チーム運営とシナジーを生む仕組み 仮想チームとして分かれて活動しつつも、グループ全体としての知見の共有や、職種を越えた連携を支えるための「場」や「仕組み」を大切にしています。 MLOpsとDSを繋ぐフィードバックループ MLOpsエンジニア主体のプラットフォームチームは、2週間のスプリントで動いています。スプリントの終わりには、基盤の利用者(主にDS)に向けた「ML基盤アップデート共有会」を実施しています。 ここでは新機能の周知だけでなく、利用者からの改善リクエストや困りごとを直接受け付けるスプリントレビューのような役割も果たしています。「作って終わり」ではなく、常に利用者の声を聞きながら基盤をブラッシュアップしていく。この対話の仕組みこそが、DSG内での高い開発体験を支えています。 AIも駆使して刺激を与え合う「学び」の習慣 私たちは技術的な研鑽も欠かしませんが、その「継続しやすさ」にもこだわっています。DSG内では定期的に勉強会を開催していますが、現在は隔週1時間で「毎回3,4名が10〜15分ずつ発表する」というスタイルをとっています。 意識しているポイントとしては、発表のハードルを極限まで下げていることです。発表時間を短くすることで、トピックの論点を端的にまとめやすくし、発表のハードルも下げています。発表資料の作成にはNotion AIやNotebookLMといったツールを積極的に活用し、準備の省力化を推奨しています。これにより「資料作りに追われてアウトプットが億劫になる」のを防ぎ、ハイスピードで知見を循環させることに挑戦しています。 また、グループ内に閉じず、他部署のエンジニアを交えた合同輪読会を行っているチームもあり、組織を越えて互いに高め合う文化が根付いています。 制度を活用した「チームビルディング」 仕事以外での繋がりも、心理的安全性を高める重要な要素です。タイミーにはチームビルディング費用の補助が出る全社的な福利厚生制度があり、これを活用して毎月、部署内外のメンバーと交流(飲み会や親睦会)を行っています。 部署内の結束を深める月もあれば、他部署のメンバーと交流する月もあり、こうした定期的な交流の場が「困った時にいつでも相談できる」関係性の土台になっています。 6. おわりに 今回は、タイミーのデータサイエンスグループ(DSG)がどのような組織構造で、どのような思想を持って日々開発・運用を行っているのかをご紹介しました。 私たちが「仮想チーム」や「Squad Lead(SL)」という運用に行き着いたのは、単に組織を管理するためではなく、「メンバー一人ひとりが認知負荷に振り回されず、本来の専門性を最大限に発揮して、プロダクトに価値を届けられる環境」を作りたかったからです。 組織の形は、プロダクトのフェーズや課題に合わせて柔軟に変わっていくべきものです。今回ご紹介した体制も現在の「最適解」ではありますが、今後さらに組織が拡大していく中で、私たちはまた新しい壁にぶつかり、形を変え続けていくはずです。そうした変化を楽しみながら、仕組みそのものをアップデートしていけることも、今のタイミーDSGの面白さだと感じています。 この記事を通じて、私たちの組織運営やチームの雰囲気が少しでも伝わっていれば幸いです。 We’re Hiring! タイミーではデータサイエンティスト・MLOps Engineerをはじめ、一緒に働くメンバーを募集しています! カジュアル面談 も行なっておりますので、興味のある方はぜひお気軽にお申し込みください! https://product-recruit.timee.co.jp/
アバター
はい、亀井です。 yykamei という名前でインターネットではやらせてもらっています。所属はタイミーです。 Regional Scrum Gathering Tokyo 2026(RSGT2026)に、ボランティアスタッフとして参加しました。 今年は会場が変わったこともあり、運営側としても新たな挑戦が多い年でした。今回は「運営としての学び」と、セッションや対話から得られた「実践知としての学び」という二つの視点から、今年のRSGTを振り返ります。 ボランティアスタッフとして見た「現場」と「適応」 今年の大きなトピックは、やはり会場が変わったことでした。これによって、長年蓄積されてきた「あの会場ならこう動けばいい」という特定の場所に依存したノウハウが使えなくなりました。 しかし、具体的な手順書がリセットされた状態でも、スタッフそれぞれが「このイベントにおいて自分は何をやるべきか」という本質を理解していたため、阿吽の呼吸でなんとかなったように思います。自己組織的なコミュニティーですね。終わった後にスタッフでこのRSGT2026について全員が一言を述べるのですが、皆さん、それぞれの視点からいろいろな学びやフィードバックを持ち込んでくださったり、「そもそも今回はどのような心持ちで望んでいたか」という話をしてくれたりして、カンファレンスのスタッフとしてどのような価値を出すべきかということについてハッとさせられました。 今回の私のスタンスは「無理にがんばらない」ということでしたが、終わってみるとそこそこの歩数を稼いでしまったので、目標達成はできなかったようです。しかし、それだけ人との会話を楽しめたのかなと思います。 「空調」と「導線」 会場の空調管理が難しかったです。結果として「寒い」という意見がマジョリティを占めてしまったように感じます。RSGTは例年1月の最も寒い時期に開催されるため、基本的には「高めの温度設定」をデフォルトにしておくのが正解だという明確な学びを得ました。これは来年への重要な引継ぎ事項かもしれないですね。とはいっても、空調管理は他のスタッフがやってくれていたので、まずは空調機器の操作方法を覚えるところからが来年のスタートになりそうです。 また、会場レイアウトについても気づきがありました。Hall AとHall Bは基本的には同じ作りのはずなのですが、机の配置の影響で、Hall Aは両サイドに廊下的スペース(通路)がなく、人の移動がしづらい状態になっていました。一方でHall Bは余裕があり、スムーズな回遊ができていました。来年はHall AもHall Bのような配置をするといいのだろうなと思っております。 壁を取り払う 今回の会場であるベルサール羽田空港は、部屋と部屋をつなげるなど、レイアウトに柔軟性があります。また、部屋の数も多いので、今回はスポンサーブースとして部屋を二つ借り、その間の壁をなくしてつなげていました。 これは大成功だったようでして、スポンサーの方からも「参加者が回遊できてよい」というポジティブなフィードバックがあったようです。 「情報保障」と能動的なキャッチアップ RSGTは昨年同様、今年も情報保障にかなり力を入れていました。しかし、ボランティアスタッフとして参加していながら、その具体的な仕組みや運用ノウハウについて、私自身が意外と知らないことに気づかされました。 運営マニュアルとして手取り足取り教えられるわけではないので、スタッフ自身が積極的に知ろうと動かないと、その裏側にある努力や仕組みを知ることができません。 これってオンボーディングのない会社に入社したときと同じですよね。来年は、この情報保障の領域についても、もっと能動的にキャッチアップしていこうと心に決めました。 セッションを見た感想 運営の合間に参加したセッションと、部屋付きとして参加したセッションについて書いてみます。 改めてスクラムについての学び ryuzeeさんのキーノートでの デイリースクラム Deep Dive のセッションに部屋付きとして入りました。デイリースクラムは単なる報告会ではなく、透明性を確保し、検査と適応を行うためのイベントです、と。「スプリントゴール達成が唯一の目的」であり、そのための検査である、といったことをおっしゃっていたように思います。特に印象的だったのが、「タイムボックスの延長を許すのは『割れ窓理論』と同じである」という指摘です。一度時間を守らなくなると、他の規律もなし崩し的に守らなくなるとのことでした。「PBI単位で、上から順番に確認する」という具体的なアドバイスや、スプリントゴールチェックインという手法は、すぐに現場で試せる知見でした。 また、Yohさんの よくわからないことが多い場合の計画づくりのコツ にも部屋付きで入りました。「わからないことはわからない」と認め、細かく計画しすぎず、「わからないことを見える化」するために頻繁に計画を見直す、といったことをおっしゃっていたような気がします。面白いのは、「わからないことリスト」的なものを作成しておく、という点ですかね。これは、Kent Beckが『Tidy First?』で言っていた「お楽しみリスト」みたいなものかもしれない、と勝手ながら思いました。リストに含めておく、という行為がいったん忘れることができるのでいいですよね。 とみたさん・田口さんの Sprint Reviewで、ビジネスと開発の「当たり前」を同期する 、こちらも部屋付きで聞かせていただきました。レビューが盛り上がらない根本原因は「学習の場になっていない」ことにあるという指摘には深く頷きました。ステークホルダーには「アジャイル」という用語を使わずに対話するという話があったのですが、すごくいい話だなと思いました。 複雑さと向き合う組織づくり 組織論の観点では、長沢さんの EBM実践のカタ —— 実践とゴールと計測を結びつけるアジャイルのありたい姿へ が印象に残っています。「開発作業ではなく実験をするべき」という言葉。そして、リーダーは戦略的ゴールを示し、実践者が戦術的ゴールを定めるという構造は、健全な自律組織の条件だと感じます。 森さんの 「私の要求最優先!あなた後回し」そんな対立を超えてビジネス、開発、顧客が本当に欲しかったものを全両立するプロダクト組織の作り方 での「循環構造型トレードオフ(AをやるとBがだめになり、BをやるとAがだめになる)」という話も、プロダクト開発のリアル!という感じでしたね。ビジネス、開発、顧客の間で揺れ動く中で、「長期的な有害」をマネジメントするという発想はなかったなーと思いました。今まで気にならなかったものが気になり始めたら、それは工夫が始まっている証拠だという言葉には勇気づけられました。 およべさんの AI時代のアジャイルチームを目指して - "スクラム"というコンフォートゾーンからの脱却- では、組織を「チームのような密度」で捉え、ロールを動的にしていくという、これからの組織のあり方が示唆されていました。振り返ってみると、これはDay3の漆原さんの クロージングキーノート につながっていたな、という気がします。 人、モチベーション、そして物語 Day2のいくおさんの 自己管理型チームの一員となるためのセルフマネジメント:モチベーション編 、こちらはたまたま私のフリーな時間が重なったので話を聞くことができました。「自己管理型チームと個人のセルフマネジメント 〜モチベーション編〜」というタイトルです。ERG理論(成長・関係・存在)とかABC理論(出来事・信念・結果)といった理論を紹介しつつ、ご自身の経験をもとにした発表で、「え、いくおさん、そんなことを思っていたんだ」という感じです。その中でも「自分はいつもメンバーに恵まれている」と言っていたのですが、シンプルにこれを言えるマネージャーってすごいな、と思いますよね。 ちんもさんの 田舎で20年スクラム(後編):一個人が企業で長期戦アジャイルに挑む意味 、こちらは部屋付きで入っていました。急遽、部屋付きを一人でやることになってバタバタしそうだったのですが、それでも内容は結構印象に残っています。私の印象では一言で言えばチェンジエージェントの話です。しかし、チェンジエージェントといってもそれを20年やっているわけですよ。言葉の重みが違いますよね。現場を変えようとする人々の背中を押すような素晴らしい内容でした。 最後に セッションだけでなく、廊下での雑談もRSGTの醍醐味です。たぶんインターネットで公開できないような話も聞けたと思います。 ボランティアスタッフの打ち上げ的な飲み会で、永瀬さんがおすすめしてくれたものをメモしたのを見返すと、「セサミストリート」「スンスン」と書いてありました。 会場変更という大きな変化の中で、ボランティアスタッフとして「適応」を実践できたこと。そして、セッションを通じてスクラムの「基本」と「本質」に立ち返れたこと。 今年のRSGTは、運営という立場だからこそ得られた「組織としての動き方」の学びと、コンテンツからの学びがリンクする、非常に濃密な時間でした。 ここで得た熱量と知見を、明日からの現場、そして来年のRSGTにつなげていきたいと思います。
アバター
はじめに こんにちは、タイミーでPlatform Engineerをしている近藤です。 タイミーでは、インフラ管理においてTerraformを積極的に活用しています。 当初はAWSリソースの管理が中心でしたが、事業や組織の拡大に伴い、管理対象は多岐にわたるようになりました。 現在では、以下のような様々な用途でTerraformリポジトリが運用されています。 AWSインフラ: メインとなるサービス基盤の構築・運用 GCPインフラ: BigQueryなどのデータ分析基盤や、特定のGoogle Cloudリソース管理 SaaSアカウント管理: GitHubやDatadogなどのユーザー・権限管理 その他: Elastic Cloudなどの専用リソース管理 このように、クラウドプロバイダーも用途も異なる複数のリポジトリが存在する状況において、私たちは「Terraformワークフローの共通化」に取り組みました。 共通化前の課題 リポジトリが増えるにつれて、開発・運用チームは次のような課題に直面していました。 ワークフローの実装と機能のバラつき リポジトリごとにCI/CDの設定がコピペと独自改変を繰り返して作られていたため、「あるリポジトリではLintが走るが、別のリポジトリでは走らない」「あるリポジトリではSlack通知が飛ぶが、別のリポジトリでは通知自体がない」といった不整合が起きていました。 メンテナンスコストの増大 新しいセキュリティチェックツールの導入や、Terraformのバージョンアップに伴うCI修正を行おうとすると、全てのリポジトリに対して個別に修正PRを送る必要がありました。 新規リポジトリ作成への心理的ハードル 「リポジトリを分けたほうが責務が明確になる」と分かっていても、「またあのCI設定をコピーしてメンテナンスするのか」という負担が頭をよぎり、既存のリポジトリに無理やりリソースを追加してしまうケースがありました。 結果として、ワークフローの維持管理が大変そうで、新しい用途での活用を躊躇してしまうという状態になっていました。 解決策:共通Terraformワークフロー基盤の開発 これらの課題を解決するために、社内のTerraformリポジトリで利用するためのCI/CDワークフローを共通化し、単一のプロダクトとして管理する共通Terraformワークフロー基盤を開発しました。 安全かつ自動化された配布の仕組み 共通化にあたっては、変更が全リポジトリに波及するリスクを考慮し、安全に開発・配布できる仕組みを構築しました。 サンドボックス用リポジトリでの開発 まず、Terraform用の実験リポジトリで機能追加や修正を行います。ここで実際にTerraformを動かし、動作を検証します。 共通ワークフロー基盤リポジトリへの自動PR サンドボックスでの検証が完了して main ブランチにマージされると、自動的に共通Terraformワークフロー基盤リポジトリに対してPull Requestが作成されます。 各リポジトリへの自動配布 共通Terraformワークフロー基盤側でPRをマージすると、その変更が対象となる全ての実利用リポジトリ(AWS用、GCP用、SaaS用など)に対して自動的に配布されます。 このサイクルにより、開発者は安心して共通基盤を改善でき、利用者も常に検証済みの最新ワークフローを享受できるようになりました。 同期ワークフローの実装 上記の配布フローは、GitHub Actions と GitHub App を使った同期ワークフローによって実現されています。具体的な実装を見ていきましょう。 同期ワークフローの全体像 name : Sync Workflow on : push : branches : [ main ] workflow_dispatch : jobs : # 配布先リポジトリ一覧を設定ファイルから読み込み load_repositories : outputs : repositories : ${{ steps.load.outputs.repositories }} steps : - uses : actions/checkout@v4 - id : load run : | REPOS=$(yq -o=json '.repositories' sync-repositories.yaml | jq -c) echo "repositories=$REPOS" >> "$GITHUB_OUTPUT" # 各リポジトリに対してマトリクス実行で同期 sync_workflow : needs : load_repositories strategy : matrix : include : ${{ fromJson(needs.load_repositories.outputs.repositories) }} steps : # GitHub Appで配布先リポジトリ用のトークンを発行 - uses : actions/create-github-app-token@v2 id : app-token with : app-id : ${{ vars.BOT_APP_ID }} private-key : ${{ secrets.BOT_APP_PRIVATE_KEY }} owner : ${{ matrix.owner }} repositories : ${{ matrix.name }} # ソースと配布先の両方をチェックアウト - uses : actions/checkout@v4 with : repository : ${{ matrix.owner }}/${{ matrix.name }} token : ${{ steps.app-token.outputs.token }} path : target-repo # sync-files.yaml に基づいてファイルをコピー - name : Copy workflow files run : .github/scripts/sync-copy-files.sh # 差分があればPRを作成 - name : Create PR if changed run : .github/scripts/sync-create-pr.sh env : GH_TOKEN : ${{ steps.app-token.outputs.token }} 配布先リポジトリの設定(sync-repositories.yaml) 配布先となるリポジトリは、設定ファイルで管理します。共通基盤リポジトリでは、実利用リポジトリすべてを配布先として定義しています。 # 共通基盤リポジトリの sync-repositories.yaml repositories : - owner : your-org name : repo-a # 利用リポジトリA - owner : your-org name : repo-b # 利用リポジトリB - owner : your-org name : repo-c # 利用リポジトリC # ... 他の利用リポジトリ 一方、サンドボックスリポジトリでは、共通基盤リポジトリのみを配布先として定義します。 # サンドボックスの sync-repositories.yaml repositories : - owner : your-org name : workflow-base # 共通基盤リポジトリのみ 同期対象ファイルの設定(sync-files.yaml) 同期するファイルと除外するファイルは、設定ファイルで明確に管理します。 # .github/config/tf/sync-files.yaml # 同期対象のファイル・ディレクトリ files : - .github/config/tf/ # 共通設定ファイル - .github/workflows/ # ワークフローファイル - .github/actions/tf_* # カスタムアクション # 除外対象(リポジトリ固有の設定) exclude : - .github/workflows/tf_sync_workflow.yml # 同期WF自体 - .github/config/tf/sync-files.yaml # 同期設定 - .github/config/tf/sync-repositories.yaml - .github/config/tf/.env.local # ローカル環境変数 - .github/config/tf/dirs.json # 対象ディレクトリ一覧 - .github/config/tf/filters.local.yaml # ローカルフィルタ - .github/config/tf/.tflint.hcl # tflint設定 - .github/config/tf/trivy.yaml # trivy設定 このように、共通化すべきファイルと、リポジトリ固有であるべきファイルを明確に分離することで、柔軟性を保ちながら一貫性を維持しています。 設定ファイルによる振る舞いの制御 共通ワークフローの振る舞いは、階層化された設定ファイルによって柔軟に制御できます。 設定ファイルの階層構造 .github/config/tf/ ├── .env # グローバル設定(共通) ├── .env.local # リポジトリ固有の設定 ├── dirs.json # 対象ディレクトリ一覧 ├── filters.yaml # グローバル変更検出フィルタ ├── filters.local.yaml # ローカル変更検出フィルタ ├── .tflint.hcl # tflint設定 └── trivy.yaml # trivy設定 envs/ ├── production/ │ └── .env # ディレクトリ固有の設定 └── staging/ └── .env グローバル設定(.env) 全リポジトリで共通の設定です。同期によって配布されます。主な設定項目は以下の通りです。 Terraform実行設定 : 並列数( TF_MAX_PARALLEL_JOBS )、CLI引数( TF_CLI_ARGS_plan )など Git設定 : コミット時のユーザー名・メールアドレス Slack通知設定 : ステータスごとの色・メッセージ・絵文字・アイコンを SLACK_STATUS_{STATUS}_{PROPERTY} 形式で定義 Slack通知の設定はデータとして定義し、ワークフロー側ではシェルの間接変数展開を使ってジョブのステータス(success / failure / cancelled / maintenance)に応じた値を動的に参照する設計にしています。 リポジトリ固有・ディレクトリ固有の設定 グローバル設定を上書きする設定は、以下の2箇所で定義できます。 .env.local : リポジトリ全体に適用される設定(同期の除外対象) envs/{env}/.env : 特定のディレクトリにのみ適用される設定 主な設定項目: TF_MAX_PARALLEL_JOBS : APIレート制限を考慮した並列数の上書き AWS_ROLE_TO_ASSUME / GCP_WORKLOAD_IDENTITY_PROVIDER : 認証設定 SLACK_CHANNEL_ID / SLACK_MENTION_NAME : 通知先チャンネルとメンション 対象ディレクトリ設定(dirs.json) terraform plan/apply の対象ディレクトリを定義します。 [ " envs/production ", " envs/staging ", " envs/development " ] 変更検出フィルタ(filters.yaml) 共通モジュールや設定ファイルの変更時に全ディレクトリを再実行するためのグローバルフィルタです。 # .github/config/tf/filters.yaml(共通) terraform_trigger : - modules/ - .github/config/tf/ - .github/actions/tf_*/** - .github/workflows/tf_* - .github/workflows/*tf** - .terraform-version # .github/config/tf/filters.local.yaml(リポジトリ固有) terraform_trigger : - shared/ # リポジトリ固有の共有モジュール 認証処理の共通化(tf_init アクション) 認証処理はComposite Actionとして共通化し、AWS OIDC / GCP Workload Identity Federation の両方に対応しています。 # .github/actions/tf_init/action.yml name : Terraform Init inputs : directory : required : true credentials : required : false runs : using : composite steps : # リポジトリ固有のパッチがあれば適用 - name : Check if tf_patch exists id : check-patch shell : bash run : | if [ -d ".github/actions/tf_patch" ] ; then echo "exists=true" >> "$GITHUB_OUTPUT" fi - name : Apply patches if : steps.check-patch.outputs.exists == 'true' uses : ./.github/actions/tf_patch with : directory : ${{ inputs.directory }} # Terraformバージョンのセットアップ - name : Setup Terraform uses : hashicorp/setup-terraform@v3 with : terraform_wrapper : false terraform_version : ${{ steps.var.outputs.terraform-version }} # 環境変数の読み込み(グローバル → ローカル → ディレクトリ固有) - name : Load environment variables shell : bash run : | for env_file in \ ".github/config/tf/.env" \ ".github/config/tf/.env.local" \ "${{ inputs.directory }}/.env" ; do if [ -f "$env_file" ] ; then envsubst < "$env_file" >> "$GITHUB_ENV" fi done # AWS OIDC認証(設定がある場合) - name : Configure AWS credentials if : env.AWS_ROLE_TO_ASSUME != '' uses : aws-actions/configure-aws-credentials@v4 with : aws-region : ${{ env.AWS_REGION }} role-to-assume : ${{ env.AWS_ROLE_TO_ASSUME }} # GCP Workload Identity認証(設定がある場合) - name : Authenticate to Google Cloud if : env.GCP_WORKLOAD_IDENTITY_PROVIDER != '' uses : google-github-actions/auth@v2 with : workload_identity_provider : ${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }} service_account : ${{ env.GCP_SERVICE_ACCOUNT }} # Terraform init - name : Terraform init shell : bash run : | terraform -chdir=${{ inputs.directory }} init 導入成果 運用面での改善 共通基盤を1箇所修正するだけで、全リポジトリに改善が行き渡るようになりました。セキュリティスキャンの追加やツールのバージョンアップも、一括で適用可能です。 また、どのリポジトリを触っても、「PRを出せばPlanが走り、結果がコメントされる」「マージすればApplyされる」という同じ挙動が保証されるようになりました。これにより、エンジニアが新しいリポジトリを触る際の学習コストが下がりました。 技術的に実現できたこと 共通Terraformワークフロー基盤では、インフラ運用に必要な仕組みを次のような形でまとめて提供しています。 Terraform実行パイプラインの共通化: PRごとに  terraform plan 、mainマージ時に  terraform apply  を自動実行し、複数環境をマトリクス実行しながら並列数を制御。 実行の安全性とレートリミット対策: ワークフローのコンカレンシーやキャンセルポリシーを設定し、不要な再実行を避けつつ、GitHub API やクラウドプロバイダAPIのレートリミットにかからないように実行を制御。 品質・セキュリティチェックの標準化:  terraform fmt  /  validate  /  tflint  /  trivy  に加え、各種Lintを一括で走らせ、結果をPRレビューとしてフィードバック。 ドリフト検出と自動PR: 定期的なPlanで実環境とのドリフトを検出し、差分があれば自動でPRを作成・管理。 PRレビュー体験の強化: Plan/Apply結果や診断結果に加え、AIベースのPRエージェントによる要約・レビューコメント生成でレビュー負荷を軽減。 認証と権限管理の一貫性: AWS OIDC / GCP Workload Identity Federation とアクセスキー認証の両方に対応し、 plan  /  apply  ごとに適切な認証情報を選択できるよう統一。 設計時に意識したこと Terraformワークフローを「単なるCI設定」ではなく、継続的に拡張・改善していける共通基盤にするために、次のような設計方針と実装上の工夫を取り入れています。 1つのソースから複数リポジトリへ安全に配布できること 共通ワークフローの更新がそのまま全リポジトリに波及するため、必ずサンドボックスで検証してから共通基盤に取り込む二段階フローにしています。その上で、GitHub App を使ったトークン発行と同期専用ワークフローにより、「人手でコピペせずに、レビュー済みの変更だけを各リポジトリへ配布する」という流れを自動化しました。 配布方法としては、reusable workflow を使って直接呼び出す案も検討しました。しかし、ユースケースが社内限定であること、配布時の差分をPRとして確認できたほうがレビューしやすいこと、呼び出し元ワークフロー側の設定も含めて将来的に変更する可能性があることから、GitHub App で各リポジトリにPRを作成する方式を選びました。 設定ファイルで振る舞いを切り替えられること Terraform の実行対象やトリガーとなるファイルパターンなどは、ワークフロー内にベタ書きせず、グローバル設定とリポジトリごとの設定ファイルをマージして解決する構造にしています。これにより、「共通のベースラインは維持しつつ、プロジェクトごとに監視対象や実行頻度だけ変える」といった調整をコード変更なしで行えるようにしました。 認証・権限まわりをワークフロー側で肩代わりすること AWS OIDC / GCP Workload Identity Federation によるキーレス認証と、従来のアクセスキー認証の両方をラップし、 plan / apply などのアクションごとに適切な権限を選び分けられるようにしています。個々のリポジトリでは「どのロール/サービスアカウントを使うか」だけを意識すればよく、認証フローそのものの実装は共通基盤に閉じ込めています。 共通ワークフローと各リポジトリの実装を柔軟につなげられること ワークフローの中で、Terraformファイルに対して小さなパッチを当てる専用アクション tf_patch を用意しています。 例えば、各リポジトリの providers.tf には、過去の経緯からローカル開発用のAWS認証設定(プロファイル指定やロール引き受け設定)が含まれています。CI環境ではOIDC認証を使用するためこれらの設定は不要であり、むしろ干渉してしまいます。 tf_patch アクションは terraform init の前にこれらの行を自動的に削除し、どのリポジトリでも同じOIDC認証の前提で共通ワークフローを実行できるようにしています。 このように、共通ワークフローと各リポジトリ固有の実装の間をつなぐアダプタとして機能させることで、既存コードへの変更は最小限に抑えたまま共通化を進められるようにしています。 現状の課題 共通化によって多くのメリットを得られましたが、運用を続ける中でいくつかの改善点も見えてきました。 同期除外対象の管理 現在、同期対象から除外するファイルは sync-files.yaml にファイル名を個別で定義しています。しかし、除外対象が増えるにつれてこのリストの管理が煩雑になってきました。ディレクトリ構造を整理し、「共通化するもの」と「リポジトリ固有のもの」を明確にディレクトリで分離することで、除外設定をシンプルにできる余地があります。 ファイルの差分管理 同期ワークフローは「ソースリポジトリにあるファイルを配布先にコピーする」という動作をしますが、ソースリポジトリでファイルを削除・移動した場合に、配布先の古いファイルを自動で削除するような仕組みにはなっていません。そのため、ファイル構成を変更した際には、配布先リポジトリに不要なファイルが残ってしまうことがあります。この問題も、上述のディレクトリ構造の見直しによって対応できると考えています。現状では、AIコーディングエージェントの Devin を活用して、不要になったファイルのお掃除PRを作成してもらうなど、人力での対応を行っています。 おわりに 共通Terraformワークフロー基盤によって、インフラや各種 SaaS アカウント管理のワークフローは一貫性を持って運用できるようになり、個々のリポジトリごとに CI を実装・メンテナンスする負担は大きく減りました。そのうえで、開発者は「リポジトリごとの Terraform の中身」に集中しやすくなり、ワークフロー自体は共通基盤として継続的に改善していける状態になっています。 また、この記事で紹介したのと同じような考え方で、アプリケーションのモノレポに対するデプロイワークフローも共通化しています。こちらについても、機会があれば別のエントリとして詳しく紹介できればと思います。
アバター
こんにちは、タイミーでバックエンドのテックリードをしている新谷( @euglena1215 )です。 Rails アプリケーションの開発をしていると、fat になってしまった Sidekiq worker や、ドメインロジックらしき実装が書かれている Serializer に遭遇したことがあるのではないでしょうか。 この記事では、MVC アーキテクチャを一段階抽象化して捉えることで、Rails のさまざまなレイヤーに対して一貫したプラクティスを適用する考え方を紹介します。ある程度 Rails を触ったことのあるエンジニアが感覚的に理解している概念を、改めて言語化したものです。 MVC の役割を改めて整理する まず、MVC の各レイヤーの役割を整理しておきましょう。 Model : ビジネスロジック、データ、ルールそのものを表現し、データの保存・取得を行う View : データをユーザーに返却するための適切な形で変換する Controller : 外部からの入力を受け取り、Model を操作しデータの取得・更新を行い、View で変換したデータを外部へ出力する ここで重要なのは、MVC を「Model, View, Controller という三つのディレクトリ」として捉えるのではなく、「三つの責務」として抽象的に捉えることです。 「実質〇〇」という視点 一番分かりやすい例は、JSON の組み立てを行う Serializer です。Serializer は app/serializers ディレクトリに配置されますが、その責務は「データを適切な形に変換してユーザーに返却する」ことであり、これは 実質的に View です。 この「実質〇〇」という視点でタイミーの Rails アプリケーションの各レイヤーを分類してみましょう。 実質 Model ディレクトリ 説明 app/models Model そのもの app/policies 特に認可にフォーカスしたもの app/validators 特にバリデーションにフォーカスしたもの Policy や Validator は、ビジネスルールを表現するという点で、 Model の責務を担っています。 実質 Controller ディレクトリ 説明 app/controllers Web API リクエストにおけるエントリポイント app/workers 非同期処理におけるエントリポイント app/mailers メール送信におけるエントリポイント lib/tasks rake タスクにおけるエントリポイント app/services エントリポイントから括り出された処理 app/forms エントリポイントから括り出された処理 ポイントは、Service *1 や Form *2 がエントリポイントではないものの、Controller に実装されるべき処理を括り出したものであるという点です。そのため、実質的には Controller と捉えるのが妥当です。 実質 View ディレクトリ 説明 app/views HTML やメール文面の組み立て app/serializers JSON の組み立て Serializer を View と捉えることで、View に関するプラクティスを Serializer にも適用できるようになります。 この視点のメリット 「〇〇は実質的に Model / View / Controller である」という感覚を持つことで、MVC の一般的なプラクティスを MVC 以外のレイヤーにも適用できます。 例えば、以下のようなセルフチェックが可能になります。 一般的な MVC のプラクティス チェックリスト 実質 Controller は十分に薄く、ドメインロジックや表示用ロジックが混ざっていないか? ドメインロジックは実質 Model に寄せているか? 表示のためのデータ加工は実質 View に寄せているか? 実質 Model は実質 Controller に依存していないか? 実質 Model は実質 View に依存していないか? 具体例 例えば、「Service クラスが肥大化している」という問題があったとします。 Service は実質 Controller なので、「Controller が肥大化している」と言い換えられます。Controller が肥大化する原因は、ドメインロジックや表示用ロジックが混入していることが多いです。 したがって、解決策は以下のようになります。 ドメインロジック → Model(または Policy, Validator)に移動 表示用ロジック → View(または Serializer)に移動 このように、MVC のプラクティスを適用することで、自然と適切な設計に導かれます。 まとめ MVC は「三つのディレクトリ」ではなく「三つの責務」として捉える Rails の各レイヤーを「実質 Model / View / Controller」で分類することで、一般的な MVC プラクティスを適用できる Service は実質 Controller、Serializer は実質 View、Policy は実質 Model この視点を持つことで、一貫性のあるクラス設計が可能になる 日々のコードレビューや設計判断の際に、「これは実質どのレイヤーか?」と問いかけてみてください。 *1 : タイミーでは、Service クラスをController や Sidekiq worker から呼ぶものと位置付け、Model からは呼び出されないようなルールにしています。詳細は https://tech.timee.co.jp/entry/2024/01/29/170000 をご覧ください。 *2 : タイミーでは、Form クラスにおける明確なルールはないものの、特定のエンドポイントにおける処理を括り出したものという位置付けの使い方をしていることが多いため、こういった整理をしています。
アバター
こんにちは、タイミーのデータサイエンスグループでマネージャーをしている菊地です。 本記事では、タイミーのデータサイエンス組織が直面した「認知負荷」や「優先順位」の課題に対し、チームトポロジーの考え方を取り入れて、どのように体制を見直したかを紹介します。 具体的には、データサイエンティストをストリームアラインドチームから「コンプリケイティッド・サブシステムチーム」へと再配置した背景と、その後のチーム間連携を円滑にするための「プロトコル」の設計・運用についてお話しします。 はじめに タイミーの開発組織ではチームトポロジーに基づいた組織運営を行っており、ストリームアラインドチーム、プラットフォームチーム、イネイブリングチーム、コンプリケイティッド・サブシステムチームといったチームタイプに分かれて、日々の開発業務を行っています。 チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計 tech.timee.co.jp データサイエンスを用いた機能開発の初期フェーズでは、その立ち上げを軌道に乗せるために、データサイエンティストがストリームアラインドチームに所属し、プロダクト開発と並走する体制をとっていました。データサイエンティストがドメイン知識を深く理解し、ビジネス課題に対して即応性の高い分析やモデル構築を行う必要があったからです。 しかし、事業が急成長し、プロダクトが大規模化・複雑化するとともに、サブシステムとして運用しうるものが一定程度できてくるにつれて、「ストリームアラインドチームにデータサイエンティストが同居する」体制の限界が見え始めてきました。 そこで、 高度な専門性が求められる特定の領域 (審査システムや推薦システムなど)において、データサイエンティストをストリームアラインドチームから切り出し、コンプリケイティッド・サブシステムチームとして再編成する組織リデザインを行いました。 以下では、その背景にあった具体的な課題と解決策、そして運用で定着しつつある具体的な連携プロトコルについて紹介します。 課題:ストリームアラインドチームにおけるデータサイエンティストの認知負荷と専門性のコンフリクト 以前まで特定のプロダクト領域では、データサイエンティストがストリームアラインドチームの一員として活動していました。この体制には「ドメイン知識の獲得」や「デリバリーのスピード」というメリットがあった一方で、運用を続ける中で以下のような課題が顕在化してきました。 1. 認知負荷の高まり ストリームアラインドチームの取り組みは、ユーザーへの価値提供に集中し、高速にイテレーションを回すことが求められます。一方、高度なML/LLMシステムの開発・運用には、論文調査や実験設計、長期的な精度改善といった、通常の開発サイクルとは異なる時間軸と専門知識が必要です。 ストリームアラインドチームにおける日々のユーザーへの価値提供と高度なMLモデルの研究開発を、同時に同一チーム内で担うことは、脳のスイッチングコストが非常に高く、認知負荷の限界を超えつつありました。結果として、「機能は作れるが、モデルの精度改善やアーキテクチャの刷新に手が回らない」という状況が生まれ始めていました。 2. 優先順位の競合 ストリームアラインドチームは、その時々のプロダクトゴールに向かってバックログの優先順位を決定します。一方で、ML/LLMシステムには「一度作って終わり」ではなく、データ傾向の変化への追随や継続的な精度モニタリングといった恒常的な改善が不可欠です。しかし、こうしたタスクは直近のゴールには直接結びつかないことが多く、結果として構造的に優先順位を上げにくいという課題がありました。 例えば、MLモデルの定期的な再学習パイプラインの整備や、将来の施策に向けた技術検証(PoC)、論文調査などは、短期的にはユーザー価値に直結しにくいため、スプリントの中で後回しにされがちでした。さらには、正式なタスクとしてバックログに載せることを諦め、メンバーが個人的に時間を捻出して整備を行うといった「隠れた稼働」が発生してしまうこともありました。これにより、データサイエンティストの活動が見えにくくなったり、キャリア成長の機会が損なわれたり、技術的負債が蓄積するといった懸念がありました。 解決策:チームトポロジーに基づくコンプリケイティッド・サブシステムチームの組成 これらの課題を解決するため、チームトポロジーの概念におけるコンプリケイティッド・サブシステムチームとして、対象領域ごとに専門チームを新設しました。 コンプリケイティッド・サブシステムチームの役割は、「高度な専門知識を必要とする複雑なサブシステムの管理に責任を持ち、その複雑さを他のチームから隠蔽すること」です。 これにより、データサイエンティストはコンプリケイティッド・サブシステムチームに所属し、複雑なサブシステムの開発・運用に集中できるようになります。同時に、ストリームアラインドチームは「中身の複雑なロジック」を意識することなく、提供されたAPIを利用するだけで高度な機能をユーザーに届けることができるようになります。 Before flowchart TB subgraph SAT1 ["🔹 Stream-aligned Team"] direction TB DS1("📊 Data Scientist"):::ds Others1("👥 Other Members<br>(PdM, Designer, Eng, Scrum Master, etc.)"):::others end %% Styles classDef ds fill:#fff9c4,stroke:#fbc02d,color:black,stroke-width:2px,rx:5,ry:5 classDef others fill:#ffffff,stroke:#bdbdbd,color:black,stroke-width:1px,rx:5,ry:5 style SAT1 fill:#f8f9fa,stroke:#dee2e6,stroke-width:2px,rx:10,ry:10 After flowchart TB subgraph SAT2 ["🔹 Stream-aligned Team"] direction TB Members2("👥 Team Members<br>(PdM, Designer, Eng, Scrum Master, etc.)"):::others end subgraph CSub ["✨ Complicated Subsystem Team ✨"] direction TB DS2("📊 Data Scientist"):::ds end CSub == "API (X-as-a-Service)" ===> SAT2 %% Styles classDef ds fill:#fff9c4,stroke:#fbc02d,color:black,stroke-width:4px,rx:10,ry:10 classDef others fill:#ffffff,stroke:#bdbdbd,color:black,stroke-width:1px,rx:5,ry:5 style SAT2 fill:#f8f9fa,stroke:#dee2e6,stroke-width:2px,rx:10,ry:10 style CSub fill:#fff3e0,stroke:#ef6c00,stroke-width:3px,stroke-dasharray: 5 5,rx:10,ry:10 linkStyle 0 stroke:#ef6c00,stroke-width:3px,color:#ef6c00 インタラクションモードとプロトコルの明文化 組織を分けることで最も懸念されるのが、「サイロ化」と「連携コストの増大」です。これを防ぐため、基本的には X-as-a-Serviceモード を採用しつつ、状況に応じて コラボレーションモード を使い分ける運用としています。 基本方針:X-as-a-Service 日常的な開発・運用においては、コンプリケイティッド・サブシステムチームが提供するサービス(API、ドキュメント等)をストリームアラインドチームがセルフサービスで利用する形をとります。 ストリームアラインドチームとの連携境界における、コンプリケイティッド・サブシステムチームの主な責務は以下の通りです。 安定したAPIの提供と、SLA/SLOの維持。 専門的なロジックの隠蔽と、利用しやすいインターフェースの設計。 ドキュメントの整備(ストリームアラインドチームが自律的に利用できるようにする)。 ストリームアラインドチームは、いちいちコンプリケイティッド・サブシステムチームに「これどうなってますか?」と確認することなく、APIドキュメントを参照して開発を進めることができ、開発スピードを維持できます。 もちろん、API仕様書だけを投げ合うのが非効率な場面(新規機能開発や大きな変更時など)では、同期的な会議や一時的なスクラムイベントへの参加などを通じて、柔軟にコラボレーションを行っています。基本は疎結合(X-as-a-Service)を保ちつつ、必要な時には密に連携できる柔軟性を持たせています。 プロトコルの明文化 「X-as-a-Service」や「コラボレーション」といったモードを定義しても、実際の現場では「このタスクはどっちの責務?」「今はどっちのモードで動くべき?」といった迷いが生じがちです。 そこで、これらの実行を補完する役割として、特に密接に関わっているストリームアラインドチームとコンプリケイティッド・サブシステムチームの間で「チーム間連携プロトコル」というドキュメントを作成し、合意形成を行いました。 このドキュメントには、主に以下のような内容を記載しています。 各チームのミッションと責務の定義 : ストリームアラインドチームとコンプリケイティッド・サブシステムチームがそれぞれ何に責任を持つかを明記。 自律的に実行できる活動リスト : 連携や確認なしで進めて良いタスクを具体的にリスト化(例:公開API仕様内でのリファクタリングなど)。 連携が必要なケースとフロー : コミュニケーションが必要な具体的なトリガーと、その際の推奨連絡手段。 エスカレーションパス : 解決しない場合の判断フロー。 こうした具体的な「期待値調整」をドキュメント化しておくことで、日々のコミュニケーションコストを削減し、迷いを減らすことができています。 おわりに 組織構造は、その時点でのビジネスフェーズと技術的な複雑さに応じて進化させる必要があります。かつてはデータサイエンス的な要素を含んだ機能開発を行うため、ストリームアラインドチームにデータサイエンティストが在籍する体制をとっていましたが、フェーズの変化に伴い、コンプリケイティッド・サブシステムチームとして切り出す形がより適した状態へと変わりました。 今回のリデザインにより、データサイエンティストはより専門性を発揮しやすく、ストリームアラインドチームはよりユーザー価値に向き合いやすい体制が整いつつあります。特に、データサイエンティストからは「技術的な深掘りがしやすくなった」「コンテキストスイッチが減った」という声が上がっており、組織としての健全性も向上しています。 この事例が、拡大するエンジニアリング組織におけるチーム設計の参考になれば幸いです。 We’re Hiring! タイミーではデータサイエンティストをはじめ、一緒に働くメンバーを募集しています! カジュアル面談 も行なっておりますので、興味のある方はぜひお気軽にお申し込みください! https://product-recruit.timee.co.jp/
アバター
はじめに この記事は Timee Product Advent Calendar 2025 の25日目の記事です。 MLOpsエンジニアの tomoppi です。データエンジニアリング部 データサイエンスグループ(以下DSG)に所属し、ML/LLM基盤の構築・改善に取り組んでいます。 2024年10月にタイミーへジョインし、気がつけば1年あまりが経ちました。2025年はLLM/LLMOpsに奔走した1年で、PoCを実施した施策の本番導入や、LLMの可観測性・プロンプトマネジメントに取り組み、走りながら考え、考えながら走る日々でした。 そんな中で、ふと思うようになりました。「2026年、タイミーのLLM基盤はどうあるべきか?」 本記事は、その問いに対する私なりの答え——というより、 夢と妄想 です。この1年で見えてきた課題と、それを乗り越えるための構想を、できるだけ具体的に描いてみます。 2025年の振り返り 個人的な振り返り まずは、私がこの1年取り組んできたことについて、簡単に触れさせていただきたいと思います。 年初時点では、社内でいくつかのLLM関連PoCが動いているフェーズで、まだMLOpsとしてのLLMへの関わりは薄い状態でした。一方で、DSG内ではLLMへの注目が高まり、キャッチアップを目的としたLLM勉強会が始まりました(この勉強会は現在も継続しています)。 その流れで、2月に「LLMOpsとは何か」をテーマに勉強会を開催し、評価手法やプロンプト管理、モニタリングなど、従来のMLOpsとは異なる論点をDSGで共有しました。 3月に入ると、PoC段階だったLLM機能を本番導入する動きが増え、「どう設計すれば安全かつ現実的に運用できるか」を一から詰めていくことになりました。この過程で得られた知見・経験は、 LLMアプリケーション向けProduction Readiness Checklist 執筆の動機になりました。 LLMOpsツール導入の検討も並行して行い、10月頃、LLMOps基盤としてDatadog LLM Observabilityの本格運用を開始しました。 「なんとなく動いている」から「ちゃんと運用できている」状態へ、徐々に進めている感覚がありました。 また、Datadog社からのお声がけで、 Datadog LLM Observabilityを題材とした登壇 の機会もいただき、実りの多い1年となりました。 LLMOpsとTeam Topologies MLOpsチームは、Team Topologiesで言うCollaboration Modeで、データサイエンティストチーム(as Complicated Subsystem Team)やプロダクトエンジニア(as Stream-aligned team)と密に連携してきました。 AI施策ごとにMLOpsエンジニアがプロジェクトに参画し、初期の壁打ちからアーキテクチャ設計、実装まで伴走してきました。この進め方は、ナレッジが少なく不確実性が高い状況で、知見を素早く蓄積し、開発のアジリティを確保するうえで非常に有効でした。 一方で、この体制は長期的には持続しないことも見えてきました。 「AIを使いたい」という熱量が全社的に高まるほど、インフラやガバナンス整備待ちの「行列」が生まれ、結果としてビジネスのスピードを落としてしまいます。 同時に、LLM利用が拡大するにつれ、プロンプトインジェクションをはじめとするセキュリティ対策やコスト最適化、利用モデルの透明化といったガバナンスが、より重要になってくると考えています。 その規模になると、個別対応をずっと続けることは現実的ではありません。 2025年末の課題 整理すると、現状の課題は次の3つです。 Agility(俊敏性の欠如) 検証環境構築のリードタイムが長く、高速な検証を阻害する状況になっています。 LLM開発では「評価データの準備」「プロンプト変更→評価→改善の反復」「モデルの切り替え」「コスト見積(トークン/レイテンシ/単価)」など、環境以外にも反復のボトルネックが多く、施策の立ち上げや改善の速度を落としてしまいます。 Scalability(拡張性の限界) LLM施策の需要増に対しMLOpsチームの供給体制が追いつかず、組織全体でのLLM施策がスケールしません。 ボトルネックが「技術(インフラ)」ではなく「人(MLOpsチーム)」になっていることは、構造的な制約であり、このままではスケール上の限界に直面します。 Governance(統制の分散/部分最適) 施策ごとに個別最適な判断・実装が積み上がり、環境や運用がサイロ化します。その結果、コスト配賦や利用実態の把握、セキュリティ対策、監査対応などがチームごとにバラバラになり、全社としての管理が難しくなっています。 2026年に目指したいタイミーのLLMOps Collaboration ModeからX-as-a-Serviceへ 前述したような課題を乗り越え、LLM活用を全社的にスケールさせるために、2026年はMLOpsチームが個別のプロジェクトに入り込むのではなく、「セルフサービスで使えるプラットフォーム」を提供することを目指しています。Team Topologiesで言う X-as-a-Service への移行です。 プロダクトチームが自律的にLLM機能を開発・運用できる基盤——これを Unified LLM Platform と呼ぶことにします。 「The Art of AI Maturity」とPlatform Engineering Maturity Modelへの接続 とはいえ、「本当にUnified LLM Platformとしての共通基盤は必要なのか?」という問いには答えておきたいところです。戦略的なフレームワークを参照しながら、その必要性を整理してみます。 そのフレームワークとして、 The Art of AI Maturity と Platform Engineering Maturity Model を参照していきます。 The Art of AI Maturityから見た Unified LLM Platformの必要性 The Art of AI Maturityは、Accentureが提唱するAI成熟度を評価するフレームワークで、17のKey Capabilitiesを定義しています。タイミーでは、このフレームワークを全社的に参照しています。 Unified LLM Platformの構築は、以下の8つのKey Capabilitiesに対する実行施策となります。 Key Capability Unified LLM Platformとの関係 #3. Proactive vs Reactive 先行投資によるプラットフォーム整備により、市場ニーズ発生後の追随ではなく、先回りでAIオポチュニティを創出 #4. Readily Available AI/ML Tools セルフサービス化されたLLM開発環境により、開発者が環境準備で待たされない状態を実現 #5. Readily Available Developer Networks 統一インターフェースやオープンなアーキテクチャにより、OSSコミュニティとの連携を促進 #6. Build vs Buy 競争優位を生むコア領域(LLM features)は内製、基盤部分でのUtilityはSaaS/PaaS/OSSを活用するポートフォリオ戦略を実現 #7. Platform & Technology 推論基盤(マルチプロバイダー対応、統一API)、ガードレール(DLP/ポリシー/ツール実行制御)、可観測性(トレーシング/メトリクス)、評価、コスト管理をプラットフォームとして標準化し、安全で再現性のある運用を実現 #13. Innovation Culture Embedded 探索の自由度を高めるプラットフォームにより、日常業務に実験・学習サイクルを組み込む文化を促進 #16. Responsible AI 技術的統制(PIIマスキング、監査ログなど)により、倫理・法規制に適合したRAIプロセスを実現 #17. Responsible AI — Change RAI体制の継続的強化を、プラットフォームレベルで自動化・標準化 Platform Engineering Maturity Modelから見た Unified LLM Platformの必要性 次に、Platform Engineering Maturity Modelを参照してみます。 Platform Engineering Maturity Modelとは、プラットフォームエンジニアリングを5つの観点(Adoption、Interfaces、Investment、Measurement、Operations)で評価するフレームワークです。 これまでプロジェクト単位でのスピードを優先してきたため、プラットフォームとしての成熟度は「レベル1(暫定的)」であり、部分的に「レベル2(戦略的)」という評価になります。 0→1の立ち上げ期においては、この「都度対応」が最も機動力を発揮しました。しかし、1→10、10→100へとスケールさせるこれからのフェーズにおいては、かつての最適解(レベル1)が最大のアンチパターンになりつつあります。「レベル1だからダメ」なのではなく、「レベル1のやり方で戦えるフェーズは終わった」と認識しています。 2025年の振り返りで述べた課題や体制を踏まえると、現在のタイミーのLLMOpsは、各観点で以下のような状態にあると考えられます: 観点 現状 Investment(投資) プロジェクトごとの個別対応が基本で、MLOpsチームの部分的なタスクとして遂行している状況です。 Adoption(採用) LLMが必要なチームが散在する社内ナレッジをもとに施策を検討し、MLOpsチームも都度個別対応を行っていたため、標準的なプラクティスやポリシーが不十分な状態です。 Interfaces(インターフェース) これまではMLOpsエンジニアが伴走し、プロジェクトごとに最適な構成を提供してきました。部分的に共通化できている箇所もありますが、セルフサービスで利用できる統一インターフェースは整っていない状況です。 Measurement(測定) LLM基盤として指標は定義できておらず、収集もできていない状況です。 Operations(運用) これまではプロジェクトごとのリクエストに応じた柔軟な対応で素早く価値を届けてきましたが、モデルの利用状況や、更新対応は個別管理になっており、LLMライフサイクルを中央集権的に管理できていない状態です。 2026年に目指すのは、各観点でレベル3(スケーラブル)への移行です。これはチャレンジングな目標ですが、Unified LLM Platformの構築により実現を目指します: 観点 実現内容 Investment MLOpsチームがPlatform Teamとして明確な役割を持ち、LLM Platformのロードマップに基づく計画的な投資を実行していきます。 Adoption 「Golden Paths over Cages」 の方針により、「強制」ではなく「便利だから使われる」プラットフォームを実現。ドキュメント整備とオンボーディング(利用開始までの手順・ガイド)を含めたSelf-service化を推進し、プロダクトチームが自律的にLLM機能を開発・運用できる状態を目指します。 Interfaces 統一されたエンドポイントとOpenAI互換の単一API仕様を提供。認証・認可はインフラ層で透過的に実行され、開発者は意識不要。Observability by Defaultにより、追加実装なしで全リクエストのトレース・レイテンシ・コストを可視化し、セルフサービスで利用できるようにします。 Measurement LLM基盤のSuccess Metrics(標準指標)を定義し、必要な計装(テレメトリ/ログ/利用データ)を組み込みます。定期レビューにより、利用状況と改善効果を可視化し、意思決定と改善サイクルを回せる状態にします。 Operations どのサービスがどのモデルを利用しているのかを中央集権で管理し、モデルの非推奨対応や新規モデルのロールアウト統制を取れる状態にします。加えて、Migration手順、責任分界(責任共有モデル)、ロールバック戦略を標準プロセスとして整備します。 実現に向けたエンジニアリング ここからは、どのようにUnified LLM Platformを実現するのか、エンジニアリング観点で整理していきます。 「探索の自由度」・「運用時の信頼性」・「技術的統制」 プラットフォームを設計するにあたり、特に重視したい要求を3つに整理しました。 1. 探索の自由度(Freedom of Exploration) 「データサイエンティストやプロダクトエンジニアが、面倒な環境構築なしに、アイデアを即座に試せる環境」 を実現したいです。 LLM開発は「試行錯誤」がすべてです。エンジニアだけでなく、PMやビジネスサイドのメンバーもプロンプトを直接触れられることが、開発速度に直結します。 この要求を満たすため、以下の要素が重要です。 モデルの切り替え(Model Agnostic) 「Geminiで試したけど、AnthropicやBedrockだとどうなる?」をコード変更なしで、設定の切り替えだけで素早く試せること。 統一インターフェース プロバイダーごとに異なるAPI仕様(OpenAI / Azure / Bedrock / Vertex AIなど)を意識せず、統一されたSDK/APIで呼び出せること。 プロンプトのバージョン管理とプレイグラウンド Gitのように「v1.2のプロンプト」と「v1.3のプロンプト」をGUI上で比較実行できる環境。エンジニアに依頼せずとも、画面上でパラメータを調整して挙動を確認できること。 評価駆動開発(Eval-driven Development)のための環境 オフライン評価における実験管理やLLM-as-a-judgeなどを、Day1から行えること。 Open-weight Modelsの活用 必要なユースケースでは、GKE上のvLLMなどでOpen-weight Modelsを扱える選択肢を残すこと。 2. 運用時の信頼性(Operational Reliability) 「確率的なLLMを、確定的なエンタープライズシステムとして振る舞わせるための安定化機構」 が必要です。 PoCでは許されても、本番環境では「APIが落ちていました」「遅すぎます」は許されません。 この要求を満たすため、以下の要素が重要と考えています。 リトライとフォールバック(Fallbacks) プロバイダー障害時に別経路へ切り替えたり、高性能モデルがタイムアウトしたら高速なモデルで再試行したりする冗長化構成。 ただし、 フォールバックは「評価で許容できる」と確認できた組み合わせに限定 。(挙動差分が大きいと品質事故につながるため)。 スマートキャッシング(Caching) 同一リクエストにはキャッシュから応答し、レイテンシ短縮とコスト削減を両立。将来的にSemantic Cacheも検討。 レート制限と公平性 一部のヘビーユーザーがトークンを使いすぎて他のサービスに影響を与えないよう制御できること。 オブザーバビリティ 開発者がモニタリング環境の構築を意識せず、モデルの性能やリソース使用状況を確認できること。 3. 技術的統制(Technical Governance) 「組織としてリスクをコントロールし、野良AIや青天井のコストを防ぐためのガードレール」 を整備したいです。 この要求を満たすため、以下の要素が重要と考えています。 PII/機密情報のマスキング (Redaction) クレジットカード番号、メールアドレスなどがプロンプトに含まれていたら、LLMに送信する前に自動でマスキングする機能。 プロンプトインジェクション対策(Prompt Injection Mitigation) 入力/出力のフィルタリング(疑わしい指示の検知・遮断、システムプロンプトや機密情報の漏洩防止など)と、コンテンツポリシー(許可/禁止の基準)をプラットフォーム側で標準化する。 Tool Use(外部API呼び出し、DB参照、チケット発行など)を行う場合は、ツールのAllowlist化・引数検証・権限境界の設計などにより「実行制御」を行い、必要に応じてサンドボックス(隔離環境)で安全に実行する。 認証方式の統一化 全てのLLMリクエストをLLM Gatewayを通すことで、認証方式を統一化し、プロジェクト固有で認証部分を行う必要性をなくす。 コストの予算管理 (Cost Budgeting) 「プロジェクトAは月額◯◯円まで」といったキャップを設定し、超過しそうになったらアラートを出す仕組み。 監査ログ (Audit Logs) 「誰が」「いつ」「どんなプロンプトを」「どのモデルに」投げたか追跡可能にすること。 ここは強い統制になる一方、 ログの取り扱い(PIIの扱い、保持期間、閲覧権限、暗号化、マスキング後のみ保存など) も同時に設計対象。 プラットフォームの構成イメージ これらの要件を同時に満たすために、 AI Gateway(LLM Gateway) というアーキテクチャパターンを中心に据えることを検討しています。 イメージ図 アプリケーションとLLMプロバイダーの間に「ゲートウェイ」を挟むことで、開発者は自由にAPIを呼び出せます。一方で、裏側では自動的にログが取られ、セキュリティチェックが走り(統制)、キャッシュやリトライが効く(信頼性)という構成です。 設計原則 プラットフォームを構築・運用していく上で、以下の原則を大事にしたいと考えています。これらは Platform Engineering 、 セキュリティ 、 SRE / Observability 、 LLMOps の各分野から学んだものです。 原則 概要 Platform as a Product プラットフォームを「社内向けプロダクト」として捉え、利用者(プロダクトチーム)の体験を最優先に設計する。「インフラを提供する人」ではなく「開発者という顧客にプロダクトを届ける人」としてのマインドセットを持つ TVP(Thinnest Viable Platform) 初期スコープは「ガバナンスと可観測性」を解決する純粋なLLM APIプロキシに絞る。RAGやTool Useは後から。まずは「安全で、誰が使ったか、いくらかかったかがわかるAPI」を全社に民主化する Golden Path の提供 「推奨される使い方」を明確にし、その道を歩めば自然とベストプラクティスに沿える状態を作る。自由度は残しつつも、迷わないための道標を用意する Secure by Default LLMはプロンプトインジェクションやPII流出など従来とは異なるリスクがあるため、ガードレールをデフォルトで有効にした状態を標準とする。「セキュリティを意識しなくても安全」な状態を作る Observable by Default LLMは確率的に動作するため、入出力の追跡なしには改善のポイントが見えない。特別な設定なしで自動的にトレーシングとメトリクス収集が行われる状態を目指す Eval Driven(評価駆動) LLM開発ではリグレッションが頻繁に発生するため、「感覚」ではなく「評価」で改善を確認する。評価データセットの整備、CI/CDへの評価組み込み、LLM-as-a-Judgeによる自動スコアリングを開発フローに組み込む アーキテクチャ設計 現在、初期検証で構築しているアーキテクチャは下図のようになっています。 技術選定 AI Gateway まずはAI Gateway(LLM Proxy)の技術選定から着手しました。ここで満たしたい要件は、ざっくり言うと次のとおりです。 マルチプロバイダー対応 : Vertex AI / AWS Bedrock / GKE上のvLLM(セルフホスト)を同じ入口で扱えること 認証 : LLMプロバイダー側へのキーレス認証(OIDCなど)と、クライアント向けのVirtual API Key トラフィック制御と信頼性 : リクエスト数・トークン数ベースのレート制限、フォールバック、ストリーミング 統一インターフェース : OpenAI互換APIなどのスキーマ正規化、Embeddingsのサポート オブザーバビリティとコスト : OpenTelemetry連携、コスト追跡(チーム/キー単位の配賦)、(将来的な)セマンティックキャッシュ ガードレール : PII/DLPのマスキング(Redaction)を含む入力/出力のフィルタリングに加え、プロンプトインジェクション対策(ポリシー、検知/遮断、必要に応じたTool Useの実行制御) 10個強のツール( LiteLLM Proxy / Envoy AI Gateway / APISIX / Kong / Portkey.ai など)を調査した結果、現時点では LiteLLM Proxy が要件を最も素直に満たせそう、という結論になりました。 一方で、 Envoy AI Gateway もKubernetesネイティブで魅力的です。将来的に本格的な本番運用(GitOps前提の運用、より厳格なトラフィック制御、低レイテンシ)に寄せるなら有力候補です。しかし現段階では、初速を優先して LiteLLM +(認証を担う)Envoy Sidecar の構成から始めるのが現実的だと感じています。 LLM Observability Tool 現在利用しているDatadog LLM Observabilityは、プラットフォームでも引き続き中核の可観測性基盤として活用する想定です。AI Gateway 経由の呼び出しを起点に、レイテンシやエラー、トークン使用量などを一貫して可視化し、運用改善や評価(Eval Driven)に繋げます。 Envoy Sidecar vs Service Mesh Cloud Runのマルチコンテナ機能で、Envoy → Backend にする必要があるかどうかについては、代替案としてService Mesh(Istio・Cloud Service Mesh)が考えられます。 しかし、現状Service Mesh構成ではなく、この取り組みのために0からService Meshを構築することは、TVPの考え方に反します。そのため、Envoy Sidecarを採用することにしました。 AWS → GCPのキーレス認証 クロスクラウド連携で悩ましいのが、 AWS → GCP の認証 です。従来の Workload Identity Federation だと、GCP側のSTSを呼び出してアクセストークンを取得する必要があり、実装・運用の負担が大きくなりがちです。 そこで最近登場した、 AWS IAM Outbound Identity Federation を使って、 AWS STSが発行するJWTを、Cloud Run前段のEnvoyで直接検証する 方式を採用することにしました。 おわりに ここまで読んでいただきありがとうございます。 この構想には多くの不確実性があり、自由と統制のトレードオフとも向き合い続けることになると思います。「夢妄想」と銘打ったとおり、すべてが計画どおりに進む保証はありません。 それでも、「安全に、再現性を持ってLLMを活用できる状態をつくる」という軸だけはブレずに、2026年はタイミーのLLM基盤を前に進めていきたいと思います。 来年のアドベントカレンダーで、「あの夢妄想、現実になりました」と報告できることを目指して。 タイミーのMLOps・LLMOpsって面白くなりそうと思ってもらえた方はぜひ、お話ししましょう! プロダクト採用サイトTOP カジュアル面談申込はこちら
アバター
はじめに 前提:アウトカムに向き合う「プロダクトエンジニア」と組織構造 ① 「チームトポロジー」に基づくストリームアラインドチーム ② 「プロダクトエンジニア」という在り方 ③ 2sidesの顧客に向き合う複合ドメインのプロダクト なぜ私たちは「超人EM」を組織の前提とするのをやめたのか 役割のアップデート:「実行」から「診断」へ 構造①:診断 (Diagnosis) 〜 核心を見極める 〜 構造②:基本方針と行動 (Guiding Policy & Actions) 〜 「埋め方」のデザイン 〜 「個のスパイク」を組織のポートフォリオにする 仕組みで支える:AI活用と評価制度 ① AI・LLMによる「診断力」のブースト ② キャリアラダーとコンピテンシーの再設計 まとめ:Engineering Managementを「個人のスキル」から「組織の機能」へ 未来のエンジニアリングマネジメントのあり方を一緒に描いていただけませんか? はじめに この記事は Timee Product Advent Calendar 2025 の24日目の記事です。 株式会社タイミーでVPoEをつとめております、赤澤 a.k.a chango( @go0517go )です! 「ええやん!」が口癖なので、社内では「VP of Eeyan」なんて いじられ 呼ばれたりもしています。 さて、アドベントカレンダーも佳境の24日目。 今回は、私が以前登壇した内容をベースにしつつ、来年の「EMConf JP 2026」にProposalとして提出していたテーマのうちの1つである「チームで立ち向かうエンジニアリングマネジメント」についてお話しします。 Engineering Managementに関するテーマや内容は自分にとっても深く、私たちも常に試行錯誤しながら探索し続けている領域です。 今回のアドベントカレンダーでは、その「触り」となるエッセンスや、根底にある思想にフォーカスして書きたいと思います。 なお、こちらのProposalは残念ながら採択されませんでした涙…。ですが、タイミーはEMConf JP 2026のプラチナスポンサーとして協賛しております! 弊社のCTOである山口 a.k.a ZIGOROu( @zigorou )がスポンサーセッションで登壇しますので、タイミーの技術戦略やエンジニアリング組織論に興味がある方は、ぜひ会場でZIGOROuのセッションを聞いてください! それでは、急拡大する事業とプロダクト開発の中で私たちが描いた、「診断医」としてのエンジニアリングマネジメントについてお話しします。 前提:アウトカムに向き合う「プロダクトエンジニア」と組織構造 EMの役割についてお話しする前段階として、そもそもタイミーのエンジニアリング組織がどのような組織構造で、どのようなエンジニア像をもって開発しているかをお話しさせてください。 ① 「チームトポロジー」に基づくストリームアラインドチーム タイミーの開発組織は、『チームトポロジー』の考え方に基づき、特定の価値を提供する継続的な流れ(バリューストリーム)を対象とした「ストリームアラインドチーム」で構成されています。 これは、 エンジニアだけでなくPdMやデザイナーを含む6±2名程度の「職能横断型組織」 であり、DiscoveryからDelivery、つまり価値の探索と検証から実際の開発、そして運用までを一気通貫で担い、高速に仮説検証のサイクルを回すことを目的としています。 タイミーにおけるストリームアラインドチーム ② 「プロダクトエンジニア」という在り方 そして、そこで働くエンジニアに求めているのは、単に機能を作るだけの役割ではありません。私たちは「プロダクトエンジニア」という在り方を掲げています。 これは、「 プロダクトの提供価値を継続的に高めることでお客様の課題を解決するエンジニア 」と定義しており、全員がアウトカム(顧客への価値提供)に向き合うことを前提としています。 提供価値向上: 機能を作ることではなく、顧客課題を解決することに責任を持つ。 越境性: 自分の専門領域に閉じず、ドメインや役割を越えて知識を追求する。 オーナーシップ: 「How(どう作るか)」だけでなく、「Why(なぜ作るか)」「What(何を作るか)」の段階から関与する。 ③ 2sidesの顧客に向き合う複合ドメインのプロダクト さらに重要なのが、私たちが向き合っているプロダクトの特異性です。 タイミーは「ワーカー(働き手)」と「クライアント(事業者)」という異なる2つの顧客(2sides)に価値を提供するプラットフォーム であり、その裏側は複数のビジネスドメインが密接に連携する複合システムとなっています。 「スキマバイトのマッチングアプリ」として、UI/UXとともに想起いただくことが多いと思いますが、実はそのバックグラウンドには極めて広範な機能群が存在しています。 例えば、いくつか代表的な機能要素を見ても、QRコードによる出退勤、銀行API連携を伴う給与計算・振込処理、そして法令対応を含む労務管理など、これらすべてがなめらかな雇用体験と良いマッチングを実現するために不可欠な要素として統合されています。 つまり、タイミーのEMが管掌するのは、「職能横断で自律的に動き、Why/Whatから考え、これら複雑な複合ドメインのアウトカムにコミットするチーム」なのです。 2sidesの顧客に向き合う複合ドメインのプロダクト なぜ私たちは「超人EM」を組織の前提とするのをやめたのか さて、ここからが本題です。 上記のような複雑かつ高水準なチームを率いるエンジニアリングマネージャー(EM)には、どのような能力が求められるでしょうか? 一般的に語られる「EMの4つのマネジメント領域」を見てみましょう。 Technology: 技術的負債の解消、アーキテクチャ設計、生産性向上 People: 採用、育成、評価、目標設定、メンタリング Process: 開発プロセスの最適化、アジャイルの実践 Product: 顧客課題の発見、ドメイン知識、法要件の理解 知らず知らずのうちに、これら全てを一人で高い水準でリードできる「超人(スーパーマン)EM」を、理想像として求めてしまってはいないでしょうか? もちろん、各マネジメント領域においてプレイヤー性を高め続けることを、個人のキャリアとして追い求めることは重要であり、私自身もそうありたいと願っています。 しかし、同時に 組織としてその超人的存在を前提としすぎると「ひずみ」が拡大してしまいます。 全4領域で常に100点のプレイングができる人材を求めることは、現実には極めて困難であり、個人の負荷を過剰にします。その結果、採用基準も高止まりし、適切な人材が集まらなくなる。そうして、事業の急成長にエンジニアリング組織とそのマネジメントが追いつかないという、組織的な「ひずみ」が生み出されるのです。 なぜ、知らず知らずのうちに、そこまでの理想を求めてしまうのでしょうか? そもそもEMという職種は役割定義が曖昧になりがちな上に、タイミーの場合は多様なバックグラウンドを持つEMが中途入社で多く参画いただく状況でした(私自身もその一人です)。だからこそ、「この混沌を個人の力で解決してほしい」という期待が先行し、採用要件や期待値の中に、無意識のうちにこの「スーパーマン像」を投影してしまうケースがあると考えています。 私たち自身も過去を振り返り、そのような判断があったと振り返っています。 かといって、現実解として特定の領域、例えば「People Management」だけに単純に絞り込むこともできません。 顧客課題を深く理解するProductの視点、そして最適な実装を判断するTechnologyの視点。これらを欠いたままでは、「エンジニアリング組織」のマネージャーとして本質的な課題解決ができないからです。 同時に、一人の人間にすべての領域のリードを求めれば、マネジメントの人材不足はより顕著になります。 そもそも、 「あれもこれも全部やる」というのは、戦略ではありません。それは単なる「願望(Wish List)」です。 『良い戦略、悪い戦略』の著者、リチャード・P・ロメルトが指摘するように、戦略の本質は「何をやらないか」を選択することにあります。 タイミーのエンジニアリング組織では、「超人EM」という個人の頑張りに過度に依存する構造から脱却し、組織として持続可能な仕組みを作る必要があると判断しました。 役割のアップデート:「実行」から「診断」へ 「全てをやる」という願望(Wish List)から離れたとき、私たちの目の前に残った問いは明確です。 「では、限られたリソースで最大のアウトカムを出すために、今『何をするか』を誰が決めるのか?」 複雑で混沌とした状況の中で、無数にある課題から本質的な「急所」を見極め、チームの力をそこに集中させる。 自分で手を動かして全てを解決するのではなく(もちろんそれも重要な手段です)、「何を解くべきか」を正しく定義することこそが、この規模の組織におけるEMの最大の提供価値ではないか。 そう考えたとき、私たちの指針となったのが、戦略論の名著『良い戦略、悪い戦略』にある「戦略のカーネル」という概念でした。 これはタイミーのプロダクト開発組織においてしばしば用いられる、あらゆる戦略や方針を検討する際の「骨格」となっているフレームワークであり、私自身もタイミーにジョインした後、CTOのZIGOROuから注入された代表的なエッセンスです笑。 【参考:戦略のカーネルとは】 診断 (Diagnosis): 状況を単純化し、取り組むべき課題の「核心」を見極める。 基本方針 (Guiding Policy): 診断された課題に対処するための、全体的なアプローチ。 一貫した行動 (Coherent Actions): 方針に基づき、リソースを集中させた具体的なアクション。 私たちは今、これをベースに、EMの役割を「プレイヤーとして全てを実行すること」から、「チームが実行できるように『診断』し設計すること」へとアップデートしようとしています。 構造①:診断 (Diagnosis) 〜 核心を見極める 〜 EMの第一の責務は、Technology、People、Process、Productの全領域において、「何が問題の『核心(Kernel)』なのか」を高い解像度で見極めることだと考えています。 単に「課題リスト」を作るのではありません。「開発スピードが遅い」という現象があったとき、その真因は技術的負債なのか、意思決定フローなのか、それともメンバーの心理的安全性なのか。 無数にある課題の中から、そこさえ解けば状況が好転する「急所」を見抜くこと。この診断をエンジニアリングの現場で適切に行えることをEMの重要な役割だと考えております。 構造②:基本方針と行動 (Guiding Policy & Actions) 〜 「埋め方」のデザイン 〜 診断によって「何が足りないか(Gap)」が明確になれば、次はそれをどう埋めるか。 ここで重要なのは、「基本方針(Guiding Policy)」を定め、それに基づいた「一貫した行動(Coherent Actions)」に落とし込むことです。 その「埋め方」の選択肢は、決して「EMが頑張る」ことだけではありません。チームの状況に合わせて、最適な打ち手をデザインする必要があります。 プレイヤーとしてEMが補う(「オレが3人分になる...」) メンバーのケイパビリティ獲得を支援する(育成・学習機会の提供) 組織構造やリチーミングで解決する(チーム構成の変更) 外部からケイパビリティを獲得する(採用・外部の組織や企業との連携) 重要なのは、自分がスーパーマンになることではなく、診断結果に基づき、最適な「方針」を選び取り、迷いなく「行動」に移すことです。 逆に言えば、「自分はやらない(チームや仕組みに任せる)」と決める勇気を持つことでもあります。 個人の万能さに過度に依存するのではなく、チームとしての総力を最大化する道を選ぶ。これが今取り組んでいる(そして試行錯誤し悩みながら進んでいる!)私たちのエンジニアリングマネジメントです。 「個のスパイク」を組織のポートフォリオにする 「診断医」モデルにおいては、EM個人の「弱み」は個人としては、今後補強していく点であると同時に、組織としては「補い合うべき余白」になります。 私たちは、各EMのバックグラウンド(エンジニア、PdM、アジャイルコーチ・スクラムマスターなど)による「スパイク(突出した強み)」を歓迎し、それを個人のスキルではなく「組織のアセット」として考えようとしています。 Tech-oriented EM: 技術的な診断や意思決定の「構造知」を言語化し、他のEMに共有する。 Product-oriented EM: 複雑なドメインや法要件の読み解き方を形式知化し、組織全体のProduct理解を底上げする。 Process-oriented EM (Engineering Operations Manager): 開発フローやデリバリーのボトルネックを可視化し、チーム間の学習速度と成果再現性を高める。AI活用やリチーミング設計など、継続的改善のサイクルを仕組み化。 もちろん、現実的な運用においては、「チームが取り組む課題」と「EMの強み」が必ずしもパズルのように完璧にマッチするとは限りません。 特に現在のタイミーでは、EMが目標設定や評価も担う組織上の上長も兼ねています。心理的安全性や長期的な育成の観点からも、プロジェクトの都合だけで上長を高頻度に変えることは望ましくありません。 そこで重要になるのが、「EMs(EMチーム)間での相互補完」です。 担当チームの課題に対して、そのEMのケイパビリティが不足している場合、他の得意なEMがクロスで入って支援する。個人の不足を「個人の努力」だけで埋めるのではなく、「組織(EMs)の総力」でフォローする体制を構築しています。 さらに現在はテックリードなどの役割をあらためて定義、各領域のマネジメントをより委譲・分散していく体制についても、CTOや私(VPoE)、そして現場のEMたちと議論し、進行しています。 ここはまだまだ議論や方針を定めている最中で、まさにこれから推進していきたい「組織の伸び代」でもあります。 一人でフルスタックを目指すのではなく、EMチーム全体、そして組織全体でポートフォリオを組み、相互に診断を支援し合う。 これこそが、複雑化・巨大化する組織に対する唯一の対抗策だと信じています。 仕組みで支える:AI活用と評価制度 この新しいEM像を考え方で終わらせないために、いくつかの「仕組み」での実装に現在取り組んでいます。 ① AI・LLMによる「診断力」のブースト 全領域のキャッチアップを人間の脳だけで行うには限界があります。そこで私たちはAIを「診断アシスタント」としてフル活用しています。 コードベースの把握: DevinやCursorを用い、技術的な仕様や依存関係を高速に把握する。 組織状態のモニタリング: Slackのpublicな業務チャンネルでの重要なトピックや会話のサマリ、チーム全体のGitHubのアクティビティ傾向など、客観的な数値指標を参考にエンゲージメントの変化の予兆(診断材料)を提示する。 ② キャリアラダーとコンピテンシーの再設計 「スーパーマン」を求めない以上、評価基準も変える必要があります。 ここが今まさに私たちが挑戦している最前線なのですが、EMのキャリアラダーにおいて、「個人の実行能力(どれだけコードが書けるか、どれだけ仕様に詳しいか)」の評価軸をさらに拡張して、以下の能力を重視するコンピテンシー設計へとシフトを進めています。 診断の正確さ: 課題の核心(Kernel)をどれだけ深く捉えられているか。 チームへの移譲・設計能力: 成果を特定の個人に依存させず、再現性のある仕組みとして設計・実装できているか。 相互補完: 自身の強みを組織知として還元し、他EMを支援できているか。 「個人のスキル」ではなく「組織の機能」としてEMを定義し直す。この評価制度の設計こそが、超人EMへのアンチテーゼを完遂させる最後のピースだと考えています。 まとめ:Engineering Managementを「個人のスキル」から「組織の機能」へ 急拡大する組織と複雑なドメインに向き合う中で、私たちがたどり着いたエンジニアリングマネジメントの現在地は、以下の4点に集約されます。 役割の再定義 EMに求めることは、「自らが全領域を実行すること(超人的になること)」ではありません。「チーム全体で全領域を実行できるように、状況を『診断』し『設計』すること」です。 強さの源泉は「構造化」 個人の馬力に頼るのではなく、「診断 → 基本方針 → 行動」のサイクルを回し、課題解決を構造化できることこそがEMの強さであると考えています。 「個のスパイク」を組織の武器に 全方位完璧である必要はありません。EM個人の「スパイク(突出した専門性)」を歓迎し、足りない部分はEMチーム全体で相互補完する設計を進めています。 「個人のスキル」から「組織の機能」へ Engineering Managementを、属人化した個人のスキルではなく、再現性のある「組織の機能」へと昇華させること。これが、私たちの現在進行形の挑戦です。 この新しいEM像の実装はまだ道半ばです。だからこそ、私たちと一緒にこの挑戦を楽しんでくださる仲間を求めています! 未来のエンジニアリングマネジメントのあり方を一緒に描いていただけませんか? 私たちは今、これまでのエンジニアリングマネジメントを構造や仕組みで再現性持って継続していくというチャレンジの最中です。 「EMの仕事は負荷が高くて辛い」「一人の個人に求められる要素が多すぎる」という課題に対して、「チームで戦う」「診断と設計で価値を出す」というスタイルを確立したい。 タイミーではエンジニアポジションを全方位で全力拡大採用中です!そして今回お話しさせていただいたEngineering Managerポジションも特に注力しているポジションです。 採用ポジション:Engineering Manager 少し話聞いてみようかな、くらいの気軽さで私たちはとても嬉しいです、ぜひ気軽にお話しさせてください!明日25日の記事もお楽しみに! プロダクト採用サイトTOP カジュアル面談申込はこちら
アバター
はじめに この記事は Timee Product Advent Calendar 2025 の23日目の記事です。 背景 営業やマーケティングの現場では、連続変数を特定のしきい値で区切って2値のKPIとして扱うケースがあります。例えば、「月の購入金額が1万円を超えた顧客を『ロイヤル顧客』と定義する」といったケースです。ここで、このKPIに対する施策の効果測定を行う際は、「ロイヤル顧客への転換率」をアウトカムに設定し、ABテストで群間の差を検定するのが最もシンプルなアプローチとして挙げられます。 図1: Geminiもそう思います(2025/12/17, Gemini 3 Pro) 連続的な現象を2値データとして観察した場合は、連続的な潜在変数および誤差項のモデリングと、閾値を基準とした2値化によって定式化できます。例えば、誤差項にロジスティック分布を仮定した場合にはロジットモデル(ロジスティック累積分布関数)に従います[1][2]。本ケースもこれと同様に考え、施策効果の分布の推定が可能です。ただし、ビジネス上の定義としてはわかりやすいこの2値化処理は、同時に本来持っていた情報を捨てることになり、効果測定における検出力が低下する(正規分布に従う変数を中央値でカットした場合、同じ検出力を得るためにはサンプルサイズが1.5倍必要[3])と報告されています。 このようなケースではもとの連続量も併せてモニタリングすることが推奨されますが、本稿では連続量のままモデリングする手法の有効性検証に焦点を当てます。 具体的には、2値化されたアウトカムを2値として扱う場合と、連続量分布を推定してから事後的にKPIを計算する場合とで、効果測定の正確さがどう変わるかを比較します。 実験 1.分布の仮定が正しい一回試行での比較 仮想のECサービスを考え、「売上が1万円以上」をロイヤル顧客とみなし、顧客のロイヤル率を改善する施策をABテストした状況を想定してサンプルデータを作成しました。 具体的には、「非購入者(0円)」と「購入者(対数正規分布に従う売上)」が混在する売上分布を仮定し、以下のパラメータp, μ, σのもと、各グループで500顧客分ずつ作成しました。 パラメータ Control Treatment 購入率 p 0.50 0.53 対数平均 μ 8.0 8.20 対数標準偏差 σ 1.0 1.0 このとき、各サンプルデータが従う真の統計と施策効果は以下のようになります。 指標 Control Treatment 効果 期待売上 ¥2,457 ¥3,182 +¥724 ロイヤル率 5.65% 8.28% +2.62pt 次に、サンプルデータに対して以下の2つの手法でロイヤル顧客率に対する効果を推定し、真の施策効果を基準として比較しました。 アウトカム2値化: 売上が1万円以上か否かのフラグを立て、その比率の差を直接比較する。 アウトカム連続+ラベル事後計算: 真の尤度関数を用いて売上金額の分布を推定し、事後分布からロイヤル顧客の定義である「売上が1万円以上」を超える確率を計算して差を比較する。 2.分布の仮定が正しい複数回試行での比較 データが従う分布のパラメータを以下の範囲でランダムに変化させて作成しなおし、その他は1の設定を踏襲した実験を100回繰り返しました。そのうえで、2つの手法間で測定される効果の正確さを比較しました。 項目 値 購入率 p 0.6〜0.8 購入率 p への効果 +0.02〜+0.10 対数平均 μ 7.9〜8.2 対数平均 μ への効果 +0.05〜+0.20 対数標準偏差 σ 0.7〜1.1 3.分布の仮定が誤っている複数回試行での比較 2.と同様の手順でサンプルデータを20回作成し、各データに対して3通りの尤度関数(対数正規分布・ガンマ分布・パレート分布)を用いた効果測定をそれぞれ実施しました。そのうえで、各尤度関数間で測定した効果の正確さを比較しました。 結果 1.分布の仮定が正しい一回試行での比較 2つの手法間での結果の差を図2に示します。 図2: 2値化しないほうが分布の山が真値に近く、信用区間の幅も狭い。 2つの手法はどちらも真の効果をほぼ捉えていますが、「アウトカム連続+ラベル事後計算」手法(グラフ橙色)は真の効果である+2.62pt付近に鋭い分布でピークがあり、真値に近い効果を比較的高い確信度で捉えました。 2.分布の仮定が正しい複数回試行での比較 2つの手法を繰り返したとき、測定した効果の真値に対する差の比較を図3に、分布の幅の広さの差を図4に示します。 図3: 2値化しないほうが平均的に分布の山が真値に近い。 図4: 2値化しないほうが平均的に信用区間の幅が狭い。 「アウトカム連続+ラベル事後計算」手法のほうが平均的に真値に近い効果を推定しました。 3.分布の仮定が誤っている複数回試行での比較 「アウトカム連続+ラベル事後計算」手法について、尤度関数を変えたとき測定した効果の真値に対する差の変化を図5に示します。 図5: 尤度関数の当てはまりが悪いほど真の効果に対するバイアスが増加する。 尤度関数として真の分布と異なる分布を仮定した場合、当てはまりが悪いほど測定した効果が真値から離れる傾向があり、いずれも「アウトカム2値化」手法と比較して正確さが悪化しました。 結論 連続量を2値化したKPIに対しては、Beta-Binomialモデルを用いた2値KPIに対する効果測定を、複雑な分布仮定を必要としないロバストなベースラインとして採用できます。 より高い検出力を追求したい場合、連続量のまま分布をモデリングして効果測定し、事後分布からKPIを再計算するアプローチが有効な選択肢となりえます。 ただし誤った分布を仮定すると逆効果となるため、WAICによるモデル選定や閾値周辺の適合度の目視確認など、厳密なモデル選定が必要です。 参考文献 [1] Greene, W. H. (2003). Econometric Analysis (5th ed.), pp. 665-669. [2] C. M. ビショップ (2007). パターン認識と機械学習 上 (元田 浩 他 訳). [3] Cohen, J. (1983). The cost of dichotomization. Applied Psychological Measurement, 7 (3). おわりに タイミーではデータ分析を通じてプロダクトの成長を支えるメンバーを募集しています。ご興味のある方はぜひお話ししましょう! プロダクト採用サイトTOP カジュアル面談申込はこちら
アバター
こんにちは。タイミーQAエンジニアの矢尻です。 この記事は Timee Advent Calendar 2025 シリーズ1の23日目の記事です。 「アドベントカレンダー」といえばキリスト教の待降節ですが、実は私、元 神主(神職) というちょっと変わった経歴を持っています。 「異教徒がアドベントカレンダーを書いていいのか?」と心配される方もいるかもしれません。しかし、日本の神道には「八百万(やおよろず)の神」という、あらゆるものに神性を見出す懐の深い概念があります。クリスマスも正月も祝う日本人の精神性において、このテックブログもまた、技術の神々に感謝を捧げる「祭り」の一環と捉えれば、何ら問題はありません(ほんとに?)。 さて、今日はそんな異色の経歴を持つ私が、 神社祭式とソフトウェア品質保証(QA)の驚くべき共通点」 について、少しマニアックに語りたいと思います。 神社は「巨大なレガシーシステム」 神職からエンジニアに転身して最初に感じたこと。それは「やっていることが本質的に同じだ」という衝撃でした。 神社には「祭式(さいしき)」という厳格なプロトコルが存在し、「式次第」というプログラムがあり、「祝詞(のりと)」という仕様書が存在します。これらが緻密に相互作用し、バグ(不作法)なく執り行われることで、初めて「祭り」というシステムが正常稼働(デプロイ)されます。 私がQAエンジニアとして日々システムに祈っている「平穏」は、神主時代に祈っていた「安寧」と、構造的に全く同じものなのです。 1. 「祓(はら)へ」と「デバッグ」:ケガレを除去するリファクタリング 神道には 「ケガレ(穢れ/気枯れ)」 という概念があります。これは罪や穢れ、気力が枯渇した状態を指します。これを元の清浄な状態(あるべき姿)に戻すのが「祓(はら)へ」です。 システム開発における「バグ」や「技術的負債」、あるいは「不安定なテストデータ」。これらはまさにシステムにおける「ケガレ」です。 修祓(しゅばつ): 祭儀の最初に行うお祓いは、本番環境(祭場)へ移行する前の 初期化処理 や スモークテスト です。 大祓(おおはらえ): 定期的に蓄積した罪穢れを祓う行事は、定期的な リファクタリング そのものです。 「祓へ」によって場をクリーンにしなければ、どんなに素晴らしい祝詞(機能)も神様(ステークホルダー)には届きません。QAがバグを見つけ出し修正を促す行為は、システムを「清浄」に保つための神聖なプロセスなのです。 2. 祭式をコードで理解する 神社の儀式はブラックボックスに見えますが、実は非常に堅牢なアーキテクチャで設計されています。 ここでは、神職が奉仕する「家内安全祈願祭」を、あえてエンジニアの皆様に馴染み深いコードに置き換えて紹介したいと思います。 身体的プロトコル:「進左退右」というコーディング規約 コードに入る前に、マニアックな仕様の話をさせてください。 神職が祭場を歩くとき、 「進左退右(しんさたいゆう)」 という厳格なルールがあります。「進むときは左足から、退くときは右足から」という決まりです。 「どっちでもいいだろ」と思われるかもしれませんが、これは 「オペレーションミスによる障害」を防ぐための物理的な制約 です。 上位(神前)に近い足を軸にすることで、体の向きが安定し、神主同士がぶつかったり(コンフリクト)、転んだり(クラッシュ)、神様に背中を向けたり(要求定義からの逸脱)するリスクを最小化しています。祭式とは、 人間の身体動作に実装されたコーディング規約 なのです。 Rubyによる式次第の実装 では、祭りの進行表である「式次第」をRubyのコードに落とし込みます。 原文のプロセスとコードのロジックが完全に1対1で対応している点にご注目ください。 【原文】家内安全祈願祭 式次第 参進(さんしん):祭場へ入る 修祓(しゅばつ):心身を祓い清める 献饌(けんせん):お供え物を捧げる 祝詞奏上(のりとそうじょう):願い事を申し上げる 玉串拝礼(たまぐしはいれい):拝礼する 撤饌(てっせん):お供え物を下げる 退下(たいげ):祭場から退く 【コード】KanaiAnzenService.rb class KanaiAnzenService include ShintoProtocols # 祭事は不可分な一連の処理であるため、トランザクションとして扱う def execute ( devotee :) ActiveRecord :: Base .transaction do begin # 1. 参進(さんしん) # ※Linter: 進左退右プロトコルに準拠すること enter_shrine(devotee, step_strategy : :shin_sa_tai_u ) # 2. 修祓(しゅばつ):初期化・クリーンアップ # ※ここが最重要。穢れ(Bug/Dirty Data)が残っていると後の処理は全て無効 unless perform_purification( target : devotee, level : :strict ) raise UncleannessError , " 祓い清めが不十分です。儀式を続行できません。 " end # 3. 献饌(けんせん):リソースロード # 依存関係順(米→酒→塩→水)にロードしないとエラーになる offer_shinsen( type : :sake_and_food , order : :strict ) # 4. 祝詞奏上(のりとそうじょう):コアロジック実行 # 言霊パラメータを神界へ送信 invoke_norito( type : :kanai_anzen , target : devotee) # 5. 玉串拝礼(たまぐしはいれい):ユーザーインタラクション # ユーザー(参拝者)自身によるコミット操作 guide_tamagushi_worship(devotee) # 6. 撤饌(てっせん):リソース解放 withdraw_shinsen rescue UncleannessError => e # 異常系:儀式の中断。再浄化(Fix & Re-test)が必要 handle_kegare(e) raise e ensure # 7. 退下(たいげ):プロセス終了 # 成功失敗に関わらず、最後は退室する exit_shrine end end end end transaction ブロックで囲んでいるのがポイントです。お祓いに失敗したまま祝詞だけ読んでも、それは儀式として成立しません(コミットされません)。実際の祭りでもロールバック(やり直し)されます。ACID特性が求められるのです。 3. 祝詞の仕様定義:Gherkin 次に、祭儀の核となる「祝詞(のりと)」です。 祝詞は、「誰が」「どういう状態で」「何をすれば」「どうなるか」を宣言するものです。これは、振る舞い駆動開発(BDD)における Gherkin記法 そのものです。 「家内安全」の祝詞の原文と、それをGherkinに翻訳したものを並べてみます。 【原文・Gherkin対応】 Feature: 家内安全 (Family Safety) In order to 平穏無事な生活を送るため As a 氏子/崇敬者 I want to 神の加護を得て災いを防ぐ Scenario: 祓い清められた状態で祈願を行う # 【原文】掛けまくも畏き(かけまくもかしこき)XX神社の大前(おおまえ)に # 【意味】言葉にするのも畏れ多い、XX神社の神様の御前にて Given ターゲット環境は "XX神社本番環境" である # 【原文】宮司 氏名 恐み恐みも白す(かしこみかしこみもまおす) # 【意味】宮司の[氏名]が、謹んで申し上げます And 実行ユーザー(Actor)は "認定神職" である # 【原文】此の氏子(うじこ)◯◯の家族(やから)一同 # 【意味】この氏子である[住所][氏名]の家族全員が And 対象オブジェクトは "氏子[住所][氏名]のFamilyクラス全インスタンス" である # 【原文】過ち犯す事無く 災い触れる事無く # 【意味】過ちを犯すことなく、災難に遭うこともなく When "HumanError" および "ExternalDisaster" イベントが発生しない条件を適用し # 【原文】夜の守り 日の守りに守り恵み給い # 【意味】昼も夜も守り恵んでいただき And "24/365" の監視体制(Protection)を有効化し # 【原文】平らけく安らけく 孫の代に至るまで # 【意味】平穏無事に、子孫の代に至るまで Then システム稼働状況は "平らけく安らけく(Stable)" であること And データ永続性は "孫の代(LongTerm)" まで保証されること # 【原文】家門(いえかど)高く広く 立ち栄えしめ給へと 恐み恐みも白す # 【意味】家がますます繁栄しますようにと、謹んで申し上げます And "家門(BusinessValue)" は右肩上がりにスケールすること 「言霊(ことだま)」とは、言葉にしたことが現実になるという信仰 ですが、エンジニアリングにおいても 「コード(言語)にしたことが実際の挙動になる」 という点は全く同じです。 正確な言葉(コード)で記述しなければ、システムは意図通りに動きません。 4. 式年遷宮という名の「大規模リプレース」 エンジニアの世界では、大規模なシステムリプレースのことを冗談交じりに「式年遷宮(しきねんせんぐう)」と呼ぶことがあります。 伊勢神宮で20年に一度行われる、社殿を新しく建て替える一大プロジェクトのことですね。 実はこれ、神道的な観点でも意図・目的が完全に一致しています。 式年遷宮の真の目的は、建物を新しくすることだけではありません。 「宮大工の知識と技術の継承」 こそが本質です。 20年というサイクルは、ベテランから若手へ技術を継承するのに最適な期間(世代交代の期間)として設計されています。 システムも同じです。どんなに堅牢なコードも、それを保守する技術者がいなくなれば(属人化すれば)いずれ朽ち果てます。 コードを書き直し、技術スタックを新しくすることは、システムという「神」を若返らせ、技術という「伝統」を次世代へ継承するための、聖なる営みなのです。 結びに代えて:「平らけく安らけく」の祈りを込めて 神道の祝詞によく登場する 「平(たい)らけく安(やす)らけく」 という言葉があります。 これは「波風が立たず、平穏であること」を願う言葉です。 私がQAエンジニアとしてリリース直前に願うこと。それは新機能の華々しい成功よりも先に、「システムがクラッシュせず、ユーザーにとって当たり前の日常(平穏)が守られますように」という祈りです。 しかし、神主の祈りは「神頼み」ではありません。 掃除をし、場を整え、身を清め(テストをし)、作法を極めた(バグを修正した)上で、最後の最後に捧げるのが祈りです。 「人事を尽くして天命を待つ」。このプロセスこそが品質保証の本質であり、それは「祭り」の準備と何ら変わりがないのです。 今年も残りわずかとなりました。 アドベントカレンダーという「祭り」を通じて、皆様と知見(?)を共有できたことを嬉しく思います。 来る新玉(あらたま)の年が、皆様そして皆様の開発するシステムにとって、バグなき清浄なものであり、 弥栄(いやさか) に栄え、 平らけく安らけく あらんことを、心よりご祈念申し上げます。 タイミーでは一緒に働く仲間を募集しています。ご興味があればぜひお話ししましょう! プロダクト採用サイトTOP カジュアル面談申込はこちら
アバター
この記事は Timee Product Advent Calendar 2025 の22日目の記事です。 はじめに こんにちは!kazzhiraと申します。タイミーでプロダクトエンジニアとして働いています。 この記事では、AIエージェント開発をチームに定着させようと奮闘したストーリーと、そこで得た学びを語ろうと思います。 よってこの記事はAIの技術解説ではありません。 『AI推進』という答えのない課題に直面して空回りしたエンジニアが、どのようにして仕事を前に進めるコツを掴んだのかを記録したものです。 何かを推進する立場の方にとって学びや励みになればと思い、執筆しています。 背景 チームメンバーは全員がプロダクトエンジニアで、AI時代よりも前から開発経験があります。 主にフロントエンド、バックエンド、Androidのケイパビリティがあります。 Cursor、Claude Code、Devin、GitHub Copilot、Geminiを個々人の判断で利用可能です。 プロダクト組織ではAI活用が進んでおり、 私も「AI活用を進めて生産性を上げたい」という強いモチベーションがありました。 上司からもチャンスをいただけたので、即「やっていきます!」と推進をしていくことに。 推進で試行錯誤した3ヶ月間の話 これまで私は開発業務の遂行、個人で生産性を上げる取り組み、短期的な組織運営を経験してきました。 今回引き受けたAI推進は、チーム全体をスコープとする中長期の組織的な取り組みです。 このスコープでの取り組みで成功体験が少なく、私にとって新たな挑戦でした。 当初の状況を整理すると、組織としてはTipsは転がっているものの、AI活用の状況は個々人に閉じていました。 AIの技術進化は近年目まぐるしく、AIを中核にワークフローを組んだりサービスを作ってもすぐに陳腐化してしまうなど、不確実性が高い領域です。 この状況を認識しつつも悶々としたまま、2週間が過ぎました。そう、身動きが取れていない状態だったのです。このときの行動のループをまとめると、 推進って具体的にどうするの?自分の中で良さそうと思っていることを単に広めるってこと? ブレストして、共通項をまとめる… 結局それで何になるの?AI活用が今より進んでいるってどういう状態? 今振り返ると、焦りから完全に空回りしていました。 AI開発標準の作成エピソード 頭を悩ませているうちに時間が経過し、自分自身のモチベーションも下がっていることに気づきました。このことを上司に相談したところ、的確なフィードバックをもらいました。 「情報収集と分析が足りていない」(意訳) ハッとしました。 チームには情報がありません。当然、情報収集が必要です。 私はテックブログや時事ネタを眺め、それを手元で試したり、試さずに終わってしまったりしている状態でした。 「なぜやるのか」「どうやるのか」をチームに腹落ちさせるだけの材料も、 自分自身の確固たる言葉も持っていなかったのです。 その日から私は情報をかき集め、Geminiと相談しながら内容を深掘りし、知見を深めました。 80%くらいのAI開発標準v0.1を即座に作成し、メンバーからフィードバックを受けてブラッシュアップしました。 次に示すのはドキュメントで定義した開発フロー図の一部です。 前後のPhaseは本質と関係ないため図から除外しています。 核心としては、CursorやClaude Codeなどで実装されているPlanモードで実装計画とレビューを挟むことで、AIの出力を高品質にし、手戻りを減らす開発スタイルを言語化したものです。 コンテキスト用意の部分を解説します。 ガードレール設計 リポジトリ毎に規約が決まっていることが多いので、その参照を持たせます プロンプティング 役割や制限事項を含めた命令文を書きますが、コンテキストはガードレール、Design Doc、MCPサーバで補完できることが多いため、プロンプトの分量はそれほど多くなりません Design Doc作成 DB設計書、API設計書など必要に応じて設計書を作成します MCPサーバ接続 Figma MCPやGitHub MCPを利用して外部のコンテキストを取得します AIエージェント、推論モデルは目まぐるしく変化するため、そこに依存せず中長期的に運用できる内容を目指して作成しました。 AI開発標準v1.0は、フィードバックと改善が活発に行われ、知見が共有されたり目線が揃ったことで、個々人の生産性には多少の変化がありました。 しかしチームで提供する価値の面では大きな成果は上がりませんでした。 なぜならば、資料の説明は抽象的で、かつ現在地を示したに過ぎず、チームも具体的に動きようがなかったからです。 チームの課題や生産性のボトルネック、理想とする開発体験など、「なぜやるのか(Why)」「何をやるのか(What)」「どう実行するのか(How)」が、全くもって抜けていました。 この成果物は開発手法の共通項を抜き出したガードレールになっただけでした。 ガードレールがあるのは良いのですが、チームの状態としては相互理解や知見が少々増えて開発が楽になったに過ぎず、会社が「期待以上だった」と評価を下せるほどの成果ではありません。 スクラムに着想を得た推進の勘所 ここでふと、今まで長期に渡り実践してきたスクラム開発を思い出しました。 スクラム開発ではプロダクトゴールとスプリントゴールを設定して不確実性が高い環境でも継続して価値提供を実行します。 先ほど反省した通り、中長期の組織的な取り組みにもゴールとマイルストーンを設定し、計画的に進めることが大事なのだと気づくことができました。 日々やっているはずなのに、なぜできなかったんだろう、忘れてしまったんだろう…と落ち込みましたが、今では伸びしろだと考え直しています。 気づくといろいろなものが見えてきて、何をすべきかがわかります。 最近、上司から的確なフィードバックをもらいました。 「今のままでも前に進むとは思いますが、ゴールと計画を具体化した方がいいですね」 まさに!です。 まず、理想の開発体験をチームで話し合ってみることに決めました。 議論を進めるうちにチームでは次の結論が出ました。 作業さえ切り出してしまえば、実装はボトルネックになっていない リファインメントで議論が発散する時間が長く、収束に時間がかかる場合がある AIにはビジネス戦略、顧客課題、ユーザーストーリーが渡っていない。 ドメインの知識を詰め込んだGeminiのGem、もしくはNotion AIを用意することで、期待に近い出力を得ることができそうだ AIの出力が微妙な時は、整理されたコンテキストが足りていないことが多い。 仕様の記述もAIを中心に進め、レビューを開発者が行えば、質とスピードが担保できそうだ。 これらを満たすSDD(仕様書駆動開発)に、投機的に取り組んでみる これにより、以前よりも一歩前に進むことができ、次の具体的な計画を立てることができます。 明確な成果に紐づけるところまでは達成していませんが、以前よりも議論が活発になり、開発体験をより良くしていく動きができるようになりました。 推進を着実に進める方法 今回の試行錯誤から得た学びを箇条書きにすると、 なぜ、なにを、どのように、を突き詰めて課題の解像度を上げること 動く前に今わかる範囲での計画を立てること( AIは手段であり、まずは解決したい課題とゴールを定義しないと空回りする ) AI技術を定期的に取りこんでチームに適用してみる活動を行い振り返るループを作ること 何よりも自分自身がワクワクすること これは推進に限らず、あらゆる仕事で通じることですが、改めて勉強になりました。 抽象的な仕事を具体化して進めるコツが掴めたような気がします。 世には最近読ませていただいた ” **抽象度の高い仕事の進め方 ”** のように勉強になる記事がたくさんあるので、ぜひご覧になってください。 まとめ ここに至るまで、チームメンバーと上司、ストーリー上では触れなかった方々も含め、ご助力いただきありがとうございます。ここで感謝の意を表したいと思います。 引き続きワイワイ楽しみつつ一緒に進めていきましょう。 私はまだインパクトの大きい価値を生み出せてはいませんが、 推進のためにやることが明確になったので引き続き取り組んでいきます。 最後に、この記事を読んでくれた方の推進力になることを願っています。 ここまで読んでいただき、ありがとうございました! タイミーには、こうした挑戦と学び、そして発信を歓迎する文化があります。 ともに挑戦し成長していきたい方、興味があればぜひ1度お話ししましょう! プロダクト採用サイトTOP カジュアル面談申込はこちら
アバター