TECH PLAY

株式会社LIFULL

株式会社LIFULL の技術ブログ

660

こんにちは、LIFULL HOME'Sのネイティブアプリ開発チームでエンジニアリングマネージャーをしている佐々木です。 「この画面、何が表示されてるか教えてもらえますか?」 目の前のタスクに集中しているときにSlackに飛んでくるこの一文で、エンジニアの手は止まります。悪気はない。でもチームのリードタイムは確実に伸びていく。 この問題を、AIに業務知識を構造化して渡すことで解消した話をします。 背景:人間が"コンテキストの運び屋"になっていた 試行錯誤:最初からこの形だったわけではない 何を作ったか:業務知識をパッケージ化する なぜ効いたか:3つの設計判断 ① 定義の集約:誰がいつ聞いても同じ答えが返る ② スキル化:「やりたいこと」を伝えるだけで手順が走る ③ ツール統合:分析もチケット起票も1箇所で完結 成果:「聞く側」も「聞かれる側」も変わった 余談:世界では「コンテキストレイヤー」と呼ばれているらしい まとめ 背景:人間が"コンテキストの運び屋"になっていた 私たちのチームでは、メイン施策を進めている最中に、次の施策のための質問・相談が頻繁に飛んできていました。 PdMから:「この画面の表示ロジックってどうなってる?」 デザイナーから:「この機能、実装上の制約ある?」「この表現はコード的に可能?」 マーケから:「この数値、どのイベントで計測されてる?」 エンジニアは手を止めてコードを読み、回答する。1往復30分〜数時間。これが毎日何回も発生していました。 問題はそれだけではありません。質問する側も「エンジニアの手を止めてしまう」という心理的ハードルを感じていて、遠慮して質問を溜め込む → まとめて聞く → 大量の回答待ちが発生する、という悪循環もありました。 本質は明確でした。 チームの業務知識が人の頭にしかなく、AIが参照できる形になっていなかった 。 試行錯誤:最初からこの形だったわけではない 前提として、利用者は非エンジニアです。GitHubアカウントを持っていない人がほとんどで、 git clone もターミナルも使えない。この制約の中で、どうやってコードベースの知識をAIに渡すか。 最初に試したのはGoogle GeminiのGem(カスタムAI)+ GitHub連携でした。でも連携した本人しか使えず、チームには共有できない。NotebookLMも同じ問題。 Repomix (コードを1ファイルに圧縮するツール)も試しましたが、ディレクトリ構造やファイル間の関係性が失われ、調査精度が出ませんでした。 結局たどり着いたのは「コードをそのまま同梱してzipで配る」という原始的な方法でした。全員が同じ環境を使えて、コードの構造もそのまま残る。「Googleドライブからダウンロード→解凍→フォルダを開く」だけで始められる。これが一番確実だった。 何を作ったか:業務知識をパッケージ化する 作ったのは、チームの業務知識を構造化してAIエージェントに渡す「パッケージ」です。zipを解凍して Kiro IDE (AIエージェント機能を内蔵したエディタ)で開き、日本語で質問するだけで使えます。 パッケージの中身は3層で構成されています。 steering(ルール・定義) : KPI定義、データソースの所在、業務上の制約 skills(手順・ナレッジ) : 分析の手順、レポート作成の方法、調査の進め方 agents(専門家) : コード調査担当、データ分析担当など、役割に特化したサブエージェント 3層構造の概念図 このしくみを、現在4チームに展開しています。 対象チーム 当初の課題 利用者 状態 ネイティブアプリ開発チーム 仕様調査でエンジニアの手が止まる PdM・企画・デザイナー ✅ 稼働中 デジタルマーケティングチーム 数値管理・レポートが手作業で属人的 マーケター ✅ 稼働中 アプリ広告運用(ASA/ASO)チーム 運用判断に専門知識が必要 企画・マーケター 🔶 一部利用 賃貸・流通領域チーム 仕様調査の横展開 PdM・企画・デザイナー 🔶 検証中 このほかにも試作段階のものがあり、少しずつ適用範囲を広げています。 このしくみの展開により、従来のコミュニケーションフローが大きく変わりました。 Before/Afterフロー比較 なぜ効いたか:3つの設計判断 ① 定義の集約:誰がいつ聞いても同じ答えが返る 「この指標の定義は?」「この計算式の出どころは?」。これまで人の頭にしかなかった情報を、Markdownファイルに一元管理しました。誰がいつ聞いても、AIが同じ定義に基づいて同じ答えを返します。属人化が構造的に解消されるしくみです。 ② スキル化:「やりたいこと」を伝えるだけで手順が走る 「着地見込を出して」と伝えるだけで、AIがデータ取得→計算→フォーマット整形まで実行します。利用者は「やりたいこと」を伝えるだけでよく、手順を知っている必要がありません。業務手順の暗黙知がスキルとして構造化されているからです。 ③ ツール統合:分析もチケット起票も1箇所で完結 BigQueryでの数値分析も、Jiraへのチケット起票も、Confluenceへの報告書投稿も、全部同じKiro IDEの中で完結します。「あの作業はスプレッドシート、この分析はGemini、あれはGoogle Apps Script」というツール跨ぎが消え、非エンジニアにとっての認知負荷が劇的に下がりました。 成果:「聞く側」も「聞かれる側」も変わった 利用者の一人である企画メンバーは、公式noteで以下のように書いてくれています。 以前は、「この仕様はどうなっていますか?」とエンジニアに確認を依頼し、その回答を待つまでに数時間〜1日ほどのリードタイムが発生していました。エンジニア側の作業を止めてしまうという心理的ハードルもありました。 しかし現在では、企画担当である私自らが調査パッケージを使い、5分〜10分程度でコードベースの一次調査を完結させています。コミュニケーションの往復が消えたことで、調査工数は約80〜90%削減され、施策検討のサイクルは圧倒的に加速しました。 — エンジニアから企画へ。LIFULL HOME'S アプリ部署で目撃した、AIシフトがもたらす「職種を越えた共創」 単に工数が減っただけではありません。「ここまで調べた結果、ここを変えれば実現できそうですが、どう思いますか?」という提案ベースの相談ができるようになったことで、意思決定の質も上がっています。 そしてエンジニア側は、調査依頼に中断されることなく、メイン施策の開発に集中できるようになりました。 余談:世界では「コンテキストレイヤー」と呼ばれているらしい ちなみに、2026年3月にa16z(米国の大手VC)が公開した記事「 Your Data Agents Need Context 」では、こう述べられています。 データ・分析エージェントは適切なコンテキストなしでは本質的に役に立たない。曖昧な質問を解きほぐすことも、ビジネス定義を解読することも、散在するデータを横断して推論することもできない。 同記事では、この問題の解決策として「企業のデータを束ね、ビジネスロジックを理解できる層をエージェントに供給する基盤」を「コンテキストレイヤー」と呼んでいます。振り返ると、私がやっていたことはまさにこれでした。 この記事を知ったのは後からです。現場の課題を解決していたら、同じ構造にたどり着いていました。 まとめ AIがどれだけ賢くなっても、チーム固有の業務知識を構造化して渡さなければ正しくは動きません。 大げさなプラットフォームがなくても、Markdownとスキル定義を整備してzipで配るだけで始められます。「人に聞く」を「AIに聞く」に変えるだけで、チームの循環は確実に変わります。 次回は、このしくみの技術的な設計と具体的なファイル構成について詳しく書く予定です。 最後に、LIFULLではともに挑戦し成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 https://hrmos.co/pages/LIFULL/jobs/010 https://hrmos.co/pages/LIFULL/jobs/010-9998
こんにちは、LIFULLでシニアエンジニア兼エンジニアマネージャーをしている渡邉です。普段はLIFULL HOME'Sの流通領域のエンジニアチームにて、マネジメントを担当しています。 最近のお気に入りはSupabaseです。 今回は、私たちが1年半にわたって磨き上げてきたGitHub完結型リリースフロー「Beezy」が、ついに弊社の一番メインのLIFULL HOME'Sシステム群に採用されたという大きなマイルストーンを迎えたことをご報告します。 これまでの歩み 🐝 「Beezy」という名前に込めた想い 名前の由来 なぜハチなのか なぜEasyなのか Beezyが目指すもの なぜメインシステム群への採用が重要なのか 本質的な課題は「スケールの壁」 Beezyが目指す3つの柱 1. 集約化:すべての情報をGitHubに 2. 自動化:人間の判断に頼らないしくみ 3. 加速化:価値をより早くユーザーへ Beezyの主要機能 承認フロー Issue駆動開発 リリースチェック 自動リリース リリース依存関係管理 Hotfixフロー 自動バージョンアップ 導入までの険しい道のり 最初の壁:既存フローへの愛着と不安 第二の壁:既存運用を損なわないための工夫 リリースカンバン機能の実装 リリース履歴ダッシュボードの作成 JIRAとの連携維持 第三の壁:技術的な課題の山積 1. 複数リポジトリ間の依存関係 2. 多様なリポジトリ形態への対応 3. 導入方法の簡略化 4. パフォーマンスの最適化 第四の壁:組織的な合意形成 ステークホルダーの多様性 合意形成のプロセス 1年半の成長の軌跡 フェーズ1:言語化とシステム化(最初の3ヵ月) フェーズ2:流通チームでの実証と汎用化(次の3ヵ月) フェーズ3:流通チーム以外への展開(次の6ヵ月) フェーズ4:メインシステム群への導入準備(次の6ヵ月) フェーズ5:メインシステム群への導入完了(現在) 導入を成功させた5つの要因 1. スモールスタートと段階的な展開 2. 早い段階での汎用化とリポジトリ分離 3. 複数マーケットでのテストマーケティング 4. 既存の運用を尊重する姿勢 5. 丁寧なサポート体制 組織全体への波及効果 開発者の声 今後の展望 さらなる進化に向けて まとめ これまでの歩み 私たちのリリースフロー改革の取り組みは、これまでに2回ブログで紹介してきました。 1本目の記事では、リリースフローをGitHubに集約し、自動化を図った初期の取り組みについてお伝えしました。 www.LIFULL.blog 2本目の記事では、その後の進化として、Chrome拡張機能の開発や自動リリース機能の実装など、さらなる改善について紹介しました。 www.LIFULL.blog そして今回、1年半のスモールスタートでの検証を経て、ついに弊社の一番メインのシステム群への採用が決定しました。 今回は導入までの行ってきたことを紹介させていただきます。 🐝 「Beezy」という名前に込めた想い 本格的な展開を前に、私たちはこのリリースフローシステムに「Beezy」という名前を付けました。 名前の由来 Beezy(ビージー)は、 Bee(ハチ)とEasy(楽)を組み合わせた造語 です。 なぜハチなのか ハチは自然界で 最も効率的で組織的な生き物 の一つです。巣の中では、それぞれのハチが明確な役割を持ち、無駄のない動きで協働しています。女王蜂、働き蜂、それぞれが自分の責務を果たすことで、巣全体が機能します。 このリリースフローも同じです。エンジニア、CodeOwner、G長(グループ長。開発チームの責任者)、PJ承認者(プロジェクト単位でリリース可否を判断する役割で、主に企画担当者が担う)、リリーサー(本番環境へのデプロイを実行する担当者)、企画担当者、デザイナー。 それぞれが自分の役割を果たし、GitHub上で一つの「巣」として機能します。 リポジトリごとにリリースに必要なactionsを適用していくことで、最終的に完璧なリリースパッケージが完成する。まさにハチの巣の構造そのものです。 また、ハチは 「集約」の象徴 でもあります。花から花粉を集め、一つの巣に集約し、蜂蜜という価値を生み出す。私たちも、 JIRAやSlack、Googleスプレッドシートに散らばっていた情報をGitHubという一つの巣に集約し、価値創造を加速させる基盤 を作りました。 なぜEasyなのか このリリースフローの最大の成果は、 「楽になった」 ことです。 リードタイムが最大60%短縮された という数字以上に、 承認者やリリーサーの心理的負担が劇的に軽減 されました。情報を探し回る手間、手作業でのチェック、見落としへの不安。これらがGitHub Actionsによる自動チェックで解消され、 人間は本当に必要な判断だけに集中できる ようになりました。 「Easy」は単なる「簡単」ではなく、 「気楽に、安心して」リリースできる状態 を意味しています。 Beezyが目指すもの Beezyは、 ハチのように効率的で組織的でありながら、誰もが気楽にリリースできる世界 を目指しています。 将来的にはリリーサーすら不要になる完全自動化を見据えながらも、今この瞬間、 チーム全員がリリースを「重荷」ではなく「日常」として扱えるようになること 。それがBeezyの願いです。 Busy(忙しい)ではなく、Beezy(ハチのように効率的で楽)なリリースを。 なぜメインシステム群への採用が重要なのか 本質的な課題は「スケールの壁」 私たちがBeezyを開発した当初、まずは小規模なシステムでスモールスタートを切りました。これは正しい判断でした。新しいしくみを導入する際には、リスクを最小化しながら検証を重ねることが重要だからです。 しかし、本質的な課題は「メインシステム群でこそ顕在化する」ということを、私たちは理解していました。 リリース頻度の高さ : メインシステムは日々多くの機能追加や改善が行われ、リリース頻度が圧倒的に高い 関係者の多さ : 開発者、企画担当者、デザイナー、リリーサーなど、多くのステークホルダーが関わる 承認プロセスの複雑さ : ビジネスへの影響が大きいため、承認プロセスも慎重にならざるを得ない 情報の分散 : JIRAとGitHubを行き来する手間、Slackでの確認など、情報が分散している つまり、メインシステム群でこそ、Beezyの真価が問われるのです。 Beezyが目指す3つの柱 Beezyの開発において、私たちが一貫して追求してきたのは以下の3つです。 1. 集約化:すべての情報をGitHubに 従来の課題 : リリースチケットはJIRA コードレビューはGitHub 承認依頼はSlack リリース履歴は別のツール 情報が分散していると、承認者やリリーサーは必要な情報を探すだけで多くの時間を費やしてしまいます。 Beezyのアプローチ : リリースに関わるすべての情報をGitHubのPRとIssueに集約 PR作成時に自動的に関連Issueが作成され、必要なタスクがすべて可視化 リリースカンバン機能により、GitHub上で進捗管理が完結 リリース履歴ダッシュボードで、過去のリリースも追跡可能 Before After 2. 自動化:人間の判断に頼らないしくみ 従来の課題 : 承認者は手動でチェックリストを確認 リリーサーは目視でリリース可否を判断 リリース忘れは人間の記憶に依存 Beezyのアプローチ : GitHub Actionsによる自動チェック 必要な承認がそろっているかを自動検証 リリース可能な条件を満たしたPRを自動検出 リリース忘れを防ぐ自動通知システム 自動リリース機能により、条件が整い次第リリーサーの介入なしでリリース 3. 加速化:価値をより早くユーザーへ 従来の課題 : リリースまでのリードタイムが長い 週2回程度のリリース頻度 承認からリリースまで数日かかることも Beezyのアプローチ : リードタイム中央値を最大60%短縮 1日2回のリリースが可能に 承認からリリースまで数時間に短縮 Beezyの主要機能 Beezyは、30以上のGitHub Actionsで構成された包括的なリリースフローシステムです。主要な機能を紹介します。 承認フロー LIFULLでは、本番環境へのリリース前に「G長承認(開発チーム責任者による技術的な承認)」と「PJ承認(企画担当者によるプロジェクト観点でのリリース可否判断)」という2段階の承認プロセスを設けています。これをGitHub上で完結させます。 G長承認・PJ承認のGitHub完結化 : PRのコメントで /G長承認OK 、 /PJ承認OK と書くだけで承認完了 適切な権限を持つ人のみが承認可能(GitHubチームで管理) Chrome拡張機能により、ボタン一つで承認コメントを投稿 自動承認スキップ : ドキュメントのみの変更など、プロダクトに影響のないファイルのみの変更は自動的に skip-release-check ラベルを付与 .dockerignore または .releasecheckignore でスキップ対象を定義可能 Issue駆動開発 SubIssueによるタスク管理 : PR作成時に、Epic IssueとSubIssueが自動生成 開発チェックシート、テスト仕様書、デザインチェックなど、必要なタスクを自動で分解 SubIssueの完了状況がPR上に進捗バーとして表示 すべてのSubIssueが完了すると、自動的に subissue-close ラベルを付与 リリースチェック ステージング確認・本番確認の自動化 : リリースPR上でチェックボックスをクリックするだけで確認完了 確認忘れを防ぐ自動通知機能 定時実行により、未確認のリリースを検出してSlack通知 自動リリース 条件が整い次第、自動的にリリース : ステージング確認・本番確認が完了したPRを自動検出 Googleカレンダーと連携してリリース可能日を判定 指定されたスケジュールで自動実行 リリース依存関係のチェックにより、順序を守ったリリースを実現 リリース依存関係管理 マイクロサービス間の依存関係を自動制御 : 設定ファイルで依存関係を定義 依存先のリリースが完了するまで、後続のリリースを自動的にブロック システム障害を防ぐための安全装置 Hotfixフロー 緊急リリースにも対応 : 通常のリリースフローとは別の、簡略化されたHotfixフロー Hotfix後のreverse merge PR(本番ブランチからdevelopへのPR)は自動承認 緊急時の対応をスムーズに 自動バージョンアップ メンテナンスの自動化 : Beezyのバージョンアップ時に、自動的にPRを作成 各リポジトリでの手動更新作業が不要 常に最新の機能とバグフィックスを利用可能 Beezy Flow 導入までの険しい道のり 最初の壁:既存フローへの愛着と不安 メインシステム群への導入を提案した際、最初に直面したのは「既存フローへの愛着」と「新しいフローへの不安」でした。 既存フローの強み : 長年の運用で培われた安定性 チーム全員が慣れ親しんだ手順 JIRAを中心とした統一的な管理 問題発生時の対応パターンが確立されている これらはけっして軽視できるものではありません。私たちは、この既存フローの良さを理解したうえで、Beezyを提案する必要がありました。 チームからの懸念 : 「GitHubに移行して、本当に大丈夫なのか?」 「企画担当者やデザイナーがGitHubを使えるようになるのか?」 「今までのリリース履歴はどうなるのか?」 「リリースカンバンでの進捗管理はどうするのか?」 「移行期間中、二重運用になって逆に負荷が増えるのでは?」 これらの懸念は、すべて正当なものでした。そして、私たちはこれらの懸念に一つ一つ真摯に向き合う必要がありました。 第二の壁:既存運用を損なわないための工夫 Beezyの開発で最も時間をかけたのが、「既存の運用を損なわない」ための機能開発でした。 リリースカンバン機能の実装 既存の運用 : JIRAのカンバンボードで、リリース予定のチケットを管理し、進捗を可視化していました。これは、リリーサーや企画担当者にとって、リリース状況を一目で把握できる重要なツールでした。 Beezyでの実現 : GitHub Projectsを活用したリリースカンバンの実装 PRの状態に応じて自動的にカードが移動 ラベルによる視覚的なステータス表示 フィルタリング機能により、特定の条件のPRのみを表示 試行錯誤の過程 : 最初は、GitHub Projectsの標準機能だけで実現しようとしましたが、既存のJIRAカンバンとの操作感の違いが大きく、ユーザーからの抵抗がありました。そこで、GitHub Actionsを使って、JIRAに近い操作感を実現するための自動化を追加しました。 リリース履歴ダッシュボードの作成 既存の運用 : 過去のリリース履歴を追跡し、「いつ、何がリリースされたか」を確認できることは、障害発生時の原因特定や、機能のリリース時期の確認に不可欠でした。 Beezyでの実現 : マージされたリリースPRの一覧表示 リリース日時、リリース内容、担当者などの情報を集約 検索・フィルタリング機能 各リリースに含まれる変更の詳細へのリンク 試行錯誤の過程 : 当初は、GitHubのリリース機能を使おうとしましたが、私たちの運用フローとは合いませんでした。そこで、GitHub APIを活用して、独自のダッシュボードを構築しました。これにより、既存の運用で必要だった情報をすべて提供できるようになりました。 JIRAとの連携維持 既存の運用 : すべてのプロジェクトがGitHubに移行できるわけではなく、一部のチームはJIRAでの管理を継続する必要がありました。 Beezyでの実現 : JIRAチケットとGitHub PRの相互リンク JIRAチケットの状態をGitHub上でも確認可能 段階的な移行をサポート これらの工夫により、「既存の運用を損なわない」という約束を守ることができました。 第三の壁:技術的な課題の山積 既存運用への配慮と並行して、技術的な課題にも取り組む必要がありました。 1. 複数リポジトリ間の依存関係 メインシステム群は、複数のマイクロサービスで構成されており、リリース順序に依存関係があります。 課題 : A→B→Cの順でリリースしなければならない場合、順序が逆転するとシステム障害につながります。 試行錯誤 : 最初は手動でのチェックを考えましたが、それでは自動化の意味がない 次に、依存関係を設定ファイルに記述する方式を試しましたが、メンテナンスが煩雑 最終的に、リリースブロック機能(release_block)を実装し、依存先のリリースが完了するまで後続のリリースを自動的にブロックするしくみを構築 実装のポイント : 依存関係を設定ファイルで定義することで、自動的にリリース順序を制御できるようになりました。 2. 多様なリポジトリ形態への対応 メインシステム群には、モノリス、マイクロサービス、フロントエンド/バックエンド分離など、多様な構成のリポジトリが存在します。 課題 : すべてのリポジトリ形態で同じ操作感を実現する必要がある。 試行錯誤 : 最初は個別にワークフローを作成していましたが、メンテナンス性が悪化 共通化を進めすぎると、柔軟性が失われる バランスを取るために、設定ファイルベースのアプローチを採用 実装のポイント : release_actions.config.yaml という設定ファイルを導入し、リポジトリごとに必要な機能を選択できるようにしました。 workflows : # G長承認とPJ承認をGitHub上で行う - id : approval_on_github enabled : true # 自動リリース機能 - id : auto_release enabled : true # Issue駆動開発 - id : issue_driven_development enabled : true inputs : ORGANIZATION : lifull REPOSITORY : your-repository-name PRODUCTION_BRANCH : main # その他、リポジトリごとの設定 この設定ファイルを用意した後、 renovate_actions ワークフローを実行することで、必要なワークフローファイルが自動生成されます。これにより、導入の手間を大幅に削減できました。 3. 導入方法の簡略化 課題 : 当初、対話形式のCLIツールを開発しましたが、以下の問題が発生しました: ローカル環境でのセットアップが必要 Node.jsのバージョン依存 チーム全員が同じ手順を踏む必要がある 試行錯誤 : CLIツールは便利でしたが、導入のハードルが高いという問題がありました。そこで、より簡単な方法を模索しました。 最終的な解決策 : release_actions.config.yaml と renovate_actions ワークフローを組み合わせた方式に変更しました。 導入手順 : テンプレートから release_actions.config.yaml と release_actions_renovate_actions.yaml をコピー release_actions.config.yaml を編集して、必要な機能を有効化 GitHubのActions画面から renovate_actions ワークフローを手動実行 自動的にPRが作成され、必要なワークフローファイルがすべて生成される この方式により、ローカル環境のセットアップが不要になり、導入のハードルが大幅に下がりました。 4. パフォーマンスの最適化 メインシステム群では、1日に数十件のPRが作成されることもあります。 課題 : GitHub Actionsの実行回数が増えると、コストとパフォーマンスの問題が発生します。 試行錯誤 : 不要なワークフローの実行を減らすためのフィルタリング キャッシュの活用 並列実行の最適化 実装のポイント : 変更されたファイルに応じてワークフローをスキップするしくみを導入しました。これにより、ドキュメントのみの変更では、重いチェック処理をスキップできるようになりました。 第四の壁:組織的な合意形成 技術的な課題以上に難しかったのが、組織的な合意形成でした。 ステークホルダーの多様性 開発者 : 新しいツールへの学習コスト、既存の開発フローの変更 企画担当者 : GitHubアカウントの作成、新しい承認フローへの適応 リリーサー : 役割の変化への不安、新しいツールの習得 マネジメント層 : 移行リスクへの懸念、投資対効果の検証 合意形成のプロセス 1. 小規模チームでの実証(3ヵ月) : 協力的なチームで実証実験を実施 週次で振り返りを行い、問題点を洗い出し フィードバックをもとに機能改善 2. 成果の可視化(6ヵ月) : リードタイムやリリース頻度の改善を数値で示す 開発者、企画担当者、リリーサーそれぞれの声を収集 定量的・定性的な成果をレポートにまとめる 3. 段階的な展開計画の策定(3ヵ月) : 一気に移行するのではなく、段階的な計画を提示 リスクの高いシステムは後回しにする 移行期間中のサポート体制を明確化 4. 充実したサポート体制の構築(継続) : 詳細なドキュメントの整備 ハンズオンセッションの定期開催 Slackチャンネル(リリースフローに関するすべての窓口)でのリアルタイムサポート Chrome拡張機能による操作の簡略化 特に重要だったのは、「既存の運用を尊重する」という姿勢を明確に示すことでした。リリースカンバンやリリース履歴ダッシュボードの実装は、この姿勢を具体的な形で示すものでした。 1年半の成長の軌跡 Beezyの開発は、決して一直線ではありませんでした。多くの失敗と学びを経て、現在の形にいたっています。 タイムライン フェーズ1:言語化とシステム化(最初の3ヵ月) 目標 : 現在のリリースフローの構成要素を言語化し、システム化する 取り組み : このフェーズでは、とにかく既存のリリースフローを徹底的に分解し、理解することに注力しました。 既存のリリースフローの各ステップを洗い出し それぞれのステップの目的と必要性を言語化 一つのリポジトリを対象に、大量のワークフローを作成 少しずつ検証を進めながら、システム化の可能性を探る 直面した課題 : 暗黙知として存在していたルールの発見 「なぜこの手順が必要なのか」を理解すること GitHub Actionsでどこまで実現できるかの見極め ワークフローの数が増えすぎて管理が煩雑に 学んだこと : リリースフローは想像以上に複雑で、多くの暗黙知が存在する すべてを一度に自動化しようとすると失敗する 小さく検証を重ねることの重要性 ワークフローの整理と構造化の必要性 この3ヵ月は、地味で泥臭い作業の連続でした。しかし、この期間に得た理解が、その後の開発の基盤となりました。 フェーズ2:流通チームでの実証と汎用化(次の3ヵ月) 目標 : 実際のチームで使ってもらい、汎用化する 取り組み : 私の所属する流通チームの企画担当者とエンジニアに説明し、マイクロサービスの1リポジトリで導入させてもらうことを握りました。 流通チームの企画担当者とエンジニアへの説明会を実施 マイクロサービスの1リポジトリで導入 実際に使ってもらいながら、フィードバックを収集 機能開発とユーザビリティ改善を並行して実施 汎用化への挑戦 : このタイミングで、ほかの流通リポジトリにも導入するつもりだったので、まずは今の1リポジトリに作ったワークフローをcomposite actionsとして汎用化することに全力を尽くしました。 個別のワークフローをcomposite actionsに分解 共通部分と個別部分を明確に分離 設定ファイルによるカスタマイズのしくみを構築 composite actions用の専用リポジトリを作成し、移設 この専用リポジトリの作成が、後の展開において非常に重要な役割を果たすことになります。 他の流通リポジトリへの展開 : 汎用化ができ次第、ほかの流通リポジトリでも検証を開始し、効果を検証しました。 直面した課題 : 企画担当者のGitHub習熟度のばらつき リポジトリごとの微妙な運用の違い composite actionsの設計の難しさ ドキュメントの不足 学んだこと : 実際のユーザーからのフィードバックの価値は計りしれない 汎用化は想像以上に難しい 「使いやすさ」は技術的な正しさとは別の次元 ドキュメントとサポート体制の重要性 早い段階での汎用化とリポジトリ分離が、後の展開を容易にする この期間で、Beezyは「動くもの」から「使えるもの」へと進化しました。 フェーズ3:流通チーム以外への展開(次の6ヵ月) 目標 : 流通以外のチームでも使ってもらい、効果を確固たるものにする 取り組み : 機能改善も行いながら、マイクロサービスを運用しているほかのチームに、流通での結果をもとに導入の相談を持ちかけました。 流通チームでの成果をレポートにまとめる ほかのチームへのプレゼンテーションと導入相談 導入サポートを丁寧に実施 実際に使ってもらってアンケートを実施 改善の数字を確固たるものに テストマーケティングの効果 : 社内のさまざまなチームで先にテストマーケティングさせてもらっていたことが、後のメインリポジトリ導入において非常に大きな意味を持つことになります。 成果の可視化 : リリース頻度の向上 リードタイムの短縮 リリーサーの作業時間の削減 開発者、企画担当者、リリーサーそれぞれの満足度 直面した課題 : チームごとの運用の違いへの対応 「流通でうまくいったから」だけでは説得力が不足 導入サポートの負荷 機能改善と導入サポートの両立 学んだこと : 数字で示すことの重要性 定量的な成果だけでなく、定性的な声も重要 導入サポートは想像以上に時間がかかる 異なるチームでの成功事例が説得力を生む 複数のマーケットでの実績が、組織全体への認知度を高める この期間で、Beezyは「流通チームのツール」から「複数チームで使えるツール」へと進化しました。そして、メインシステム群への導入に向けた確信を得ることができました。 フェーズ4:メインシステム群への導入準備(次の6ヵ月) 目標 : LIFULL HOME'Sのメインリポジトリ群への導入を実現する 取り組み : いよいよLIFULL HOME'Sのメインリポジトリ群への導入相談と調整を開始しました。 組織的な調整 : ものづくり全体への導入相談 予算の確保 ステークホルダーとの合意形成 移行計画の策定 認知度の高さが後押し : いろんなマーケットで先にテストマーケティングさせてもらっていたので、いざメインリポジトリに導入するとなった時にも、多くの関係者はBeezyについて知ってくれていました。これは非常に大きなアドバンテージでした。 「あのリリースフローのことね」という認識がすでにあった 成功事例を知っている人が多かった 「使ったことがある」という人が組織内に点在していた 新しいツールへの抵抗感が大幅に軽減された 課題解決への注力 : とにかく課題解決に時間を費やして粛々と準備を進めました。 リリースカンバン機能の実装 リリース履歴ダッシュボードの作成 JIRAとの連携維持 複数リポジトリ間の依存関係管理 パフォーマンスの最適化 運用上の問題への対策 : 運用上の問題が発生しないように、ドキュメントの充実と告知もしっかり行いました。 詳細なドキュメントの整備 企画担当者向けガイドの作成 ハンズオンセッションの実施 Slackチャンネルでのサポート体制の構築 Chrome拡張機能の開発 直面した課題 : メインシステム群特有の複雑さ 既存フローへの愛着と新しいフローへの不安 多様なステークホルダーとの調整 移行リスクへの懸念 学んだこと : 大規模な変更には、技術以上に組織的な調整が重要 既存の運用を尊重する姿勢を示すことの重要性 丁寧な準備が成功の鍵 予算確保には明確な効果の提示が必要 事前の認知度が、導入のハードルを大きく下げる この期間は、技術的な開発よりも、組織的な調整と準備に多くの時間を費やしました。しかし、この準備があったからこそ、スムーズな導入が実現できました。 フェーズ5:メインシステム群への導入完了(現在) 目標 : メインシステム群への導入を完了させる 取り組み : 準備が整い、いよいよメインシステム群への導入を開始しました。 段階的な導入計画の実行 リアルタイムでのサポート 問題発生時の迅速な対応 継続的なフィードバックの収集と改善 成果 : そして今、メインリポジトリへの導入が完了しました。 品質の向上 : 人的ミスの完全排除 リリース品質の安定化 直面した課題 : 導入初期の混乱 予期しないエッジケース ユーザーの習慣を変えることの難しさ 学んだこと : 1年半の準備があっても、導入時には予期しない問題が発生する リアルタイムでのサポート体制の重要性 継続的な改善の必要性 成功は一つのマイルストーンであり、ゴールではない 導入を成功させた5つの要因 1年半の道のりを振り返ると、メインシステム群への導入を成功させた要因は、以下の5つだと考えています。 1. スモールスタートと段階的な展開 一気に大規模な変更を行うのではなく、小さく始めて段階的に展開したことが成功の鍵でした。 最初の3ヵ月: 1リポジトリでの検証 次の3ヵ月: 流通チーム内での展開 次の6ヵ月: 流通チーム以外への展開 次の6ヵ月: メインシステム群への導入準備 各段階で学びを得て、次の段階に活かすことができました。 2. 早い段階での汎用化とリポジトリ分離 フェーズ2の段階で、composite actions用の専用リポジトリを作成し、ワークフローを移設したことが、後の展開を大きく容易にしました。 メリット : 複数のリポジトリで同じアクションを使える バージョン管理が容易 機能追加や修正が一ヵ所で完結 導入リポジトリ側のメンテナンスコストが低い この判断により、ほかのチームへの展開やメインシステム群への導入が、スムーズに進みました。 3. 複数マーケットでのテストマーケティング いろんなマーケット(チーム)で先にテストマーケティングさせてもらっていたことが、メインリポジトリ導入において非常に大きな意味を持ちました。 効果 : 組織内での認知度が高まった 「使ったことがある」という人が点在していた 成功事例を知っている人が多かった 新しいツールへの抵抗感が大幅に軽減された いざメインリポジトリに導入するとなった時にも、多くの関係者はBeezyについて知ってくれていました。これは、説明コストを大幅に削減し、導入のハードルを下げる大きな要因となりました。 4. 既存の運用を尊重する姿勢 新しいシステムを導入する際、既存の運用を否定するのではなく、尊重する姿勢を貫きました。 リリースカンバン機能の実装 リリース履歴ダッシュボードの作成 JIRAとの連携維持 これらの機能は、技術的には必須ではありませんでしたが、ユーザーの信頼を得るために不可欠でした。 5. 丁寧なサポート体制 技術的に優れたシステムでも、サポートがなければ使われません。 詳細なドキュメント 企画担当者向けガイド ハンズオンセッション Slackチャンネルでのリアルタイムサポート Chrome拡張機能 特に、企画担当者向けガイドとChrome拡張機能は、技術者以外のユーザーにとって大きな助けとなりました。 組織全体への波及効果 メインシステム群での成功は、組織全体に波及効果をもたらしています。 ほかのチームへの展開 : 成功事例を見たほかのチームからも導入希望が相次いでいる ベストプラクティスの共有 : Slackチャンネルを通じた知見の共有 継続的な改善 : ユーザーフィードバックをもとにした機能追加や改善 開発者の声 開発者からの声 : 「ボタン一つで承認が終わるなんて!」 「タスクの進捗が自動で更新されるから楽」 「リリース忘れがなくなった」 「リリーサーを待つ必要がなくなった!」 企画担当者からの声 : 「GitHubは難しいと思っていたけど、ガイドがあるから安心」 「Chrome拡張機能のおかげで、承認が簡単になった」 「リリース状況が一目で分かるようになった」 リリーサーからの声 : 「定型作業から解放されて、より重要な仕事に集中できる」 「自動リリース機能のおかげで、リリース日の緊張感が減った」 「リリース履歴ダッシュボードで、過去のリリースも簡単に追跡できる」 今後の展望 さらなる進化に向けて メインシステム群への採用は、ゴールではなくマイルストーンです。私たちは今後も、以下の方向性で進化を続けていきます。 1. より多くのチームへの展開 : 全社的な展開 グループ会社も含んだLIFULLグループ全体への導入 2. 機能の継続的な改善 : ユーザーフィードバックをもとにした改善 新しい技術の導入 パフォーマンスの最適化 3. Developer Experienceのさらなる向上 : より直感的なUI/UX ドキュメントの充実 サポート体制の強化 まとめ 1年半のスモールスタートを経て、ついにメインシステム群への採用を実現できたことは、私たちにとって大きな達成感をもたらしています。 しかし、それ以上に重要なのは、この取り組みを通じて得られた「組織の変化」です。 技術者が創造的な仕事に集中できる環境 心理的安全性の向上 チームの幸福度の向上 これらは、単なる効率化では得られない、本質的な価値です。 私たちは「価値創造を加速させ続ける」ことをビジョンの一部に掲げています。今回のメインシステム群への採用は、そのビジョンに向けた大きな一歩だと確信しています。 「仕方がない」と思っているポイントこそ、変化の余地があるかもしれません。開発フローにおけるそれぞれの構成要素をあらためて見直し、最低要件を確認してみることで思わぬ改善の糸口が見つかる可能性があります。 今後も一歩ずつ改善を積み上げることで、リリースのさらなる加速化につなげていければと思います。 最後に、LIFULL ではともに挑戦し成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 https://hrmos.co/pages/LIFULL/jobs/010 https://hrmos.co/pages/LIFULL/jobs/010-9998
こんにちは、LIFULLの渡邉です。シニアエンジニア兼エンジニアマネージャー(EM)として、普段はLIFULL HOME'Sの流通領域のエンジニアチームにてマネジメントを担当しています。日々チームの開発生産性やDeveloper Experience(DX)の向上に取り組んでいます。 今回は、長年スプレッドシートで管理されてきた「開発チェックシート」を、GitHubリポジトリ + GitHub Sub Issues + GitHub Actionsで再構築した話をお伝えします。スプレッドシートで管理している運用ドキュメントをGitHubに移行するひとつのサンプルケースとして紹介させていただきます。 課題の背景と目的 開発チェックシートとは スプレッドシート運用の限界 具体的なアプローチ 設計方針:既存のフローを壊さない 技術選定 エンジニアが実際にやること Markdownで管理する意味 AI時代の開発プロセスとの融合 MarkdownのAI親和性 各プロセスへの導入 MCP化による情報アクセスの容易化 直面した壁と乗り越え方 合意形成と移行の進め方 GitHub Sub Issuesの制約 成果と今後の展望 得られた成果 今後の展望 まとめ 課題の背景と目的 開発チェックシートとは LIFULL HOME'Sの開発では、以下のようなプロセスで開発が進行します。 実装 → 実装レビュー → テスト仕様書作成 → テスト仕様書レビュー → テスト この実装前、もしくは実装後に「開発チェックシート」を複製してチェックする工程があります。過去に発生した障害やバグを事前に検知するためのもので、組織の学びが蓄積されたナレッジそのものです。 スプレッドシート運用の限界 従来はGoogleスプレッドシートでマスタを管理し、開発案件ごとに複製 → チェック → レビューという流れで運用していました。この運用自体は機能していましたが、いくつかの課題が顕在化していました。 マスタ情報の所在があいまい : 「最新版はどれ?」とスプレッドシートを探す手間が発生する AI活用との親和性が低い : スプレッドシートのデータ構造はLLMに読ませるには不向き 開発プロセスとの統合が困難 : チェックシートの確認が開発フローから切り離された「別作業」になりがち 本質的な課題は、チェックシートの情報が開発のコンテキストから分離していることでした。 具体的なアプローチ 設計方針:既存のフローを壊さない 重要だったのは、「スプレッドシートを複製 → チェック → レビュー」という既存の運用フローを崩さないことです。運用が定着しているプロセスを無理に変えると、チームの認知負荷が上がり、結果的に誰も使わなくなります。 そこで、以下の方針で設計しました。 既存の「複製 → チェック → レビュー」のフローはそのまま維持する ツールとフォーマットだけを、よりエンジニアリングに適した形へ置き換える 技術選定 従来 新 役割 スプレッドシート(マスタ) GitHubリポジトリのMarkdownファイル(mainブランチ) チェック項目の原本管理 スプレッドシートの複製 Issue Templateからepic issueを作成 案件ごとのチェックシート作成 各シートに記入 epic issueでのチェックをトリガにsub-issueが自動生成 詳細チェック項目の展開 手動チェック&レビュー 各sub-issue上でのチェック&レビュー チェック・承認フロー ─ GitHub Actions 自動化・AI連携 スプレッドシートの「複製」に相当するのが、Issue Templateからのepic issue作成です。epic issueで該当する項目にチェックを入れると、GitHub Actionsがそれをトリガに詳細なチェックリストを持つsub-issueを自動生成します。開発者は生成されたsub-issue上で一つ一つチェックを進めていく流れです。 エンジニアが実際にやること 全体の流れを図にすると以下のようになります。 sequenceDiagram participant 開発者 participant GitHub participant レビュアー 開発者->>GitHub: Issue Templateからテンプレート選択 開発者->>GitHub: 施策情報入力&該当項目にチェック GitHub-->>GitHub: sub-issue自動生成 開発者->>GitHub: 各sub-issueのチェックリストを埋める 開発者->>GitHub: 必要に応じてコメント記載 開発者->>レビュアー: レビュー依頼 レビュアー->>GitHub: epic issue・各sub-issueを確認 レビュアー->>GitHub: 親issueにレビューOKコメント レビュアー->>GitHub: 親issueをclose GitHub-->>GitHub: 全sub-issue自動close 具体的な手順は以下の通りです。 1. 新規チェックシートの作成 リポジトリの「New Issue」から対象のテンプレートを選択 施策名・実装者・対象リポジトリを入力 該当するチェック項目にチェックを入れてIssueを作成 チェックした項目に対応するsub-issueがGitHub Actionsにより自動生成されます。 2. チェックの実施 自動生成された各sub-issueのチェックリストを確認し、該当/非該当をチェック 必要に応じてコメント欄に対応内容や対応不要の理由を記載 3. レビュー & 完了 レビュアーが各sub-issueと親issue(epic)の内容を確認 問題なければ親issueにレビューOKのコメントを記載 親issueをclose → 全sub-issueが自動でcloseされる スプレッドシート時代の「複製 → チェック → レビュー」という流れがそのまま「Issue作成 → チェック → レビュー&close」に置き換わっている点がポイントです。 Markdownで管理する意味 チェック項目をMarkdown形式でリポジトリに格納したことで、以下の利点が生まれました。 Single Source of Truth : mainブランチが常に最新のマスタ。探す必要がない 変更履歴の追跡 : Git履歴で「いつ、なぜ、誰が」項目を追加・修正したかが明確 Pull Requestによる更新プロセス : チェック項目自体の追加・変更もレビューを経て反映される AI時代の開発プロセスとの融合 今回の移行で最も大きなインパクトがあったのは、AI活用との親和性の向上です。 MarkdownのAI親和性 スプレッドシートのデータをLLMに読ませる場合、セル構造の解釈やフォーマットの揺れに精度が左右されます。一方、Markdownは構造化テキストとして最もLLMが正確に理解できるフォーマットのひとつです。 この特性を活かし、開発プロセスの随所にチェックシートの知見を組み込めるようになりました。 各プロセスへの導入 [実装] → [実装レビュー] → [テスト仕様書作成] → [テスト仕様書レビュー] → [テスト] ↑ ↑ ↑ ↑ AI支援 AI支援 AI支援 AI支援 (チェック項目を (チェック項目を (チェック項目を (チェック項目を プロンプトに含む) レビュー基準に含む) 仕様に反映) 確認基準に含む) 具体的には以下のようなことが可能になりました。 実装時 : チェックリストの情報をプロンプトに含めることで、AIが「そもそも既知の障害パターンを回避する実装」を提案してくれる レビュー時 : レビュアー(人・AI問わず)がチェック項目を基準として参照できる GitHub ActionsによるAI自動レビュー : PR作成時に自動でチェック項目との整合性を検証 従来は「実装が終わってからチェックシートで確認」という事後確認型でしたが、開発プロセス全体に予防的にチェックの知見を浸透させることが可能になりました。手戻りが減り、生産性を最大化する方向に大きく前進したと感じています。 MCP化による情報アクセスの容易化 さらに、チェックシートの情報をMCP(Model Context Protocol)サーバとして提供することで、開発者がAIアシスタントを通じて自然言語でチェック項目を参照できる環境を整備しました。「この実装でセキュリティ面において気を付けることある?」と聞けば、関連するチェック項目が返ってくるイメージです。 直面した壁と乗り越え方 合意形成と移行の進め方 移行にあたっては、事前にエンジニアチャンネルで構想を共有し、関係各所との合意形成を行いました。肯定的な意見が多く集まり、スムーズに推進できました。 実際の移行では、以下を心がけました。 移行期間中は旧スプレッドシートも並行稼働 「まず1案件だけ新フローで試す」スモールスタート メンバーからのフィードバックを即座にマスタへ反映し、「自分たちが育てているチェックリスト」という当事者意識を醸成 GitHub Sub Issuesの制約 GitHub Sub Issuesはまだ比較的新しい機能であり、いくつかの制約もありました。UIの表示やフィルタリングなど、スプレッドシートの一覧性には及ばない部分もあります。ここはGitHub Actionsによる自動生成テンプレートで補い、手作業を最小限にとどめる工夫をしています。 成果と今後の展望 得られた成果 マスタ情報の一元化 : 「最新版どこ?」がなくなった AI活用による予防的チェック : チェックシート確認前に多くの問題が解消されるようになった 開発プロセス全体への浸透 : 特定のタイミングだけでなく、各工程でチェック知見が活用されている 自動レビューとの統合 : GitHub ActionsによるAIレビューにチェック項目を組込み属人化を排除 チェックシートの形を変えただけで、開発プロセスの質が全体的に底上げされるといった手応えを感じています。 今後の展望 チェック項目が「過去の障害やバグの記録」である以上、継続的に更新されていくものです。GitHubリポジトリで管理することで、障害対応のポストモーテムからそのままPRでチェック項目に追加する、というフローも自然に回り始めています。 技術的にはシンプルな構成ですが、「スプレッドシートで十分動いているもの」をあえてエンジニアリングの文脈に持ち込みました。AI時代の開発プロセスに自然に統合できる形に進化させられた事例として共有させていただきます。 組織の中で「なんとなくスプレッドシートで管理しているもの」があれば、Markdownでリポジトリ管理することを検討してみてください。AI活用という文脈で、想像以上の恩恵があるかもしれません。 まとめ 「スプレッドシートで運用しているものをGitHubに移す」という、一見するとシンプルな取り組みですが、その先に見えた景色は想像以上のものでした。 本質的な課題は、チェックシートの情報が開発のコンテキストから分離していたことでした。それをエンジニアリングの文脈に統合したことで、以下のような変化が生まれています。 AIが開発プロセス全体でチェック知見を活用できる状態 手戻りの削減による、技術者が創造的な仕事に集中できる環境 PRベースの更新フローによる、チーム全員がナレッジを育てている当事者意識 これらは、単なるツール移行では得られない、本質的な価値だと考えています。 「スプレッドシートで十分動いている」と思っているものこそ、変化の余地があるかもしれません。既存の運用フローを壊さずに、ツールとフォーマットだけを変えるアプローチであれば、チームへの負荷を最小限に抑えながら大きな恩恵を得られる可能性があります。 今後もチェック項目を継続的に育てながら、開発プロセスのさらなる改善につなげていければと思います。 最後に、LIFULLではともに挑戦し成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 https://hrmos.co/pages/LIFULL/jobs/010 https://hrmos.co/pages/LIFULL/jobs/010-9998
こんにちは。LIFULL HOME'S の CRM領域で開発を担当しているソンです。 LIFULL HOME'Sでは、賃貸の一部レコメンドメールに掲載するレコメンド物件に対して、LLMを活用した「推薦文」を自動生成しています。これは「なぜこの物件がお勧めなのか」を自然な日本語で伝える短い文章です。物件情報をもとにユーザーごとの関心に寄り添った説明を添え、物件理解の促進とメール経由の詳細閲覧率向上を目指しています。 この記事では、その推薦文の品質を守るために私たちが構築した「AI監視システム」にフォーカスし、どのような基準で文章をチェックしているのか、実際の検出事例を交えて紹介します。 1. 導入:AIが書く文章は「便利」のその先へ 2. 根拠のない「充実」は、ただのノイズ 3. 「日本一」や「最高」が法に触れる理由 4. わずか12文字の攻防:128〜140文字のルール 5. AIが「空気を読む」:スペック羅列を超えた文章へ 6. 2段構えの監視:システムのしくみ 7. 結び:誠実な言葉こそ、選ばれるマーケティング 1. 導入:AIが書く文章は「便利」のその先へ AIによる推薦文の自動生成は、私たちのサービスにおいて欠かせない存在になりました。ただ、AIが生成する文章にはコンプライアンス上のリスクもあります。 実はこの施策の立ち上げ当初から、推薦文の品質監視は重要な課題として認識していました。LLMの特性上、意図しない表現が生成される可能性は避けられません。初期段階では生成ログをもとに人が目視でチェックしていましたが、確認できる量には限界があり、監視の精度にも課題がありました。 そこで私たちは、監視の自動化に取り組みました。2026年4月現在、「推薦文不正文言AI監視システム」が日々稼働しています。このシステムは、日中のコアタイムに定期的に生成された全文章を精査しています。私たちの監視システムは、ルールベースの用語スクリーニングとLLMによる文脈判定を組み合わせた構成へと進化しています(詳細は6章で解説します)。 この監視システムが、どうやって問題のある表現を検出しているのか。そのしくみと、私たちが目指す「言葉の質」について、技術と規制の両面から紹介していきます。 2. 根拠のない「充実」は、ただのノイズ 監視システムのログを分析して最も多く検出されるのが、「根拠なし表現」による「警告」です。「充実した設備」や「買い物便利」といった言葉は、つい多用されがちな表現です。しかし、監視システムにとってこれらは、具体的な裏付けのない不十分な表現に過ぎません。たとえ近くにスーパーがあったとしても、単に「便利」と書くだけでは不十分なのです。 監視システムの指摘例 「買い物便利」:近隣にコンビニ(徒歩800m以内)はあるが、もう少し具体的な説明が望ましい。 「充実した設備」:具体的設備名が明記されていないため根拠不足。 「日当たり良好」:方角や採光面などの理由が併記されていない。 読み手であるユーザーは、形容詞ではなく「事実」を求めています。監視システムに定義された「OK例」は、そのままプロフェッショナルの記述作法となります。 NG : 買い物便利 OK : スーパー(100m)近隣のため買い物便利 NG : 設備充実 OK : 設備充実(床暖房/追い焚き/WIC) 「近さ」や「多さ」を主観で語るのではなく、数値や施設名という「根拠」を添える。結局、具体的な根拠があるかどうかが品質の分かれ目です。 3. 「日本一」や「最高」が法に触れる理由 不動産広告には、明確に「違反」と判定される表現もあります。それは「不動産公正競争規約」によって厳格に定められた、最上級表現や完全性を意味する用語の使用です。 「日本一」「No.1」「最高級」「完全」「絶対」。これらの言葉は、客観的かつ調査にもとづいた具体的なデータがない限り、消費者に誤認を与える不当表示とみなされます。この規約にもとづくルールが監視システムに設定されており、過度な装飾は瞬時に「違反」と判定されます。 また、意外な落とし穴が「新築」という言葉の扱いです。 「違反」判定の事例 「新築複数」:『新築』と表記できるのは建築後1年未満かつ未入居の物件に限られるため、複数物件をまとめて『新築』と謳うことは規約違反のリスクが高くなる。また、新築と呼ぶための根拠説明も欠如している。 「格安」「破格」:射幸心をあおる表現として排除対象。 「早い者勝ち」:不当なあおりとして排除対象。 監視システムを通じて、こうした表現がブランドの信頼を損なうリスクをあらためて実感しました。 4. わずか12文字の攻防:128〜140文字のルール 推薦文の品質を左右するのは、言葉の意味だけではありません。システムには、非常に厳格な「文字数」という物理的制約が課せられています。私たちの監視基準では、推奨範囲は「128〜140文字」と極めてタイトに設定されています。 1文字でも超えれば警告が出ます。141文字になった瞬間、「文字数違反」として検出されます。 監視ログの記録 「推薦文が141文字と140文字を超えています」 「183文字で推奨範囲128〜140文字を超過」 なぜ、ここまで厳格なのでしょうか。それは、ユーザーのデバイス上でストレスなく読める「情報の密度」を、表示幅やスクロール量をもとに社内で検討した結果、この範囲が最適と判断したためです。ユーザーが読みやすい情報量を検討した結果、この範囲に落ち着きました。 5. AIが「空気を読む」:スペック羅列を超えた文章へ 「3LDK、南向き、駅徒歩5分」。こうした事実の羅列は、間違いではありませんが、優れた推薦文としては評価されません。監視システムには「スペック羅列」という警告項目が存在し、情報の羅列に終始した文章を「品質が低い」と判定します。監視システムは単なるキーワード検索ではなく、「自然な日本語で物件の魅力を伝えているか」という文章としての自然さも判定しています。 品質基準の定義 自然な日本語で物件の魅力を伝える文章であること。 スペック羅列のみは不可。 たとえば、条件だけを並べて最後に「ゆとりある毎日を実現します」と付け加えただけの文章は、「説明が薄く、スペック羅列寄り」と判定されます。 求められているのは、そのスペックが実際の生活にどう役立つのか、という視点です。物件データを生活のイメージに変換する力こそが、私たち書き手が意識すべき役割だと考えています。 6. 2段構えの監視:システムのしくみ この品質管理を支えているのが、LLMを活用した「推薦文不正文言AI監視システム」です。本システムは、コアタイムに定期的なチェックを実行します。 AI判定の前段階では、まず「ルールベース」による完全禁止用語のスクリーニングが行われ、それを潜り抜けた文章のニュアンスにリスクがないかをAIが判定します。特筆すべきは、AIに対して高い推論精度を求める設定を施している点です。これにより、AIは単なる文字のマッチングを超え、文脈を踏まえて、表面的には問題なさそうな表現のリスクも判定します。 システムの3つの強み 即時性の担保 : 違反検出時は、即座に担当者へ通知され、即応可能です。 高度な推論 : LLMの深い推論能力により、「一見よさそうだが実は根拠があいまいな表現」も見逃しません。 継続的改善 : 定期的に結果がまとめられ、組織全体のコンプライアンス意識の向上にもつながっています。 このしくみによって、人的チェックでは見落としがちな表現もカバーできます。常に高い水準で広告品質を維持する。これが私たちの目指す広告品質管理の姿です。 7. 結び:誠実な言葉こそ、選ばれるマーケティング AI監視システムが導き出した「安全」な文章。それは、けっして個性を殺した無機質なものではありません。むしろ、誇張を取り除いた、物件本来の価値を伝える言葉です。 結局のところ、監視システムが問題なしと判定する文章とは、「嘘がなく、具体的で、相手の人生に寄り添った誠実な文章」にほかなりません。どれだけテクノロジーが進化しても、 信頼の土台になるのは、事実にもとづいた言葉の積み重ねです。 AIを活用して推薦文を運用する私たちは、常に自らこう問いかけるべきでしょう。「あなたのその言葉に、読み手が信頼できる根拠はありますか?」その問いへの誠実さが、ユーザーから信頼されるサービスへとつながると考えています。 この監視システムはまだ導入したばかりですが、すでに大きな収穫がありました。監視結果を分析する中で、既存の推薦文生成プロンプトや監視用プロンプトそのものにも改善の余地があると見えてきたのです。監視システムは品質を守るだけでなく、私たち自身のしくみを見直すきっかけにもなっていると実感しています。 最後に、LIFULLではともに成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
こんにちは、プロダクトエンジニアリング部の江口です。 私は普段 LIFULL HOME'S 賃貸マーケットの技術負債解消に取り組むエンジニアリングチームのリーダーをしています。 本記事では、賃貸マーケットで長年の課題だった「ユーザー行動ログ送信処理」の技術負債解消について紹介します。技術的な取り組みだけでなく、エンジニアとして技術負債にどう向き合っていくべきかを考えるきっかけにもなった経験をお伝えできればと思います。 何が問題だったのか なぜこれまで解決できなかったのか どうアプローチしたか 難易度を下げてから勝負する 依存先の調査 古いログへの依存を一つずつ断ち切る 実装・テスト・移行での工夫 プロジェクト推進の難しさ やり遂げて思ったこと:技術負債解消とROI 終わりに 何が問題だったのか 賃貸物件の詳細ページは過去にリニューアルされ、新システムへ移行済みでした。しかし、ユーザー行動ログの送信処理だけは旧システムに残ったままで、新システムから旧システムのエンドポイントを叩くことでこの処理を委譲していました。つまり、詳細ページを1回表示するたびに、バックエンドへのリクエストが実質2倍発生している状態です。 これまでの行動ログ送信処理 これによって、負荷が集中する繁忙期には、DBのパフォーマンスの低下も懸念されました。もちろん、私たちも新システム側でクローラー判定を行い旧システムへのリクエストを抑制したり、ログの生成に関係のないバックエンドへのリクエストを停止したりと、できる限りの負荷軽減策を講じてきました。しかし、これらはあくまで対症療法に過ぎません。この状況を根本から解消するため、私たちのチームがこの問題に決着をつけることになりました。 これまでの試行錯誤の歴史については、ぜひこちらの記事もご覧ください。 www.lifull.blog なぜこれまで解決できなかったのか 過去にもログ送信処理の移植は試みられてきましたが、以下の理由により断念されてきました。 膨大な移植コスト : 約10年前のレガシーなロジックが複雑に絡み合い、2〜3名で1年かけても終わらない規模 品質担保の壁 : 不動産会社が掲載効果を分析するためのレポート機能に関わるため、集計結果の変動を許容しづらい ログの完全一致が困難 : 旧システムと新システムでは物件情報データの取得経路に微妙な違いがある どうアプローチしたか 難易度を下げてから勝負する このプロジェクトで最も重要だった判断は、「難しい問題を頑張って解く」のではなく、「問題の難易度そのものを下げる」という方針を取ったことです。 具体的には、ユーザー行動ログに依存する周辺システムを、社内でデファクトスタンダードとなっているユーザー行動解析基盤であるTealiumへ先に移行させることで、古いログへの依存を一つずつ断ち切っていきました。 これにより、新システムへの移行時に保証すべきログの属性値(スキーマ)を大幅に削減し、「守るべき範囲」を意図的に狭めることで、テスト工数と不確実性を下げました。 依存先の調査 まず、ログが格納されたS3のバケットポリシーから、アクセスが許可されているアカウントやロールを洗い出しました。中には過去に使われていたと思われるAWSアカウントからの許可や、AWSアカウントレベルでの広いアクセス許可が残っており、具体的にどのシステムからのアクセスなのかがポリシーだけでは判別できないケースもありました。そうした許可については、CloudTrailで実際のアクセス有無を確認しながら整理を進めています。その上で、S3の接続情報をキーにGitHub上のリポジトリを横断検索し、該当するコードを地道に追っていきました。それでも埋まらない部分は、社内のConfluence・Jira・チャットログ・GitHub Discussionsを当たり、マーケットの垣根を越えて担当者に直接確認することで、一つずつ依存先を明らかにしていきました。 最終的に、ログに直接依存しているシステムは20以上にのぼり、さらにBigQueryにも連携されていたため、その先ではアナリストも分析に利用している状況でした。 この調査は、このプロジェクトで最も骨が折れたパートです。 アーキテクチャ図 古いログへの依存を一つずつ断ち切る 依存先が明らかになった後は、そのうち賃貸の物件詳細ページのログに直接関わるシステムについて、Tealium経由のデータに切り替えてもらう調整に入りました。しかし、これが一筋縄ではいきませんでした。レガシーなシステムであるがゆえに、主管部署の担当者自身がシステムの仕様を十分に把握できていないケースが多く、「何のデータをどう使っているのか」を一緒に紐解くところから始める必要がありました。 アナリストに対しては、BigQuery上のデータ切り替えについて告知を行いました。実態としては、アナリスト自身もどのデータを使っているか明確に把握しきれていない状況でしたが、データを外部に販売しているような重要度の高い用途については、個別にしっかりヒアリングを行い、影響がないことを確認しました。 また、依存先の洗い出しを促進するため、プロジェクトの進捗や影響範囲を社内に定期的に周知し、「自分のシステムも該当するかもしれない」と気づいてもらえるよう働きかけました。 実装・テスト・移行での工夫 テストでは、旧システムから出力されるログと新システムから送信されるログを突き合わせて比較する方針を取りました。完全一致しない項目については、後続のシステムで実際に使用されていないことを一つずつ確認しています(今後、使われていない項目は削除していく予定です)。 特に重要だったのは、不動産会社向けレポート機能への影響確認です。集計バッチの出力結果を旧ログ・新ログそれぞれで比較し、差分がないことを検証しました。ただ、テスト環境自体にパフォーマンスの課題やCI/CDの課題があり、動作確認を回すだけでもかなりの労力がかかりました。 移行は段階的ではなく、一括で切り替えました。二重にログを保持し続けるコストや、切り戻し時に古いログで後続システムを再実行する運用の複雑さを考慮し、この方式を選択しています。万が一の失敗に備え、リカバリー方針と関係者への対応フローを事前に策定しておくことで、リスクをコントロールしました。 プロジェクト推進の難しさ このプロジェクトは、技術的な難しさ以上に、推進そのものに大きな負荷がかかるものでした。 自チームでのログ送信処理の移行作業に加え、旧ログに依存する周辺システムについて、Tealiumへのリアーキテクチャのサポートとコードレビューを自ら担いました。各システムの技術スタックも事情も異なる中で、設計方針の提示からレビュー、問題発生時の判断までを一手に引き受ける形です。 さらに、主管部署の担当者がシステムの仕様を把握しきれていないケースでは、仕様の調査や整理から伴走する場面も少なくありませんでした。マーケットや部署の垣根を越えた調整を重ね、関係者全員が同じゴールに向かえる状態を作ることも、このプロジェクトにおける自分の重要な役割でした。 やり遂げて思ったこと:技術負債解消とROI この取り組みをやり遂げた今、「これは本当に事業に必要だったのか?」と自問することがあります。 バックエンドへの負荷が実質2倍という状態は健全ではなく、実際に繁忙期にはDBへの負荷が問題になっていました。解消すべき課題だったのは間違いありません。一方で、技術負債の解消にはそれなりのコストがかかり、その間ユーザーに直接価値を届ける開発に割けるリソースは減ります。そのバランスをどう取るかは、リーダーとして常に問い続けるべきテーマだと感じるようになりました。 この経験を通じて、技術負債解消は「エンジニアが気持ちよく開発するため」だけではなく、事業のROIを踏まえた上で優先度を判断すべきものだという考えに変わりました。今回のケースはDB負荷という差し迫った理由があったからこそ正当化できましたが、常にそうとは限りません。 今後は、技術負債の解消を特別なプロジェクトとして切り出すのではなく、日常の開発の中で自然に改善していける状態を目指したいと考えています。エンジニアとしての本分は、技術力でユーザーに価値を届け、事業の優位性を築くことにあるはずです。プロダクト開発に軸足を置きながら、健全なコードベースを維持していく——そのサイクルを回せるチームでありたいと思っています。 終わりに 本記事では、LIFULL HOME'S 賃貸マーケットにおける技術負債解消の取り組みについて紹介しました。 このプロジェクトの作業は泥臭いものの連続でしたが、それを完遂できたときの達成感は大きく、負債解消へのインパクトも確かなものでした。同時に、「技術的に正しいこと」と「事業として正しいこと」の間で考え続けることの大切さも学びました。 LIFULL では、こうした課題に一緒に向き合い、ともに成長していける仲間を募集しています。興味を持っていただけた方は、ぜひ以下のページもご覧ください。 hrmos.co hrmos.co
こんにちは、LIFULL QAエンジニアの木住野(きしの)です。 普段はQAエンジニアやUXリサーチャーチームのマネジメントを行っています。 2026年3月20日に開催された JaSST'26 Tokyo へ、QAエンジニア3名(星野、鐘、木住野)が参加しました。 本記事では、印象的だったセッションの紹介と、そこから得た学びを自社QAにどう活かすかについて考察します。 今回はビッグサイト開催 参加の目的 今回の参加目的は、生成AIが急速に普及する中でのテスト技術動向の把握と、自社QAプロセスへの還元です。 特に2026年は、AI駆動開発(AIDD)やLLMを活用した開発が本格化しており、QAエンジニアの役割や品質保証の在り方が大きく変わりつつあります。 この変化の波の中で、私たちが何を観測し、どう行動すべきかを学ぶことが今回の最大の狙いでした。 参加の目的 各メンバーが選んだ注目セッション 鐘:AIDD・SDD時代のQA対応 ―QAは何を品質として観測するのか― セッション概要 QAEとしての気付き 実務への適用案 星野:AIと品質保証のこれまでとこれから セッション概要 QAEとしての気付き 実務への適用案 木住野:Beyond Quality Assurance -AIと拓くQAの未来像- セッション概要 QAEとしての気付き 実務への適用案 セッションから見えたチーム内での振り返り 自社とのギャップ:現在の体制と比較した不足点や強み 今後の注力領域 まとめ 各メンバーが選んだ注目セッション 今回のJaSSTでは、AI時代のQAをテーマにした学びあるセッションが盛りだくさんでした! その中から、各メンバーが特に印象的だった1つをチョイスして紹介します。 鐘:AIDD・SDD時代のQA対応 ―QAは何を品質として観測するのか― セッション概要 登壇者:小川 椋徹氏(2WINS)、久保 雅之氏(ポールトゥウィン)、後藤 香織氏(ポールトゥウィン) AIが実装だけでなく設計やテストまで担う時代に、QAエンジニアは何を観測すべきか。このセッションでは、4つの議題を通じてAI時代の品質保証について議論されました。 1. 品質が保証されていることの意味 AIは次に来る単語を予測する性質上、必ず一定の割合で不具合を含むコードを生成します。AIがコードを書き、AIがテストしても、それだけで品質を担保することは困難です。95%の正解率を99%に引き上げるという考え方が重要で、そのためには上流工程の段階からしっかり設計しておく必要があります。 2. AIツールのできること、できないこと AIが日進月歩で進化する中でも、変わらず重要なのはドメイン知識やノウハウをちゃんと残すことです。 AIのできること:コード生成、コード解析など AIのできないこと:非機能要件、設計レベルのセキュリティ欠陥、環境依存の問題、ビジネスロジック 3. 品質のエビデンスの再定義 AIで開発スピードが飛躍的に上がっている今、「なぜこのような実装をしたのか」を追跡できるようにすることが重要です。 大規模・長期間プロジェクトでは仕様書が古くなり、小規模・短期間プロジェクトではエビデンスをスキップしがちです。AI開発が早すぎて仕様書が追いつかない問題を解消するには、 自動でエビデンスを残すしくみ が必要です。 4. QAエンジニアの役割の変化 下流はAIが得意ですが、上流はよく間違えます。QAエンジニアはAIツールを駆使して、コードから逆算した仕様の把握や、仕様書の作成・更新を自動化し、AIが苦手とする上流工程をもっと考える役割が求められます。 QAEとしての気付き AIはビジネスロジックやユーザーの利用シーンを考えにくいため、開発のベースである上流の設計をQAがレビューすることで、根本から欠陥を防ぐことが重要だと感じました。 実務への適用案 小規模開発・個人開発でエビデンススキップによる属人化が起きていますが、 「属AI化」 も起きているのではないでしょうか。AIに要件を伝えた後、AIが実装し、AIがテストし、開発者は何を実装したか詳細まで把握していない状態です。 対策として、開発後に必ずAIでドキュメント化させ、依頼した要件と照らし合わせて確認・更新することが必要だと考えています。 星野:AIと品質保証のこれまでとこれから セッション概要 登壇者:須原 秀敏氏(ベリサーブ)、松木 晋祐氏(ベリサーブ)、山﨑 崇氏(ベリサーブ) 台本なしのスペシャルトークセッションとして、AI品質保証の技術的変遷と今後の展望が語られました。 従来の検証技術の限界 LLMのプロダクトにそのまま適用するのはとても難しいと語られていました。 メタモルフィックテスティング :入力内容を変異させても出力に同じ関係性が維持されているかを検証する手法ですが、出力が多様化しているLLMではルールベースなどのシンプルな評価は難しい。 ニューロンカバレッジ :内部構造の網羅性に着目しテストデータが内部ロジック(ニューロン)を網羅した(発火させた)か評価する手法ですが、これもLLMに対しては巨大すぎるために適用させるのは難しい。 テストの在り方は変わるのか 実はあまり変わらないのかもしれません。日本の製造業で培われたのは 統計的 品質管理です。 かつてバラツキを制御して抜取検査で品質を評価してきたように、LLMを搭載したプロダクトには決定論的な正誤ではなく、確率的な精度で評価をする必要性があるだけです。 先進的な技術のキャッチアップだけでなく、古典として評価されているような技術書に立ち返り基礎となる考え方と技術を学習する必要性を再認識しました。 サービスの自由度を狭める必要性 サービスの使われ方が多様化しないよう、自由度を狭める必要があります。たとえばIRページにチャットbotを設置する場合、ハルシネーションは法的なリスクがあります。サービスが想定外の利用方法をされないように縛りが必要です。 フライホイール型のQAと継続的な監視 LLMを搭載したプロダクトの場合、リリース後にも精度が下がっていないことを継続的に監視する必要があります。テスト環境よりもコンテキストが明らかに広くなり、外部環境の変化によって使われ方や求められる出力も変化します。だして終わりではなく、フィードバックループを構築する技術が必要です。 QAEとしての気付き 仕様の引き算・制限することの重要性を能動的に広め、リスクヘッジが必要 LLMの精度を保ち続けるための監視(メトリクスの設計) 自身が社内に提供するツールや開発プロセスにLLMを活用する場合もこれらを意識しなければ、生産性や成果物の質に影響が出そう 基礎となる考え方は変わらない。品質保証の古典やソフトウェア工学についてあらためて知識と技術を深めることが重要 実務への適用案 「AIに何をさせないか」の意識を持つことが大切です。社内に配布するツールも同様で、意図しない用途での利用により問題のあるハルシネーションを起こす可能性があります。 木住野:Beyond Quality Assurance -AIと拓くQAの未来像- セッション概要 登壇者:池之上 あかり氏(LINEヤフー)、平田 香織氏(LINEヤフーコミュニケーションズ) AI導入におけるQA組織の現状と課題について、コーチングの技術を用いた組織変革の事例が紹介されました。 対策のアプローチ チームのAIに対する価値観(不安や恐ろしさ)を変える 新しい価値観をチームにインストール 余力による改善活動が増えたなどの効果が見え始めた QAEとしての気付き 私自身はAIを活用することを推進することに躊躇はなく、拡張するツールである認識でしたが、一方でこの発表のようにAIに脅威や不安を感じている人もいるということがわかりました。 組織横断的な改善も多いので、こういった考え方を知れたことが大きかったです。価値観・信念の摩擦といった言語化しづらい障壁についても知れたのが良かったです。 実務への適用案 AIに限らず新しい技術・思想、あらゆる事象は人によって受け入れること自体に障壁がある可能性もあるため、それを考慮してQAチーム、ひいてはLIFULLの開発組織によい変化を作っていきたいと考えています。 セッションから見えたチーム内での振り返り 自社とのギャップ:現在の体制と比較した不足点や強み 不足点・課題 以下の点については改善の余地があると感じました: エビデンス管理の自動化 :AI開発のスピードに仕様書が追いつかない問題に対して、自動でエビデンスを残すしくみが不足しています。 上流工程へのシフト :QAエンジニアがより上流工程に関与し、設計レビューを強化する体制が必要です。 組織的な心理的障壁への配慮 :AIに対する不安や恐れを持つメンバーへの配慮と、組織全体での価値観の共有が必要です。 リリース後の継続的監視 :LLMを活用したプロダクトにおいて、リリース後の精度監視とフィードバックループの構築が課題です。 今後の注力領域 各メンバーが挙げた「明日から変えたいこと」 AI開発後のドキュメント (鐘):AIで開発した後、必ずドキュメント化し、要件と照らし合わせて確認する習慣をつける AIに何をさせないかの意識 (星野):社内ツールでも、意図しない用途で利用されることを防ぐ設計を意識する 新技術受け入れの障壁への配慮 (木住野):新しい技術や思想を導入する際、人によって受け入れに障壁があることを考慮する まとめ JaSST '26 Tokyoを通じて、AI時代におけるQAエンジニアの役割が大きく変わりつつあることを実感しました。しかし同時に、テストの本質は変わらず、品質保証の基本的な考え方が今後も重要であることを確認できました。 本記事で紹介したセッションをベースにすると以下のような視点で学びがありました。 鐘 : 技術的視点 から、上流工程の重要性とエビデンス管理の課題を指摘 星野 : 検証技術の変遷と本質 から、テストの統計的性質とフィードバックループの必要性を強調 木住野 : 組織・人的視点 から、AIに対する心理的障壁とコーチング手法の重要性を学んだ 私たちが得た最大の気付きは、「AIの進化に合わせてQAも進化しなければならない」という危機感と、「基本を押さえていれば対応できる」という自信の両立でした。 JaSSTで得た外部知見を、自社の品質向上につなげていきます。 最後に、LIFULL では一緒に働く仲間を募集しています。 よろしければこちらのページもご覧ください! hrmos.co hrmos.co
LIFULL HOME'S不動産査定 ・ ホームズマンション売却 の開発をしている、ジョン ヨンソクです。 今、私たちのエンジニアリングの世界は大きな転換期にあります。生成AIの登場によって、開発のスピード感や求められるスキルセットが劇的に変化しているからです。 そんな中、私はチーム内の「生成AI活用」を促進するための活動に取り組みました。今回は一人のエンジニアとして、チームと向き合いながら、どのようにメンバーとAIの距離を縮めていったのか、その試行錯誤のプロセスを綴ります。 一方的な「レクチャー」を避けた理由 目標は「使いこなすこと」ではなく「親密度」 「親しくなる」ための設計 前半:「まず触れる」ための基礎固め 後半:「実務で使う」ための実践編 アンケートから「まだ使えていない領域」を見つける 「親密度」はどう変わったか 「とりあえず聞いてみる」が当たり前になるまで 次の「当たり前」に向けて 一方的な「レクチャー」を避けた理由 活動の起点となったのは、事業目標である利益(KGI)の達成です。その先行指標として「売却開発サイクルタイムの短縮」を掲げ、目標達成のための最重要成功要因(CSF)として生成AIの活用を定義しました。このCSFを具体化し、最終的なKGI達成へとつなげるための指標が、開発工程における生成AIの活用率(KPI)です。目指す姿は、全メンバーが一定水準以上でAIを活用し、開発工程全体でAIが担う割合を大幅に引き上げることです。 活動を開始した当初、チーム内には「すでに使いこなしているメンバー」と「まったく触れていないメンバー」の間に大きな差がありました。どのレベルのメンバーにとっても意味のある時間にしたい。そう考えたとき、「AIの使い方」や「サービスの比較」を一方的に教えるような、いわゆる「講習」形式は避けるべきだと感じました。 単なる情報の提供は、ともすれば受け身の姿勢を生んでしまいます。インターネットにはすばらしい情報が溢れていますが、同じ業務ドメインを持つメンバーどうしが対話を通じて生み出す活用例には、それを超える実践力があります。私がやるべきことは情報の横流しではなく、こうした知見を共有し合う 「文化」の土壌を整えること だったのです。 目標は「使いこなすこと」ではなく「親密度」 文化を作るために、まず定義したのが「AIと親しくなる」という状態です。KPIの数字を追う前に、まずはメンバー全員が 「日常的にAIに触れている」状態を作ること が最優先であると判断しました。 そこで、その状態を測るスモールステップとして設定したのが「アクティブ率」です。 「1ヵ月のうち、何日AIにアクセスしたか」を営業日数で割り、その比率が40%以上になることを第一の目標に掲げました(社内で利用しているAIツールの管理機能から、メンバーごとの利用日数を確認できます)。 「最初からうまく活用すること」よりも「毎日少しでも相談してみる」こと。この「親密度」を重視した設計が、結果としてメンバーの心理的ハードルを下げることにつながりました。 「親しくなる」ための設計 活動期間から逆算し、隔週を基本におよそ10回の構成としました(軽い共有は毎週開催することも)。この限られた機会の中で何をどう届けるか、活動の企画を一緒に担ってくれたメンバーと設計を進めました。 まず、活動全体を大きく2つに分けました。前半は基礎的なインプット中心、後半は実務活用中心です。最終的にはメンバー自身が活用事例を持ち寄り、互いに共有し合う場にしたいと考えていました。 前半:「まず触れる」ための基礎固め 社内で主に使用しているAIツールの導入と基本操作から始め、MCPを活用して社内の実務ツール(Confluence、Jira、データベースなど)と連携させる方法を扱いました。最後に、AI利用時の注意点やセキュリティについて共有しました。また、ほか部署でAIを積極的に活用しているメンバーをゲストに招き、実体験を語ってもらう回も設けました。 ただし、基礎的なインプットはどうしても一方的な講義になりがちです。そこで各回は、発表を10〜30分に抑え、残り30〜50分は実習・Q&A・ディスカッションの時間としました。実習で扱う内容は事前に共有し、必要な環境構築を済ませておいてもらうことで、限られた時間を「一緒に考え、試す」ことへ集中できるようにしました。 実習では、MCPを使って社内の情報にアクセスする方法など、 すぐに業務で役立つ内容を中心に据えました 。そして、この実習を通じて生まれた疑問や気付きを、そのままディスカッションにつなげていきました。同じ業務ドメインを持つメンバーどうしが議論することで、「自分ならこう使う」「この場面でも使えそう」といった具体的なイメージが互いに鮮明になっていく。この対話の時間こそが、単なるインプットを「自分ごと」に変える鍵だったと感じています。 後半:「実務で使う」ための実践編 前半がインプットと実習を織り交ぜた構成だったのに対し、後半は実際の活用にフォーカスしました。AIを活用したコードレビューの協業プロセスや、テストケース作成の効率化など、日々の開発業務に直結するテーマを取り上げました。 まずは私自身の使い方を共有するところから始めました。特にコードレビューでは、「PRをまるごとAIに渡してレビューして」と大きく投げるのではなく、作業を小さな単位に分解し、各ステップで人間が確認を挟む協業構造を提案しました。AIは確率ベースで動作するため、一度に任せるステップが長くなるほど精度は落ちていきます。短く区切って人間が介入するポイントを増やす——この「分解」の意識が、AI活用の精度を上げる鍵になります。「どう使えばよいか、少し感覚がつかめた」という声が聞こえてきたのは、この回でした。 そして当初の狙い通り、後半に進むにつれて発表者が私だけではなくなっていきました。たとえば、ある回で共有したAIツールのプランニング機能を、あるメンバーが日常的に愛用するようになりました。また、エージェントのカスタマイズ方法を共有したことをきっかけに、自分のローカル環境のエージェント設定を実際に改善するメンバーも現れました。知見を共有し合う文化の輪郭が、少しずつ見え始めたことが、この活動における一番の収穫だったととらえています。 アンケートから「まだ使えていない領域」を見つける 活動の方向性を決めるうえで活用したのが、社内で定期的に実施しているアンケートです。アンケートでは「実際に担当している業務領域」と「その中でAIを活用している領域」の2軸で回答を集めています。この結果を突き合わせることで、担当業務のうちAIを活用できている割合と、まだ活用方法のわからない領域が明確になります。活動ではこの分析を活用し、活用が進んでいない領域を優先的に共有会のテーマに取り上げていきました。たとえば、テスト領域でのAI活用が進んでいないと分かったため、テストにおけるAI活用の進め方をテーマにした回を設けました。 固定的なカリキュラムではなく、チームの状況に合わせて柔軟に内容を調整していく。この「活用シーンの具体化」と「共有の場」の両輪が、チームの変化につながりました。 「親密度」はどう変わったか 直近の計測データである2026年2月時点の結果をもとに振り返ります。 まず、アクティブ率の変化です。 Before(2025年10月) After(2026年2月) 変化 アクティブ率 40%以上 約60% 100% ↑約40% アクティブ率 100% 約40% 約75% ↑約35% アクティブ率 0% 約25% 0% ↓25% そして注目すべきは、アクティブ率だけでなく、AIとのやりとりの深さを示す総活動量(トークン使用量)にも変化が現れたことです。 たとえば、あるメンバーは活動開始前からアクティブ率は高かったものの、実際のトークン使用量はごくわずかでした。AIを起動はしていても、何を聞けばよいかわからず、深い活用にはいたっていなかったのです。それが活動を経て、トークン使用量は10倍以上に増加しました。また、アクティブ率0%だったメンバーも、起動頻度の増加に伴ってトークン使用量が着実に伸びていきました。 この変化は、「まずAIを開く習慣」が先行指標となり、「活用の深さ」が自然と後からついてくるという構造を示しています。 頻度を追うことで、結果として質も伴ってくる 。 「とりあえず聞いてみる」が当たり前になるまで 数字の変化の裏側には、メンバー一人一人の意識の変化がありました。 「何を聞けばよいかわからない」と戸惑っていたメンバーも、共有会での具体的な活用例を自分事としてとらえることで、徐々に「とりあえずAIに聞いてみる」という動きが習慣化していきました。最初は受け身だったメンバーが、やがて「こういう場面でも使えそう」と自ら提案するようになっていく。 「隣のメンバーがこう使っているなら、自分も試してみよう」 そんな小さな刺激の連鎖が、チーム全体のエンジニアリングを底上げしていく。 次の「当たり前」に向けて 約5ヵ月にわたる活動を振り返ると、エンジニアチームのAI活用に対する解像度は明らかに上がりました。 「何を聞けばよいかわからない」から「自分なりの使い方を持っている」へ 。その変化は、数字にも日々のやりとりにも表れていました。 一方で、次の課題も見えています。開発者の業務効率化だけでは、事業目標への貢献には限界があります。エンジニアがAIで開発を速くしても、何を作るかの判断はエンジニアだけでは完結しません。企画メンバーが持つドメイン知識の深さは、エンジニアには代替できません。その知識とAIを掛け合わせるためには、企画メンバー自身がAIという道具に親しくなる必要があります。 今回の活動で得たアプローチを、次は企画メンバーにも届けたい。それぞれが自分なりの活用法を持ったとき、チームの枠を超えた本当の変化が始まると信じています。 最後に、LIFULL では一緒に働く仲間を募集しています。よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
生成AI初心者エンジニアが3ヵ月でAI駆動開発を習得するまで こんにちは。LIFULL HOME'S の CRMで開発を担当しているソンです。 2025年4月に復職してから、業務では生成AIをほぼ使ったことがない状態でしたが、社内ではAI活用や導入が活発に進み始めていました。エンジニアチーム内ではAI活用の開発手法を学ぶ社内研修が行われており、自分も参加して実際にAIを活用した開発を経験できていました。そしてAI活用開発プロジェクトの担当になったとき、本格的に生成AIを利用した開発を始めようとしていました。 この記事では、生成AI初心者だった私が試行錯誤しながら、本格的にAI駆動開発に取り組んだ直近3ヵ月(2025年12月〜2026年2月)の過程と、そこから得た学びを共有します。最初の1ヵ月は失敗続きでしたが、社内のサポート体制やナレッジ共有を活かすことで、月あたりのGitHub Contributionが約3.5倍に増加しました。担当プロジェクトではCTR・CTORの改善成果も得られました。同じように「AIを使ってみたいけど、どう始めればよいかわからない」という方の参考になれば幸いです。 生成AI初心者エンジニアが3ヵ月でAI駆動開発を習得するまで プロジェクト概要 開発したもの 最初の壁:「適当な」プロンプトの代償 期待と現実のギャップ 具体的な失敗例 失敗1:複雑すぎるコード 失敗2:AIも間違える——参照先の確認不足 転機:チームとサポートの力 職種を超えたAI活用の文化 全社共有の設定とツールの活用 keelaiチームの手厚いサポート 成果:数字で見る変化 アウトプット量の変化 コード品質の向上 学んだこと:3ヵ月の試行錯誤から 1. AIをどう使うかを考える 2. 設定と使い方を学ぶことが成功への近道 3. 生成AIは日々成長している。恐れず耳を傾けよう 4. チームとサポートの重要性 今後の課題と展望 AIへの依存度が高まる怖さ さらなる活用の可能性 終わりに プロジェクト概要 開発したもの シナリオメールという、問い合わせ(反響)を行ったユーザーに対して配信されるレコメンド物件メールがあります。このメールで推薦される物件に対して「なぜその物件がお勧めなのか」を生成AIで自動説明し、ユーザーの物件理解促進とCVR(コンバージョン率)向上を図るプロジェクトでした。 レコメンド物件は毎回ユーザーごとに変わるため、手動やロジックだけでは自然な推薦文を作ることが難しいという課題がありました。そこで、生成AIを活用して物件の特徴を自然言語で説明する方法を採用しました。 結果として、既存パターンと比較してCTR(クリック率)とCTOR(クリック・トゥ・オープン率)がともに改善しました。 最初の壁:「適当な」プロンプトの代償 期待と現実のギャップ 最初のプロンプトで作られたコードを見た感覚ではうまくやれば2日もかからず終わりそうだと思っていました。 開発を行ったリポジトリのアーキテクチャにも沿っているし、APIで必要な基本的な構造やチェック、テストコードもできていました。 しかし、詳細をチェックしていくと問題だらけでした。 具体的な失敗例 失敗1:複雑すぎるコード 生成されたコードは、一見すると「ちゃんと動きそう」に見えました。しかし、実際には以下のような問題がありました。 エラーハンドリングが過剰で、本来キャッチすべきでないエラーまで握りつぶしていた 不要な抽象化レイヤが追加され、コードが読みにくくなっていた パフォーマンスを考慮していない実装(毎回ファイルを開閉するなど) 結局、生成されたコードの一部では手作業で修正したり、AIに再度修正を依頼したりの繰り返しでした。「最初から自分で書いた方が早かったのでは?」と感じたときもありました。 失敗2:AIも間違える——参照先の確認不足 OpenAIのPrompt Caching機能を使った設計と実装を、AIコーディングアシスタント(Claude)に依頼したときのことです。OpenAIの公式ドキュメントのURLも参考資料として渡していました。 しかし、実際にはURLの読み込みに失敗しており、AIはOpenAIではなく自分自身(Claude)のPrompt Cachingの仕様に基づいたコードを生成していました。両者ではPrompt Cachingのしくみが異なるため、そのまま使えば動かないコードになっていたのです。PRから作成されるEphemeral Environmentでテストしたところ、改修内容が反映されていないことに気付き、もう一度ドキュメントを確認して原因が判明しました。 AIが「もっともらしく」回答しているときほど要注意です。前提となる情報源を正しく取得できているか、出力結果が意図した仕様に基づいているかを常に確認する必要があります。 それでも使い続けた理由は、これはAIの実力の問題というよりは使い方の問題であることがわかったからです。 転機:チームとサポートの力 職種を超えたAI活用の文化 社内のSlackでもさまざまなナレッジが共有されていますが、月1回の定例で行っているエンジニア組織の月次定例会でも生成AIを活用したナレッジ共有とワークも行っています。 そこで学んだ開発手法や共有されたプロンプトが大きな力になりました。 また、エンジニアチームだけでなく、CRMチームでは非エンジニアメンバーの間でも生成AIの導入と活用が活発に行われています。普段の会話の中でも自然にナレッジ共有ができており、職種を超えたAI活用の文化が根付いています。 全社共有の設定とツールの活用 社内では、MCP(Model Context Protocol)を使ったPrompt-serverが提供されており、開発関連のプロンプトが共有されていました。MCPとは、AIツールが社内のコードベースや開発ルールを参照できるようにするしくみです。 さらに、全社で生成AIを活用するための設定が共有されています。これにより、個人でゼロから環境を整える必要がなく、すぐに生成AIを活用できる基盤が整っていました。 周りから学んだナレッジを一つ一つ適用していくことで、少ない手順で目標の成果物へ近付けるようになりました。そしてナレッジを学んで適用していくのがどんどん楽しくなりました。 keelaiチームの手厚いサポート このプロジェクトで最も助けられたのが、社内のAI活用推進チームであるkeelaiチームのサポートでした。 開発中のPRをそっと見に来てくれて、性能改善に役立つコメントやリンクを教えてくれる Slackで企画メンバーと相談していると、まだメンションも投げていないのに現れて、理由や解決方法を教えてくれる まるでAIのような対応速度と的確さで、初めて生成AIを使う私にとって、これ以上ない心強いサポートでした。 成果:数字で見る変化 アウトプット量の変化 GitHub Contributionを見ると、変化は明らかでした。 2025年(4月〜12月) : 229 contributions 2026年(1月〜2月) : 186 contributions 2025年は9ヵ月間で229 contributions、月平均約25件。2026年は約2ヵ月で186 contributions、月平均約90件。contributionの数がそのまま開発速度を表すわけではありませんが、アウトプット量の変化を示す一つの指標として、月あたりの生産量で比較すると約3.5倍のペースになっています。 コード品質の向上 アウトプットの量の変化だけでなく、コードの質も向上しました。 コメントの充実 : AIでコードを生成することで、抜けがちなコメントが詳細に作成されるようになった 設計書の詳細化 : 仕様駆動開発(要件定義→設計→実装の順にAIと対話しながら段階的に進める手法)を取り入れ、要件と設計を明確にしてから開発するようになった。手作業では時間がかかるフロー図やシステム図の作成が簡単になり、記載漏れが減った テストケースの網羅性 : エッジケースを含めた包括的なテストケースを生成できるようになった 学んだこと:3ヵ月の試行錯誤から 1. AIをどう使うかを考える 最初の失敗から学んだ最も重要なことは、AIは 優秀 だがあくまでも アシスタント であることです。 AIは、与えられた情報の範囲内で最善の出力をしようとします。しかし、情報が不足していたり、参照先が間違っていれば、不完全な出力しか得られません。 大切なのは「AIをどう使えば効率的か」を常に考えることです。 2. 設定と使い方を学ぶことが成功への近道 プロンプトの書き方も大切ですが、それ以上に重要なのは、AIを使うための環境設定と基本的な使い方を理解することです。 社内で共有されているAIツールの共通設定を活用すれば、個人で試行錯誤する時間を大幅に短縮できます。MCPやPrompt-serverといったツールの使い方を学んだことで、AIの能力を最大限引き出せるようになりました。 良い設定と使い方の条件は、以下のようなものです。 再現性 : 誰が使っても同じ結果が得られること 共有可能 : チーム全体で活用できること 拡張可能 : 新しいユースケースに対応できること そして、設定や使い方自体もチームでレビューし、改善していくべきものです。 3. 生成AIは日々成長している。恐れず耳を傾けよう 生成AIの技術は日々進化しています。「以前試してダメだったから」と諦めるのではなく、常に最新の情報にアンテナを張り、新しい可能性に耳を傾けることが大切です。 私の場合、最初の1ヵ月は失敗続きでしたが、周りの情報やサポートに耳を傾けて、積極的に試してみることで、3ヵ月後には開発速度が約3.5倍になりました。 AIの進化速度は想像以上に速く、数ヵ月前には不可能だったことが今では当たり前にできるようになっています。恐れずに、まずは試してみることが重要です。 4. チームとサポートの重要性 一人でAIと格闘していたら、おそらく挫折していたと思います。 チームでプロンプトを共有し、レビューし合う文化 Prompt-serverのような、知見を蓄積・共有するしくみ keelaiチームのような、専門家のサポート これらがあったからこそ、短期間でAI駆動開発を習得できました。 会社でも積極的にAI活用を支援しているので、最近では非エンジニアの間でもAIを使うときのコツがよく共有されています。この流れは、今後さらに加速していくでしょう。 今後の課題と展望 AIへの依存度が高まる怖さ 最近、少し怖いと感じることがあります。 直接コードを書くことや、繰り返し行われる作業を見ると、ついついプロンプトを作ってAIに任せたくなるのです。 これは効率的である一方、基礎的なコーディング力が落ちるリスクもあります。AIに頼りすぎず、自分で考える時間も大切にしたいと思っています。 さらなる活用の可能性 今回のプロジェクトを通じて、AIの可能性を実感しました。 今後は以下のような活用も試していきたいと考えています。 設計段階でのAI活用の深化 : 仕様駆動開発(要件定義→設計→実装を段階的にAIと進める手法)を始めているが、要件定義の精度をさらに上げたい チーム横断でのプロンプト標準化 : 個人の知見をチーム全体の資産にするしくみづくり AIの出力品質の定量評価 : 生成コードの品質を客観的に測定する基準の確立 終わりに 生成AI初心者だった私が、3ヵ月のAI駆動開発で学んだことです。 「AIをどう使うか」を常に考える 設定と使い方を学ぶことが成功への近道 生成AIは日々成長している。恐れず耳を傾ける チームとサポートの力を活かす もしあなたが「AIを使ってみたいけど、どう始めればよいかわからない」と思っているなら、まずは小さく始めてみてください。 最初はうまくいかないかもしれません。私も最初は失敗続きでした。しかし、諦めずに試行錯誤を続ければ、必ず成果は出ます。 そして、周りの情報やサポートに耳を傾けてください。一人で悩むより、チームで共有し、専門家に相談する方が、はるかに早く成長できます。 AIを使った開発は、もはや「特別なスキル」ではなく、「当たり前のスキル」になりつつあります。この波に乗り遅れないよう、今日から一歩を踏み出してみませんか? 最後に、ともに開発フロー改善に取り組んでくださる仲間を募集しています。 hrmos.co hrmos.co
KEELチーム の相原です。 前回のエントリは「比較的安全にMCPサーバを動かす」でした。 www.lifull.blog 今回は信頼できる可観測性基盤を提供するべく、KubernetesクラスタにおけるPull型アプローチ由来のログ・メトリクス欠損と色々向き合った話を書きます。 Pull型アプローチとそのトレードオフ kubeletにログファイルを削除される前にFluentdに読ませたい eBPFでunlinkat(2)を遅延実行させる PrometheusがCounterのインクリメントをScrapeするまでPodを待機させたい SIGTERMを受け取ったら次回のScrapeまで待機するプロキシを挟む まとめ Pull型アプローチとそのトレードオフ まずPull型アプローチについて軽く触れておきます。 Pull型アプローチとは、ログやメトリクスをその持ち主がどこかに公開しておいて、FluentdやPrometheusなどの他の誰かに取得しに来てもらうアプローチを指します。 対となるPush型アプローチは逆に持ち主がログやメトリクスを直接対象に送りつけるというものです。 Push型アプローチはサーバ側で流量のコントロールが難しかったり、Rate Limit時などのリトライの責任がクライアント側に要求される一方で、Pull型アプローチはその点が単純という関係性にあります。 Kubernetesクラスタで素直にログとメトリクスを収集しようと思うと、大体Pull型のアプローチを採用することが多いのではないかと思います。 コンテナランタイムはコンテナの標準出力をファイルとして出力しているのでそれをFluentdやPromtailで収集し、メトリクスはPrometheus Exporterで公開してPrometheusがScrapeするといった感じです。 ここで考えたいリスクが、「 Podが削除される時までに本当にそのログ・メトリクスは収集されているのか 」というものです。 Kubernetes上でコンテナランタイムを司るkubeletは、Podの削除時にログのファイルを削除します。 Podが削除されれば当然Scrapeするためのエンドポイントも無効になるためメトリクスも収集できません。 削除直前に出力されたログやインクリメントされた Counter はどうなるのでしょうか。 恐らくそれらは欠損している可能性が高いです。 Fluentdは比較的すぐにログを読みますがそれでも読み込みが間に合わず欠損することはありますし、PrometheusのScrapeの間隔は一般に短くとも秒単位なので望みは薄いです。 kubeletにログファイルを削除される前にFluentdに読ませたい まずはログの欠損から考えていきましょう。 最初に思いつく対処はkubeletがログを削除するまでに遅延を入れたり、削除を無効化にするといったことだと思います。 それはこの辺のIssuesで議論されていますが、今のところこれといった方法はありません。(Grafana AlloyとかはKubernetes API経由でのログ取得にも対応していますが、こちらの削除タイミングも同様のはずです) github.com github.com かといって全てのPodにログ転送用のサイドカーをデプロイして送信というのも辛いのでどうにかプラットフォーム側で対処したいところです。 こんな時、eBPFはいつでも私達の銀の弾丸になってくれます。 (eBPFとは、という話は以前に書いたのでこちらをご覧ください) www.lifull.blog eBPFでunlinkat(2)を遅延実行させる アプローチとしては、eBPFでkubeletが発行するファイル削除のunlinkat(2)をhookしたら bpf_override_return でファイルを削除することなく終了コードを偽装して返し、裏でFluentdが対象のファイルを読み切ったことを確認出来たら実際の削除を行うというものです。 Fluentdは *.pos ファイルで読み込んだファイルのバイト数を記録しているため、これを見ればファイルを読み切ったことを確認できます。 まずはこんな感じにunlinkat(2)をhookしましょう。 bpf_override_return は kprobeの一部の関数 からしか利用できないことに注意してください。 // /sys/kernel/debug/tracing/events/syscalls/sys_enter_unlinkat/format SEC ( "tracepoint/syscalls/sys_enter_unlinkat" ) int sys_enter_unlinkat ( struct trace_event_raw_sys_enter *ctx) { u64 __pid_tgid = bpf_get_current_pid_tgid (); gid_t tgid = __pid_tgid >> 32 ; pid_t pid = __pid_tgid; struct task_struct *task = ( struct task_struct *) bpf_get_current_task (); u32 ppid = BPF_CORE_READ (task, real_parent, tgid); if (tool_config.this == tgid || tool_config.this == ppid) { return 0 ; } const char *pathname = ( const char *)ctx->args[ 1 ]; int flag = ( int )ctx->args[ 2 ]; // AT_REMOVEDIR // https://elixir.bootlin.com/linux/v6.10.6/source/include/uapi/linux/fcntl.h#L104 if (flag & 0x200 ) { return 0 ; } struct arg arg = { .pathname = pathname, }; bpf_map_update_elem (&args, &pid, &arg, BPF_ANY); return 0 ; } SEC ( "kprobe/" SYS_PREFIX "sys_unlinkat" ) int BPF_KPROBE (sys_unlinkat) { u64 __pid_tgid = bpf_get_current_pid_tgid (); gid_t tgid = __pid_tgid >> 32 ; pid_t pid = __pid_tgid; struct arg *argp = bpf_map_lookup_elem (&args, &pid); if (!argp) { return 0 ; } int zero = 0 ; struct event *eventp = bpf_map_lookup_elem (&unlinkat_heap, &zero); if (!eventp) { goto end; } eventp->tgid = tgid; eventp->pid = pid; eventp->uid = bpf_get_current_uid_gid (); eventp->pathname[ 0 ] = '\0' ; if ( bpf_probe_read_user (eventp->pathname, sizeof (eventp->pathname), argp->pathname) < 0 ) { goto end; } u8 directory[DIRECTORY_MAX]; if ( bpf_probe_read_kernel (directory, sizeof (directory), tool_config.directory) < 0 ) { goto end; } if (! filter_directory (directory, eventp->pathname)) { goto end; } bpf_override_return (ctx, 0 ); bpf_perf_event_output (ctx, &events, BPF_F_CURRENT_CPU, eventp, sizeof (*eventp)); end : bpf_map_delete_elem (&args, &pid); return 0 ; } bpf_override_return(ctx, 0); によって即座にkubeletに返るので、これでファイルの削除処理をスキップすることができます。 unlinkat_heap は PERCPU_ARRAY にしているのでnull byteを区切り文字にしています。 Kubernetesのノード上で実行することになり余計なunlinkat(2)も流れてくるため、 filter_directory でcontainerdのログディレクトリ以外のイベントは無視しなければなりません。 if (tool_config.this == tgid || tool_config.this == ppid) は、ファイル削除を遅延実行する関係上unlinkat(2)を自身も実行するため、無限ループ防止のために hostPID: true における自身のpidを this として受け取ってスキップしています。 あとは std::ffi::CStr::from_bytes_until_nul でユーザ空間から pathname を取得して、 *.pos ファイルと突合しながらFluentdが読み切るまで待機してファイルを削除するだけです。 そこそこ流量は多くなるので、mtimeを見て適当に *.pos ファイルはキャッシュしておきます。 while let Some (pathname) = unlink_rx. recv ().await { let current_mtime = std :: fs :: metadata ( & args.pos_file) . and_then ( | m | m. modified ()) . unwrap_or ( std :: time :: SystemTime :: UNIX_EPOCH); let needs_refresh = pos_cache. read ().await.mtime != current_mtime; if needs_refresh { let new_pos = parse_pos_file ( & args.pos_file); let mut cache = pos_cache. write ().await; cache.mtime = current_mtime; cache.entries = new_pos; } if let Some (offset) = pos_cache . read () .await .entries . get ( & pathname) . map ( | (offset, _) | * offset) { let path = std :: path :: Path :: new ( & pathname); if let Ok (metadata) = path. metadata () && metadata. len () != offset { let unlink_tx = unlink_tx. clone (); tokio :: spawn (async move { tokio :: time :: sleep ( std :: time :: Duration :: from_secs ( args.delayed_seconds, )) .await; if let Err (e) = unlink_tx. send (pathname. clone ()) { eprintln! ( "Failed to re-queue {}: {}" , pathname, e); } }); continue ; } } let result = std :: fs :: remove_file ( & pathname). or_else ( | e | { if e. kind () == std :: io :: ErrorKind :: IsADirectory { std :: fs :: remove_dir ( & pathname) } else { Err (e) } }); if let Err (e) = result { if e. kind () == std :: io :: ErrorKind :: DirectoryNotEmpty { if let Ok (entries) = std :: fs :: read_dir ( & pathname) { for entry in entries. flatten () { let entry_path = entry. path (). to_string_lossy (). to_string (); if let Err (e) = unlink_tx. send (entry_path. clone ()) { eprintln! ( "Failed to queue {}: {}" , entry_path, e); } } } let unlink_tx = unlink_tx. clone (); tokio :: spawn (async move { tokio :: time :: sleep ( std :: time :: Duration :: from_secs ( args.delayed_seconds, )) .await; if let Err (e) = unlink_tx. send (pathname. clone ()) { eprintln! ( "Failed to re-queue {}: {}" , pathname, e); } }); } else { eprintln! ( "Failed to remove {}: {}" , pathname, e); } } } kubeletが実行するGoの os.RemoveAll はファイルとディレクトリを区別せずにとりあえずunlinkat(2)してくるので、ユーザ空間側では中身を削除しながらディレクトリが空になるまで待機するようにしています。 本来は EISDIR を受け取ってからAT_REMOVEDIR付きのunlinkat(2)にフォールバックするんだと思いますが、今回はbpf_override_returnでEISDIRを握り潰してしまっているので、 os.RemoveAll 前提の気持ち悪さはありつつもこちらで削除まで責任を持ちます。 (ファイルのみが渡ってくる vfs_unlink を使えるといいんですが、 ALLOW_ERROR_INJECTION されておらずこちらは bpf_override_return が使えません) また一つだけ注意点があって、containerdは /var/log/containers 以下にログファイルを作成しますが、実際にはこれは /var/log/pods へのシンボリックリンクとなっているため、unlinkat(2)が呼ばれる pathname とFluentdの *.pos ファイルが指すファイルが異なる可能性があります。 私はFluentd側を修正せず *.pos ファイルを読む時についでにシンボリックリンクも解決してしまいました。 この辺もあって *.pos ファイルはキャッシュしています。 fn parse_pos_file (path: & std :: path :: Path) -> std :: collections :: HashMap < String , ( u64 , u64 ) > { let mut pos = std :: collections :: HashMap :: new (); if let Ok (file) = std :: fs :: read_to_string (path) { for line in file. lines () { let mut parts = line. split_whitespace (); if let ( Some (path), Some (offset), Some (inode)) = (parts. next (), parts. next (), parts. next ()) { let resolved_path = std :: fs :: canonicalize (path) . map ( | p | p. to_string_lossy (). to_string ()) . unwrap_or_else ( | _ | path. to_string ()); pos. insert ( resolved_path, ( u64 :: from_str_radix (offset, 16 ). unwrap_or_default (), u64 :: from_str_radix (inode, 16 ). unwrap_or_default (), ), ); } } } pos } これで晴れてkubeletの実行するunlinkat(2)が握りつぶされ、ユーザ空間で安全にFluentdのin_tailを待ってから遅延削除されるようになりました。 同じようなアプローチはPromtailなどでも有効なはずです。 PrometheusがCounterのインクリメントをScrapeするまでPodを待機させたい 次はメトリクスの欠損です。 Gauge(UpDownCounterの実装がGaugeなこともありますが、用途としてのGauge)などのMetric typeは割とどうでもいいんですが、Counterなどは意外と重要なケースもあってインクリメントが欠損してしまうと困ることがあります。 LIFULLでは大きめのKubernetesクラスタをマルチテナントで運用しているということもあり、PrometheusがScrapeする間隔は30秒程度が限界で、Podが削除されるまでの30秒間のインクリメントが失われてしまうという問題がありました。 もっと短い間隔で運用できるのであれば、Kubernetes 1.29から利用できるようになった KEP-3960: Introducing Sleep Action for PreStop Hook で雑にsleepしてもいいですが、問答無用で30秒も待ってしまうとPodのロールアウトが遅くなってしまうためそうもいきません。 なるべくロールアウトに影響を与えないよう、きっちりScrapeされるまでを待てると理想です。 SIGTERMを受け取ったら次回のScrapeまで待機するプロキシを挟む 素直にはScrapeされたことを検知できないと思うので、間にプロキシを挟ことにしましょう。 アイデアはシンプルで、以下のようなPrometheusとPrometheus Exporterの間に挟んでScrape時刻を記録するプロキシを作ります。 Prometheus ExporterはPod削除時に送られてくるSIGTERMでそのままGraceful Shutdownされてしまうので、終了直前のメトリクスを cachedMetrics に入れておいてSingleHostReverseProxyのErrorHandlerでPrometheus Exporterがシャットダウンして疎通しなくなったらそれを返すようにしています。 type CachedResponse struct { Body [] byte ContentType string } var ( lastScrape atomic.Value terminating atomic.Bool scrapeChan chan struct {} cachedMetrics atomic.Pointer[CachedResponse] ) targetURL, err := url.Parse(a.TargetURL) if err != nil { return xerrors.Errorf( "failed to parse target URL: %w" , err) } proxy := httputil.NewSingleHostReverseProxy(targetURL) proxy.ErrorHandler = func (w http.ResponseWriter, r *http.Request, err error ) { if cached := cachedMetrics.Load(); cached != nil { w.Header().Set( "Content-Type" , cached.ContentType) w.WriteHeader(http.StatusOK) _, _ = w.Write(cached.Body) return } http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable) } server := &http.Server{ Handler: http.HandlerFunc( func (w http.ResponseWriter, r *http.Request) { lastScrape.Store(time.Now()) if terminating.Load() { select { case scrapeChan <- struct {}{}: default : } } proxy.ServeHTTP(w, r) }), } そのためにこのプロキシはSIGTERMを受け取った時にPrometheus Exporterから最新のメトリクスを取得してからキャッシュし、 scrapeChan で待ち受けて次回のScrapeまで待機します。 SIGTERMの送信とEndpoint ControllerがEndpointを削除する処理は同時に行われるということは広く知られていて、LIFULLではこれへの対処のために全てのPodは終了時に数秒sleepするようにしています。 kubernetes.io 最新のメトリクスをSIGTERM時に取得する処理は、この設定とGraceful Shutdownの実装に依存している部分があることには注意したいです。 signal.Notify(quit, syscall.SIGTERM) <-quit ctx, cancel := context.WithTimeout(context.Background(), a.TerminationGracePeriod) defer cancel() t, ok := lastScrape.Load().(time.Time) if ok && !t.IsZero() { timeSinceLastScrape := time.Since(t) if timeSinceLastScrape > a.ScrapeWaitThreshold { if request, err := http.NewRequestWithContext(ctx, http.MethodGet, a.TargetURL, nil ); err == nil { if response, err := http.DefaultClient.Do(request); err == nil { defer func () { _ = response.Body.Close() }() if response.StatusCode < 400 { if body, err := io.ReadAll(response.Body); err == nil { cachedMetrics.Store(&CachedResponse{ Body: body, ContentType: response.Header.Get( "Content-Type" ), }) } } } } terminating.Store( true ) select { case <-scrapeChan: case <-ctx.Done(): } } } まとめるとこのプロキシは以下のように動きます。 常にPrometheusとPrometheus Exporterの間に入って最終Scrape時刻を記録しておく SIGTERMを受け取った時にScrapeWaitThreshold以内にScrapeされていなければ、Prometheus Exporterから最新のメトリクスを取得してキャッシュする 次回Scrape時にそのキャッシュからメトリクスを返して終了する これでPod終了直前にインクリメントされたCounterなどの値がPrometheusにScrapeされず欠損する問題を解決できました。 あとはPrometheus Operatorを使っているなら PodMonitor を、PodのアノテーションによるService Discoveryを利用している場合は metadata.annotations をこのプロキシに向けるだけです。 LIFULLではPodのアノテーションによるService Discoveryを利用しているため、 prometheus.io/wait: true と付与するとこのプロキシを注入するMutating Admission Webhookを開発して、このタイミングで prometheus.io/port もプロキシのポートに書き換えるようにしました。 これにより、利用者はPodアノテーションの付与をするだけで最小限のロールアウト遅延と引き換えに信頼性の高いメトリクスを得ることができます。 なお、KubernetesがSIGTERM送信後に諦めてSIGKILLを送るまでの spec.terminationGracePeriodSeconds のデフォルト値は30秒であるため、Scrape間隔が長いなどでこれを超えてプロキシが待機しなければならない場合はPodの spec.terminationGracePeriodSeconds を伸ばす必要もあります。 まとめ このエントリではKubernetesクラスタの可観測性基盤でよく採用されるPull型アプローチのトレードオフと、そのトレードオフへの対処を紹介しました。 一部コミュニティでは問題視されているものの、素直に利用していると意外と見落としがちな問題だと思っていて、お手元のKubernetesクラスタの監視を見直すきっかけになれば幸いです。 メトリクスはともかくログは欠損してしまうとそれなりに問題があるはずで、特にCronJobとかは実行ログを出力してから比較的すぐPodが終了することが多く、 successfulJobsHistoryLimit , failedJobsHistoryLimit を0にしていると直前のログはほぼ欠損していると考えてよいでしょう。 最近はトレースのSpanにログを持たせてしまうことも増えましたが、依然ログは重要な可観測性のシグナルだと思うので欠損がないように運用していきたいところです。 Fluentdのバッファはちゃんと設計しましょうとか、Prometheusの冗長化とか、Grafana Lokiは max_chunk_age の値に応じて送信が遅延してしまった同一ストリーム内の古いログを捨ててしまうので、fluent-plugin-grafana-lokiにパッチ当てて該当エラーの場合にUnrecoverableErrorを返すことでFluentdのsecondaryに流して、別ストリームとして送信し直すことで取りこぼさないようにしましょうとか、Pull型アプローチ由来以外の欠損を防ぐ話はまた別の機会に書きたいと思います。 ご興味をお持ちいただけましたら、ぜひ以下のページもご覧ください。 hrmos.co hrmos.co
LIFULLは、国立情報学研究所(NII)が運営する情報学研究データリポジトリ(IDR)に、 LIFULL HOME'Sデータセット を提供しています。 本記事では、先日開催された IDRユーザフォーラム2025 のご報告として、LIFULL HOME'Sデータセットを活用した研究発表や、LIFULLとしての取り組みについてご紹介します。 IDRユーザフォーラム2025とは 2025年5月、新たにLIFULL HOME'Sデータセットを追加 LIFULL HOME'Sデータセットを活用した研究ポスター発表 不動産情報の俯瞰的閲覧を可能にするVR探索インタフェース 公示地価・人口動態予測データを用いた機械学習による将来賃料の予測 スタートアップセッションにおける企業賞の授与 住宅ローン税制は住宅購入者の利益になっているか LIFULLからの発表:不動産データのビジネス応用事例 おわりに 一緒に不動産データの可能性を広げるエンジニアを募集しています 前回および前々回のフォーラムの様子については、以下の記事でもご紹介していますので、あわせてご覧ください。 www.lifull.blog www.lifull.blog IDRユーザフォーラム2025とは IDRユーザフォーラムは、NIIが提供する研究データ基盤を活用した研究成果を共有し、データ提供者・研究者・利用者が一堂に会して議論する場です。 不動産、医療、交通、社会経済など、分野横断的なデータ利活用の事例が紹介される点が特徴で、年々参加者・発表内容ともに広がりを見せています。 2025年5月、新たにLIFULL HOME'Sデータセットを追加 2025年5月には、IDRにおける LIFULL HOME'Sデータセットの拡充が行われました。 これにより、より多様な分析・研究テーマへの応用が可能となり、学術研究と実社会をつなぐ基盤としての価値がさらに高まっています。 データセットの詳細は、以下のページで公開されています。 情報学研究データリポジトリ LIFULL HOME'Sデータセット LIFULLとしては、引き続き「実社会で蓄積されたデータを、研究を通じて社会に還元する」ことを重視し、IDRを通じたデータ提供を進めていきます。 LIFULL HOME'Sデータセットを活用した研究ポスター発表 IDRユーザフォーラム2025では、LIFULL HOME'Sデータセットを活用した研究発表が複数行われました。 ここでは、特に印象的だった2件のポスター発表をご紹介します。 不動産情報の俯瞰的閲覧を可能にするVR探索インタフェース 中山 裕紀 氏,大島 裕明 氏(兵庫県立大学) ポスター資料 本研究では、不動産情報をVR空間上で俯瞰的に探索できるインタフェースが提案されました。 LIFULL HOME'Sデータセットを用いることで、従来のリスト表示や地図表示では捉えにくかった空間的・構造的な特徴を、直感的に把握できる点が示されていました。 不動産情報とXR技術の融合は、住まい探しや都市理解の新しい可能性を感じさせる研究事例でした。 公示地価・人口動態予測データを用いた機械学習による将来賃料の予測 佐藤 豪栄 氏,秦野 亮 氏,西山 裕之 氏(東京理科大学) ポスター資料 こちらの研究では、LIFULL HOME'Sデータセットに加えて、公示地価や人口動態予測データを組み合わせ、将来の賃料を機械学習によって予測する手法が提案されました。 不動産市場の将来予測という社会的ニーズの高いテーマに対し、オープンデータと民間データを組み合わせた分析は、IDRならではの研究アプローチと言えます。 スタートアップセッションにおける企業賞の授与 今回のIDRユーザフォーラム2025では、スタートアップセッションも開催されました。 LIFULLは企業賞として、以下の研究発表を表彰させていただきました。 住宅ローン税制は住宅購入者の利益になっているか 河瀬 豊 氏(神戸学院大学) 発表資料 本研究は、住宅ローン税制が実際に住宅購入者の利益につながっているのかを、データに基づいて検証したものです。 不動産・住宅政策とデータ分析を結びつけた点、そして社会的インパクトの大きさを評価し、LIFULLとして企業賞を授与させていただきました。 LIFULLからの発表:不動産データのビジネス応用事例 データ提供者セッションでは、LIFULLからも発表の機会をいただきました。 speakerdeck.com このセッションでは、実際の不動産データがどのようにビジネスの現場で活用されているかを、具体的な事例と技術アプローチの観点から紹介しました。発表はデータ提供者セッションにて行われ、参加者のみなさまにも幅広い関心を寄せていただきました。 発表では、以下のようなトピックに触れました。 「おとり物件」の防止に向けた取り組み:不動産情報の信頼性向上を目的とした取り組みと技術的背景の紹介 不動産売却査定におけるLLM活用:大規模言語モデルを用いた査定支援サービスの事例 LIFULL HOME'Sデータセットの拡充とその活用可能性:2025年5月に追加されたデータの内容と、これを活かした応用事例の可能性 この発表を通じて、データ利活用が不動産ビジネスにもたらす価値を、研究者・実務者双方の視点から捉えていただくことを目指しました。 LIFULLでは、今後もデータ駆動型サービスの可能性と実装事例を共有し、研究コミュニティとの対話を深めていきたいと考えています。 おわりに IDRユーザフォーラム2025を通じて、LIFULL HOME'Sデータセットが多様な研究テーマに活用されていること、そして研究成果が社会課題の理解や解決に寄与しうることを改めて実感しました。 LIFULLは今後も、 データ提供を通じた研究支援 学術と実社会をつなぐ取り組み 不動産・住まい領域におけるデータ利活用の発展 を継続していきます。 研究者の皆さま、データ利用者の皆さま、そしてIDR事務局の皆さま、改めてありがとうございました。 一緒に不動産データの可能性を広げるエンジニアを募集しています IDRユーザフォーラム2025を通じて、LIFULL HOME'Sデータセットが研究・ビジネスの両面で多様な価値を生み出していることを改めて実感しました。 これらの取り組みは、エンジニアリング・データサイエンス・AI技術の積み重ねによって支えられています。 LIFULLでは現在、不動産データやAI技術を活用し、社会課題の解決に取り組むエンジニアを積極的に募集しています。 データ基盤、機械学習、LLM活用、プロダクト開発などに関心のある方にとって、実データを使いながら挑戦できる環境があります。 エンジニア向けの募集職種一覧は、以下の採用ページをご覧ください。 hrmos.co 研究コミュニティと連携しながら、実社会にインパクトを与えるプロダクトをつくりたい方、不動産・住まい領域のデータ利活用に興味のあるエンジニアの皆さまのご応募をお待ちしています。
はじめに こんにちは、基盤グループでインフラの運用管理を担当している布川です。 今年の10月28日にAWS目黒オフィスにて、堅牢で回復力に優れたシステムの構築について学ぶAWS Architectural Resilience Dayが開催されました。 本イベントには弊社から基盤グループのメンバー3名が参加しました。本記事では、その内容や得られた学びをレポートとしてご紹介します。 はじめに 高いレジリエンスの実現に向けた6つのステップ 1. システムの中でビジネスクリティカルな部分を明確にする 2. 個々のコンポーネントに具体的な目標を設定する 3. 実際に設計に落とし込む 4. 現在の設計で目標を達成できるか?テストする 5. 適切な監視体系を構築する 6. 定期的に振り返りを実施する 講義を終えて 弊社のシステムに置き換えた話 実務で意識したいこと おわりに 高いレジリエンスの実現に向けた6つのステップ 講義では、システムを停止させないこと、また停止した場合でも影響を最小限に抑えることを目的として、システムのレジリエンスを高めるための6つのステップが示されました。 また、ハンズオンを通じて、AWS上に構築したシステムでこれらのステップを実践するための具体的な方法について学びました。 1. システムの中でビジネスクリティカルな部分を明確にする サービスを構成するシステム全体を見たとき、すべてのコンポーネントが同じ重要度を持つわけではありません。 まずは、ここだけは止めてはならない、止まったとしても最優先で復旧すべき、といったビジネスクリティカルな部分を明確にすることが重要だと学びました。 たとえば、弊社が運用する不動産ポータルでは、最低限のサービスレベルとして、地図サービスなど外部依存部分を除き、物件検索・問い合わせ、物件更新等の基本機能が一通り動く状態を定義しています。一方で、SEOや読み物コンテンツなど、ユーザ獲得を目的とした機能はこの範囲から外して考えています。 2. 個々のコンポーネントに具体的な目標を設定する 次に、ビジネスクリティカルと定義したコンポーネントについて、レジリエンスに関する具体的な目標値を設定します。講義では、次のような観点から整理していました。 項目 High Availability(高可用性) Disaster Recovery(災害復旧) 対象とする障害 小規模で頻度の高いイベント まれだが影響の大きい障害 具体例 ネットワークの問題、負荷スパイクなど 自然災害、技術的障害、人的ミスなど 対処方法 自動緩和、自己回復 事前に備えた復旧対応 評価指標 通期の平均値 MTBF ÷ (MTBF + MTTR) など 単一イベントでの測定 RPO, RTO など RTO(目標復旧時間)やRPO(目標復旧時点)は、ビジネス上どこまでの損失を許容できるかを元に決定します。たとえば、あるECサイトで1時間あたりの売上が1,000万円、サイトダウン時に許容できる機会損失額を1,000 万円(年 1 回まで)とした場合、RTOは1時間という考え方になります。 ハンズオンではAWS Resilience Hubを用いて、CloudFormationで管理されているリソース群にRPO, RTOを設定し、現在の構成がその目標を満たしているかを評価しました。また、S3のバージョニング有効化やDynamoDBのバックアップ設定などを追加し、要件を満たすまでの流れを体験しました。 3. 実際に設計に落とし込む 復旧目標が定まると、自己回復しない障害が発生した際に、目標時間内に復旧するための設計を考えられるようになります。 設計における基本方針は静的安定性の確保です。静的安定性とは、「自己回復しない障害が発生した時、システムをこちらから操作・変更しなくても復旧してくれる性質」のことを指します。 障害は大まかに、発生頻度の高い順に以下のように分類できます。 コードのデプロイや設定ミス(デプロイ失敗、証明書失効など) コアインフラストラクチャの障害(データセンター障害、ホスト障害など) データや状態の問題(データ破壊) めったに起こらないシナリオ(自然災害、全インターネット障害、電力等のサプライヤー障害など) 今回の講義では、特に4のようなレアケースでも重要業務を継続できるよう回復力を確保する設計に焦点が当てられていました。そのための方針として、APIや管理画面といったコントロールプレーンの操作を前提とせず、データプレーンのみで自律的に切り替わる構成とすることが重要である、という説明がとても参考になりました。(参考AWSドキュメント: コントロールプレーンとデータプレーン ) この前提のもと、マルチAZやマルチリージョンといった構成を検討します。ただし、コストをかけるほど復旧は早くなる一方で、金銭・運用負荷・複雑性といったトレードオフも発生します。抑えたい損失と支払うコストを天秤にかけ、現在の事業フェーズに合った手段を選択することが重要です。 ディザスタリカバリ戦略 出典: クラウド内での災害対策オプション (AWSドキュメント) 講義では深くは触れられていなかったものの、1〜3のような比較的発生頻度の高い障害に対しても、静的安定性を意識した設計を行うことが重要だと感じました。 デプロイや設定ミスに対してはCI/CDの整備やCanaryリリース、設定のIaC管理等を行うことでリスクを低減でき、インフラ障害に対してはマルチAZ等の冗長な構成を採用すること、データ障害に対しては定期的なバックアップやガードレールの導入を行うといったことが対策として考えられます。このような取り組みによって静的安定性を確保しながら、障害による影響や発生自体を抑える環境を作ることが求められると感じました。 ハンズオンではマルチリージョン構成のもとで、CloudFrontのオリジン(S3)のフェイルオーバーや、Route53によるALBの振り分け先のフェイルオーバーを実際に試しました。 4. 現在の設計で目標を達成できるか?テストする 現在の設計が確実に復旧目標を達成できることを確認するために、本番相当の環境、もしくは実際の本番環境のうちの一部のトラフィック群に対して、レジリエンステストを実施することを学びました。 ここでは、回復力を測る対象となる障害を意図的にシステムへ注入し、想定通りの挙動によって定常状態を維持、もしくは目標時間内に復旧できるかを確認します。 AWSでは、Resilience Hubの機能の一つであるFault Injection Service (FIS)を利用することで、電源の中断やインスタンス障害など、通常は再現が難しい障害シナリオを安全にテストできます。 ハンズオンでは、この後に学ぶ監視体系の構築と合わせて、FISを用いたAZの電源中断シナリオやリージョン障害発生時のシナリオを注入し、これまでに学んだレジリエンス対策を施したサービスが、目標時間内に復旧できるかどうかを、Cloudwatch SyntheticsのCanaryを用いて確認しました。 5. 適切な監視体系を構築する 目標とするレジリエンスを達成するシステムを設計・テストし、運用に乗せた後は、ユーザ体験の把握や障害の検知・影響判断、原因調査や復旧を支援するための監視が必要になります。 ただし、過剰な計測はデータ疲れを招くため、ビジネス目標を踏まえ、アプリケーションにとって重要な指標に絞って監視することが重要であることを学びました。 講義で紹介されていた監視体系の一例を整理すると、以下のような情報をバランスよく収集することが有効であると感じました。 リクエストの文脈:いつ・誰が・どのAPI/機能で・どこのAZ/リージョンで・何をしようとしていたのか 成否と結果:レスポンスコードやエラーの種類・原因 レイテンシと内訳:全体の処理時間や、接続・キャッシュやDB上の処理・アプリ上の内部処理にかかった時間 リソースの使用状況:キャッシュヒット等のリクエスト単位で計測できるもののほか、CPU使用率等の継続的に測定できるメトリクス 6. 定期的に振り返りを実施する 最後に、運用中に実際の障害が発生した後、どのように振り返りを行うべきかについて学びました。講義で紹介された事例では、以下のような観点で情報が整理されていました。 障害の概要:障害の影響、経緯、対策等のハイレベルな情報 メトリクス:障害の影響や問題の特定に利用したメトリクスのグラフ 影響範囲:障害の影響を受けたユーザ数、時間や程度、ビジネスへの影響 タイムライン:障害中に発生したすべてのイベントや、実施したプロセスを時系列で整理 ラーニング:対応や分析を通じて得られた学び アクションアイテム:改善策を優先度・責任者とともに明確化 特に重要な点として、個人を非難せず、プロセスや仕組みにフォーカスすることが強調されていました。 弊社でも障害対応のナレッジを蓄積するスペースを運用しているため、この考え方は共感しやすい内容でした。 講義を終えて 本講義を通して、堅牢で回復力の高いシステムをどのように構築するかを、段階的・体系的に学ぶことができました。なお、細かな説明については一部省略している点をご留意ください。 これまでふわっとした理解にとどまっていたレジリエンスについての考え方や具体的な手段について、このタイミングで整理して学べたことはとても有意義だったと感じています。 弊社のシステムに置き換えた話 弊社には KEEL(キール) と呼ばれるKubernetesベースの独自のアプリケーション実行基盤があり、多くのアプリケーションがその上で稼働しています。 マルチAZ構成を前提としているため、自然災害に対する静的安定性が確保されており、この点は大きな強みだと感じました。 また、運用中のサービスが必要なレジリエンス要件を満たしているかを定期的に確認することも重要だと感じました。 弊社では、サイバー攻撃を含むリスクに備えたマルチアカウント構成の事業継続計画(BCP)を策定しており、災害時などの緊急時において、損害を最小限に抑えつつ主力事業の継続や早期復旧を可能とするため、手順・担当者・作業範囲などをあらかじめ定めています。こちらについて、現状の対応は主にバックアップとリストアが中心であり、パイロットライト構成などを検討する余地もあると感じました。 このように、ハードウェア・論理的構成の両面で適切なレベル・手段を選びながら、想定されるさまざまな障害への対応策を講じておくことで、より堅牢なシステムを実現できるのだと理解しました。 実務で意識したいこと 基盤Gでは、運用に必要なアプリケーションも含めて開発・運用を行っています。 ステップ3でも触れられていましたが、システムが持つ静的安定性を最大限に活かすためのアプリケーション設計には、意識して取り組む必要があると感じました。 また、基盤グループでのこれまでの経験から、障害の原因の多くは人為的ミス、たとえばデプロイの失敗や設定不備であることが多いということは明らかです。 そのため、十分に統合テストを実施すること、リリースにあたっては影響範囲を明確にしつつ関係者と合意を取り、動作確認を行う体制を整備すること、といった基本的なことを積み重ねた上で、今回のようなレジリエンス設計や障害対応の議論ができる状態を作っていくことが重要だと感じました。 おわりに 本記事では、AWS Architectural Resilience Dayで学んだ、堅牢で回復力に優れたシステム構築に関する考え方や、その実践的な内容についてご紹介しました。 この記事が、レジリエンス向上に向けた動き方を検討する際の一助となれば幸いです。最後までお読みいただき、ありがとうございました。 最後に、LIFULLではともに成長していける仲間を募集しています。ご興味をお持ちいただけましたら、ぜひ以下のページもご覧ください。 hrmos.co hrmos.co
1. 始めに こんにちは。LIFULLでエンジニアをしている稲垣です。 2025年10月の3日間、AWSが提供する「AI駆動開発ライフサイクル(AI-DLC)Unicorn Gym」の研修に参加しました。この研修では、6つのチームに分かれて、AI-DLCを活用しながら実際のプロジェクト課題に取り組みました。 私たちのチームが取り組んだのは、「サポートが終了したサービスの新基盤への移行計画」です。具体的には、Amazon Linux 2のサポート終了(EOL: End of Life)への対応として、既存システムを新しい基盤へ移行する計画の策定に取り組みました。 このようなOSマイグレーションでは、以下のような課題に直面します: 取り組むべき手順や優先順位が不明確 移行オプションの調査と比較に数日かかる リスクの洗い出しが担当者の経験に依存し、見落としが発生しやすい この記事では、これらの課題に対してAI-DLCがどのように解決策を提供してくれたのか、実際の開発プロセスと得られた学びを共有します。特に、AIがルーティンタスクを処理する間に、チームは問題解決や意思決定に集中できる「ダイナミックなチームコラボレーション」がどのように実現されたかをお伝えします。 1. 始めに 2. 研修の内容とカリキュラム AI-DLCとは AI-DLCの開発フェーズ 私たちのチームの課題 私たちのチームの取り組みの流れ 私たちのチームの取り組みの流れ図 3. AI-DLCを活用した開発プロセス AI-DLCの基本サイクル 当初の構想とAI-DLCによる方針転換 Inception Phaseでの実践 Construction Phaseでの実践 4. 直面した課題とAI-DLCでの解決 5. 研修を通じて得られた気付きや学び AI-DLCを使った開発スタイルについての気付きと今後の活用 チーム開発での学び OSマイグレーションという課題から得た学び 6. まとめ 2. 研修の内容とカリキュラム AI-DLCとは AI-DLC(AI-Driven Development Lifecycle)は、AIが開発プロセスを主導する開発手法です。単なるコード生成ツールにとどまらず、要件定義から設計、実装、テスト、運用まで、開発の各フェーズでAIがタスク分解や実装を主導し、人間がレビュー・承認を行います。今回の研修では、Amazon Q Developerを使用してAI-DLCを実践しました。 AI-DLCの開発フェーズ AI-DLCは大きく3つのフェーズで構成されています: Inception Phase(構想フェーズ) - 現状分析、技術選定、計画策定を行うフェーズ Construction Phase(構築フェーズ) - 実装、テスト、ドキュメント作成を行うフェーズ Operation Phase(運用フェーズ) - 本番環境へのデプロイとインシデント管理を行うフェーズ 私たちのチームの課題 研修では6つのチームがそれぞれ異なる課題に取り組みました。私たちのチームは「サポートが終了したサービスの新基盤への移行」という課題に挑戦しました。 この課題は、参加チームの中でも比較的珍しいものでした。AWSの担当者によると、「AI駆動開発ライフサイクル(AI-DLC)Unicorn Gym」では、これまで主にアプリケーション開発の課題が扱われてきましたが、OSマイグレーションという領域でAI-DLCを活用するのは初の事例とのことでした。 具体的には、以下の点でほかのチームとは異なる挑戦となりました: 活用事例が少ない :インフラ移行という領域でのAI-DLC活用は前例が少ない 技術的な複雑さ :既存システムの完全な理解と、複数のAWSサービスにまたがる変更が必要 リスク管理の重要性 :本番環境への影響を最小限に抑える慎重な計画が求められる この特徴が、AI-DLCの新しい活用方法を模索する良い機会となりました。 私たちのチームの取り組みの流れ 今回の研修では、このAI-DLCのフェーズに沿って、OSマイグレーション計画を進めました。以下は、私たちのチームが実際に取り組んだ内容です。 Inception Phase(構想フェーズ) 既存システムの構成調査とAWSインフラの棚卸し 移行方法の比較検討と技術的制約の分析 ユニット(AI-DLCで用いる作業単位)への分割と依存関係の整理 Construction Phase(構築フェーズ) 以下の作業を並行して実施(研修時間内では途中まで): リスク管理台帳の作成と対応策の検討 技術調査レポートや運用手順書の作成 ベースイメージの作成 私たちのチームの取り組みの流れ図 図1:私たちのチームの取り組みの流れ。(Inception PhaseからConstruction Phaseの途中まで実施) 3. AI-DLCを活用した開発プロセス 本章では、AI-DLCを実際どのように活用して開発を進めたかを紹介します。 AI-DLCの基本サイクル AI-DLCでの開発は、以下のサイクルを繰り返します: AIにプランを作らせる 人がプランをレビュー AIがプランを修正 AIがプランを実行 人が結果を確認 図2:AI-DLCの基本サイクル。このサイクルを繰り返して成果物を完成させる 当初の構想とAI-DLCによる方針転換 プロジェクト開始時、私たちはAmazon Linux 2のEOL対応として、Amazon Linux 2023へのOSリプレイスを検討していました。既存のAmazon EC2(仮想サーバー)環境を維持したまま、OSのみをアップグレードする方針です。この方針は、既存システムへの影響を最小限に抑えられるという理由から選択しました。 しかし、AI-DLCを活用して検討を進める中で、方針が大きく変わりました。AIが生成した技術調査レポートで複数の移行オプションを比較した結果、 Amazon ECS(コンテナ実行基盤)へのコンテナ化 が望ましいという提案がありました。 理由は以下の通りです: 環境の再現性(不変性)の向上により、デプロイやロールバックが容易になる 将来的なミドルウェアアップグレードの基盤となる 長期的な保守性と運用効率の向上が期待できる コンテナ化という選択肢自体は、チーム内で漠然と認識していました。しかし、AI-DLCが生成したレポートを見るまでは、その具体的なメリットや実現可能性が明確ではありませんでした。AIが各オプションのメリット・デメリット、工数、コストを整理してくれたことで、チームでの議論が活性化しました。「環境の再現性(不変性)の向上」という観点や、「将来的なアップグレードの基盤」という長期的な視点は、AIの提案によって初めて明確になった部分です。 チームでの議論を経て、最終的にコンテナ化の方針で Construction Phaseを進めることに決めました。これは、AI-DLCが単なる作業支援ツールではなく、技術的な提案を行い、プロジェクトの方向性の決定に良い影響を与えてくれました。 図3:AI-DLCによる技術選定の変化。OSリプレイスからコンテナ化へ方針転換 Inception Phaseでの実践 Inception Phaseでは、現状分析と技術選定を行いました。 AIと人間の役割分担 AI-DLCでは、AIがルーティンタスクを処理することで、人間は問題解決や意思決定に集中できます。 AIが担当: 既存システムの構成情報の収集と整理 複数の移行オプション(OSリプレイス vs コンテナ化)の比較レポート生成 各オプションのメリット・デメリットの洗い出し 人間が担当: 移行方針の最終決定(ECSコンテナ化を選択) ビジネス要件との整合性確認 技術的な実現可能性の判断 Construction Phaseでの実践 Construction Phaseでは、計画策定とリスク管理を行いました。 AIと人間の役割分担 AIが担当: ユニットへの分割案の生成 依存関係図の作成 リスク項目の網羅的な洗い出し リスク管理台帳の初稿作成 人間が担当: タスクの優先順位付け リスクの重要度評価と対応策の決定 実装スケジュールの調整 たとえば、依存関係図の生成では: 人間がシステム情報を提供 AIがドキュメントを分析し、依存関係図を自動生成 人間が図をレビューし、不足部分を指摘 AIがフィードバックを反映して修正 チームが図を見ながら移行順序を議論 Mob Construction(いわゆるモブレビュー/モブ作業。チーム全体でのフィードバックと問題解決)の実践: Mob Constructionは、AI-DLCにおけるチーム開発の手法で、AIが生成した成果物に対してチーム全員でレビューとフィードバックを行い、より良い解決策を議論する取り組みです。 リスク管理時には、AIが洗い出したリスクをチームでレビューしました。「このリスクは優先度が高い」「この対応策では不十分」などフィードバックを行い、チームでリスク対応策をブレインストーミングし、実装の優先順位を議論して決定しました。 AIがリスクの洗い出しや台帳作成を処理している間に、チームメンバーは技術的な実現可能性の議論、過去の経験からの知見共有、より効果的な対応策の検討に集中できました。これにより、作業効率が向上しただけでなく、チーム全体の技術力向上にもつながりました。 4. 直面した課題とAI-DLCでの解決 課題1:技術選定の複雑さ Amazon Linux 2023への直接移行とECSコンテナ化、どちらを選択すべきか判断が難しい状況でした。 AI-DLCの活用: 複数の移行オプションを比較した技術調査レポートを生成 各オプションのメリット・デメリット、工数、コストを整理 チームでの議論の材料として活用 結果: 長期的な視点でECSコンテナ化を選択する判断ができました。 課題2:リスク管理の網羅性 OSマイグレーションには多くのリスクが潜んでおり、見落としがないか不安でした。 AI-DLCの活用: 技術的なリスクを網羅的に洗い出し リスク管理台帳の初稿を作成 リスク評価マトリックスを生成 結果: 30個以上のリスクを識別し、優先順位をつけて対応策を検討できました。 課題3:ドキュメント作成の負荷 移行計画書、技術調査レポート、運用手順書など、多くのドキュメントが必要でした。 AI-DLCの活用: ドキュメントの初稿を自動生成 フォーマットの統一 情報の整理と構造化 結果: ドキュメント作成の時間を大幅に削減し、内容のレビューと改善に時間を使えました。 5. 研修を通じて得られた気付きや学び AI-DLCを使った開発スタイルについての気付きと今後の活用 AIは技術的な提案も行う 当初はOSリプレイスを検討していましたが、AI-DLCが生成した技術調査レポートでECSコンテナ化を提案され、最終的にその方針を採用しました。AIは単に指示されたタスクをこなすだけでなく、より良い選択肢を提示することもあると実感しました。 今後の業務では、新しいプロジェクトの技術選定時に、AIに複数のオプションを比較させることで、より客観的な判断材料を得られると考えています。 プロンプトの重要性 AIに何を依頼するか、どのようにコンテキストを与えるかで、成果物の質が大きく変わります。効果的なプロンプトを書くスキルが、今後ますます重要になると感じました。 今回の研修で効果的だったプロンプトの要素: 役割の明確化 : 「あなたは熟練したクラウドエンジニアです」のように、AIに期待する専門性を明示 具体的なタスクの指定 : 「aidlc-docs/inception/migration_plan.md ファイルにステップを記載してください」のように、成果物の形式と保存場所を明確に指定 作業プロセスの指示 : 「計画を作成したら、私のレビューと承認を求めてください」のように、レビューのタイミングを明示 制約条件の設定 : 「独自の判断や決定は行わないでください」のように、AIが勝手に判断しない範囲を明確化 日常業務では、ドキュメント作成や技術調査の際に、これらの要素を含めたプロンプトを作成することで、AIの支援を最大限活用できます。 レビューの重要性 AIが生成した内容をそのまま使うのではなく、必ずレビューして修正する必要があります。AIの提案を批判的に評価する能力が求められます。 コードレビューと同様に、AIが生成した成果物のレビューを習慣化することで、品質を担保しながら効率化を実現できます。 チーム開発での学び 役割分担の明確化 AIが得意なタスクと人間が得意なタスクを明確に分けることで、効率的に作業を進められました。 AIが得意なタスク: 情報の収集と整理(既存システムの構成情報、移行オプションの比較) ドキュメントの初稿作成(技術調査レポート、リスク管理台帳) 網羅的な洗い出し(リスク項目、依存関係) 定型的な作業(タスク分割、フォーマット統一) 人間がやるべきタスク: 最終的な意思決定(移行方針の選択、優先順位の決定) ビジネス要件との整合性確認 技術的な実現可能性の判断 AIが生成した成果物のレビューと修正 チーム内での議論とコンセンサス形成 この役割分担により、AIがルーティンタスクを処理する間に、人間は問題解決や意思決定に集中できました。 OSマイグレーションという課題から得た学び 活用事例が少ない領域でのAI活用 一般的な開発タスクではない領域でも、AI-DLCは有効に活用できることがわかりました。特に、複数の移行オプションを比較する技術調査レポートの生成や、30個以上のリスクを網羅的に洗い出す作業では、AIの支援が大きな価値を発揮しました。 段階的なアプローチの重要性 大きな移行プロジェクトを複数のユニットに分割し、依存関係を整理することで、リスクを管理しながら進められることを学びました。 6. まとめ この研修を通じて、AIがルーティンタスクを処理する間に、チームは問題解決や意思決定に集中できる「ダイナミックなチームコラボレーション」を実践的に学ぶことができました。 また、OSマイグレーションという活用事例の少ない領域でも、AI-DLCは有効に活用できることを実証できました。 LLMは、単なるコード生成ツールではありません。AI-DLCという開発手法を通じて、LLMを開発のライフサイクル全体で活用することで、チームの生産性と創造性を高めることができます。今後の業務でも、この経験を活かして、より効率的で質の高い開発を実現していきたいと思います。 最後に、LIFULLではともに成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
3行まとめ 仕様書を渡すとリスク分析からテストケース生成までやってくれるよ ステップ単位で人が軌道修正して精度をあげて(維持して)いるよ 指摘内容や成果物からナレッジを抽出してPRを出すので賢くなる仕組みだよ 3行まとめ はじめに つくったもの ポイント① 仕様書の理解から始める ポイント② 人間が軌道修正する ポイント③ 使うほど賢くなるように 「ドメイン知識」と「テスト技術」に分けた理由 実際どうなの? テストケースのフォーマット 課題:プロンプトやナレッジの管理・改善 おわりに はじめに こんにちは、クオリティアーキテクトグループでQAエンジニアをしている星野です。 この記事は LIFULL Advent Calendar 2025 の記事になります。 QA活動でLLM、活用してますか? 今回はテスト分析からテスト実装(テストケースの作成)までを効率化するためにつくったAIエージェントの話をします。 ただ単に「テストケースを作って」「テスト観点を出して」とお願いするだけではなく、 人間が軌道修正しながら精度を上げていく仕組みと、 その修正内容から学習して次に活かす仕組みも入れてみたので、その話をします。 残念ながらプロンプト群は公開できませんが、アプローチや設計思想は参考になるかもしれません。 つくったもの 仕様書を渡すと、以下のステップでテストプロセスを進めます。 仕様書の理解 - 曖昧な表現の確認や不足・矛盾を指摘、プロダクトリスクを洗い出す テスト観点の抽出 - ドメイン知識やテスト知識を活用してテスト観点を生成 ユーザーレビュー - 人間が確認して修正指示(最大5回まで) テストケース生成 - JSON形式でテストケースを出力 知識の抽出・保存 - ここまでの指摘・修正内容からナレッジを抽出してPRを出して蓄積 ポイントは3つあります。 ポイント① 仕様書の理解から始める いきなりテスト観点を抽出させたりテストケースをつくらせません。まず仕様書を理解させるところから始めます。 まず大前提として、完璧な仕様書は存在しません。少なからず間違いや曖昧な表現、後々変更される内容を含んでいます。 また、仕様書には書かれていない暗黙の前提、ドメイン特有の重要な項目や不安、課題だとかリスクがありますよね。 それらをどう認識されているかわからないままスタートをすると、そのズレは徐々に影響が大きくなって成果物がトンチンカンな内容になりがちです。 なので、それらを先に確認し、あわよくば後続のプロセスに活かします。 たとえば、 システム的にケアされていてテストの必要がないもの 仕様以前の要求、サービスそのものの目的や理念 非機能要件として求めるレベル感 仕様書に書かれていない制約や前提 こういったものを最初に確認しておくと、後のテスト観点抽出がブレにくくなります。 なので、このステップでは以下のようなことをやっています。 機能概要・対象範囲の要約 不足・矛盾・曖昧な点の確認 プロダクトリスクの特定 ユーザーにはLLMの解釈が正しいか確認を促して指摘を(必要なら仕様書を修正して)もらってから次に進みます。 ポイント② 人間が軌道修正する LLMも人間同様に誤りを生みますし、コンテクストが大きいと過去の指示や内容と矛盾したりもします。 なので、ステップごとにレビューポイントを設けています。 さきほどの仕様理解の最後に入れていた確認と同様のものを他ステップでも行います。 ユーザーからの承認を得なければ次のステップに進まないようにLLMに指示をしています。 また、修正は最大5回までにしています。 修正回数が多い時には中断を促すメッセージを出すんですが、これは仕様書側に矛盾や不足が多かったり、必要な情報があまりにも足らなくて精度が出ないおそれがあるからです。 精度が悪いと最終成果物も誤りだらけでレビューが大変に(そもそも使えないものに)なりますし、それ以前にインプットの品質に懸念があるということは、コードベースなど他の成果物も少し不安がありますよね。 そのため、ドキュメント自体の見直しを促すようにしています。 ポイント③ 使うほど賢くなるように 仕様書に書かれない暗黙的な情報が多いって話を前述しました。狙いはそこです。 毎回初手で同じような補足を入れるのは面倒ですし、人によって差がでます。 また、テストにとってドメイン知識はかなり重要で、しかしそれはアウトプットされない限りは各人の記憶に隠れてしまいます。 だからこのシステムでは、レビューを挟んだとき、そこで得た指摘をベースにナレッジ化、PRを作成し本体へフィードバックしてくれる仕組みにしました。 具体的には、 人間が指摘・修正した内容を記録 「なぜ修正が必要だったか」「どう修正したか」を抽出 ナレッジとして蓄積(「ドメイン知識」と「テスト技術」に分類) 次回のテスト分析で活用 という流れです。 ナレッジを含むこのエージェントのプロンプト群はリポジトリで管理されているので、CLIで動くLLMはPRも出してくれます。 脳内のドメイン知識を書き出す負担をユーザーから取り除き、かつ他のユーザーもそのナレッジを利用できるようになります。 こういう情報はわざわざ書き出すのは大変ですし変更を追うのも難しかったものですが、 これなら使う人が多ければ多いほど、使えば使うほど蓄積されてメリットがスケールしていくんです。 仮に指摘がないなら、それは人間に納得のいく精度の出力を出すために今のナレッジで足りているということなので、余計なものを蓄えずに済むようになっています。 「ドメイン知識」と「テスト技術」に分けた理由 「ドメイン知識」と「テスト技術」にわけたのは、汎用的に使える考え・知識なのか、特定のシステムや体制によるものなのかを区分するためです。 利用するのは様々なチームで、その中にもいくつものテストベースがあります。すべてをひとつにまとめてしまうと「あっちではこれが必要だけどこっちでは重要視していない」みたいな衝突が起きてしまいます。 似ている目的や名前のページが存在していても、ドメイン知識として仕様書にあるリポジトリ名やサービス名からテストベースを判断でき、必要な情報だけを参照できるようにしています。 実際どうなの? 現時点ではいい感じに使えています。 私自身はもう基本的にこのエージェントを使用しており、成果物に少し手直しを加える程度で運用できています。 使いながら気になったらプロンプト自体をその場で直してしまえるので、改善のサイクルも早くて快適ですね。 テストケースのフォーマット 社内で使ってもらう・自分が使うにあたって、テストケースは標準化されたフォーマットから離れると定着しにくい・使いにくいため、JSONで出力するようにしました。 今のフォーマットは 以前の記事 に書いたようにスプレッドシートベースなので、GASでJSONからインポートできる機能をつけました。 ついでに最終成果物からナレッジを得て学習できるようにエクスポート機能も実装し、具体的なテストデータとかpath、手順などの仕様書に書かれない前提が輸入しやすくする狙いがあります。 また、JSONフォーマットと各カラムの目的と記載内容を言語化したドキュメントも配布することで、私がつくったプロンプトではなく独自に改善を行っている方にも利用しやすくしました。 囲い込んでユーザーを増やすよりも自由度を大事にしています。 課題:プロンプトやナレッジの管理・改善 今は自動的に飛んでくるPRをレビューして、問題(偏った判断基準や誤った省略など)がなさそうかを見ています。 ユーザーが少ないうちはこれでいけるんですけど、全ものづくりメンバーが使い出したらこれをどうするかは悩んでいます。 たぶんCLIにAIレビュアーを入れて重複削除や一貫性の担保をすることになると思います。 また、ナレッジが肥大化してきたときに正しく扱えるのか、制御できるのかが少し懸念です。 システムが昔よりもメモリ不足を気にしなくなったように、LLM側が進化してコンテクストウィンドウのオーバーフローを気にしなくてもよくなればいいんですけどね。 おわりに LLMを使ったテストプロセスの改善について、アプローチや設計思想を紹介しました。 「人間が軌道修正する仕組み」と「使うほど賢くなる仕組み」を入れることで、実用的なツールになったかなと思っています。 LLM活用のアプローチとして、何か参考になれば幸いです。 以上です。 お読みいただきありがとうございました。 最後に、LIFULLでは一緒に働いていただける仲間を募集しています。 カジュアル面談も実施しておりますので、もし興味があればそちらもご覧いただければと思います。 hrmos.co hrmos.co
はじめに iOSDC Japan 2025とは 印象に残ったセッション ユーザー数10万人規模のアプリで挑んだトップ画面のUI刷新 ABEMAモバイルアプリがKotlin Multiplatformと歩んだ5年 ─ 導入と運用、成功と課題 iOSエンジニアキャリア設計入門 〜”先進性”をキャリアの武器へ〜 カスタムUIを作る覚悟 イベントの雰囲気 まとめ はじめに こんにちは!LIFULL HOME’S iOSアプリエンジニアの遠藤・佐藤です。 今回は、2025年の9月19日(金) 〜 9月21日(日)の3日間で開催された、iOSに関連した技術をコアテーマにしたテックカンファレンス「iOSDC Japan 2025」に参加してきました。この記事では、3日間で行われたセッションの中から私たちの印象に残ったセッションやイベントの様子について振り返ります。 iOSDC Japan 2025とは iOSDCは、記念すべき第10回目の開催を迎えました!これまでは早稲田大学理工学部 西早稲田キャンパスにて開催されていましたが、第10回となる今回は会場がグレードアップし、有明セントラルタワーホール&カンファレンスにて開催されました。トークテーマはiOSに関する内容を始め、Vision Proやクロスプラットフォーム、AIといった多岐にわたる分野を網羅し、LT大会や多数の企画も充実していました。 iOSDC Japan 2025の公式サイトはこちら iosdc.jp トーク動画の視聴はこちら www.youtube.com 印象に残ったセッション ユーザー数10万人規模のアプリで挑んだトップ画面のUI刷新 speakerdeck.com この発表では、ユーザー数10万人超のアプリにおいて、WebViewベースであったトップ画面をネイティブ実装に刷新した事例が紹介されていました。従来の操作感を損なわずに段階的に移行を進めたプロジェクトで、多くのユーザーを抱えるアプリのUI刷新の事例として非常に参考になる内容でした。 特に印象的だったのは、ユーザー体験を最優先にした移行戦略です。段階的な移行を進める中で、各フェーズごとにユーザーからのフィードバックを収集し、課題を一つずつ解決していったそうです。具体的な指標として「ロールバック率(新画面から旧画面に戻したユーザーの割合)」を計測し、改善を重ねていった点が紹介されていました。 こういったフィードバック収集と改善の結果、最終的にロールバック率5%未満という高い受け入れ率も記録しつつ移行を完遂されており、ユーザーとの対話を徹底したUI刷新の成功事例として、とても勉強になりました。(遠藤) ABEMAモバイルアプリがKotlin Multiplatformと歩んだ5年 ─ 導入と運用、成功と課題 speakerdeck.com こちらの発表では、ABEMAにおいて約5年間にわたってKMP(Kotlin Multiplatform)を運用してきた具体的な事例を紹介されており、実際に業務でKMPを扱う私にとって、とても興味深い発表でした。 2020年ごろから検証を開始し、段階的に導入を進めてきた経緯を詳しく説明して下さっていました。現在では、サービスの中心となる画面に関連するロジックの多くがKMPによって共通化されているとのことで、大規模サービスでの長期運用がどのように実現されているのか、その実態を知ることができました。 また、KMPの導入プロセスや実際に生じた課題、そしてチームでの実装効率がどう変化したかなど、実践的な内容が取り上げられていました。特に、処理をどこまで共通化すべきかという判断基準や、Swift6やSwiftUIの導入とKMPをどう両立させたかなど、現場で直面する具体的な課題への取り組みを紹介されていて、多くの学びを得ることができました。(遠藤) iOSエンジニアキャリア設計入門 〜”先進性”をキャリアの武器へ〜 speakerdeck.com このセッションでは、ネイティブアプリエンジニアを取り巻く最新の市場動向を知ることができました。スマートフォンアプリ開発全体では、クロスプラットフォームであるFlutter(Dart)の勢いが増しており、SwiftとFlutterの両方を使うエンジニアも増加しているという明確なトレンドを解説してくださいました。 AIの活用によって開発効率は急速に向上していますが、企業側からのニーズは引き続き高い水準を保っているそうです。 今後のキャリア戦略としては、iOSとAndroidの両OSのネイティブ知識に加え、共通化の判断ができる能力がより重要になると感じました。 ちなみに、弊社のLIFULL HOME’Sアプリでも、Kotlin Multiplatformを使ってバックエンドの共通化を行い、ネイティブの特性を活かしつつ開発効率の向上に取り組んでいます。詳細については、過去の記事( LIFULL における Kotlin Multiplatform(KMP) - LIFULL Creators Blog )でご紹介していますので、ぜひご覧ください!(佐藤) www.lifull.blog カスタムUIを作る覚悟 speakerdeck.com カスタムUIは、標準UIが持つアクセシビリティや多様な入力への対応を、すべて自力で担う必要があるという、そのコストと難しさを改めて痛感させられる内容でした。 iOS/iPadOSアプリ開発における基本的な考え方は、標準APIを最大限に活用することです。安易にナビゲーションやコントロールをカスタム化してしまうと、ユーザー体験を損なうリスクがあることを認識しておく必要があります。カスタムUIを選択するということは、単に実装する技術的な問題ではなく、UIデザイナーとエンジニアが静的なデザインを超えて密に連携すること、そして時には勇気ある撤退も視野に入れるという「覚悟」が不可欠だと学びました。 後日、このセッションの動画をエンジニアだけでなく、企画職やデザイナー職も交えて視聴し、それぞれの視点からの学びを共有しました。カスタムUIの選択が、プラットフォームへの深い理解、UX、そしてチーム全体の総合的な判断に関わる重要な問題であるという認識を、チーム全体で共有できたことは非常に貴重な機会となりました。(佐藤) イベントの雰囲気 ルーキーズLTでは会場全体が登壇者の好きな色にサイリウムの色を切り替えて、応援していました!一人一人に合わせた応援で登壇者を後押しする、温かい演出が印象的でした! サイリウムを振ってLT発表者を応援📣 会場の1フロアほぼ全体にスポンサー企業ブースが立ち並び、各社の技術紹介やノベルティ配布、クイズなどで大盛況でした🥳 ビンゴ形式のスタンプラリーで各社のブースを巡る企画もあり、楽しみながら企業の取り組みを知ることができる工夫が印象的でした! スポンサー企業ブース1 スポンサー企業ブース2 ちなみにday1、day2ともに、朝にドーナツが配られていました〜🍩 会場が変わっても、早朝から用意してくださった運営の皆さんの熱量と気配りに感謝です! 4Fの展示ルーム前にドーナツがデプロイされました! 是非ご賞味ください 🍩 #iosdc pic.twitter.com/ulEsr2t0Wo — iOSDC Japan (@iosdcjp) 2025年9月21日 まとめ 今回iOSDCに参加して、様々なセッションを通じて、各社の取り組みや技術選定の背景など、日頃の開発現場の姿を垣間見ることができました。 また、昨今はFlutterやKotlin Multiplatformをはじめとしたマルチプラットフォーム開発が活発であったり、比較的新しいアーキテクチャを取り入れる事例も見受けられるなど、モバイルアプリ開発が依然として目まぐるしく変化していることを改めて実感しました。 弊社のアプリチームでも実際にSwiftUI、Kotlin Multiplatformを取り入れた開発をメインで行っていることもあるので、今回得た視点、知見を日頃の開発業務にぜひ活かしていこうと思います。 最後に、LIFULLでは一緒に働いていただける仲間を募集しています。単にサービス開発をするだけでなく、自らの知見を深め、エンジニアやプロダクトマネージャーとしてのキャリアを築く上で大切な事を得る機会が多くある職場です。カジュアル面談も実施しておりますので、もし興味があればそちらもご覧いただければと思います。 hrmos.co hrmos.co hrmos.co
こんにちは。フロントエンドエンジニアの根本です。 LIFULL HOME'Sのプロダクト開発とスポーツ関連の新規事業開発に携わっています。 今回は、PdM兼開発担当として携わった「注文住宅サイトの画像検索機能」について、開発の裏側をご紹介します。 画像検索機能とは? 開発前の事前調査 AIを活用したプロダクト設計 なぜAI活用に踏み切ったのか AI導入における挑戦と工夫 AIとプロダクトの付き合い方 チームを支えるプロダクトビジョン 今後について 最後に 画像検索機能とは? この機能は、 プレスリリース でもご紹介した通り、ハウスメーカーや工務店が持つ施工事例画像と、LIFULL HOME'Sが独自に収集しているユーザー投稿画像を使い、理想の家のイメージに合う会社を直感的に探し出せる、新しい検索体験を提供するものです。 開発前の事前調査 機能開発に先立ち、今回も職種横断での事前リサーチを実施しました。リサーチ活動の詳細については、こちらの記事もぜひご覧ください。 職種横断チームでのUXエンジニアとしての働き方 - LIFULL Creators Blog RESEARCH Conference 2024に登壇しました - LIFULL Creators Blog AIを活用したプロダクト設計 なぜAI活用に踏み切ったのか 注文住宅には、「和モダンスタイル」や「北欧スタイル」など、多様な家づくりのスタイルが存在します。従来、検討者の方々はそうしたスタイルを意識しながら検索をしていました。 しかし、LIFULL HOME'Sが抱える膨大な施工事例画像をすべて手動でスタイル分類するのは非常に困難でした。また、クライアント様にも大きなご負担がかかることが予測されました。 そこで、この課題を解決する手段として、AIを用いたスタイル自動判定の活用を検討し始めました。 AI導入における挑戦と工夫 AI判定の品質を100%保証することは難しく、開発過程では多くの挑戦がありました。 特にコストと品質のバランスを考慮しながら、プロンプト設計の検証を繰り返していました。 たとえば教師データの粒度を変えて分類精度を比較したり、「木の家」「北欧」といったスタイルを誤判定しないよう詳細なスタイル定義をプロンプトに盛り込むパターンを試すなど、さまざまなアプローチを検討しました。その過程自体が今後の改善につながる重要な知見になっています。 こうした技術的な試行錯誤と並行して、私たちが最も懸念したのは誤った判定によるクライアント様へのご不便でした。 そこで、もしAIが誤ったスタイルを判定した場合でも、クライアント様ご自身でスタイルを簡単に修正できる機能を合わせて開発しました。 スタイル判定結果を確認後、すぐに更新できるような導線を設計することで、ご負担を最小限に抑えられないかと考えました。この判定品質は今後も継続して改善を進めてまいります。 AIとプロダクトの付き合い方 AIは、クリエイティブな発想や複雑な意思決定をサポートしたり、単純作業を代替したりするツールとして、すでに有益な役割を果たしていると思います。 今回、プロダクトの一部としてAIを取り入れて痛感したのは、現時点ではAIに100%の精度を求めるのは難しく、人間の最終的な判断や修正が必要不可欠だということです。 だからこそ、AIの判断を補完する機能や、万一のエラーに備えた代替手段を用意することで、ユーザーにより安全で信頼性の高いサービスを提供することが重要であると考えます。 チームを支えるプロダクトビジョン 「"好き"から始める家づくり」を実現できる世界を作る この画像検索機能の開発は、PdM、デザイナー、エンジニア、全員の挑戦から生まれたプロダクトであり、それを支えたのがプロダクトビジョンです。 私たちの開発は、単に機能を実装することだけを目的としていません。チーム全員で定めた「「"好き"から始める家づくり」を実現できる世界を作る」というプロダクトビジョンの実現を目指しています。 開発中には、AI品質に関する膨大な検証や、ユーザーの使いやすさなど、多くの課題に直面しました。しかし、全員が同じビジョンを共有することで、技術的な困難や仕様の変更にも柔軟に対応し、チーム一丸となってプロダクトの初期リリースを迎えることができました。 しかし、プロダクトビジョンの実現にはまだ遠く及びません。注文住宅検討者にとって素敵な出会いを創出し、ハウスメーカー・工務店様には会社のファンになったユーザー様をマッチングできるように今後も邁進いたします。 今後について 本機能はリリースしたばかりです。今後は、利用意向調査やユーザビリティ調査を実施しながら、ユーザーにとってより使いやすいプロダクトへと磨き込みを続けます。 特に技術面では、AI判定精度の向上と、機能の拡張を必須命題として取り組んでまいります。 最後に LIFULLではともに成長できるような仲間を募っています。 よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
はじめに こんにちは。プロダクトエンジニアリング部でAndroidのネイティブアプリエンジニアをしている久野です。 2025年9月10日から12日にかけて開催された「DroidKaigi 2025」に現地参加してきました。 この記事では、カンファレンスの現地の様子や、特に印象に残ったセッションについてご紹介します。 はじめに DroidKaigi 2025 について 特に印象に残ったセッション 1. 基礎から学ぶ大画面対応 2. 共有と分離 Compose Multiplatform 本番導入の設計指針 3. テストコードはもう書かない。JetBrains AI Assistantに委ねる非同期処理のテスト自動設計・生成 4. スマホ新法、何が変わる?公正取引委員会担当者が語る特定ソフトウェア競争促進法 おわりに DroidKaigi 2025 について DroidKaigiは、Android技術をテーマにしたエンジニア向けのカンファレンスです。 今年もオフラインでの開催となり、多くのAndroid開発者が集まりました。 また、DroidKaigiの大きな魅力の一つは、セッションの動画がYouTubeに公開される点です。しかも、驚くほど早いスピードでアップロードされます。これにより、会場に参加できなかったとしても、後から動画で学習できるのは本当に素晴らしいことだと思います。私も昨年まではオンラインで視聴しており、大変お世話になりました。 もちろん、現地参加には代えがたい価値があります。どのセッションに人が集まっているかを見ることで技術的なトレンドを肌で感じられたり、企業ブースで他社の方々と交流してモチベーションが上がったりと、多くの刺激を受けました。 この記事で紹介するセッションにも、後から見返せるようにYouTubeのリンクを併記しておきます。 特に印象に残ったセッション ここからは、私が聴講した中で特に印象に残ったセッションをいくつか紹介します。 1. 基礎から学ぶ大画面対応 資料 speakerdeck.com セッション概要 Androidアプリにおける大画面対応の基本的な考え方から実践的な実装方法まで解説されていました。実際に「Large screen differentiated」の認定を受けているアプリの開発知見なので、今後のアプリ開発で大画面対応をする際に、ぜひ参考にさせていただきたい内容でした。 特に学びになった点・感想 タブレット対応でヘッダー画像が画面を埋めてしまう問題に対し、画像のサイズを制限し左右にグラデーションを追加するという解決策が印象的でした。大画面に対応しつつ、ユーザー体験を損なわない工夫が非常に実践的だと感じました。 また、大画面では両手での利用が多くなることを想定し、 Navigation rail を導入する点や、 LazyVerticalGrid と WindowSizeClass を利用して画面サイズに応じてUIを切り替える点も、すぐにでも取り入れたい実践的なテクニックで普段の業務で活かしていきたいと思いました。 2. 共有と分離 Compose Multiplatform 本番導入の設計指針 資料 speakerdeck.com セッション概要 Compose Multiplatform (CMP) を本番環境へ導入した際の設計指針に関するセッションでした。会場では3〜4割の人がKMP(Kotlin Multiplatform)開発経験者で、CMP(Compose Multiplatform)を触ったことがある人は1割程度という状況でした。 特に学びになった点・感想 セッションでは、CMPの採用理由やチーム構成など、導入の裏側まで詳しく解説されていました。 特に印象的だったのは、現状Androidエンジニア1名で両プラットフォームの機能開発を行っているという点です。AndroidエンジニアだけでiOSアプリ開発までカバーできるのは、マルチプラットフォームならではの大きな強みだと改めて感じました。 また、91.5%のコードを共通化できた一方で、共通化が難しかった残りの8.5%(デバイス機能や入出力周り)についても詳しく解説されており、とても有益でした。 作りたい機能がある場合、まずはKMP対応ライブラリを探すのが重要という点は、すぐに実践できると感じました。KMPライブラリの検索サービス klibs.io や、JetBrains公式のサンプルプロジェクトは今後の開発で大いに参考になりそうだと感じました。 3. テストコードはもう書かない。JetBrains AI Assistantに委ねる非同期処理のテスト自動設計・生成 資料 speakerdeck.com セッション概要 JetBrains AI Assistantを活用して、非同期処理を含むAndroidのテストコード作成を自動化する手法についてのセッションでした。業務でテスト作成にAIを使い始めたため、より良いテストコードの書き方を学びたいと思い聴講しました。 特に学びになった点・感想 セッションでは、Androidテストにおける現実的な課題として、非同期処理の複雑さやメンテナンスコストの高さが挙げられていました。 特に、非同期処理のテストではスレッドの差し替え、非同期な値の監視、依存のモック化といった定型的な作業が発生しがちです。このような作業こそAIに任せるべき、という考え方にとても共感しました。 セッションで紹介された、5つの評価軸(正確性、網羅性、再現性、保守性、速度・コスト)で「どこまでAIに任せるか」を判断するというアプローチは、自分の業務に置き換えても非常に参考になりました。 単純なCRUD(作成・読み取り・更新・削除)処理のテストでは、正常系や定型パターンはAIに任せられるものの、異常系や境界値のテストは人間の修正およびレビューが不可欠であること。また、WorkManager のような複雑な処理でも、雛形作成はAIに任せられるが、拡張性や保守性を考慮した修正やレビューは人間が行うべき、という切り分けが明確で分かりやすかったです。 AIにテストの雛形作成を任せることで開発速度を上げつつ、品質担保や拡張性が求められる部分では人間がしっかり修正、レビューする、というAIとの協業スタイルが、今後のテスト開発の鍵になるということを学びました。 4. スマホ新法、何が変わる?公正取引委員会担当者が語る特定ソフトウェア競争促進法 資料 セッション概要 2025年12月18日に施行予定の「スマートフォンにおいて利用される特定ソフトウェアに係る競争の促進に関する法律」(通称スマホ新法)について、公正取引委員会の担当者の方から直接解説を聞けるという、技術カンファレンスとしては珍しいセッションでした。多くの開発者が注目しており、会場は満席でした。 特に学びになった点・感想 OSの標準機能(通信、音声入力など)の利用可能性向上や、アプリ外での商品提供(ウェブサイトでのイベント告知など)の拡大といったトピックは、Android開発者として非常に興味深く、勉強になりました。 これまでスマホ新法について自分の理解が浅い部分がありましたが、このセッションを通じて、法律が制定された背景や目的(「なぜ」「何を」するのか)を深く知ることができました。 普段なかなか詳しく学ぶ機会のないテーマだからこそ、担当者の方から直接お話を聞けたのは非常に有意義な体験でした。 おわりに 2日間にわたって参加したDroidKaigi 2025、非常に多くの学びと刺激を得ることができました。 大画面対応やCompose Multiplatformといった実践的な技術セッションから、AIによるテスト自動化、そしてスマホ新法という新しい領域の動向まで、多岐にわたるテーマに触れることができ、Android開発のモチベーションがとても高まりました。 特に、今年はセッション・企業ブースを問わず、 生成AI と Kotlin Multiplatform、 Compose Multiplatform に関する話題が非常に多かったのが印象的でした。業界全体の大きなトレンドを肌で感じることができました。 オンラインでの参加も手軽で素晴らしいですが、やはり現地では、こうした会場の雰囲気や他の参加者とのコミュニケーションを通じてとても勉強になることを改めて実感しました。 最後になりますが、LIFULL では一緒に働いていただける仲間を募集しています。今回希望してイベントに参加をしたように、エンジニアが成長できる機会が盛りだくさんの職場です。カジュアル面談もやっていますので、よろしければこちらもご覧ください。 hrmos.co
はじめに LIFULLにて基盤グループのマネジメントをしている磯野です。 2025年8月28日に開催された「 Amazon Q Developer Meetup #2 Amazon Q Developer を業務で活用した成果共有と最新情報 Update 」に参加し、LIFULLでの活用事例について発表させていただきました。 当日は株式会社マイナビ様の事例発表もあり、他社での活用状況を知ることで多くの共通点や共感できる部分がありました。また、懇親会では各社の担当者の方々と直接お話しでき、様々な活用方法や課題について情報交換することができ、今後更にいろいろ試せそうで非常に有意義な時間を過ごさせていただきました。 本記事ではイベントで発表した内容をもとに、Amazon Q Developerの導入から社内展開、そして多職種での活用事例について、LIFULLでの実践例をご紹介します。エンジニアだけでなく、サービス企画やデザイナーまで幅広い職種で活用が広がっている現状と、その具体的な事例をお伝えします。 はじめに 導入から拡大まで 導入のきっかけ 拡大戦略 1. 草の根で広げる 2. 波に乗る 現在の利用者数 事例紹介① スライド作成自動化 課題:スライド作成の効率化 解決策:HTMLスライドの生成 HTMLスライドのメリット 自動化ワークフロー 事例紹介② サービス企画・PMでの活用 1. プロトタイプ作成 社内への影響 2. 施策のアイデア出し 設定するコンテキスト 制約条件ドキュメントの育成プロセス 3. 効果測定レポート自動化 Before vs After 品質向上への取り組み その他の活用事例 社内MCPサーバー Qランキング ローカルMCP 通知機能 社内AIサービスとの連携 プロジェクト専用エージェント設定(検証段階) エージェント用設定ファイル 起動方法 実際の動作例 デザイナーでの活用(検証段階) プロトタイピング サービス改善 まとめ 導入から拡大まで 導入のきっかけ 昨年10月から今の部門のマネジメントを任されており既存の課題である対応スピードの改善を主要なミッションの1つとして持っています。 とくに、LIFULL HOME'Sの主要サービスのAWSアカウントやそこで動くインフラの管理をしている関係で、自動化やIaCの推進をしてくことが急務だったため、AIエージェントを活用していきたいと考えていました。 具体的には以下のようなことを意識して選定しています ほとんどコードを書かない基盤グループでCDKでの開発を推進する CLIでの作業が基盤グループの業務にマッチしていた AWSコンソールや認証への統合など、AWS環境との親和性が高い 利用していく中で、開発だけでなく調査や分析もLinuxコマンドを活用しながら処理でき、想像以上に便利だったため、「これはイケる!」という手応えを感じました。 拡大戦略 その手ごたえを受けて、もっと広く活用してもらえるのではないかと考えた結果、 Amazon Q Developerの社内展開を以下の2つのアプローチで進めました: 1. 草の根で広げる 近くのエンジニア部門のマネージャ、リードエンジニアに自分の使っているところを見せて使ってもらう 乗り換えを受け入れられるように予算・登録・利用方法を整備する 2. 波に乗る Qのアップデートを積極的に取り入れる MCP対応 / Claude Sonnet 4対応 企画の検証の1つとして使ってもらう この草の根 + 波に乗る戦略により、利用者が着実に拡大していきました。 特にマネジメント層が前向きに導入を進めてくれた部門では部門の総会などで活用事例を共有してくれるなど周りの後押しにも支えられています。 また、Q自体のアップデートのタイミングも本当に素晴らしく、ほしいときに欲しい機能がリリースされてくれたため強い後押しになりました。 導入検証開始 → Q CLIがmcpに対応 エンジニア全体に拡大開始 → Q CLIがClaude Sonnet 4に対応 サービス企画の導入検証開始 → 上記2つがIDE版に対応 直近ではエージェントの作成機能が追加されるなどまだまだ追加されるものは多く、今後にもとても期待しています。 話が少しそれてしまいますが、個人的に最近のアップデートで最高だったものはログインのawscliへの統合です。 これによりQへのログインはせずにAWSにログインするだけで利用できるため、朝のログイン作業が劇的に楽になりました。 # 環境変数を設定 export AMAZON_Q_SIGV4=1 export AWS_PROFILE=[プロファイル] # AWS SSOでログイン aws sso login # Q Chatを開始 q chat 現在の利用者数 現在ではエンジニアを中心にサービス企画やデザイナーなどに浸透し、その範囲においては9割以上のメンバーが登録済みの状態です。 ここから先は当日発表した事例についての説明です。 当日はスライド自動作成はLIFULL HOME'Sの流通領域のエンジニアチームにてマネジメントをしている渡邉から、サービス企画・PMでの活用事例はパーソナライズやレコメンド機能などのPMをしている井上から発表させていただきました。本記事は私が取りまとめて執筆しています。 事例紹介① スライド作成自動化 課題:スライド作成の効率化 管理職になってスライド作成機会が激増する中で、以下の課題を抱えていました: デザインに自信がない 細かい調整が苦手 時間がかかりすぎる 従来は4時間かけてPowerPointと睨めっこしていたのが、Amazon Q Developerを使うことで数分で完成するようになりました。 解決策:HTMLスライドの生成 最初はpptxをAIに作らせようと考えましたが、「伝える」上でフォーマットにこだわる必要はないと気づき、 Amazon Q DeveloperにHTMLでスライドを生成してもらう アプローチを採用しました。 HTMLスライドのメリット コードブロック対応 : スクローラブルなデザイン、コピー機能付き Git管理 : バージョニングが容易、チーム共有も簡単 高い自由度 : デザインや画面幅の制約が少ない、レスポンシブ対応 統一感 : GUIDELINE.mdで自動適用、再現性のあるデザイン 自動化ワークフロー GUIDELINE.mdで定義された3ステップで自動化を実現: アウトライン生成 : README内容を読み解いてOUTLINE.md作成 スライド生成 : アウトラインを元にHTMLスライド作成 ファイル出力 : 絶対パスで表示、ブラウザ確認可能 実際に今回のスライドも5分程度で生成することができています。 例えば、"自動化ワークフロー"の実際の生成されたページは以下のようになっています。 自分でパワーポイントでやってもできる自信はないです。 HTMLでのスライドの為ここに貼れないのが残念ではありますが、スライド作成についての詳細は以下を是非ご覧ください www.lifull.blog 事例紹介② サービス企画・PMでの活用 1. プロトタイプ作成 DeNAさんが企画書にプロトタイプを必須化というニュースにインスパイアされ、早速トライしたところ、 1時間程度でかなり良いプロトタイプが完成 しました。 社内への影響 「企画でもプロトタイプが作れる!」というインパクトから利用者が急増し、以下の効果が生まれました: プロトタイプを作成するプロジェクトが 増加中 従来の企画書・仕様書に代わる 新しいコミュニケーション手段 として定着 デザイナー・エンジニアとのコミュニケーションが 格段にスムーズ に 「動くもの」で認識合わせを行うことで、認識齟齬を大幅削減できています。 2. 施策のアイデア出し ChatGPTなどでもアイデア出しは可能ですが、コーディングエージェントのメリットは コンテキストの活用 です。 設定するコンテキスト プロダクトの概要・ターゲットユーザー・仕様など 技術的制約、予算制約、時間制約などの 制約条件(特に重要) 制約条件がないと実現性度外視のアイデアばかりが出てくるため、 制約条件の提供がアイデア精度向上の鍵 となります。 制約条件ドキュメントの育成プロセス 実践的な3ステップで制約条件ドキュメントを育成: まずAmazon Q Developerにアイデアをたくさん出してもらう 「◯◯という理由でできない」を逐一伝えていく 「今回伝えた制約条件をドキュメントにまとめておいて」 制約条件ドキュメントを育てることで、かなり精度の高い(ハズレの少ない)アイデア出しができています。 3. 効果測定レポート自動化 Before vs After 従来の作業プロセス(半日〜1日の手作業) - データの抽出 - 分析・考察の作成 - ネクストアクションの検討 - 他の人に読みやすく整理 Amazon Q Developerで効率化(1〜2時間で完結) - データをテキストで貼り付け - 自動で分析・考察を生成 - 次の施策案も自動提案 - MCP経由で直接投稿 結果として、 80%の作業時間削減 を実現しています。 品質向上への取り組み 初回から完璧な結果は得られないため、以下の問題に対処: 問題1 : 事実と推測が混在、推測を事実かのように断言 問題2 : 根拠の低い、説得力のない仮説を立ててくる 問題3 : ネクストアクション(施策)が10個以上出てきて絞り込めない 逐一修正指示を行い、その内容を ルールとして蓄積 し、次回以降の効率化につなげています。 その他にも企画業務全般で活用が広がっています。さらなる生産性向上に向けて、企画職全体で取り組みが進んでいます。 その他の活用事例 以上が主な活用事例ですが、他にも社内では活用していくにあたっていろいろと進めていますので簡単な事例として紹介させてもらいます。 おそらく各担当が今後ブログなどで記事を作成してくれると思います。 社内MCPサーバー 社内システムとの連携を実現するMCPサーバーを構築し、Amazon Q Developerから直接社内システムにアクセスできる環境を整備しています。 インストール型ではなくサーバーで稼働させることで職種の隔てなく簡単に導入できるようになっています。 具体的なシステムとしては Jira/Confluence, データベースのテーブル定義情報などです。 Qランキング 利用状況の可視化と競争要素の導入により、利用促進を図っています。 ランキング出力部分もAmazon Q Developerに指示して作成してもらっているので、こういった活用により自分のランキングもかなり上位になっています。 (TOP3には入れるんですが1位にはなれないのでまだまだ活用が足りないようです) ローカルMCP 通知機能 タスク完了の通知をMCP経由でOSの通知に送信 通知でも弱いのでOSの音声再生に送信 ※Qの処理時間が長くなると忘れてて20分後に通知がくる場合があって、MTG始まってたりするとざわつくので最近止めてます 社内AIサービスとの連携 使い道は模索中 将来的な拡張性を見込んだ基盤構築 開発者体験の向上を追求しています。 プロジェクト専用エージェント設定(検証段階) 最近追加されたエージェント機能により、開発だけでなく、調査や運用でも活躍できる特化エージェントを設定できます。手順書があれば細かいコードを書かなくてもエージェントが助けてくれる環境を構築中です。 以下は最近作ってみた「静的サイトをS3+CloudFrontで公開するためのエージェント」の例です。 エージェント用設定ファイル 基盤グループで稀に発生する静的サイトの公開をエージェントでできるようにしています。 もともとはエージェント関係なくQ用にコンテキストを作成していたので、エージェントはこのファイルを読み込む設定をしただけで数分で完成しています。 定義ファイルを簡単に記載しつつ、詳細なコンテキストは別ファイルとして渡しています。 起動方法 設定ファイルに指定した名前を指定してプロジェクト内で起動します。 実際の動作例 このように手順書やAI用のコンテキストがあれば、簡単に特定機能に特化したエージェントを作成できるので可能性は無限大だと思います。 事例1で紹介したプレゼンテーション作成のエージェントも今後はリポジトリ上でエージェントとして管理していけるように調整中です。 デザイナーでの活用(検証段階) まだこれからの段階ですがデザイナーでもPMでの活用をうけて検証を開始しています。 それによりAIを活用し素早いユーザー価値提供を目指しています。 プロトタイピング HTML/CSSでプロトタイプ作成 簡単な動作確認 FigmaとのMCP連携 サービス改善 企画からデザインのガイドライン化 企画から直接HTMLへ反映 デザインプロセスの省力化 まとめ Amazon Q Developerは、コーディングだけではなく、 設計からタスク定義、そしてエンジニア以外の生産性を革新的に向上させるプラットフォーム として機能しています。 LIFULLでは、エンジニアから始まった活用が、サービス企画、デザイナーまで広がり、各職種の特性に合わせた活用方法を見つけることで、組織全体の生産性向上を実現しています。 今後もさらなる活用を目指し、新しい可能性を探求していきます。 ※本記事はスライド用HTMLを出力する前のmarkdownファイルをもとにQ CLIでブログ用に出力し手動で整形して提供しています。 最後に、LIFULL ではともに成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
こんにちは。プロダクトエンジニアリング部の江口です。主に賃貸部門の開発を担当しています。 このたび、LIFULL HOME'Sの賃貸詳細ページにおけるサーバーサイドの処理速度を改善し、 99パーセンタイルを60%改善しました 。 本記事では、このパフォーマンス改善をどのように実現したのか、具体的な技術的アプローチについて解説します。 背景 分析から見えたパフォーマンスボトルネック 改善のためのアプローチ 成果 終わりに 背景 サーバーサイドの処理遅延は、ユーザー体験だけでなく収益にも悪影響を及ぼします *1 。特に、平均処理時間は良好でも99パーセンタイル(p99) *2 が高い場合、一部のユーザーは大きな遅延に遭遇し、不満を感じてサイトから離脱してしまいます。そのため、p99を改善することは離脱率の低下に直結し、長期的には収益にも良い影響をもたらします。 こうした課題は多くのWebサービスで共通していますが、LIFULL HOME'Sの賃貸詳細ページでも例外ではありませんでした。詳細ページのサーバー処理時間のp99は、平均値と比較して大きく遅延している状態でした。 賃貸詳細システムにおけるサーバーサイド処理時間の比較 そこで、詳細ページにおけるボトルネックを特定し、p99の改善活動に取り組みました。 分析から見えたパフォーマンスボトルネック まず、アプリケーションのメトリクスやトレースから、ボトルネックとなっている処理の特定を試みました。分析を進める中で、特に以下の点が明らかになりました。 計測不能な処理時間の存在 : トレースのスパンとして計測されない、実体の不明な処理に時間がかかっている箇所が見られました。 イベントループの遅延 : 最大1秒にも及ぶイベントループの遅延が判明しました。これは、他のリクエスト処理もブロックし、サービス全体の応答性能を低下させる要因となりえます。 賃貸詳細システムのトレース イベントループの最大遅延(秒) これらのデータから、イベントループのブロッキングがアプリケーションロジックに起因する可能性が高いと判断しました。そこで、CPUの使用状況とメモリ消費を継続的に監視できるPyroscope(継続的プロファイラ)を導入し、詳細な調査を開始しました。Pyroscopeによる継続的プロファイリングの結果、イベントループのブロッキングとCPU占有を引き起こしていた可能性のある処理を見つけることができました。 URLエンコードの同期的な高負荷処理 : APIへのリクエスト送信前に、特にセッション情報のような長い文字列をURLエンコードする処理が、同期的に実行されていました。この処理はCPUを長時間占有することで、イベントループをブロックし、アプリケーション全体の応答性を低下させる要因となる可能性があります。 セッション情報のデシリアライズ : バックエンドAPIから取得するセッション情報は、PHPのシリアライズ形式で格納されています。このPHP形式のデータをアプリケーションで利用可能な形式にデシリアライズする処理もまた、CPUを大量に消費する同期処理でした。この処理がイベントループをブロックし、パフォーマンスの低下につながる可能性がありました。 同期的なサーバーサイドレンダリング : 賃貸詳細システムのHTMLレンダリングにはPreactを使用しています。サーバーサイドレンダリング(SSR)の際、tsxデータから仮想DOMノードを生成し、それをHTML文字列に変換する処理が同期的に実行されていました。この一連の処理はCPUを長時間占有することで、他のリクエスト処理の応答性を阻害する要因となりえます。 これらのボトルネックは、いずれも同期的な高負荷処理が原因でイベントループをブロックし、アプリケーション全体のパフォーマンスに影響を与えていたと考えられます。これら以外にも多数のボトルネックが存在しますが、代表的なものは上記の3点でした。 改善のためのアプローチ イベントループのブロッキングを抑制する一般的なアプローチとしては、CPUバウンドな処理の高速化やWorker Threadsへの処理のオフロードなどがあります。 試行錯誤の結果、URLエンコードの同期的な高負荷処理がイベントループをブロッキングする主要な原因の一つであることが判明しました。この処理を、外部ライブラリの qs からネイティブのURLSearchParamsに置き換えることで、イベントループのブロッキングが大幅に改善されました。特に、大規模なクエリパラメータを処理する場合、URLSearchParamsはqsと比較して最大で4倍以上高速に処理できることが確認できました。 // 変更前(qs) private convertQueryString(param: object) { return qs.stringify(param, { sort : ( a : string , b : string ) => { return a. localeCompare (b); } , arrayFormat : 'comma' , } ); } // 変更後(URLSearchParams) private convertQueryString(param: Record< string , unknown >) { const urlSearchParams = new URLSearchParams (); const sortedKeys = Object . keys (param). sort (); for ( const key of sortedKeys) { const value = param[key]; if (value == null ) continue ; if ( Array . isArray (value)) { urlSearchParams. append (key, value. join ( ',' )); } else { urlSearchParams. append (key, String (value)); } } return urlSearchParams. toString (); } URLSearchParamsに修正後の最大イベントループ遅延 この変更によって高速化できた理由は、主に「ネイティブ実装との速度差」と「処理のオーバーヘッド削減」にあります。 まず、URLSearchParamsはNode.jsにC++等で実装されたネイティブAPIであり、最適化されたマシンコードで極めて高速に動作します。対照的にqsはJavaScriptで実装されているため、実行速度に根本的な差が生まれます。さらに、qsはネストされたオブジェクトなど複雑なケースに対応する汎用的なライブラリであり、その分、内部には多くの条件分岐といったオーバーヘッドが含まれます。今回の実装は、必要な処理に特化してネイティブAPIを直接呼び出すため、こうしたオーバーヘッドが一切ありません。 これらの要因が組み合わさり、CPUを占有する同期処理の時間が劇的に短縮され、イベントループのブロッキングが解消されたと考えます。 成果 上記のURLエンコード処理の高速化のリリースによって、p99を60%改善することができました。 サーバーサイド処理時間(p99)の改善 終わりに 今回のパフォーマンス改善は、可観測性の向上を目指すところから始まりました。メトリクスや継続的プロファイリングツールの導入だけではなく、必要に応じて手動でスパンやメトリクスを追加することで、p99の高さを生み出す根本原因をデータから特定しました。 また、既存ライブラリが自分たちのユースケースにマッチしているか検証する重要性も再認識しました。汎用的なライブラリがパフォーマンスのボトルネックとなる場合があり、ネイティブAPIのような特化した代替手段を検討することで、劇的な改善につながることがあります。 ウェブアプリケーションの速度改善は、まるで謎解きのようです。メトリクス、トレースデータ、ログといった手がかりを丹念に観察し、パフォーマンスのボトルネックを特定していく作業は、個人的にとても楽しい時間です。そして、改善策を適用した結果、システムのレスポンスタイムが向上したり、プロファイルデータが変化したりするのを直接データで確認できるのは、何よりも魅力的だと感じています。 これからも、ユーザーの皆さんにより快適な体験を提供できるよう、システムのパフォーマンス改善に情熱を持って取り組んでいきたいです。 最後に、LIFULL ではともに成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 hrmos.co hrmos.co *1 : https://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html *2 : 応答時間の分布において、観測された応答時間の99%がこの値以下に収まる点を指します。
こんにちは、LIFULLでシニアエンジニアをしている渡邉です。普段はLIFULL HOME'Sの流通領域のエンジニアチームにてマネジメントをしています。 みなさんは業務の中でスライドを作る場面ってどのくらいありますでしょうか? 私は管理職になってから業務上ビジョンシェアリングの機会や総会等での発表の機会が増えました。 それに伴い以前にも増して圧倒的にスライドを作成する作業の時間が増えました。 私の場合、話したいことは思い付くし、文章に起こすこともできるのですが、それをスライドにするのが手間がかかる上スライドを作るセンスにも自信がありません。 これが回り回ってかなりストレスになっていました。 そんな課題感から、この作業をどうにか簡略化できないかを検討し、弊社で主に使われているAmazon Q Developerを使ってスライド作成を自動化するしくみを検討しました。 結果として、 従来数時間かかっていた作業が数分で完了 するようになり、生産性が大幅に向上しました。 今回は、その具体的な手法と実装について詳しく紹介します。 背景:管理職のスライド作成問題 管理職になると、ビジョンシェアリング、プロジェクトキックオフ、経営陣向け戦略発表など、さまざまな場面でスライドを作成する機会が増えます。 しかし、以下のような課題がありました。 時間がかかりすぎる : 1つのスライドセットに数時間程度必要 デザインセンスの不足 : 見栄えの良いスライドが作れない 構成の悩み : 伝えたいことをどう整理すればよいかわからない 繰り返し作業 : 似たような構成のスライドを何度も作成 これらの課題を解決するため、Amazon Q Developerを活用した自動化システムを構築することにしました。 解決アプローチ:LLMにHTMLを書かせる 今回採用したアプローチの核心は、 LLMにパワポのスライドのように動作するHTMLを生成させることで、擬似的なスライドを作成する ことです。PowerPointやKeynoteではなく、HTMLベースのスライドにすることで以下のメリットがあります。 自由度の高いデザイン : CSSを使った柔軟なレイアウト 一瞬での生成 : テンプレートに縛られない迅速な作成 簡単なデプロイ : 静的ファイルとして簡単にホスティング可能 バージョン管理 : Gitでの管理が容易 HTML故の自由度 : HTMLなのでスクローラブルなデザインにすることも可能 テキストのコピーのしやすさ : コードブロックをスライドに落とし込んだ場合テキストのコピーが容易 パワポライクな画面にも適用 : 普段のスライドアプリケーションと同様にキーボードでスライドを捲るデザインにもできる Amazon Q DeveloperはモデルとしてClaude Sonnet4を利用しているのでコードを作成することが得意です。 そのためスライドを作成するよりもスライドのように機能するHTMLを書かせる方がかなえたい要求を満たしやすいです。 実際に生成されたスライド風HTML 実装手順 1. Amazon Q CLI プロファイルの作成 まず、スライド作成専用のプロファイルを作成します。 /profile create slide 2. コンテキストファイルの設定 .aws/amazonq/rules/slide/ ディレクトリを作成し、コンテキストを紐づけます。 /context add "~/.aws/amazonq/rules/slide/*.md" 3. ガイドラインファイルの作成 最も重要なのが GUIDELINE.md の作成です。このファイルにスライド作成のルールやデザイン指針を詳細に記載します。 この名前に特に縛りはありませんが、私の場合GUIDELINE.mdとしています。 GUIDELINE.mdの主要な内容 私が実際に作成したコンテキストは以下の内容で設定して使っています。 # スライド作成用のコンテキスト ## 目的 - このコンテキストは、ビジョンシェアリングや発表資料に適したスライドを作成するために必要な情報と手順を提供します。 ## 作業の進め方 1. ユーザーから与えられた文章やREADMEの内容やURLの内容を読み解いた上で、発表資料としてわかりやすくシンプルな形になるようにアウトラインを生成します。 2. アウトラインを生成する場合には必ず、"##アウトラインの作成手順"に沿ってOUTLINE.mdを作成してください。 3. OUTLINE.mdの作成とブラッシュアップが完了した後で、OUTLINE.mdの内容を元にパワーポイントのスライドのような挙動をするHTMLファイルでスライドを生成します。 ## デザイン - #ed6103のカラーをメインの色として、その色を利用する上で違和感のないよう作成をお願いします。 - 主張したい文字や情報については文字を大きくしたり色を変更したりなど見た目でわかりやすくしてください。 - 背景は可能な限り白にして欲しい - 全体の配置として余白はあまりないように作ってください。 - 一枚目のスライドのタイトルは大きい文字でわかりやすく作ってください。 ## スライドで注意するポイント - 1スライド1メッセージもしくはシンプルな見た目のデザイン - 一枚目にはタイトルと発表者指名を記載(渡邉陸斗) - 読み上げないで説明できる内容 - 視覚効果(アイコン、グラフ)を効果的に使用 - 数字でアピールできるものに関しては必ず取り入れる - 堅い文章になりすぎないようにしつつも社会人として問題のない内容で記載 - フォントはできるだけ画面共有しても見やすいように大きめに作成する24px以上 - 必ずキーボード操作もできるように作成して欲しい - スクローラブルなブロックがある場合にはスクロールできることも記載して欲しい - スクローラブルなブロックがコードブロックの場合にはコピーボタンを記載して欲しい。 実際の使用フロー ステップ1: 伝えたいことを文章化 まず、README.mdやドキュメントに伝えたいメッセージや思い、数字を文章としてまとめます。たとえば、今回の記事の元となったREADME.mdは以下のような内容でした。 # 概要 AmazonQを使ってスライドを簡単に生成できるようにしたのでその方法の共有 ## 背景 管理職になって圧倒的にスライドを作成する時間が増えた。 話したいことは思いつくし、文章に起こせるけどそれをスライドにするのは時間がかかる。 あと絶望的にスライドを作るセンスがない。 そんな課題感からスライドの作成だけを楽にしたかった。 ## 成果 かなり雑に文章を書いてもちゃんとしたスライドに起こしてくれてビジョンシェアリング用の資料や発表用資料として生成してくれます。 普段なら4時間くらいかかっていた作業が数分で完了するので、生産性が上がっています。 ステップ2: アウトライン生成 Amazon Q Developerに文章を読み込ませ、スライドごとの構成要素をまとめた OUTLINE.md を生成してもらいます。 この段階で、スライドの全体構成と各スライドで説明したいことを整理します。 修正が必要であれば手を加えて情報の過不足をチェックしてください。 ステップ3: HTML生成 OUTLINE.md の内容に沿って、パワーポイントのようにキーボードで操作できるHTMLスライドを生成します。 生成されるHTMLには以下の特徴があります。 レスポンシブデザイン : さまざまな画面サイズに対応 キーボード操作 : 矢印キーでスライド切り替え可能 統一されたデザイン : ブランドカラー(#ed6103)を使用 読みやすいフォント : 24px以上の大きなフォントサイズ ステップ4: デプロイ 生成されたHTMLファイルをS3などの静的ホスティングサービスにアップロードします。 これによって周りの人にも資料を提供できます。 LIFULLではHTMLをホスティングするためのサービスを内製していますので、それを利用することで簡単にデプロイできます。 実際のプロンプト例 スライドを作成する場合に 実際に使用しているプロンプトの例を紹介します。 このREADME.mdの内容を元に、Amazon Q Developerを使ったスライド作成自動化について の発表用スライドを作成してください。 重要なポイント: - LLMにHTMLを書かせることで自由度の高いスライドが作れること - 4時間の作業が数分になったこと - 実際のプロンプトやコンテキストの内容も含めること まずはOUTLINE.mdを作成してください。 成果と効果 このしくみを導入した結果、以下の成果を得ることができました。 時間短縮効果 従来 : 3~4時間程度 現在 : 数分程度 短縮率 : 約90% 品質向上 統一されたデザインテンプレート 読みやすいフォントサイズとレイアウト 一貫したブランディング 柔軟性の向上 HTMLベースなので細かいカスタマイズが可能 CSSで自由なデザイン調整 JavaScriptでインタラクティブな要素も追加可能 まとめ Amazon Q Developerを活用したスライド作成自動化により、 数時間の作業を数分に短縮 できました。 特に、LLMにHTMLを直接生成させるアプローチにより、従来のプレゼンテーションツールでは実現困難な自由度の高いスライドを短時間で作成できるようになりました。 このしくみの成功要因は以下の3点です。 詳細なコンテキスト設計 : GUIDELINE.mdでの明確な指針 段階的な生成プロセス : アウトライン → HTML の2段階アプローチ HTMLベースの選択 : 柔軟性とデプロイの簡単さ 管理職として、限られた時間の中で質の高いプレゼンテーション資料を作成する必要がある方には、ぜひこのアプローチを試していただきたいと思います。 他にも報告レポートやブログ執筆用のプロファイルを生成することで作業を効率化することも可能だと思います。 Amazon Q Developerの可能性を最大限に活用することで、創造的な業務により多くの時間を割くことができるようになるでしょう。 最後に、LIFULL ではともに成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
こんにちは、LIFULLでシニアエンジニアをしている渡邉です。普段はLIFULL HOME'Sの流通領域のエンジニアチームにて、マネジメントをしています。好きなCI/CDツールはGitHub Actionsです。 以前、こちらの記事で、私たちのリリースフロー改善への取り組みをお話しました。 www.lifull.blog あれから数ヵ月が経ち、私たちのGitHub Actions集約型リリースフローは想像以上に進化を遂げました。今回は、その変化と新しく追加された機能について、実際の開発現場での体験を交えながらお伝えします。 🚀 何が変わったのか?主要なアップデート 1. セットアップが驚くほど簡単になりました 2. Chrome拡張機能で承認作業が格段に楽になりました 3. 企画担当者の方でも迷わず使えるガイドを作りました 4. リリース忘れを防ぐ機能を追加しました 5. 開発タスクの管理が自動化されました 6. 🎯 自動リリース機能でリリーサーの負荷がほぼゼロに 7.使いやすさへのこだわり 見た目でわかる設計 自動化されたリリースプロセスにおける課題を解決するためのしくみ グローバルチームにも対応 実際の開発現場での変化 導入前の悩み 導入後の声 🎉 実際の導入効果:数字で見る劇的な改善 リリース頻度の大幅向上 承認からリリースまでの時間短縮 企画担当者にもわかりやすい 自動マージ機能の効果 通知システムの効果 あらゆるリポジトリ形態に対応 柔軟な導入アプローチ ユースケースに合わせた導入方法の提供 自動リリースがもたらした革命的変化 リリーサーの役割の変化 組織全体への影響 これからの展望 まとめ 🚀 何が変わったのか?主要なアップデート 1. セットアップが驚くほど簡単になりました 以前は手動での設定が必要でしたが、今では対話形式の inquirer を用いたCLIツールを用意しました。 npm install npm run setup これだけで、チームに必要なワークフローを選択しながら自動生成できます。「どの機能を組み合わせればよいかわからない」という悩みから解放されます。 CLIを実行した様子 2. Chrome拡張機能で承認作業が格段に楽になりました リリース承認の煩雑さを解決するChrome拡張機能を開発しました。 ボタン一つで承認完了 : /G長承認OK や /PJ承認OK のコメントがワンクリック 新リリースフローの対象リポジトリにて、承認に必要なドキュメントのリンクを表示 拡張機能により提供されるもの もう「承認コメントってどう書くんだっけ?」と悩む必要はありません。 具体例 : /G長承認OK というコメントを手動で入力する代わりに、PR画面に表示される「G長承認」ボタンをクリックするだけで承認が完了します。 3. 企画担当者の方でも迷わず使えるガイドを作りました 技術に詳しくない方でも安心してリリース承認ができるよう、専用ガイドを整備しました。 確認すべきポイントを4つに絞った分かりやすい説明 豊富なスクリーンショットで視覚的にサポート 「ここだけ見れば大丈夫!」という安心感を提供 具体例 : 「Epic Issueの確認」「ビジネス観点のチェック」「PJ承認コメント」「承認状況確認」の4ステップで、技術的な知識がなくても確実に承認作業を完了できます。 4. リリース忘れを防ぐ機能を追加しました 新しく追加したRelease PR Reminder機能で、リリース日にPRが長時間未マージの場合、自動でSlack通知が送られます。 Google Calendarと連携してリリース日を自動判定 通知タイミングは調整可能(デフォルト1日) リリーサーへの確実な通知でリリース漏れを防止 5. 開発タスクの管理が自動化されました Sub-Issue自動管理システムにより、開発タスクの進捗管理が飛躍的に向上しました。 自動でタスク分解 : PRに紐づく開発作業を自動で細分化 進捗の可視化 : 全タスク完了時に自動でラベル付与 承認者も安心 : 開発作業の完了状況が一目でわかる 具体例 : PRを作成すると「QA仕様書作成」「デザインチェック」「開発チェックシート」などのSub-Issueが自動生成され、各タスクの完了に応じてPR上の進捗バーが更新されます。 subissueによるタスク分解 開発タスクの進捗状況の確認 6. 🎯 自動リリース機能でリリーサーの負荷がほぼゼロに 今回の最大の進化は、 完全自動リリース機能 の実装です。これにより、リリーサーの作業負荷が劇的に軽減されました。 自動リリースのしくみ : リリース条件がすべて満たされた場合、自動的にmasterブランチへのマージ ステージング環境テスト・プロダクション環境テストが完了したPRのみが対象 ステージング環境テスト、プロダクション環境テストが終了していない場合には開発者への訴求をGitHub上で自動通知 リリース後の開発者への通知も自動化 1日経っても未マージのリリースPRの自動検出と通知 リリーサーのタスク変化 : 従来 : 手動でのPRマージ、リリースしたことを開発者へ通知、確認作業の管理 現在 : 例外的なケースのみの対応(通常時はほぼ作業なし) メリット : 人的ミスの排除 : 手動操作によるミスが完全になくなりました リリース時間の短縮 : 条件が整い次第、即座にリリースが実行されます リリーサーの負荷軽減 : 定型作業から解放され、より重要な業務に集中できます 24時間対応 : 人の都合に関係なく、いつでもリリースが可能です 7.使いやすさへのこだわり 見た目でわかる設計 ラベルによる可視化 : 承認状況がPRのラベルで即座にわかる 進捗バー : タスク完了率を視覚的に表示 ステータスアイコン : 一目で状況を把握できる 自動化されたリリースプロセスにおける課題を解決するためのしくみ 自動導入 : リリースフローのワークフローを導入する際にCLIを利用して導入することで、手続的にリポジトリナイズされた設定を施したうえで導入が可能 権限管理 : 承認、マージする際には適切な権限を持つ人のみが実施可能 自動チェック : リリースに必要な開発タスクや、リリースチェックなど実施すべき項目が適切に行われていることをワークフローにより自動的にチェック 通知の強化 : あらゆるリリースに関する通知を自動化し、人間による通達漏れを排除 リリース依存性の担保 : リリース順序が決まっているマイクロサービスにおけるリリース順序が逆転しないようにするための依存先のリリースストップ機能 強行リリース : 何らかの理由によりワークフローが失敗し続ける際や、承認をまたずリリースしたいものがある場合のための承認者による強制リリースの実行方法の確立 グローバルチームにも対応 日本語・英語両対応のドキュメント 国際的なチームでも安心して利用可能 実際の開発現場での変化 導入前の悩み 「承認コメントの書き方がわからない...」 「どのタスクが終わっているか把握できない...」 「リリース日なのにPRがマージされてない!」 「企画の人にGitHubの使い方を説明するのがたいへん...」 「リリーサーが忙しくてリリースが遅れる...」 導入後の声 「ボタン一つで承認が終わるなんて!」 「タスクの進捗が自動で更新されるから楽」 「リリース忘れがなくなった」 「企画の人も迷わず承認してくれる」 「リリーサーを待つ必要がなくなった!」 🎉 実際の導入効果:数字で見る劇的な改善 リリース頻度の大幅向上 導入後、 1日に2回のリリース が可能になりました。従来は承認プロセスの複雑さから週1-2回程度だったリリースが、自動化により大幅に増加。これにより、ユーザーへの価値提供スピードが格段に向上しています。 リリース数の変化 承認からリリースまでの時間短縮 承認からリリースまでの時間が劇的に短縮 されました。従来は承認後数日かかっていたリリースが、現在では承認と同日、場合によっては数時間以内にリリースが完了するケースも増えています。 リリースまでのリードタイムの変化 企画担当者にもわかりやすい 専用ガイドとChrome拡張機能により、 技術的な知識がなくても確実に承認作業を完了 できるようになりました。 自動マージ機能の効果 開発チームでは 自動マージ機能 が特に高く評価されています。 自動マージには、承認が完了したPRが自動的にステージング環境でマージされる機能と自動的にリリースを行う機能の2つが用意されています。 条件の整ったPRが自動的にマージされることで、リリーサー、開発者の待ち時間が大幅に削減され、より重要な開発作業に集中できます。 通知システムの効果 リアルタイム通知システム により、リリース状況の把握が格段に向上しました。関係者全員がリリースのタイミングを正確に把握できるようになり、連携ミスが大幅に減少しています。 あらゆるリポジトリ形態に対応 私たちが特に重視したのは、 どのような形態のリポジトリでも問題なく使える汎用性 です。 モノリスアプリケーション : 単一リポジトリでの大規模開発 マイクロサービス : 複数の小さなサービスに分かれた構成 フロントエンド・バックエンド分離 : 異なる技術スタックでの開発 ライブラリ・SDK : ほかのプロジェクトから利用されるコンポーネント どのような開発スタイルでも、チームが同じ操作感でリリース管理を行えるよう設計しています。 柔軟な導入アプローチ 私たちが特に意識したのは、「チームの状況に合わせて必要な機能だけを選んで導入できる」ということです。 ユースケースに合わせた導入方法の提供 承認フローの改善 : G長・PJ承認をGitHub上で完結 開発タスク管理 : Issue駆動開発でタスク管理を自動化 リリースチェック : 本番・検証環境での確認作業を体系化 完全自動化 : リリーサー不要の自動リリースを実現 メンテナンス性 : 自動バージョンアップ機能の提供 どの段階でも確実に開発体験が向上するよう設計しています。 自動リリースがもたらした革命的変化 リリーサーの役割の変化 従来のリリーサーの1日 : 午前中: リリース予定PRの確認 昼ごろ: リリースの実施と開発者への通知 夕方: リリースチェック作業の確認 現在のリリーサーの1日 : 午前、午後: システムからの自動通知を確認(必要時のみ) 例外ケース発生時のみ対応 通常時はほかの業務を行い、リリース作業は実施せず 組織全体への影響 開発速度の向上 : リリーサーの都合を待つ必要がなくなり、定刻にリリースできるようになりました 品質の安定 : 人的ミスが排除され、リリース品質が向上しました コスト削減 : リリース作業にかかる人的コストが大幅に削減されました ストレス軽減 : リリース日の緊張感が大幅に軽減されました これからの展望 私たちの目標は変わりません。 リリース関連作業の一元管理 自動チェックによる作業負荷軽減 最終的なリリーサー不要の実現 今回のアップデートで、この目標の大部分を達成できたと感じています。特に自動リリース機能により、「リリーサー不要」という最終目標にかなり近付きました。残りの部分も、社内のプロダクト運用チームからのフィードバックを元に継続的に改善していきます。 まとめ 今回のアップデートにより、私たちのGitHubリリースフロー自動化は、単なる「効率化ツール」から「開発体験を根本から変えるシステム」へと進化しました。 特に自動リリース機能の導入により、 リリーサーの作業負荷がほぼゼロになった ことは、私たちの想像を超える効果をもたらしました。実際の導入現場では、 1日2回のリリース が可能になり、 承認からリリースまでの時間が劇的に短縮 されるなど、具体的な成果が現れています。 技術者も、企画者も、リリーサーも、全員が「使っていて気持ちよい」と感じられるシステム。それが私たちの目指した姿であり、今回のアップデートで大きく近付けたと確信しています。 もしチームでリリース作業に課題を感じているなら、ぜひ一度試してみてください。きっと、リリース作業に対する考え方が変わるはずです。 私たちは今後も、実際のユーザーフィードバックをもとにした継続的な改善を続けていきます。より多くのチームが、この「未来のリリース体験」を享受できるよう、取り組みを続けてまいります。 今後も一歩ずつ改善を積み上げることで、リリースのさらなる加速化につなげていければと思います。 最後に、LIFULL ではともに挑戦し成長していける仲間を募集しています。よろしければこちらのページもご覧ください。 hrmos.co hrmos.co