こんにちは。タイミーでPlatform Engineeringグループのマネージャーを務める橋本( @kaz-under-the-bridge )です。 2026年1月26日〜28日の3日間、AWS様と共同で AI-DLC Unicorn Gym (以下UG)を開催しました。私はタイミー側のカウンターパートとして、企画・準備から当日の運営、振り返りまでを担当しました。 AI-DLC(AI-Driven Development Life Cycle)は、要件定義からリリースまでの開発プロセス全体にAIを深く組み込むことで、従来のアジャイル開発を大幅に加速するアプローチです。Unicorn Gymは、AI-DLCを実際のプロダクト開発テーマで短期集中的に実践できる体験的な取り組みです。AWS様の支援のもと、国内でも多くの企業が参加・開催しています。 タイミーでは11チーム・約69名が参加し、各チームが実際にプロダクション搭載予定の機能をテーマにAI-DLCを実践しました。当日の実施内容、各チームの成果、参加者の声についてはAWS様の執筆レポートに詳しく書かれていますので、ぜひそちらもご覧ください。 株式会社タイミー様の AI-DLC Unicorn Gym 開催レポート: 全社横断で挑む開発生産性の変革 本記事では、UG当日の内容ではなく 「UGの後、組織に何が起きたのか」 を、実施から約1ヶ月時点のデータを交えてレポートします。 個の生産性改善から、組織のムーブメントへ UG以前、タイミーにおけるAIツールの活用はエンジニアが個人個人で使いこなす 「個の生産性改善」 が主たるものでした。各自がCopilotやCursor、Claude Codeなどを独自に活用し、それぞれのやり方で生産性を高めていました。 それがUGを経て、 チーム・組織単位でCoding Agentを使いこなす方向に大きくシフトした と見ています。以下、データでその変化を追っていきます。 Claude Code利用者数の変化 タイミーのプロダクト開発組織では、以下のCoding Agentを利用しており、申請制で自由に使えるようにしています。 利用しているCodingAgent 私は上記ツール群の管理者でもあります。UG後に最初に気づいた変化は Claude Codeの利用申請が明らかに増えた ことでした。 CCシート数推移 UG前は週1〜2名ペースだったシート追加が、UG後は 週8名と約5倍に加速 しています。1ヶ月で85名から118名へ、1.4倍に拡大しました。 Skills/Plugin整備の加速 —— 組織的なAI活用への転換 利用者数の増加だけでなく、 GitHubリポジトリ上のAI-DLC関連アクティビティ にも顕著な変化が見られました。 ここで言う「Skills」とは、Claude CodeのSkills機能を指します。指示・テンプレート・スクリプトをパッケージ化してリポジトリに配置すると、Claudeが会話内容に応じて自動で発見・ロードする仕組みです。たとえば「PRレビューの観点」や「テスト設計の手順」をSkillとして定義しておけば、チームの誰がClaude Codeを使っても同じ品質で作業できるようになります。 指標 UG前 UG後(1ヶ月時点) 変化 CLAUDE.md 保有リポジトリ 3 37 +34 Skills保有リポジトリ 1 11 +10 Skills総数 3 78 +75 UG前、Skillsを持つリポジトリは たった1つで 3 Skillsだけでした。それがUG後は 11リポジトリ・78 Skills に急拡大しています。 CLAUDE.md(Claude Codeのプロジェクト設定ファイル)を持つリポジトリも3から37へ。これは「AIにプロジェクトの文脈を伝える」取り組みが組織全体に広がりつつあると見ています。 つまり、個人がAIツールを使いこなすフェーズから、 チームがSkillsを整備して組織的にAIを活用するフェーズ へ移行していると見ています。 エンジニア以外の職種への広がり この組織的なAI活用の進展を補強するデータとして、 利用者の職種構成の変化 があります。 プロダクト組織の人数と照らし合わせると、エンジニアのClaude Code利用率はUG前の約70%からUG後 約89% へ上昇し、ほぼ全員が使っている状態になっています。一方、エンジニア以外の方の利用率はUG前の7%からUG後 約27% へ。まだ道半ばではありますが、エンジニア以外の方もClaude Codeを使い始める段階に来ていると言えます。 UG前後でのCC普及率比較 Skillsの整備によってチーム単位でのAI活用基盤が整ったことで、PdMやデザイナーにとってもCoding Agentが使える環境が生まれつつあると見ています。 何が変わったのか —— 代表的な変化のパターン Skillsの急増を支える具体的な動きを、いくつかのパターンに分類して紹介します。 既存リポジトリのAI-DLC駆動への変容 最も大きな変化を見せたのが、UG参加チームの既存プロダクトリポジトリです。UG前はCursorのコマンド設定がある程度だったリポジトリが、UG後には 23のSkillsと独自のAI-DLCフレームワーク を構築するまでに至りました。 コミットの中身を見ると、UG後は、Skillsの追加やAI-DLCフレームワークの構築、Inceptionの成果物(ユーザーストーリー、受け入れ基準、コンテキストマップ等)といった AI-DLCに関するコミットが大きな割合を占める ようになっています。これにより、個人がAIツールを使う段階から、チーム全体でAI-DLCのInception(要件定義)フェーズを実践し、プロダクト機能の設計にAIを組み込む段階へとシフトしたと見ています。 このチームの取り組みについては以下の記事もご覧ください。 失敗から学んだ仕様駆動開発――チームの暗黙知を形式知化した1ヶ月の実践と次の課題 ゼロからのAI-DLCワークスペース構築 UGをきっかけに、新たにリポジトリを立ち上げたチームも複数あります。UG初日に作成されたワークスペースの中には、backend・iOS・Androidなどのドメイン別Skills(7つ)や、inception・constructionといったAI-DLCのフェーズ別コマンド体系が整備され、今もSkillsやテンプレートの追加・改善を重ねているものもあります。 Knowledge-as-Code 特筆すべきは、 ハンドブック(社内ナレッジ)をAI Skillsとしてコード化 する取り組みです。バックエンド開発のベストプラクティス、API設計指針、テスト設計、法的考慮事項の参照といった組織知を22のSkillsとして整備し、Claude Code Pluginとして提供しています。さらに、Cursor向けへの変換パイプラインも構築されており、複数のCodingAgentで活用できる仕組みになっています。 これは単なるツール活用を超えた、 組織の暗黙知をAIが活用可能な形式知に変換する 取り組みと言えます。 こちらの取り組みについては以下の記事もご覧ください。 バックエンド開発Handbookを届けるために ― AI時代の知の高速道路を敷く Claude Skill を Cursor の Agent Skill として使えるようにした話 UG中の学びの即時適用 既にClaude Codeを活用していたチームの中には、 UG 3日目(1/28)に新しいSkillsを追加 した事例もあります。agentsやcommandsで安定運用していた状態から、UGでSkillsという新しいレイヤーを学び、その場で自チームのリポジトリに適用しているケースもありました。 UG非参加チームへの波及 興味深いのは、 UGに参加していないチームにもAI-DLCの動きが広がっている ことです。UG非参加のチームが8つのSkills(ワークフロー自動化特化)を持つリポジトリを立ち上げるなど、UG参加チームの取り組みが周囲に波及しています。 これらの変化をどう見るか 数字を俯瞰すると、UGを境に起きた変化の本質は 「個のAI活用」から「組織のAI-DLC実践」へのシフト だと考えています。 利用者の拡大 : 週1.5名 → 週8名(5倍加速)、エンジニア以外の職種にも拡大 Skillsの整備 : 1リポジトリ3 Skills → 11リポジトリ78 Skills(個人の効率化ではなく、チームの知識をAIに教える方向) チームを超えた波及 : UG非参加チームにも動きが広がっている UGはあくまできっかけであり、3日間のイベントです。しかし、そのきっかけが 1ヶ月で組織全体の行動パターンを変えた ことは、データが示しているのではないかと思います。 おわりに 現時点では、ムーブメントはまだ初速の段階です。ただ、この動きは定着していくだろうと見ています。次にやるべきことは、AIを安全に使うためのセキュリティ面の整備と、より大きなうねりにしていくためのブロッカーを一つひとつ排除することだと考えています。 もちろん、本記事で取り上げたのはClaude Codeを中心とした変化に限っています。CursorやCopilotを活用して成果を出しているケースも多くあり、組織全体のAI活用はさらに広がりを見せています。 UG開催を検討されている方へ 最後に、主催者としてひとこと。UGの開催にあたって最初に立ちはだかる壁は、「参加者が乗り気になるかどうか」かもしれません。3日間という拘束時間の長さ、AI-DLCという新しい手法への不確実性——二の足を踏む気持ちは十分にわかります。 ただ、本記事でお伝えしたとおり、タイミーではUGの3日間をきっかけに1ヶ月で組織の行動パターンが変わりました。利用者の急増、Skillsの整備、エンジニア以外への波及。これらは3日間の投資に対して余りある効果だったと感じています。開催を迷っている方にとって、一つの事例として参考になれば幸いです。 最後まで読んでいただき、ありがとうございました。こうした取り組みに興味を持っていただけた方、一緒にチャレンジしてくれる方を募集しています! タイミーの採用情報はこちら
こんにちは!タイミーでバックエンドエンジニアとして働いている福井 ( bary822 ) です。 皆さんは「Claude Code の Skills を社内の Cursor ユーザーも使えるようにしたい」と思ったことはないでしょうか? Claude Code には Claude Plugin という仕組みがあり、社内で共有したい Skills を簡単に配布できます。しかし、Cursor には Claude Plugin に相当する機能がなく、さらに Claude Code の Skills は独自の構文をサポートしているため、そのままでは動作しません。 この記事では、Claude Plugin 形式で配布している Skills を Cursor でも利用できるようにした取り組みについてご紹介します。 背景 タイミーでは、社内の開発ガイドラインに沿った開発を行いやすくすることを目的に、Claude Code の Skills を整備し、Claude Plugin 経由で配布しています。 tech.timee.co.jp Claude Code の Skills はエージェントに対してタスク実行時のコンテキストや手順を提供する機能です。この機能はもともと Claude Code 独自のものでしたが、現在では Agent Skills としてファイル名やディレクトリ構成、メタデータの種類などのオープンスタンダードが確立されつつあり、さまざまなAIプラットフォームで再利用できるようになっています。 Skills for organizations, partners, the ecosystem | Claude Overview - Agent Skills 課題: Claude Plugin で配布している Skills を Cursor で使えない Agent Skills の仕様自体は標準化が進んでいますが、配布の仕組みやサポートされる構文にはプラットフォーム間で差分があります。 配布の仕組みの差分 Claude Code には Plugin という仕組みがあり、Skills のインストール・アップデートを簡単に行えます。一方、Cursor には同等の配布機構がサポートされていません。 構文の差分 Claude Code の Skills には、Cursor でサポートされていない独自構文がいくつかあります。 !command 構文: SKILL.md 内で許可されたシェルコマンドを実行する構文。たとえば !gh api ... と書くことで GitHub API 経由でドキュメントを動的に取得できる。Cursor ではサポートされていない $ARGUMENTS 変数: スキル実行時にユーザーが渡す引数を受け取るための変数。こちらもCursor ではサポートされていない つまり、Claude Plugin で配布している Skills をそのまま Cursor に持ってきても、動的なコンテンツ取得ができず引数も渡せないため、まともに動作しない状態でした。 Cursor ユーザーにも同じ体験を提供するために、これらの構文を Cursor が理解できる形式に変換し、適切なディレクトリに配置する必要がありました。 解決策:変換スクリプトの作成 Claude Plugin 形式の Skills を Cursor 互換形式に変換するシェルスクリプト build-cursor-skills.sh を作成しました。 このスクリプトは以下の変換を行います。 動的コンテンツの埋め込み: !command 構文で動的に取得していたコンテンツを、ローカルのファイルから読み取ってテキストとして直接 SKILL.md に埋め込む 変数の変換: $ARGUMENTS を「ユーザーの指示に従って」という固定テキストに置換する 補助ファイルのコピー: Skills が参照する補助ファイル( intro.md , workflow.md , troubleshooting.md など)もコピーする 変換後の Skills を構成する各種ファイルは、ユーザー領域( ~/.cursor/skills/ )に配置されるようにしました。Cursor はこのディレクトリを自動的に走査するため、配置するだけで Skills が利用可能になります。 # Skills を管理するリポジトリで実行するだけ ./scripts/build-cursor-skills.sh 変換処理の具体例 たとえばある Claude Code Skill の SKILL.md には、以下のように GitHub API 経由でドキュメントを動的に取得する構文が含まれています。 # API設計ガイドライン 以下のガイドラインに従って API を設計してください。 ! ` gh api /repos/org/repo/contents/docs/web_api_design.md ... ` 変換スクリプトはドキュメントを管理するリポジトリ上に配置します。こうすることで、この !gh の行をローカルにあるドキュメントの内容で置き換えることができます。 # API設計ガイドライン 以下のガイドラインに従って API を設計してください。 (ローカル参照した web _ api _ design.md の内容がここに展開される) これにより、GitHub API を呼び出さなくてもドキュメントの全文がスキルに含まれるようになり、Cursor でも問題なく動作します。 動的に取得する Claude Code 形式と比較すると、ドキュメントに変更があるたびにスクリプトの再実行が必要になります。この点に関しては Claude Plugin を使っていたとしても手動でアップデート( claude plugin update <plugin> )する必要があるため、大きな差はないだろうと判断して許容しました。 出力されるディレクトリ構造 スクリプトを実行するとユーザー領域に下記のようなディレクトリ構成でファイルが展開されます。 ~/.cursor/skills/ ├── skill-ref-design-api/ │ └── SKILL.md # ドキュメントが埋め込まれたスキル ├── skill-ref-design-table/ │ └── SKILL.md ├── skill-wf-design/ │ ├── SKILL.md │ ├── intro.md │ ├── workflow.md │ ├── troubleshooting.md │ └── samples/ │ └── default.md ... Dev Container 環境への対応 変換スクリプトをリリースした後、Cursor で Dev Container を使って開発しているメンバーから「スキルが認識されない」という報告がありました。 原因はシンプルで、Dev Container 内からはホスト側の ~/.cursor/skills/ が参照できないためです。 これを解決するためにいくつかの方法を検討しました。 方法 メリット デメリット devcontainer.json で ~/.cursor をマウント 設定一箇所で済む Cursor を使っていない人のホストにも ~/.cursor/ が作成されてしまう ワークスペース直下に配置 マウント不要(ワークスペースはデフォルトでマウント済み) gitignore の設定が必要 チーム内には Cursor を使っていないメンバーもいるため、 devcontainer.json にマウント設定を追加する方法は副作用が大きいと判断し、ワークスペース直下に配置する方法を選択しました。 具体的には、変換スクリプトに --target オプションを追加し、出力先ディレクトリを指定できるようにしました。 # Dev Container 環境向け:ワークスペース直下に配置 ./scripts/build-cursor-skills.sh --target /path/to/repo これにより、スキルファイルはワークスペース直下( <repo>/.cursor/skills/ )に配置されます。ワークスペースはデフォルトで Dev Container にマウントされているため、追加のマウント設定なしでスキルが認識されます。 ただし、ドキュメントが更新されてスクリプトを再実行すると、そのたびに更新された Skills を構成するファイルに差分が出てしまいます。そこで、利用する側のリポジトリでスクリプトによって配置されるディレクトリ以下を gitignore する対応も合わせて行いました。 今後の展望 現在はビルドスクリプトを手動で実行する必要がありますが、Cursor 側で Claude Plugin と同等の配布機構や !command 構文がサポートされれば、変換スクリプト自体が不要になる可能性もあります。その動向もウォッチしつつ、現時点で最もシンプルに課題を解決できる方法として、この変換スクリプトによるアプローチを採用しています。 また、元のドキュメントに更新が入った時に手元の Skills をアップデートすることを促す通知を送信するなど、ユーザーの利便性に配慮した仕組みづくりも進めていきます。 おわりに 今回は、Claude Plugin 形式で配布している Agent Skills を Cursor でも利用できるようにした取り組みをご紹介しました。 「Claude Code で便利に使っている Skills を他のツールでも使いたい、でもプラットフォームごとに構文や配布の仕組みが違って大変」というのは、多くのチームが直面しうる課題だと思います。私たちのアプローチはシンプルなシェルスクリプトによる変換という泥臭い方法ですが、低コストで確実に課題を解決できました。少なくとも今後 Agent Skills の配布の仕組みが Cursor に搭載されるまでの暫定対応としては十分に機能していると思っています。 この記事が、同じような課題に取り組む方の参考になれば幸いです。 最後までお読みいただき、ありがとうございました!
こんにちは、タイミーでバックエンドのテックリードをしている新谷( @euglena1215 )です。 今回は、社内向けに公開したバックエンド開発Handbookと、それをClaude CodeやCursorといったAIエージェント向けスキルとして届けることで、気づいたらHandbookを参照している状態を目指した取り組みについて紹介します。 バックエンド開発Handbookとは何か バックエンド開発Handbookは、タイミーのバックエンド開発における設計・実装・運用のガイドラインをまとめたドキュメント集です。GitHub Pages でホスティングし、開発者が見やすい形で公開しています。 タイミーでは GitHub Enterprise Cloud を利用しているため、GitHub Pages のアクセス制御機能でリポジトリの読み取り権限を持つメンバーのみに公開範囲を制限できます。 バックエンド開発トップページ なぜ書き始めたのか 事業の成長・変化に伴い、バックエンド開発に関わるエンジニアが増えてきました。AIツールの進化も相まって、バックエンド以外を専門とするエンジニアが越境してコードを書く機会も増えています。 こうした変化の中で、これまでチーム内で暗黙的に共有されてきたノウハウや設計思想を形式知として残し、誰でもアクセスできる状態にしておく必要がありました。 たとえば戦略的プログラミングの重要性、概念モデリングの進め方、テーブル設計の注意点など、日々の開発で繰り返し必要になる判断基準を体系化しています。 カバー範囲 Handbookは開発プロセスの全体を一気通貫でカバーしています。 フェーズ トピック はじめに 戦略的プログラミングの心構え、秘匿情報の取り扱い、タイミーを取り巻く法律 設計 概念モデリング、ギャップ分析、テーブル設計、Web API設計、クラス設計、非同期処理設計、バッチ処理設計 実装・レビュー 実装ガイドライン、コードレビュー、自動テスト設計、コードの整頓 運用・保守 ログ設計、監視、障害対応 リリース デプロイ・リリース 設計に重点を置いているのは、バックエンド開発に慣れていない人がAIエージェントを使ったとしても、カバーしにくい領域だからです。実装やレビューのプラクティスはある程度一般化されていますが、「タイミーのバックエンドとしてどう設計するか」はチーム固有の知見が多く、形式知にする価値が高いと考えました。 たとえばタイミーでは、Sidekiq ジョブ実行中にデプロイが行われると、Sidekiq プロセスに SIGTERM が送信されます。その25秒後にたとえ実行途中であってもジョブをキューに戻す、という実装上の制約があります。開発者はこれを考慮してジョブの処理をべき等にしたり、25秒を超えないように処理対象を分割してジョブに切り出すなどの対策を行う必要があります。このような暗黙的かつ独自の制約は特に Handbook として残すべきだろうと考えていました。 Handbookをどう届けるか Handbookを書いて公開するだけでも価値はありますが、ドキュメントは自分から読みに行く必要があり、ひと手間かかります。存在を知っていても、忙しい開発中には思い出せないこともあると思います。 いま、社内の多くのエンジニアがAIエージェントを日常的に使って開発しています。Claude CodeやCursorなどのツールが開発フローに組み込まれているのであれば、 AIエージェント経由でガイドラインを届ける という選択肢があります。 開発者が意識しなくても、AIエージェントがガイドラインを参照しながら設計や実装を支援してくれる。そうすれば、「気づいたらガイドラインに沿った開発をしていた」という状態を作れます。 この考えから、Handbook公開と同時にAIエージェント向けスキルとしても提供することにしました。現在、Claude Code Plugin と Cursor Agent Skills の2つの形式で配布しています。 ここからは、AIエージェント向けスキルの技術的な仕組みと、人間側の学びを促す工夫の2つの観点で説明します。 スキルの技術設計 リポジトリ構成 1つの工夫として、Handbookのマークダウンドキュメントとスキル定義を同じリポジトリに同居させています。 handbook/ ├── backend/ # Handbookドキュメント(マークダウン) │ ├── design/ │ │ ├── web_api_design.md │ │ ├── table_design.md │ │ └── ... │ ├── implementation/ │ └── operation/ ├── .claude-plugin/ # AIエージェント向けスキル定義 │ └── timee-backend-handbook/ │ ├── plugin.json │ └── skills/ │ ├── ref-design-api/ │ ├── wf-code-reading/ │ └── ... └── scripts/ └── build-cursor-skills.sh # Cursor向け変換スクリプト ガイドラインの原文とスキル定義が同じリポジトリにあるため、ドキュメントの更新とスキルの更新を同じPRで行えます。ドキュメントとスキルが乖離するリスクを構造的に減らせます。 Reference SkillsとWorkflow Skills Handbookの内容を、AIエージェントのスラッシュコマンドで呼び出せるSkillsとして提供しています。今回、スキルの役割に応じて Reference Skills と Workflow Skills という2種類の分類を独自に定義しました。これはClaude CodeやCursorの公式な分類ではなく、Handbookスキル群の設計方針として導入した概念です。 Workflow Skill(高レベル) ├── Reference Skill A を呼び出し ├── Reference Skill B を呼び出し └── Reference Skill N を呼び出し(必要に応じて) Reference Skills Reference SkillsはHandbookの各ページと1対1で対応します。 /handbook-ref-design-api # Web API設計 /handbook-ref-design-table # テーブル設計 /handbook-ref-design-class # クラス設計 /handbook-ref-impl-code-review # コードレビュー ... たとえばAPI設計のReference Skillsは以下のように定義されています。 --- name: handbook-ref-design-api description: Web API設計のガイドラインを参照してエンドポイント設計をレビュー・提案 context: fork agent: general-purpose allowed-tools: Bash(gh *) --- ## Web API設計ガイドライン !`gh api /repos/my-org/handbook/contents/backend/design/web_api_design.md -H "Accept: application/vnd.github.raw"` ## タスク 上記のガイドラインに従って、$ARGUMENTS のWeb API設計をレビュー・提案してください。 ポイントは context: fork です。サブエージェントとして独立したセッションで実行されるため、メインセッションのコンテキストウィンドウを消費しません。情報量の多いHandbookの取得をサブエージェントに委譲し、要約のみを返すことで効率的に運用できます。 また、 gh api -H "Accept: application/vnd.github.raw" でマークダウンの原文をそのまま取得できます。Handbookが更新されれば自動的に最新の内容が反映されます。 Workflow Skills Workflow Skillsは、状況に応じて複数のReference Skillsを組み合わせるユースケース特化型のスキルです。 context: current でメインセッション上で実行されます。 現在はWorkflow Skillsを4つ提供しています。 スキル フェーズ 内容 /handbook-wf-code-reading 理解 既存機能を体系的に理解する /handbook-wf-modeling モデリング 概念モデリングを実施する /handbook-wf-plan 計画 開発中: 詳細設計を行いつつ、複数個の実装計画に落とし込む /handbook-wf-implement 実装 開発中: 与えられた入力を元に実装する たとえばモデリングフェーズのWorkflow Skillsを実行すると、以下のような流れで進みます。 イントロダクション : 概念モデリングの重要性とギャップ分析の考え方を説明 ガイドライン取得 : 必要なReference Skills(概念モデリング、ギャップ分析など)を自動で選択・呼び出し 意図の深掘りと目標の合意 : 何をモデリングしたいのか、スコープを確認 すり合わせの質問 : ドメインの境界やビジネスルールについて質問を提示 メインセッションでモデリング実行 : 回答を踏まえて一緒にモデリングを進める 開発者はスラッシュコマンドを1つ実行するだけで、必要なガイドラインの参照からモデリング作業までを一気通貫で進められます。ガイドラインの存在を知らなくても、Workflow Skillsが自動的に適用してくれます。 階層構造のメリット Reference SkillsとWorkflow Skillsの2層構造には、以下のメリットがあります。 再利用性: 同じReference Skills(たとえばギャップ分析)が理解・モデリング・設計の各Workflowから呼ばれる 動的選択: Workflow Skillsがユーザーの入力や状況に応じて、必要なReference Skillsだけを選択的に呼び出す コンテキスト効率: ガイドラインの取得処理はサブエージェントに委譲され、メインセッションには要約のみが返る また、Workflow Skillsは自作も可能です。既存のWorkflow Skillsを参考にしながら、チームの開発フローに合わせたワークフローを追加していけます。こうしたスキルが充実すれば、どのタスクに取り組むときでもHandbookの知見にガイドされる状態が作れます。新しくチームに加わった開発者でも、スキルを通じてすぐにチーム固有の設計方針をキャッチアップできるはずです。 人間の理解を置き去りにしない設計 スキルの技術設計だけでは不十分です。ここが一番気をつけたポイントです。 AWSが提唱しているAI-DLC(AI Driven Development Life Cycle) は、AIの出力を妥当にジャッジできる人間の存在を前提としています。人間側の理解が伴わなければ成り立ちません。 しかし現実には、AIの出力を「なんか良さそうだから」とそのまま使ってしまい、人間側の理解が追いつかないケースも起きがちです。AIの進化によって実装の詳細を人間が把握しなくてよくなる部分はあるでしょう。ですが、背景にある考え方を理解していなければ、AIと適切にコミュニケーションを取ることはできません。 だからこそ、このスキル群では人間に考え方やインサイトをインプットする工夫を随所に入れています。いわば、いつでも質問できるメンターをAIで実現する試みです。 工夫点1:イントロダクションで「なぜ」を伝える 各Workflow Skillsの冒頭にイントロダクションを設けています。ここではいきなり作業に入るのではなく、「なぜこのフェーズが重要なのか」「このフェーズで何を学ぶのか」を説明します。 たとえば理解フェーズのイントロでは、コード理解には概念・構造・実装の3段階があり、概念レベルから順に深めるアプローチが有効であることを説明しています。 ## 推奨アプローチ 概念レベルから順に理解を深めることを推奨します: 1. 概念レベル: まず全体像を掴む(どんな世界なのか) 2. 構造レベル: データとクラスの設計を理解(どう表現されているか) 3. 実装レベル: 具体的なロジックを理解(どう動くのか) 工夫点2:ガイドラインURLの提示 全てのスキルで、参照したガイドラインのホスティングしているURLを、ユーザーに必ず提示するようにしています。 重要: 参照したガイドライン(https://{my-org}.github.io/handbook/backend/design/web _ api _ design.html) をユーザーに必ず提示してください。 AIの要約だけで完結させず、元のドキュメントに戻れる導線を用意しています。全体像を掴んだ上で、気になった箇所は原文で深掘りできます。Handbookそのものの認知と活用が進む効果も期待しています。 工夫点3:抽象から具体へ段階的に Workflow Skillsのフロー全体が、抽象度を段階的に下げていく設計になっています。 ワークフローの4フェーズ(理解→モデリング→計画→実装)がそうですし、各フェーズ内でも同様です。理解フェーズでは概念→構造→実装と段階的に深め、計画フェーズでは概念モデルの出来事やモノをAPIエンドポイントやテーブルへ変換していきます。 一気に情報を出すのではなく、フェーズごとにすり合わせの質問を挟むことで、開発者自身が考える余白を作っています。 以下は、思考実験として「タイミーで企業合併を表現するなら?」というお題で、モデリングのWorkflow Skillsを試したときの様子です。 「将来の新設合併対応を見据えて、今回のモデルはどの程度汎用的にすべきですか?」「合併には時間的なフェーズがありますか?」という質問が飛んできました。そもそも合併に吸収・新設のパターンがあることを私は知りませんでした。Handbookの設計ガイドラインを熟知したエキスパートと、ドメイン知識を持ったエキスパートが悪魔合体するとこんな体験になるのか、と末恐ろしくなった瞬間です。 工夫点4:各ステップに学習ポイントを明示 Workflow Skills内の各ステップには「なぜそうするのか」「ここで何を学ぶか」を明示しています。 📚 学習ポイント: - 出来事(申請する、承認する)→ APIエンドポイント - モノ(勤務実績、勤務時間)→ リソースとリクエスト/レスポンス - ビジネスルール → バリデーションとエラーハンドリング 💡 ガイドラインのポイント: - 出来事は動詞で考え、APIでは名詞(リソース)として表現 - 選択された名前(例:「勤務実績」)をリソース名に反映 作業の手順だけでなく、その背景にある考え方を一緒に伝えることで、AIが出す結果の「なぜ」を開発者自身が理解できる状態を目指しています。 使ってみての感想 自分自身の所感 実際に使ってみて、これまでとは一線を画す体験だと感じています。 従来のAIエージェントの出力は、一気にたくさんの情報を出してくることが多く、情報量に圧倒されて消化しきれないことがありました。ですが、このワークフローでは抽象度を段階的に下げながら教えてくれるので理解がしやすいです。普段の会話で賢いなと感じる人は、抽象的なところから徐々に具体へ落としていくのが上手ですが、このワークフローにも同じ感覚があります。 AIエージェントは便利な開発アシストツールだと思いつつも、開発のギアが上がる感覚はこれまでありませんでした。ですが、このワークフローは明確にゲームチェンジャーだと感じています。 VPoEの反応 VPoEに実際に動かしながら紹介したところ、その場でEMチャンネルに @here 付きで共有してくれました。特に、AIエージェントが段階的にガイドラインを適用しながら開発者と対話する体験に手応えを感じてもらえたようです。 語彙力が下がっているVPoE 他開発チームメンバーの反応 現在、社内への全体発信を終えて各チームへのハンズオンを順次進めているところですが、すでに手応えを感じ始めています。 既に普段の開発で使ってくれているエンジニアからはこんなコメントをもらっています。ありがたい限りです。 handbookはここ1,2年で一番自分に刺さったプロダクトです おわりに この記事では、バックエンド開発Handbookと、それをAIエージェント向けスキルとして届ける取り組みについて紹介しました。 ドキュメントを書くだけでなく、AIエージェントを介して開発フローへ自然に組み込むことで、ガイドラインを届ける新しいアプローチを模索しています。AIへ任せきりにせず人間側の理解を促すことが、知の高速道路を敷くうえで最も大事なポイントだと考えています。 今回の取り組みを通じて、AI時代の開発組織に必要な要素が見えてきた気がしています。短期目線での開発の高速化だけでは不十分で、「全タスクがオンボーディングタスクになっていること」「メンターを基本的にAIが担い、いくらでも質問できて自走できる環境が整っていること」。この2つが揃えば、誰でもどのチームに移っても素早く立ち上がれるようになります。つまり、必要な場所に必要な人材を配置できる人員の流動性の高さに直結します。Handbookとスキルの取り組みは、その第一歩です。 今回作成した Agent Skills はカジュアル面談でもデモできるので、興味ある方はお気軽にお声がけください!実際に触ってみたい方は、ぜひタイミーに入社してください! product-recruit.timee.co.jp
こんにちは!プロダクトエンジニアのkazzhiraです。 私たちのチームでは、2025年の夏ごろから「AI活用による開発生産性の向上」に取り組んできました。しかし、当初の取り組みは抽象的なガードレールの提示や個々人の実践にとどまり、チームとして大きな成果には結びつきませんでした。 その後、SDD(仕様駆動開発)というアプローチに出会い、オープンソースの cc-sdd フレームワークをベースに試行錯誤を重ねてきました。 本記事では、AI開発標準の策定に失敗した経験から何を学び、どのように仕様駆動開発に辿り着いたのか、そして、実践を通じて得た成果と学びをご紹介します。 チームのAI導入でうまくいかなかった話 AI活用の個人最適化 当初、チームでは Cursor、Claude Code、Devin、GitHub Copilot、Gemini などの AI ツールを個々人の判断で利用できる状態でした。 しかし、AI活用の状況は個々人に閉じており、チームとしてのナレッジ共有や標準化は進んでいませんでした。 AI開発標準策定の失敗 そこで「AI開発標準」の策定を試みました。情報を収集したうえで、Planモードで実装計画を立て、途中でレビューを挟む開発スタイルを言語化しました。しかし、結果的にこの取り組みは失敗に終わりました。 資料の説明が抽象的で、チームが具体的に動きようがなかった 開発手法の共通項を抜き出しただけのガードレールに過ぎなかった 実際の開発プロセスに落とし込めず、絵に描いた餅になった 参考: 当時の考えを振り返った記事 なぜSDDをやろうと思ったのか 理想の開発体験の議論 チームで理想の開発体験・開発生産性の課題を話し合った結果、以下の課題が明確になりました。 リファインメント(仕様を決める会議)で議論が発散して収束に時間がかかる AIは顧客課題、ユーザーストーリーを知らず、要件の精度が高くない AIの出力が微妙で、整理されたコンテキストが足りない SDDとの出会い これらの課題を解決する方法として、 SDD(仕様駆動開発) に辿り着きました。 SDDの本質は、 仕様書を「単なるドキュメント」ではなく、AI と人間の両方が参照する SSoT(Single Source of Truth)として機能させる ことです。 定性面 AIがユーザーストーリー、背景、受け入れ条件から精度の良い仕様書を生成する →「AIは顧客課題、ユーザーストーリーを知らず、要件の精度が高くない」の解決 構造化された要件定義書・設計書・開発ルールで一貫したコンテキストを提供する →「AIの出力が微妙で、整理されたコンテキストが足りない」の解決 定量面 価値提供速度の向上 これらの効果を期待し、投機的に取り組んでみることを決めました。 ちなみに、「リファインメントで議論が発散して収束に時間がかかる」は当時Notion AIでの解決も試しました。しかし本題から外れるため、本記事では割愛します。 SDDの実践と工夫 cc-sddフレームワークの採用 SDD を実践するにあたり、私たちはオープンソースの cc-sdd (Spec-Driven Development フレームワーク)を採用しました。 深い理由はなく、筆者が各所で目にして実験的に入れていた背景があります。 チーム固有の課題 cc-sdd の基本的なアプローチを導入した上で、私たちのチームは以下の課題に直面しました。 複数のリポジトリを AI が横断的に操作できない チーム固有のタスク分割・実行ルールがなく、AI の出力がチームの開発フローに合わない Rails 固有の設計パターンが AI に伝わらない プロダクトのドメイン知識が AI に渡っていない 私たち独自のソリューション これらの課題に対し、私たちは以下の解決策を構築しました。 1. マルチリポジトリ横断ワークスペース Cursorによる開発を前提に、code-workspaceを生成して複数リポジトリを統合的に扱う仕組みを実装しました。 【my-team.code-workspace】 { " folders ": [ { " name ": " my-team ", " path ": " . " } , { " name ": " backend ", " path ": " ~/workspace/backend-repository " } , { " name ": " frontend ", " path ": " ~/workspace/frontend-repository " } , ... ] } これにより以下のメリットが得られました。 AI エージェント(Cursor / Claude Code 等)がリポジトリを横断して操作可能 仕様書リポジトリ(my-team)とコードベースを統合管理 私たちの最初の実装では、my-team・backend・frontendをセットで管理しました。 今はもう少し増えています。 2. タスク生成・実行ルールの整備 チーム固有のタスク生成・実行ルールを定義しました。 ルール種別 内容 タスク分割ポリシー "デプロイ可能な最小粒度" にタスク分割 Commit・Push・PRのルール 例示することで、意図した生成に誘導する。例えば "commitには変更理由とリファレンスを必ず含める"、"PRテンプレートに従う" など。 タスク実行順序の定義 Swaggerを定義してからfrontendとbackendの作業に移行する。 3. カスタムステアリングドキュメント Rails 固有の設計パターンやプロダクトのドメイン知識をステアリングドキュメントとして整備しました。 Controller Patterns( before_action の濫用禁止、個別でエラーハンドリング不要など) プロダクト固有の名称、用語、ユースケース リポジトリ構造のサマリ 採用している技術の詳細 例として「プロダクト固有の名称、用語、ユースケース」を定義した例を示します。 # Product Overview タイミーアプリのAPIサーバー、クライアント向けWebアプリケーションのAPIサーバー、 ワーカー向けモバイルアプリケーション、社内管理ツールを提供するプラットフォーム。 ## Core Capabilities 1. **ワーカー・クライアント管理**: ワーカーとクライアント企業のアカウント管理、認証、プロフィール管理 2. **求人・マッチング**: 求人作成、公開、ワーカーとのマッチング機能 3. **勤怠・給与管理**: 出勤管理、給与計算、支払い処理 4. **コミュニケーション**: チャット機能、レビュー・フィードバック機能 5. **管理機能**: 社内管理ツール、各種レポート・分析機能 ## Target Use Cases - **クライアント企業**: 求人作成・管理、ワーカー管理、勤怠確認、給与支払い - **ワーカー**: 求人検索・応募、勤怠管理、給与確認 - **社内管理者**: システム管理、データ分析、各種レポート生成 ## Value Proposition - ワーカーとクライアント企業を効率的にマッチングするプラットフォーム - 勤怠管理から給与計算まで一貫した業務フローを提供 4. カスタムコマンド cc-sddのコマンド体系以外で、チームで必要な成果物を保管するためのコマンドを用意しました。内容は長いため省略します。 QAチェックリストの自動生成「spec-qa-checklist」 Playwright MCPによるQA自動実行「playwright-mcp-qa」 最終的なファイルツリーを示します。 my-team/ ├── my-team.code-workspace # マルチリポジトリ統合ワークスペース定義(独自作成) ├── repos.yml # 対象リポジトリ一覧(独自作成) ├── repos.template.yml # ↑のテンプレート(独自作成) ├── docs/ # プロジェクト横断ドキュメント │ ├── scripts/ │ ├── setup.sh # 初期セットアップ(独自作成) │ ├── setup-workspace.sh # ワークスペース構成生成(独自作成) │ └── sync-*.sh # リポジトリ・設定の同期(独自作成) │ ├── .cursor/ │ └── commands/ # カスタムコマンド(独自作成) │ ├── spec-qa-checklist.md # QAチェックリスト生成 │ └── kiro/ # Kiro Spec-Driven コマンド群 │ └── .kiro/ ├── steering/ # アーキテクチャ制約 │ ├── product.md # プロダクト原則 │ ├── tech.md # 技術標準 │ └── structure.md # コード構造パターン ├── settings/ │ ├── rules/ # 設計・実行ルール(独自) │ │ ├── tasks-generation.md # タスク生成(プレフィクス規約・分割順序)(独自作成) │ │ └── task-execution-policy.md # 実行ポリシー(環境・Git・コミット規約)(独自作成) │ └── templates/ │ ├── specs/ # 仕様テンプレート │ └── steering/ # ステアリングテンプレート └── specs/{feature}/ # 機能単位で生成 ├── requirements.md # 要件 ├── design.md # 設計 ├── tasks.md # タスク └── e2e-qa-checklist.md # QA(独自作成) 評価 ポジティブな評価 cc-sddの短期間の導入で最も価値を感じたのは、実装速度の向上ではなく、 開発プロセスの質の向上 でした。 暗黙知の形式知化 — これまで個人の頭の中にあった仕様判断が、requirements / design / task の3つの成果物を通して言語化・共有された 手戻りの減少 — 仕様書によってコンテキストが整理されたことで、AIの出力品質が安定し、実装後の手戻りが体感として減った 合意形成の質の向上 — 仕様を厳格に言語化するプロセスが、チーム内の認識齟齬を早期に解消した モブワークとの親和性 — 構造化された仕様書が共通言語として機能し、スプリント初期の設計作業を効率的に進めることができた ネガティブな評価 一方で、チームで改善すべき課題も挙がっています。 モノにもよるが、仕様書を作る工程で同期的に1日〜1.5日の時間を使う 仕様書を精査する工程の疲労感 実装スピードとデプロイ頻度は、以前と同等か、微増している感覚 シンプルに練度不足 リファインメントが引き続きボトルネック。実装が効率化しても、要求の供給が追いつかなければ全体のスループットは上がらない 中間生成物のレビューがリファインメントに次ぐボトルネック。AIが高速に生成するアウトプットに対し、人間のレビューが追いつかない etc. データで見る事実:cc-sdd導入でデプロイ頻度は向上しなかった 前提として、開発者が3名のスクラムチームです。 【デプロイ頻度の移動平均推移】 デプロイ頻度の移動平均推移 開発生産性を測るFour Keysの1つの指標であるデプロイ頻度に着目しました。 cc-sdd導入前後でデプロイ頻度が向上していないことを観測 AIを本格導入してきた過去6ヶ月で見るとデプロイ頻度は増加傾向 先ほどのネガティブな評価の「実装スピードとデプロイ頻度は、以前と同等か、微増している感覚」とも一致しています。 ここで、他の視点も入れてみます。 【デプロイ頻度と変更リードタイムの移動平均推移】 デプロイ頻度と変更リードタイムの移動平均推移 【平均レビュープルリク数とレビューからアプルーブまでの平均時間の移動平均推移】 平均レビュープルリク数とレビューからアプルーブまでの平均時間の移動平均推移 【マージ済みプルリク数のアクティビティの推移】 マージ済みプルリク数のアクティビティの推移 これらの結果から、cc-sddによる開発について3つの事実が分かりました。 変更リードタイムは以前の開発繁忙期の時と同程度の推移 ※sddに関連するドキュメント更新のアクティビティは計測対象外です レビュー時間は以前よりも下がっている 瞬間風速的にはPR作成数が過去半年で最多を記録した cc-sddによって、設計からレビューの効率化には成功しているが、デプロイまでの流れを阻害しているボトルネックが別に存在すると読み取れます。 これまでの経緯を含めて考察すると、それはリファインメントによる要件の供給速度だということがわかります。 今後の取り組み ここまでの取り組みでは事実としてデプロイ頻度が上がりませんでした。 ネガティブな評価であがった課題を “のびしろ” と捉え、インパクトの大きい課題をコツコツ解消していく予定です。 直近では、AI-DLCのアプローチとスクラム開発と組み合わせ、リファインメントを改善する方針で以下の取り組みを進めています。 AIを要求・デザインフェーズにも適用し、仕様策定のボトルネックを解消する 仮説の壁打ち プロトタイプ作成を回す AIがアクセス可能なSSoTの範囲拡充(ビジネスコンテキスト、ユーザーリサーチ等) 価値提供のフィードバックループを短縮し、次の要求定義に繋げる まとめ cc-sddの導入で仕様の認識齟齬が早期に解消され、意図した仕様どおりの実装に到達しやすくなりました。 しかし世間で語られるようなAIによる劇的な生産性向上には至っていません。 仕様策定フェーズのボトルネックやレビュー負荷など、AIを適用できる余地は多く残されています。 私たちのチームでは、思考をAI Drivenに変化させ、要求定義から価値提供までの全体フローを、改めてAI前提で組み直す必要があることが見えてきました。 この記事を書いている時点でも新たな取り組みで急速に進化していることを実感しています。 私自身も置いていかれないように、チームに貢献できるように成果を出し続けようと思います。 引き続きこの領域に挑戦していきます。 タイミーには、こうした挑戦と学び、そして発信を歓迎する文化があります。 ともに挑戦し成長していきたい方、興味があればぜひ1度お話ししましょう! プロダクト採用サイトTOP カジュアル面談申込はこちら
はじめに こんにちは。プラットフォームエンジニアリングチームに所属している徳富( @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 カジュアル面談申込はこちら