TECH PLAY

株式会社ラクス

株式会社ラクス の技術ブログ

926

2025年、AI技術は新たなフェーズに突入しました。特に、自律的にタスクを計画・実行する「AIエージェント」の登場は、ソフトウェア開発の世界に大きなインパクトを与えています。私たちラクスでも、この技術革新の波を捉え、自社サービスを進化させるべく、社内のR&D活動「技術推進プロジェクト」にて「垂直型AIエージェント」の調査・研究に取り組みました。 申し遅れました、普段は技術広報を担当しているkawa3です。今回は久々にR&D活動を通じてエンジニア業務を担当しました。楽しかったです! 本記事では、その成果発表の内容をもとに、AIエージェントの基本からSaaSへの応用可能性、そしてPoC(概念実証)を通じて見えてきたリアルな課題と解決策までを簡潔にご紹介します。 この記事を通して、垂直型AIエージェントの技術的な面白さをお伝えするとともに、ラクスがどのように技術のキャッチアップと社内へのナレッジ展開に挑戦しているか、その一端を感じていただければ幸いです。 なぜ今「垂直型AIエージェント」なのか? AIエージェントの基本:従来のAIとの違いと得意なこと 実装への道筋:自律レベルによる6つのパターン分類 SaaS業界の最前線:競合他社のAIエージェント活用事例 AIエージェントを構成する8つのコア技術モジュール ラクス製品への反映アイデア やってみて分かったこと:AIエージェント開発フレームワークを用いたPoCのリアルな手応え 本番導入を阻む「3つの壁」と、その乗り越え方 知識を組織の力に:「垂直型AIエージェント実装ナレッジベース」 まとめと今後の展望 なぜ今「垂直型AIエージェント」なのか? AIエージェントには、分野を問わず汎用的に使える「水平型」と、特定の業界や業務(ドメイン)に特化した「垂直型」が存在します。私たちが今回「垂直型」に焦点を当てた理由は、ラクスが提供する多様なSaaSサービスへのAI導入を考えた際に、より現実的で高い価値を提供できると考えたからです。 プロジェクトの目標は以下の3つに設定しました。 国内外のAIエージェント活用パターンやユースケースの調査 ラクスが提供するサービスへの適用候補機能の洗い出し PoCによる実現可能性の判断 AIエージェントの基本:従来のAIとの違いと得意なこと まず、「AIエージェント」そのものについて整理しましょう。 AIエージェント : 自律的に計画・意思決定を行いながら作業を実行するAIです。タスク遂行に必要な情報を自ら収集し、状況に応じて最適な行動を判断・実行します。開発支援AI「Devin」などがその代表例です。 従来の生成AI・AIアシスタント : ユーザーの指示に基づき、コンテンツ出力や支援を行うAIです。対話や補助的な作業が主な役割となります。 そして、垂直型AIエージェントは、その高い専門性を活かして、特に以下の3つの領域を得意としています。 専門知識が必要な、高度な分析や判断支援 ルールに基づいた定型業務の自動化と効率化 大量のデータに基づく予測と最適化 医療の画像診断支援から金融の不正利用検知、法務の契約書レビューまで、その応用範囲は多岐にわたります。 実装への道筋:自律レベルによる6つのパターン分類 一口にAIエージェントと言っても、その自律レベルは様々です。私たちは、人間がどの程度関与するかに応じて、自律レベルを弱い方から Assist(支援) 、 Copilot(副操縦士) 、 Autonomous(自律型) の3段階に分けました。 さらに、これを具体的な機能パターンとして6つに分類しました。これにより、AIエージェント導入の難易度やステップをより明確にイメージできます。 パターン分類 自律レベル ①リサーチ&要約アシスト アシスト ②ドラフティング・ジェネレーター アシスト〜コパイロット ③意思決定コパイロット コパイロット ④業務フロー・オートメーター コパイロット〜自律 ⑤自律オペレーター 自律 ⑥モニタリング&ガーディアン 自律(単機能) SaaS業界の最前線:競合他社のAIエージェント活用事例 SaaS業界では、まさに「AIエージェント元年」とも言える状況で、各社が次々と新機能をリリースしています。 本記事では割愛しますが、社内向けの成果発表では各社のAIエージェント機能の事例を紹介しました。 各社とも、具体的な業務プロセスにAIを組み込み、「完全自動運転」を目指す動きが加速していることがわかりました。 AIエージェントを構成する8つのコア技術モジュール 私たちは、AIエージェントを構成する技術要素を8つのコアモジュールとして整理しました。 成果発表では、これらのコアモジュールの役割や技術例について解説を行いました。 LLM Core(GPT/Claude/Gemini等) プロンプト・推論エンジン(タスク分解・計画・自己修正) メモリ管理(短期/長期) RAG(幻覚抑制・ドメイン知識注入) 外部ツール連携(API/MCP/関数呼出) マルチモーダル(音声/画像/動画) 安全性・ガバナンス(Moderation/Guardrails/ルールエンジン) モニタリング・分析(Langfuse/LangSmith/OTel等) ラクス製品への反映アイデア ここでは、ラクスが展開する「楽楽明細」「楽楽販売」「メールディーラー」などの9製品を対象にAIエージェント機能の候補を洗い出しました。 9製品×6種の自律レベル = 合計54機能の実装案を検討しました。 これら案のうち、「楽楽勤怠」でのシフト自動作成機能をPoCで実施することが決まりました。 やってみて分かったこと:AIエージェント開発フレームワークを用いたPoCのリアルな手応え 私たちは、AIエージェント開発フレームワークを用いて、簡単なシングルエージェントを実装し、シフト作成の自動化を試みるPoCを実施しました。 【PoCの概要】 目的 : 従業員のスキルや希望勤務時間、各時間帯に必要な人数といった要件から、最適なシフトを自動生成する。 流れ : シフト要件を登録 従業員の勤怠情報(スキル、希望シフト等)を登録 AIエージェントにシフト作成をリクエスト AIエージェントが推論やRAG、外部ツールなどを使用しシフト案を作成 生成されたシフト案と充足状況を確認 【PoCから得られた知見】 良かった点 : AIエージェント開発フレームワークを用いることで、簡単なワークフローであれば容易に実装可能であることが確認できました。 気になった点(課題) : 処理速度 : 入力データが増えるほどレスポンスが遅くなり、タイムアウトのリスクがありました。単純なシフト作成であれば、専門の最適化ツール(例:ORTools)の方が適している可能性も感じました。 マルチエージェント化の必要性 : シフトを「作成するエージェント」「評価するエージェント」「修正するエージェント」のように役割分担させるマルチエージェント構成の方が、より真価を発揮できると感じました。 セキュリティ・保守性 : 今回のPoCでは簡単な検証に留まりましたが、本番運用を見据えると重要な課題が浮き彫りとなりました。 本番導入を阻む「3つの壁」と、その乗り越え方 PoCを通じて、AIエージェントのワークフロー自動化へのポテンシャルを実感する一方で、本番導入にはいくつかの大きな壁があることも明らかになりました。 本番導入を困難にする三大要因: 性能 : 処理が遅い、精度が低い。 コスト : API利用料などが高額になり、赤字になる可能性がある。 セキュリティ : プロンプトインジェクションのような攻撃への対処や、不適切な出力内容の精査など、企業としての責任が問われる。 これらの課題は決して低くありませんが、乗り越えるための技術やノウハウも存在します。 性能改善 : モデルの最適化、RAG(Retrieval-Augmented Generation)の精度向上、マルチエージェントによる並列化など。 コスト圧縮 : 軽量モデルの活用、推論キャッシュ、ライセンスの最適化など。 セキュリティ強化 : ガードレール(不適切な入出力を防ぐ仕組み)、ヒューマン・イン・ザ・ループ(人間の確認・介入)、モデレーションAPIの活用など。 今後は、これらの技術要素の研究やナレッジを組織として蓄積していくことが、競争力の源泉になると考えています。 知識を組織の力に:「垂直型AIエージェント実装ナレッジベース」 今回のプロジェクトの最終成果物として、私たちは調査・研究で得た知見を「垂直型AIエージェント実装ナレッジベース」としてGitHub Wikiにまとめ、社内に公開しました。 これは、AIエージェントを本番実装するための、設計から運用、評価までの実務知識を集約したものです。 ナレッジベースの主な構成 1. 基本概念 : 垂直型AIエージェントの定義や価値、ユースケースを整理。 2. 開発フレームワーク : LangChainやGoogle ADKなど、主要なフレームワークを比較。 3. 観測・分析 : Langfuseなど、トレーシングやデバッグを支えるツール群を紹介。 4. フルマネージド統合AI開発プラットフォーム : Azure, AWS, GoogleのPaaSを比較。 5. 本番運用・実践ガイド : パフォーマンス、コスト、セキュリティの観点からタスクを体系化。 6. 評価 (Evaluation) : 品質保証のための指標や評価フローを整理。 7. LLMOps : プロンプト管理や継続的改善のサイクルについて紹介。 8. 実装基盤 : アーキテクチャ設計やUX、組織体制など実装を支える土台を整理。 8-1. アーキテクチャ設計 - エージェント構成パターン / フェイルオーバ / 設計チェックリスト 8-2. ナレッジ&データ運用 - ナレッジライフサイクル / データ契約 / ドリフト監視 8-3. CI/CD & プラットフォーム自動化 - 環境分離 / パイプライン / Secrets管理 8-4. 責任あるAIとコンプライアンス - 規制マッピング / バイアス評価 / 透明性 8-5. プロダクト体験とUX - 会話設計 / 失敗UX / KPI 8-6. テストと信頼性 - 負荷/カオス/DRテスト / 演習テンプレ 8-7. 外部連携パターン - ツール連携 / Function Calling設計 / 失敗緩和 8-8. 組織と運用モデル - 役割/RACI / オンボーディング / 定例運用 このようなナレッジをオープンに共有し、誰でもアクセスできる状態にすることで、各プロダクトへのAIエージェント導入を加速させ、組織全体の技術力を底上げすることが狙いです。 まとめと今後の展望 今回の技術推進プロジェクトを通じて、私たちは垂直型AIエージェントがSaaSビジネスに大きな変革をもたらすポテンシャルを秘めていることを再確認しました。定型業務の自動化から高度な意思決定支援まで、その応用範囲は無限大です。 一方で、PoCを通じて明らかになったように、性能、コスト、セキュリティといった本番導入への壁は決して低くありません。しかし、それらを乗り越えるための技術やアプローチも着実に進化しています。 私たちラクスは、今後もこのようなR&D活動を積極的に続け、最新技術を迅速にキャッチアップし、実践的なノウハウを蓄積していきます。そして、その成果を「楽楽シリーズ」をはじめとする自社サービスに反映させ、お客様に新たな価値を提供し続けることを目指します。 AIエージェントが当たり前になる未来は、もうすぐそこまで来ています。このエキサイティングな技術革新の旅に、これからもご期待ください。
アバター
こんにちは、開発推進部 SRE課のimamotoです。 SRE課ではSlackを使ってアラートを通知しているのですが、 今回はそのアラートを確認する運用を自動化してGitHub上で運用を完結させた話をしたいと思います。 これまでのアラート確認運用について 運用の流れ 解決したかった困りごと ①見落とし・対応漏れのリスク ②手順書作成コスト ③見るべきツールが多い ④横展開の必要性 改善方針:GitHub Actionsを活用したアラート確認運用の自動化 1. GitHub ActionsによるSlackメッセージの自動分類 Slack Alert Analyzerの機能 作成されたIssue例 2. 未知のアラートのRunbookを自動作成 Issueテンプレート Pull Request 3. 対応完了処理 Slack Alert Resolverの機能 他チームへの横展開:Reusable workflowとTemplate Repositoryを利用 Template Repositoryについて フォルダ構成 README 効果 おわりに これまでのアラート確認運用について まず、今回改善した運用について簡単に説明します。 運用の流れ 毎朝Slackのチャンネル(対象:7チャンネル)を目視して、アラートの見落としが無いか確認 アラート内容の分析・判断 必要に応じて対応の実施・手順書の作成 対応状況を記録(チェックボックス) 解決したかった困りごと ①見落とし・対応漏れのリスク Slackチャンネルを日次で目視確認し、「その日の運用を実施したか」のチェックボックスをチェックする運用にしていました この方法だと「どのアラートまで確認済みか」の管理まではできないため、アラートの見落としリスクがありました。 ②手順書作成コスト 新しいアラートが発生するたびに手順書を作成する際、作成のコストがありました。 また、「一時的に無視しても良いアラート」についてはあまり手順化されておらず、アラート対応の属人化につながっていました。 ③見るべきツールが多い 7つのSlackチャンネルを目視確認し、必要に応じて適切なGrafanaダッシュボードを確認し、各所に分散した手順書を参照するので、運用が面倒でした ④横展開の必要性 SRE課以外でスプレッドシートでアラート情報を管理しているという事例がありました。 何らかの仕組みで管理を楽にして横展開したいと考えていました。 改善方針:GitHub Actionsを活用したアラート確認運用の自動化 前述した課題を解決するため、GitHub Actionsを活用してSlackアラートの確認を自動化しました。 運用は以下のような手順になりました。 毎朝GitHub Actionsをスケジュール起動して、Slackメッセージの収集・分類・GitHub Issueの作成を自動化 分類されたアラートに対応したRunbookリンクがGitHub Issue上に記載されるので、それを元に運用を実施 Runbookがない場合は、GitHubのIssueテンプレートからIssueを起票するとRunbookのマークダウンファイルを自動生成 GitHub Issueに確認終了のラベルを付与すると、Slackに対応済みである旨を記録 1. GitHub ActionsによるSlackメッセージの自動分類 Slackチャンネルの目視によるアラート分類の判断やRunbookの存在確認が非常に面倒だったため、 Slack Alert Analyzer というツールを作成してGitHub Actionsから日次で実行する形にしました。 Slack Alert Analyzerの機能 Slackアラートメッセージの収集・分類・フィルタリング GitHub Issueを起票して、分類したアラートの概要や対応するRunbook、メッセージ本文等をIssueに記載 作成されたIssue例 Slack Alert Analyzerを実行すると、以下のようなIssueが起票されます。 Issue本文:その日のアラート内容のサマリを記載 過去1週間分のアラートを収集(対応済みのアラートを除く) Issueコメント:グルーピングされたアラート情報を記載 正規表現ベースでグルーピング アラート件数、発生元チャンネル、Runbookリンク等 Slackメッセージ本文もIssueコメント上から確認可能 対応が完了したアラートのチェックボックスにチェックを入れる✅️ 2. 未知のアラートのRunbookを自動作成 Slack Alert Analyzerの設定ファイルで「既知のアラート」として登録されていないメッセージの場合、GitHub Issue上にRunbookが表示されません。 既知のアラート登録用のIssueテンプレートを使用してIssueを作成すると、以下の2つの変更を行うPull Requestが作成されるようになっています。 Slack Alert Analyzerの設定ファイルに既知のアラートとして追加 Runbookとなるマークダウンファイルを作成 Issueテンプレート こんな感じのIssueテンプレートを使っています。 Issueに add-known-alert ラベルが付与されます。 Pull Request add-known-alert ラベルがついたIssue作成をトリガーにPull Requestが作成されます。 knowledge/known-alerts.yaml に既知のアラートとして情報を追記 runbooks フォルダに新しいRunbookファイルが作成される 3. 対応完了処理 一通り確認が完了したら resolved-alerts ラベルをGitHub Issueに付与すると Slack Alert Resolver というツールがGitHub Actionsで自動実行されます。 Slack Alert Resolverの機能 Issueコメント上でチェックが付いているSlackメッセージに対して「✅️」リアクションを付与 ✅️リアクションを付与すると、次回以降に確認対象として拾われなくなる Issueを自動クローズ 他チームへの横展開:Reusable workflowとTemplate Repositoryを利用 元々SREチームでのみ使っていたツールだったのですが、 他チームにツールを展開するにあたって以下の対応を実施しました。 これによって、Template Repositoryから作成したリポジトリから迅速にセットアップして利用できるようになりました。 また、Reusable workflowにすることで、バグフィックス等の迅速な横展開も可能となりました。 Reusable workflow : Slack Alert Analyzer, Slack Alert Resolverの実行用ワークフローを再利用可能な共通ワークフローとして展開 Template Repository : Reusable workflowを呼び出すワークフローや、必要な設定ファイル・フォルダが準備された雛形のリポジトリを作成 必要なセットアップ方法も、READMEに記載 Template Repositoryについて フォルダ構成 必要なワークフローやIssueテンプレート、設定ファイルが含まれています。 README こんな感じでREADMEにセットアップ方法を記載しています。 効果 定常的な運用の動線を減らして運用を楽にすると、運用者の負荷を下げるだけでなく、品質も向上しました。 特にRunbook作成へのモチベーションが上がりました。 他チームへの横展開も迅速に開始することができました。 おわりに 今回のツールはチームの為に作ったという建付けなのですが、私自身も本当に運用作業が苦手でして、、 実は自分が一番このツールの存在を喜んでいるかもしれません。 また、今回のツール作成はGitHub CopilotのAgentモードを使って行いましたが、要件の壁打ちも含めて初版は2時間以内に作成することができました。 ちょっとした自作ツールの作成ハードルが生成AIの活用によって本当に低くなっていると感じるので、 「運用つれぇ…」 と思ったら何か作ってみるのもオススメです。 (適材適所で、生成物の品質やメンテナンスについては責任を持つ前提で) それでは、ブログをご覧いただきありがとうございました!
アバター
はじめに こんにちは、 @rs_tukki です。 ラクスの開発部では、これまで社内で利用していなかった技術要素を自社の開発に適合するか検証し、ビジネス要求に対して迅速に応えられるようにそなえる 「技術推進プロジェクト」 というプロジェクトがあります。 今回、このプロジェクトで「Passkey」に関する検証を行なったので、その結果を報告させていただきます。 はじめに Passkeyとは何か 基本概念 対応環境 ブラウザ要件 OS要件 技術的な仕組み FIDO2規格の構成 1. Web Authentication (WebAuthn) 2. Client to Authenticator Protocol (CTAP) 登録フロー 認証フロー フィッシング攻撃への耐性 リプレイ攻撃への耐性 他の認証方式との比較 多要素認証(MFA)との違い FIDO1との違い 1. UAF(Universal Authentication Framework) 2. U2F(Universal 2nd Factor) Spring Bootでの実装 システム構成 実装のポイント 1. データベース設計 2. ドメイン設定の制約 3. Passkeyの削除 BtoB SaaSへの導入に向けて Passkey導入のメリット/デメリット メリット デメリット まとめ 参考リンク Passkeyとは何か 基本概念 まず、具体的な検証内容の説明に入る前に、Passkeyについて軽く説明します。 PasskeyとはFIDOアライアンスとW3Cが共同で策定した新しい認証技術です。 従来のIDとパスワードを入力する認証方式とは異なり、ユーザはデバイスのロック解除に使う方法(生体認証やPINコードなど)を使ってWebアプリにログインすることができます。 Passkeyを利用することによるメリットは2点。 ユーザ体験を損なわず2要素認証を実現できる 点と、 複数のデバイス間で認証情報を共有できる 点です。 これにより、従来の認証方式と比較して、一定のセキュリティを担保しつつ、ユーザ体験を向上させることが可能になります。 対応環境 Passkeyを利用するには、ブラウザとOSでそれぞれ異なるバージョン要件が必要になります。 バージョンは以下の通りですが、近年の環境であればそれほど意識せずともPasskeyを利用できるかと思います。 ブラウザ要件 Chrome : バージョン109以上(Windows/Mac/Android/iOS/iPadOS) Safari : バージョン16以上(Mac/iOS/iPadOS) Edge : バージョン109以上(Chromiumベース) Firefox : バージョン122以上 OS要件 Windows : 10以上 macOS : 13(Ventura)以上 iOS/iPadOS : 16以上 Android : 9以上(Google Play開発者サービス搭載端末) 技術的な仕組み FIDO2規格の構成 実は、「Passkey」という言葉を定義する場合、 広義のPasskey と 狭義のPasskey という2種類の定義方法があります。 まずは広義のPasskeyについてですが、これは以下2つの技術仕様をまとめた、 FIDO2 を基盤として構成した認証技術です。 1. Web Authentication (WebAuthn) W3Cによって標準化された、ブラウザ上で公開鍵認証方式を利用するためのJavaScript APIです。開発者が直接操作するのは主にこのAPIになります。 2. Client to Authenticator Protocol (CTAP) FIDOアライアンスによって定められた、ブラウザと認証器(デバイスの生体認証センサーやセキュリティキーなど)との間で通信を行うための規格です。WebAuthnが内部で利用しており、開発者が直接意識することは少ないです。 この「広義のPasskey」では、認証情報を認証器(PCやスマホ端末)そのものが保持していました。 そのため、たとえばPCに対してPasskeyを登録していても、同じユーザがスマホ端末からログインしたい場合、また別の端末にPasskeyを登録し直すところから始める必要があります。 一方で「狭義のPasskey」では、上記のFIDO2仕様に加え、これらの情報を クラウド上のパスワードマネージャーに保管する ことを前提としています。 これにより、複数の端末を利用していても、パスワードマネージャーを共有することで、再登録の手間なく認証を行うことができます。 本記事では、単にPasskeyと呼ぶ場合、この「狭義のPasskey」を指して説明しています。 また、狭義のPasskeyはその特性から、 MDC(Multi-Device FIDO Credential) とも呼ばれることもあります。 登録フロー Passkeyによる認証は、「登録」と「認証」の2つのフローから成り立ちます。 登録のフローは下記の通りです。 チャレンジの生成 : サーバーが一意のチャレンジ(乱数)を生成 ユーザー検証 : デバイスのスクリーンロック解除(生体認証、PIN等)でユーザーを認証 鍵ペアの生成 : デバイスがドメインに紐づいた秘密鍵と公開鍵のペアを生成 秘密鍵の保存 : パスワードマネージャー(Google Password Manager、iCloudキーチェーンなど)に暗号化して保存 公開鍵の送信 : 公開鍵をサーバーに送信し、データベースに保存 ここで重要なのは、ブラウザとサーバの間でやりとりしている情報が チャレンジ(乱数) 秘密鍵で署名したチャレンジ 公開鍵 認証器に関するメタデータ など、 機密性の低い情報に限られる ことです。 従来のパスワード認証におけるIDやパスワード、またユーザ認証に必要な生体情報やPINコードなど、機密性の高い情報は一切やり取りされていません。 これによって、Passkeyではセキュリティを担保しているというわけです。 認証フロー Passkeyを登録した後は、以下のフローでユーザの認証を行います。 チャレンジの発行 : サーバーが一意のチャレンジを生成 ユーザー検証 : デバイスのロック解除でユーザーを認証 署名の生成 : 秘密鍵でチャレンジに署名 署名の検証 : サーバーが公開鍵で署名を検証 認証の場合も、登録時のフローと同様、秘密鍵や生の認証情報など機密性の高い情報はやり取りされていません。 また、加えて以下の仕様によってセキュリティを担保しています。 フィッシング攻撃への耐性 認証器が作成した秘密鍵は、その鍵を作成したサイトのドメイン(=RPID)と紐づいています。 これにより、偽サイトでPasskeyを利用させようとしてもRPIDが異なるため署名することができません。 リプレイ攻撃への耐性 一度サーバが生成したチャレンジは、次回以降の認証に使用することができません。 そのため、認証に成功したリクエストを再現するリプレイ攻撃へも耐性を持っています。 他の認証方式との比較 ここまでPasskeyの仕様について説明してきました。 続いては、他の認証方式とPasskeyとの違いを説明していきます。 多要素認証(MFA)との違い 多要素認証とは、認証に使われる以下の3要素のうち、2種類以上の要素を利用して認証することです。 知識情報 :パスワードやPINコードなど 所有情報 :PCやスマートフォンなどの端末そのもの、もしくはクライアント証明書など 生体情報 :指紋認証や顔認証、虹彩認証など Passkeyによる認証は、認証器を利用して照合を行うため、認証器という所有情報と、ロック解除に使用する生体/知識情報を 同時に利用して認証 しています。 二要素認証というと、よくあるパターンはワンタイムパスワードや「ログインしようとしていますか?」といったプッシュ通知を利用する二段階認証ですが、Passkeyでは認証情報を2回入力する手間を省きつつ、二要素認証によってセキュリティを担保できているわけです。 また、先述の通り、認証情報そのものを送信せず、RPIDが異なると認証できないことから中間者攻撃やフィッシング攻撃に耐性がある他、 攻撃者が大量に認証を試行することでユーザのデバイスに通知が大量に送られる、いわゆるMFA疲労攻撃に対しても耐性を持っています。 FIDO1との違い 先ほど、広義のPasskeyはFIDO2仕様を基盤にしていると説明しました。 一方で、認証方式にはFIDO1という仕様もあります。これには UAF と U2F の2つの規格があります。 1. UAF(Universal Authentication Framework) 専用のセキュリティキーで生体認証を行うパスワードレス認証です。 公開鍵と秘密鍵を利用して署名を検証する点はPasskeyと同様ですが、PCそのものでは認証ができず、外部機器が必要となります。 2. U2F(Universal 2nd Factor) 上記のUAFに2段階認証の仕組みを加えたものです。 まず最初に通常のパスワードで認証を行ったあと、セキュリティキーを用いた二要素認証を行います。 記載の通り、FIDO1では専用の外部機器が必要なことに対し、PasskeyではOSとブラウザのバージョン要件を満たしていれば PCやスマホそのものを認証器として利用できるのが大きなメリットです。 Spring Bootでの実装 さて、ここからはWebアプリに実際にPasskeyによる認証を組み込む実装を見ていきます。 システム構成 今回の検証では、以下の技術スタックを使用しました。 - AlmaLinux8 - Apache 2.4.37 - Spring Boot 3.4.5 - spring-boot-starter-security - spring-security-web - webauthn4j-core:0.29.2.RELEASE - PostgreSQL 16.8 - SimpleWebAuthn - 証明書を備えたHTTPS環境 バックエンドの実装に関しては、各言語にPasskey認証を実現するためのフレームワークがあるかと思いますが、 今回は一番手軽な、Javaの spring-security-web + webauthn4j-core の組み合わせを使用します。 フロントエンドでは、 SimpleWebAuthn を利用して、バックエンドと認証器の繋ぎ込みを行います。 実装のポイント 今回の構成では、チャレンジの作成やCredentialの検証など基本的なフローはフレームワークが担ってくれます。 そのため細かい実装内容の解説は他の記事に譲りますが、ここでは特に注意すべきポイントをいくつか解説します。 1. データベース設計 先述のフロー図で、公開鍵等のサーバが保持する情報はDBに保存すると記載しました。 Credentialを作成しDBに保存する処理は自前でinterfaceを実装する必要があるため、以下のようなテーブルを作成しておきます。 Table " public.m_passkey_credential " Column | Type | Collation | Nullable | Default -------------------------------+---------+-----------+----------+---------------------------------- id | integer | | not null | generated by default as identity credential_id | bytea | | not null | user_id | text | | not null | pubkey | bytea | | | attested_credential | bytea | | | attestation_object | bytea | | | Indexes: " m_passkey_credential_pkey " PRIMARY KEY, btree (id) " m_passkey_credential_credential_id_key " UNIQUE CONSTRAINT, btree (credential_id) それぞれのカラムに格納する内容は以下の通りです。 id :DB管理用の主キー credential_id :各認証器が生成する一意のID user_id :Credentialが紐づくユーザのID pubkey :認証器が生成した公開鍵 attested_credential :メタデータを含む、認証器の登録時にクライアントが生成したデータ attestation_object :認証器の製造元情報、証明書チェーンなどを含む、認証器の信頼性を証明するデータ 2. ドメイン設定の制約 Spring Securityを用いたWebアプリでは、以下のようなSecurityFilterChainを実装することでPasskeyの仕組みを有効化することができます。 @Bean public SecurityFilterChain securityFilterChain( final HttpSecurity http) throws Exception { http.authorizeHttpRequests(authorizeHttpRequests -> { // リクエスト許可設定(ログイン用URLとwebauthnフレームワークの関連URLは認証を不要とする) authorizeHttpRequests .requestMatchers( "/login/**" , "/webauthn/**" ).permitAll() .anyRequest().authenticated(); }) // ログインフォームの設定(デフォルト) .formLogin(formLogin -> {}) // Passkeyに関する設定 .webAuthn(webauthn -> { webauthn .rpName( "Passkey" ) // Passkeyのサービス名。任意の名称でOK .rpId( "localhost" ) // サービスのドメイン名 .allowedOrigins(Set.of( // Passkeyを利用可能なURL(完全一致) "https://localhost:8443" )); }); return http.build(); } ここで重要な設定が、 rpId です。こちらは先ほど説明した通り、Passkeyを紐づけるドメイン情報です。 指定したドメイン(もしくはそのサブドメイン)以外から認証をしようとした場合、不正な操作としてエラーになります。 そして、このRpIdの指定ですが、以下のような制約があります。 単一ドメインのみ : 1つのドメインしか指定できない IPアドレス不可 : IPアドレスでは動作しない HTTPS必須 : localhost以外では正式な証明書が必要 そのため、ローカル環境以外では、 正式な証明書が発行され、DNSで関連づけられた正式なドメインでしか検証できない ということになります。 検証用にサーバを構築している方は注意が必要です。 3. Passkeyの削除 Passkeyはパスワードマネージャーとサーバ上のDBの両方でデータを管理していますが、 このうちパスワードマネージャ上に保存されたデータは、 webauthnのAPIで削除することができません。 ブラウザ上の操作で削除可能ものはサーバ側のデータのみであるため、Passkeyを完全に削除したい場合、パスワードマネージャーから手動で操作を行う必要があります。 二段階に分けて削除を行う必要があるため登録時より手間がかかります。ユーザには予め二段階の削除が必要な旨を案内しておくのが良いでしょう。 BtoB SaaSへの導入に向けて ここまでPasskeyという技術について説明しましたが、ラクスが提供しているようなBtoB SaaSの場合、Passkeyによる認証の需要はまだ少ないです。 Amazon等BtoCのサービスでは徐々に普及しつつあるものの、BtoBでは採用されているサービスはほとんどないのが現状です。 理由としては、ユーザ側がシングルサインオンやSSLクライアント認証などの認証方式を利用しているためそれらで十分というケースが挙げられます。 また、前提として一人当たり1端末(認証器)の利用を前提としているPasskeyは、例えば複数社員で一つの端末を共有している場合などでは相性が悪かったりもします。 しかし、今後ユーザーニーズが変わり、生体認証を含めた二要素認証への理解と需要が高まってきた時には、Passkeyを導入することも検討できるのではないかと思います。 Passkey導入のメリット/デメリット 最後に、Passkeyのメリットとデメリットをそれぞれまとめておきます。 メリット ユーザビリティの向上 パスワード記憶が不要 (指紋認証や顔認証であれば)ワンタッチでログイン可能 デバイス間での同期が可能 セキュリティの強化 フィッシング攻撃への耐性 総当たり攻撃への耐性 認証情報の窃取リスクの排除 運用コストの削減 パスワードリセットの対応がほぼ不要になる (適切に実装されていれば)セキュリティインシデントの軽減に繋がる デメリット 技術的ハードル フレームワークである程度カバーできるとはいえ、セキュリティリスクも考慮すると実装の難易度は高い CredentialIDの重複による乗っ取りの可能性 originやRPIDの適切な設定が欠けていることによるフィッシングの可能性 ユーザ検証の不備によるなりすましの可能性 etc... ユーザー教育 そもそも「Passkey」という認証方法に馴染みがないユーザもいる マニュアル等で適切なサポートを行わないと、かえってユーザ体験を損ねてしまう可能性がある 互換性の課題 非対応環境の存在も考慮しなければいけない 特にスマホ端末で、MDM(Mobile Device Management)を利用している場合は互換性がない可能性も まとめ ここまで、Passkeyを使った認証方式のメリットと実装方法、またBtoB SaaSでのPasskeyの需要について説明してきました。 Passkeyによる認証は、従来のID/パスワードによるログインと同等かそれ以上のユーザ体験の向上に加え、セキュリティ面でも向上が見込める新時代の認証方式です。 現状のBtoB SaaSにおいてはまだそこまで需要の高い認証方式ではありませんが、 今後、二要素認証に対する理解が深まり、需要が高まってきた時に備え、仕組みや実装について理解しておくとよいでしょう。 参考リンク FIDO Alliance W3C WebAuthn Specification webauthn4j Documentation Spring Security WebAuthn SimpleWebAuthn パスワードはおしまい! 認証はパスキーでやろう Spring Security 6.4.0-RC1 でパスキー認証を実装してみる Passkey認証の実装ミスに起因する脆弱性・セキュリティリスク
アバター
ラクスでメールディーラーのUIUXデザインを担当しているたけしまです。 AIを活用した製品づくりに向け、上流工程から参画し、日々業務に取り組んでいます。最近では、社内でも業務効率化やナレッジの蓄積、雑務の処理などにAIを活用するようになってきました。 顧客ヒアリングの情報を収集・分析する際にもAIを活用していますが、顧客の声が蓄積されるにつれ、顧客から見たAIがどんな存在で、何を期待しているのかが少しずつ見えてきました。今回は、その気づきをデザイナー視点のAIの価値と併せてご紹介したいと思います。 顧客視点 業務変革のパートナー 5つの価値的変化 6つの役割イメージ デザイナー視点 新たなUX設計の可能性 1. 製品のUX向上 2. 広く深い顧客理解 3. UI設計と業務効率化 顧客視点とデザイナー視点の比較 まとめ 最後に 顧客視点 業務変革のパートナー 顧客企業にとってAIは、単なる便利な機能ではなく「自社や仕事をどう変えてくれるか」という価値や役割として認識されています。彼らにとってのAIは、仮想的な同僚や参謀のような存在です。 これまで手間がかかっていた作業を自動化し、属人化していた業務を解消することで、企業の能力が高まり、エンドユーザーからの評価や信頼の向上が期待されます。さらに、活用次第では市場でのポジション拡大へとつながる可能性もあります。 5つの価値的変化 業務負荷の軽減  ➡ 手を動かす時間が減り、対応漏れも防げる 判断のサポート  ➡ 優先順位や次の一手が明確になる スピードと確実性 ➡ 即レスできて、内容の抜け漏れも防げる 質の安定     ➡ 誰が対応しても一定以上のクオリティが保たれる 学習と成長の支援 ➡ 過去のやり取りやナレッジから学べる 6つの役割イメージ アシスタント  : 面倒な作業を代行 ナビゲーター  : 対応の優先度や進め方を案内 品質管理者   : 誤字・不適切表現をチェック アナリスト   : 顧客傾向を分析し提案材料を提供 記録係/図書係 : 過去データを即座に検索 コーチ     : 成功事例や改善案を提示 デザイナー視点 新たなUX設計の可能性 UI/UXデザイナーにとってAIは、業務効率化とデータ活用の両面で価値を発揮し、利用者の体験全体を "気づかないレベル" で滑らかにすることが実現できる可能性を秘めた存在です。 1. 製品のUX向上 メールディーラーを例に挙げると、エンドユーザからのお問い合わせに対し、返信文案を生成できるAIが実装されています。文章の内容をチェックしたあと、本文に挿入するだけで対応の大部分が完了するという操作フローを実現。スタッフのスキルに関わらず、一定のレベルでカスタマーサポートを実現できます。 また、メールディーラーに関してのお問い合わせに対しても、お問い合わせフォームにAIを組み込むことにより、先回り型のサジェストで顧客自身が解決しやすい環境を構築するなど、業務効率化やコミュニケーションコストの軽減により、顧客体験の改善に繋げています。 2. 広く深い顧客理解 AIを活用することで、顧客との接点や行動データを集めて整理・分析が簡単になり、定性的な情報を定量化しやすい仕組みが作れます。これにより、より精度の高いニーズの抽出やペルソナ設計、ユーザージャーニー最適化が可能になります。 3. UI設計と業務効率化 UI設計や運用に必要なルール・ガイドライン、スタイル情報などをAIに学習させることで、定型的な対応や運用の一部を任せられるようになります。
 その結果、担当者はより創造的な業務に集中でき、全体の運用もスムーズに進められます。 顧客視点とデザイナー視点の比較 顧客視点とデザイナー視点の比較 まとめ AIが当たり前になった今、顧客は業務効率化や信頼性向上といった成果を重視し、デザイナーはユーザー体験の滑らかさを重視しています。 それぞれの期待や価値を理解したうえでUI/UX設計を進めることが、効果的なAI活用につながるポイントになりそうです。 今回は、顧客理解を深める中で得られた気づきを共有しました。 顧客が価値を感じられる開発を行うことで、より魅力的な製品を生み出すことができ、営業としても自信を持って提案しやすくなるはずです。 最後に ラクスでは、現在新しいデザイナーやエンジニアを積極的に募集しています!少しでも興味を持っていただけた方は、ぜひお気軽にご連絡ください。まずはカジュアルにお話ししましょう。 みなさまからのご連絡をお待ちしています。 career-recruit.rakus.co.jp career-recruit.rakus.co.jp
アバター
はじめに こんにちは!楽楽勤怠開発チームのoo_yoshiです。 勤怠管理システムは「打刻して残業時間や休暇を計算すれば終わり」と思われがちです。しかし、実際にシステムを開発・運用してみると、その裏には複雑なルールと例外が山ほど存在します。 勤務体系は企業ごとに違い、法律や就業規則も定期的に改正されます。有休の付与や消化ルール、代休や振休の扱い、残業の丸め処理など、ひとつひとつのルールが微妙に違い、組み合わせると膨大なパターンになります。 私たちのチームでは、そうした複雑さに対応するために9年前にDDD(ドメイン駆動設計)を採用し、勤怠システムをリニューアルしました。本記事では、その9年間で感じたこと、分かったことを振り返りたいと思います。 はじめに 旧勤怠管理システムで直面した課題 リニューアル時にDDDを導入して変わったこと 属人化の解消 9年経って実感したDDDの価値 まとめ 旧勤怠管理システムで直面した課題 リニューアル前の勤怠システムは、自作フレームワークをベースに作られていました。 そのため「どこにどんな処理があるのか」が一目で分からず、長く在籍しているメンバーが「知っているからなんとかなる」という属人化した仕組みになっていました。結果として「この処理の正解は◯◯さんしか知らない」という状況も珍しくありませんでした。 新しく入ったメンバーにとってもハードルは高く、普段は残業や休暇を申請していても、システムがどう計算しているかを理解できない。用語として「休暇残数」「振休」「代休」を知っていても、コードを読んでもピンと来ない。結果として教育コストは大きく膨らみました。 私自身も新卒2年目の頃から旧勤怠システムに関わらせてもらい、数えきれないほどの失敗を経験しました。。。振り返れば大きな糧になりましたが、正直に言えば「他の人にはあまりおすすめできない環境」だったと今では思います。 リニューアル時にDDDを導入して変わったこと 旧勤怠管理システムで一番困っていたのは「何をどこで処理しているのかが不明確」という点でした。 そこで新システムではDDDを採用。まず「勤怠ドメインを整理してモデルに落とし込む」ことから始めました。 要するに「現実の勤怠の仕組みを、チーム全員が同じ言葉で説明できるようにする」というアプローチです。 モデルの分け方の例 労働パターン 勤務区分(固定、フレックス、管理監督者など)や勤務カレンダーなど勤怠計算に必要な設定を定義します。 打刻 出勤・退勤・休憩といった「事実」だけを表す。ここには「遅刻」や「残業」といった解釈は入れず、純粋に「いつ押したか」だけを残す。 勤務実績 打刻で登録された値や勤怠計算で計上された、その日の「働いた結果」を表現。ユーザーに見せるのはここからだけにした。 休暇履歴 有休の付与・取得・消滅をすべて履歴として積み上げる。残日数は履歴をたどれば自動的に導けるようにして、「この値は正しいのか?」と悩む必要をなくした。 ドメインを整理してモデルに落とし込むことで、「どの処理がどこにあるのか」が明確になり、コードを追いやすくなりました。 ※DDDを導入する際に整理した代表的なモデルを、簡単ではありますが役割とドメインルールとあわせてまとめると以下のようになります。 属人化の解消 もう一つ大きな効果は、ユビキタス言語によるチームの共通理解です。 「労働パターン」「打刻」「勤務実績」「休暇履歴」といった言葉をチーム全体で使うようにしました。以前は「ロジック名」や「○○画面の処理」といった曖昧な表現をしていましたが、今では具体的なモデル名を指して会話できるようになり、仕様確認やレビューがスムーズになりました。 その結果、属人化は大きく解消されました。知識が特定のメンバーに偏るのではなく、モデルに閉じ込めたドメイン知識をチーム全体で共有できるようになったのです。 9年経って実感したDDDの価値 9年間システムを運用してきて実感したのは、DDDが「複雑な業務知識をチーム全体で維持し続ける仕組み」としてとてもよく機能しているということです。 新メンバーの立ち上がりが速くなった 「休暇履歴」「勤務実績」といった用語をベースに理解できるようになった 制度変更にも柔軟に対応できるようになった(該当モデルにルールを追加・修正するだけで済む) 旧システムのように「勤怠ドメインの理解に数カ月」かかることはなくなりました。 まとめ 勤怠管理システムは、一見シンプルに見えて実は非常に複雑です。その複雑さは、エンジニアがドメイン知識を理解するだけでも大きな負担になります。 9年前にDDDを導入してから、私たちは「休暇履歴」や「勤務実績」といったドメインを整理し、モデルに落とし込むことで属人化を解消し、新規メンバーでも理解しやすく、制度変更にも柔軟に対応できるシステムへと進化させることができました。 振り返ってみると、DDDって単なる設計手法じゃなくて、「複雑な勤怠ドメインをチームみんなで理解し続けるための心強い道具」だったなと思います。 そして9年経った今、「あのときDDDを選んでよかった」と胸を張って言えるのは本当に嬉しいことです。
アバター
目次: はじめに 前提知識 当時の課題 実施した改善策 結果 その他 まとめ はじめに こんにちは。今年に入って2ヶ月に1回以上K-POPなどのライブに行っている、楽楽債権管理開発チームの冨澤です。 楽楽債権管理は新サービスとして2025年7月1日から販売を開始した、ラクスの中では比較的新しいサービスであり、高速に開発することが求められます。 本記事ではそんな高速開発を支える取り組みとして、CIのテスト実行時間を短縮した話をご紹介したいと思います。 前提知識 本記事での取り組みでは、以下の内容を前提としています。 対応時期 2025年3月 技術スタック 言語 Java 21 FW Spring Boot 3 テストツール Spock ビルドツール Gradle(Groovy) CI GitHub Actions アーキテクチャ オニオンアーキテクチャ 1つのGradleプロジェクトで管理しており、 /app 配下に処理に必要なディレクトリが存在し、単体テストコードも実装と同じパッケージ構成で用意しています。 また層を跨ぐ依存関係にはテストダブルを利用することで、各層の単体テストを独立して実行できるようにしています。 以下はパッケージ構成の例です(物理パスはGradle標準のsrc/main/java、テストはsrc/test/groovyなど各プロジェクト標準に準拠) src/main/.../app ├── controller ├── domain ├── infrastructure ├── persistence └── usecase src/test/.../app ├── controller ├── domain ├── infrastructure ├── persistence └── usecase 改善前のCIワークフロー設定 lintジョブ Spotlessを使ったチェック unit-testジョブ DBコンテナを起動 DBマイグレーション 単体テスト実行 カバレッジの集計 当時の課題 プロダクトフェーズから考えると、CIの時間はもちろん早い方がいいです。 ですが、当時は以下のような状況でした。 計測時期 2025年3月 テストの平均実行時間(成功のみ) 20分50秒 成功したワークフローのみを対象としたのは、失敗したワークフロー(ビルド or テスト失敗や、 cancel-in-progress による早期打ち切りなど)を含めると平均実行時間が実態より短く算出され、改善効果を正確に測定できないためです。 実行時間が長い主因として、まず直列実行を疑いました。 キャッシュの未使用やマシンスペックの問題も考えられましたが、小さく早く試して効果を検証するという観点から、設定変更で実現できる並列実行が最も着手しやすい改善策だと判断しました。 そこで今回は「テストジョブの並列実行」を第一の改善策として採用し、その効果を検証することにしました。 実施した改善策 lintジョブ Spotlessを使ったチェック 4並列のテスト実行ジョブ A B C D カバレッジジョブ 各ジョブで実施した内容を集計 GradleとGitHub Actionsの組み合わせ テストジョブの並列実行を実現するために、GradleとGitHub Actionsの2つを組み合わせました。 ①:Gradleでカスタムタスクの作成 Gradleでの並列化としてよく maxParallelForks が紹介されますが、これは単一のタスク内でJVMプロセスの並列度を上げるための設定です。 一方、今回の取り組みではCI全体の実行時間を効率よく短縮することを目的とし、GitHub Actionsのジョブそのものを分割して並列実行できるようにする必要がありました。 そこで、workflowのmatrix戦略にそのまま割り当てられる実行単位としてカスタムタスクをGradle 側に定義しました。 この方法により、特定のテストグループをジョブ単位で独立して制御できるようになりました。加えて、カバレッジの集約も簡素化され、将来的な差分テストなどへの拡張性も確保できました。 以下にその定義例を示します。 // 共通のテスト設定 tasks.withType(Test).configureEach { useJUnitPlatform() } tasks. register ( 'A' , Test) { include '**/persistence/**/*.*' , '**/infrastructure/**/*.*' , '**/domain/**/*.*' } tasks. register ( 'B' , Test) { include '**/usecase/a**/**/*.*' , '**/usecase/b**/**/*.*' , '**/usecase/c**/**/*.*' , '**/usecase/d**/**/*.*' , '**/usecase/e**/**/*.*' , '**/usecase/f**/**/*.*' , '**/usecase/g**/**/*.*' , '**/usecase/h**/**/*.*' , '**/usecase/i**/**/*.*' , '**/usecase/j**/**/*.*' , '**/usecase/k**/**/*.*' , '**/usecase/l**/**/*.*' } tasks. register ( 'C' , Test) { include '**/usecase/m**/**/*.*' , '**/usecase/n**/**/*.*' , '**/usecase/o**/**/*.*' , '**/usecase/p**/**/*.*' , '**/usecase/q**/**/*.*' , '**/usecase/r**/**/*.*' , '**/usecase/s**/**/*.*' , '**/usecase/t**/**/*.*' , '**/usecase/u**/**/*.*' , '**/usecase/v**/**/*.*' , '**/usecase/w**/**/*.*' , '**/usecase/x**/**/*.*' , '**/usecase/y**/**/*.*' , '**/usecase/z**/**/*.*' } tasks. register ( 'D' , Test) { exclude '**/persistence/**' , '**/infrastructure/**' , '**/domain/**/*.*' , '**/usecase/**' } ./gradlew test --tests hoge から着想を得ました。 また公式ドキュメントにも「テストのグループ化」というセッションで、似たような方法を紹介しており、こちらも参考にしました。 またこの4つの分け方は、実行時間が均等になるように調整しました。 なぜこの書き方なのか GradleのTestタスクは、正規表現ではなくAnt形式の include/exclude パターンをサポートしています。 クロージャーやSpecを利用した柔軟なフィルタリングもできますが、当時はとにかく早く並列化を実現したかったので、Ant形式を採用しました。 ②:GitHub Actionsでのジョブの並列実行 こちらは matrix を使って、並列実行を実現しました。 unit-test: strategy: matrix: test-task: [ A, B, C, D ] シンプルに、先ほど作成したカスタムタスクを指定し、並列で実行するように設定しました。 ③:JaCoCoレポートの作成 改善前は、1つのジョブで全てのテストを実行していたのでJaCoCoレポートの作成も容易でした。 しかし、テスト実行ジョブを4つに分割して並列化したことで、実行結果をうまくマージしないとJaCoCoレポートが作成できない問題に直面しました。 これに関しては、各テストジョブ実行後に classes ディレクトリと jacoco/*.exec をアーティファクトにアップロードし、カバレッジジョブで集計するようにしました。 レポートを作成しないと、リファクタリングの結果(カバレッジは変わっていないが、実行時間が短縮されている)を正確に確認できないので、まずはこちらを先に設定することをおすすめします。 以下にその定義例を示します。 # 各テストジョブ - name: Upload Compiled Classes and Jacoco Execution Data uses: actions/upload-artifact@n.n.n with: name: compiled-classes-and-jacoco-${{ matrix.test-task }} path: | build/classes **/build/jacoco/*.exec retention-days: 1 # カバレッジジョブ - name: Download Combined Artifact (Compiled Classes & Jacoco Data) uses: actions/download-artifact@n.n.n with: pattern: 'compiled-classes-and-jacoco-*' path: build/download-artifacts - name: Restore Compiled Classes and Jacoco Exec Files run: | mkdir -p build/classes mkdir -p build/jacoco # 各アーティファクトディレクトリからクラスファイルと.execファイルを抽出 for d in build/download-artifacts/*; do echo "Processing artifact directory: $d" if [ -d "$d/build/classes" ]; then cp -R "$d/build/classes/." build/classes/ fi find "$d" -name "*.exec" -exec cp {} build/jacoco/ \; done - name: Generate Jacoco Report run: ./gradlew jacocoTestReport --info 結果 日付 平均実行時間(成功のみ) テスト実行方法 2025年3月 20分50秒 直列 2025年3月 10分40秒(最短10分5秒) 並列 2025年4月 12分5秒 並列 2025年5月 14分26秒 並列 2025年6月 12分5秒 並列 2025年7月 13分41秒 並列 2025年8月 14分47秒 並列 テスト数は増え続けています(3月から8月で、約1,000件増加)が平均実行時間にばらつきがあるのは、GitHub Actionsのランナーリソースが他のワークフローと競合する時間帯に、実行時間が伸びる傾向があるからです。 そのため、開発が活発な期間やバグを集中改修する期間は同時実行数が増え、ほぼ同じテスト数でもリソース待ちが発生し実行時間が伸びてしまっています。 その他 CI実行時間の短縮に直接関係のある話ではないですが、この対応に関連して行ったことを少し整理してみます。 費用対効果の確認と事前調整 今回の対応によってCIのテスト実行時間が短縮されること自体は望ましいですが、並列化によりジョブ数が増えるため、その分消費するGitHub Actions の利用時間も増加します。 私たちの組織では、Enterprise単位で利用可能なGitHub Actionsの分数に上限が設けられているため、この増加が他チームの上限枠を圧迫する可能性を考慮する必要がありました。 今回の対応はCPU/OS 種別の変更を伴わず、あくまでジョブ数の増加による実行時間消費への影響が論点となります。 そのため、改善策を導入する前に社内の横断的な技術サポート組織である開発管理課に相談し、利用状況や上限枠を確認しました。 あわせて、公開情報を参考にコストと削減時間を試算し、想定される費用対効果を数値として提示しました。 その結果、管理職から速やかに承認を得ることができ、問題になる前に先に相談したことで、気持ち的にも余裕を持って対応することができました。 gh コマンド+Claude Codeを使ったワークフロー統計分析 今回の対応を実施し、毎月の推移を集計・確認していました。 内容としては成功したワークフローの実行時間を集計し、平均実行時間を出していました。 ただ集計方法は、正直パワーで押し切っていました。画面からワークフロー結果をコピペし、スプレッドシートに記載して計算していました。 MCPを使って上手く集計できないか試したんですが、当時は適切なツールが無く(自分で開発出来ず)実現はできませんでした。 ただ今回の記事を書くにあたって、 gh コマンドとClaude Codeを使ってみたんですが、これが大成功でした! 以下のようにプロンプトを入力し、期待した結果を得られました。 もし同じような操作を行う場合、選択肢の1つとして覚えていただけたらと思います。 (ちゃんと手作業で計算した結果とほぼ一致していました!) ghコマンドを利用して、hogeリポジトリの「Parallel Tests」ワークフローの2025年n月分の成功時のみの平均実行時間を計算してください!全ブランチ対象で! ↓ 📊 2025年8月 「Parallel Tests」ワークフロー実行統計 全体サマリー - 平均実行時間: 14分47秒(886.93秒) 月間推移(3月→4月→5月→6月→7月→8月) - 平均時間: 10分40秒 → 12分5秒 → 14分26秒 → 12分5秒 → 13分41秒 → 14分47秒 社内へのナレッジ展開 月1回の技術発表の機会で発表してきました。 ラクスではJavaを使った商材が他にもあるので、何か参考になればと思い発表したのですが、後日他のプロダクトのエンジニアから直接声をかけられ、対応方法を聞かれました。 早速今回の対応が少しでも他チームに貢献できるチャンスがあると思うと、嬉しい限りです! 伸び代 最後に伸び代を書きます。 キャッシュの有効活用 重複しているビルド資材のキャッシュ活用 ジョブの再配置 テスト実行時間に偏りが生じてきたため、均等に再分配 セットアップの分離 DBのセットアップ部分を1つにまとめ、各テストへ配布 Self-Hosted Runnerの利用 費用面や速度面で、改善余地の可能性 発展的な改善案 PRで変更があった部分だけテスト実行 ここで「将来的な差分テストなどへの拡張性」が有効に機能する想定 @SpringBootTest などのテストが遅くなる設定を減らす 不要な場所でも使っているので、精査し削除していくことで早くなることを期待 まとめ 今回は、Gradle + GitHub Actionsを用いたCIのテスト実行時間短縮についてご紹介しました。 実施内容と成果: Gradleのカスタムタスクによるテストのグループ化とGitHub Actionsのmatrix機能を組み合わせ、テストを4並列で実行 実行時間を20分50秒から10分40秒へと約50%短縮を実現 テスト数が約1,000件増加した現在でも、14分台で実行完了 特に重要だったポイント: 小さく早く試す - 複雑な最適化より、まず設定変更で実現できる並列化から着手 計測の正確性 - 成功したワークフローのみを対象に改善効果を測定 事前の調整 - 費用対効果を算出し、関係部署と事前に相談することでスムーズな導入 今後もキャッシュ活用や変更箇所のみのテスト実行など、さらなる改善の余地があります。 実際に高速開発には様々な要因が影響するため、今回のCIテスト実行時間の短縮ですぐ効果が出る訳ではないと思います。 しかし、CI完了待ち時間のコンテキストスイッチ減少やPRのフィードバック高速化など、間接的に貢献できていると考えています。 本記事が同様の課題を抱える、特にJavaやGitHub Actionsを利用しているチームの参考になれば幸いです。 それでは!
アバター
はじめに AI関連の話題 AI活用状況のスナップショット うまくいっていること オンボーディング支援 コードリーディングの支援 ボイラープレートの自動生成 単純で広範な一括修正の自動化 AIによるプルリクの一次レビュー うまくいかなかったこと(限界と落とし穴) 自立型コードエージェントによる実装 非決定性(出力の揺らぎ) コンテキスト忘却 Kotlin×IDEロックイン問題 学んだこと まとめ 参考文献 はじめに 楽楽請求開発チームのkyoshimotoです。 バックエンド開発チームに所属し、開発チームをスケールさせるための開発プロセス整備、チーム内でのAI活用の推進を担当しています。 本記事では、現時点のAI活用状況や、うまくいっている点・うまくいっていない点、学んだことを共有します。 AI関連の話題 AI活用に関する期待を一段と高める話題が増えています。代表例を挙げます。 AnthropicのAmodei氏「3–6ヶ月で90%のコード、12ヶ月で本質的にすべてをAIが書く可能性」に言及(Business Insider, 2025/03) MicrosoftのSatya Nadella氏「社内コードの20〜30%はAIが書いている」(TechCrunch, 2025/04) GoogleのChief Scientist Jeff Dean氏「1年以内にジュニアエンジニア相当の性能に到達し得る」(Business Insider, 2025/05) Windsurfチーム「コードの約95%はCascadeとWindsurf Tabで書かれている」(The Pragmatic Engineer, 2025/07) こうした記事を読むと心が踊る一方で、今後のエンジニアの仕事はどうなるのかと不安になる方もいると思います。とはいえ、商用プロダクトのソフトウェア開発の現場では、直近でエンジニアがAIに置き換わる気配は正直感じていません。 ツール導入の成果は確かに出ていますが、効果が顕著な領域はまだ限定的で、期待値は少し落ち着いたというのが正直な実感です。 AI活用状況のスナップショット 現在、チームで利用・検証している主なツールです。新しいツールが日々リリースされ乱立する中、IntelliJ+GitHub Copilot を標準的な開発環境としつつ、他のツールも試用しながら開発プロセスに組み込んでいます。 なお、バックエンドのプログラミング言語はKotlinがメインとなります。 AIツール 主な用途 ChatGPT ドキュメント作成/コード生成/コードレビュー Claude(検証中) コード生成 Codex コードレビュー Devin コード生成/ロジック調査/CIエラー対応/コードリーディング支援 Gemini ドキュメント作成/コード生成/コードレビュー GitHub Copilot コード補完/コード生成/ロジック調査/コードレビュー/コードリーディング支援 NotebookLM 仕様検索/新規メンバーのオンボーディング支援 うまくいっていること オンボーディング支援 外部設計書をNotebookLMに取り込み、仕様Q&Aを即時化。心理的安全性の高い質問窓口として機能し、新規メンバーの立ち上がりが加速しました。 2025年度はKotlin未経験者が10名以上ジョインしましたが、GitHub Copilotのタブ補完/チャットにより新しいプログラミング言語の習得が障壁になることなく、スムーズに実装タスクを開始できています。 NotebookLMイメージ コードリーディングの支援 IntelliJ+GitHub Copilotで既存ロジックの理解を効率化。実装から仕様を逆引きして整理でき、質問対応の精度も向上。 処理内容の要約や、UMLやER図の抽出など、コードリーディングの時間短縮やシステム理解に活用できています。 私の担当プロダクトは昨年10月にリリースしたばかりで、自社の別プロダクト(楽楽精算など)の機能実装を参考にする場面が多くあります。そこでDevinを用い、複数リポジトリを横断して実装を調査することで、調査コストを削減できています。プロダクト横断のコードリーディングが格段に楽になりました。 ボイラープレートの自動生成 マスタ系CRUDのAPI実装やValidationなどの定型実装の一部をDevinで自動生成できる成功事例が増えています。現在は、プロンプトのテンプレート化とプロセス組み込みを進めています。 プロンプトイメージ 単純で広範な一括修正の自動化 スキーマ変更に伴うエンティティ/テストデータ更新、APIリクエスト/レスポンス構造変更など、ロジックは単純だが影響範囲が広い作業は、数百ファイル規模でもDevinを使ってワンショットで完了するケースが多く、開発コスト削減の効果が出ています。 AIによるプルリクの一次レビュー PR作成直後にAIがタイポ、コメントの誤り、表記ゆれ、スタイル不一致といった軽微な指摘を先出しします。これにより、レビュアーは設計やロジックなど本質的な論点に専念できています。 (GitHub Copilot Code Review, OpenAI Codexを利用) GitHub Copilot Code Reviewイメージ うまくいかなかったこと(限界と落とし穴) 自立型コードエージェントによる実装 Devin、GitHub Copilot、Cursorを使って、実装タスクの自動化を検証しましたが、成功はボイラープレート生成と単純一括修正にほぼ限定されます。 その他では、以下のような課題が上がりました。 セッション(会話)が長引くほど生成精度が劣化し、生成コードの採用に至らない。 指示の具体化や前提整理に時間がかかり、人が実装した方が速い場面が多い。 非決定性(出力の揺らぎ) 同一プロンプトでも出力がぶれるため、AIツールで生成したコードの比較や精度評価の収束に難航しました。 AIの「非決定性」問題を認識せず、プロンプトやコンテキストに“おまじない”的な調整やハックに頼った結果、再現性のない成功パターン探しに時間を浪費してしまうことがありました。 コンテキスト忘却 プロンプトが長くなると冒頭・末尾が優先され中盤が抜けやすい(Lost in the Middle問題)。さらに、コンテキストウィンドウ上限を避けるためのコンテキスト圧縮過程で重要事項が脱落。結果として、 ガイドラインを与えても全項目の遵守は期待しづらい。 コードレビューもごく一部の規約しか参照されない。 セッションが長くなるほど残り10〜20%の実装をAIで完遂するのが難しい。 指定外リポジトリへのPR作成、プロンプトに明示した指示の無視が散見される(例:「PRを作成しないで」「プロパティファイルの定義は辞書順で」といった指示が無視される)。 Kotlin×IDEロックイン問題 標準の開発環境は IntelliJ+GitHub Copilotですが、VS Code版と比べて機能提供の遅れや不具合が目立ち、体験品質に課題が残ります。いっぽうでVS Code系(Copilot in VS Code/Cursor)はKotlinの言語サポートやコードジャンプが不十分で、AIツール導入の移行障壁になっています。結果として、Kotlinの採用により、IntelliJへの事実上のベンダーロックインが生じ、AI活用推進のボトルネックになっていると分かりました。 学んだこと 「ボイラープレートの自動生成」「単純だが広範な一括修正」「要約・逆引き」はAIの得意分野です。ここを主戦場に据えると、費用対効果は安定します。 一方で、非決定性と忘却の問題を抑え込めば、AI活用の適用範囲は広がります。プロンプトやコンテキストの小手先の最適化に偏るよりも、静的解析やユニットテストで出力を厳密に検証できる土台の強化に重きを置くべきだと考えます。期待値をコードで固定できれば、エージェントは失敗に一貫して反応し、自己修復ループに乗りやすくなります。 まとめ AIは「補助輪」です。走り出しを助け、速度を上げ、転びにくくし、学びを加速します。ただし、進むべき方向を決めるのは人間です。 できること/できないことをチームで共有し、使いどころを明確にする。こうした地道な運用こそが、いま現場で効いています。次は、この運用を標準化し、対象領域を段階的に拡大していくことが重要だと考えます。 参考文献 www.businessinsider.com techcrunch.com www.businessinsider.com Windsurf「約95%はCascade/Tabで」—LDX3講演スライド Lost in the Middle—TACL/論文(Liu et al., 2023)
アバター
はじめに こんにちは。楽楽請求でバックエンド開発を担当しているmarumoです。 楽楽請求は2024年10月にサービスを開始した新サービスで、請求書を一元管理し、経理業務を効率化する請求書受領システムです。 その中で、請求書の内容をデータ化するために OCR エンジンの API を活用し、自動データ化機能を提供しています。 請求書の自動データ化は、楽楽請求の中核を担う機能です。 サービスの価値を支えるこの仕組みを安定かつ効率的に動作させるためには、大量の請求書を迅速に処理できることが欠かせません。 大量の請求書を確実に捌くため、OCR エンジンの API 呼び出し処理は高並列化を前提に構築しました。 しかし、高並列処理の負荷検証中に「CPU やメモリは安定しているのに、スレッド数だけが増え続ける」という現象に遭遇しました。 本記事では、その原因をどのように特定し、どのように解決したのかを紹介します。 はじめに 利用技術 背景:スレッドが増え続ける 調査 解決策:HTTP クライアントの再利用 Before:毎回生成していたケース After:シングルトンで再利用するケース 検証 検証目的 検証方法 検証結果 結論 まとめ 利用技術 本記事で扱う実装は Spring Boot をベースにしています。主に利用している技術スタックは以下の通りです。 アプリケーションフレームワーク : Spring Boot 3.5 HTTP クライアント : RestTemplate(内部実装として Apache HttpClient 4 系を使用) この記事では、これらの技術を前提にHTTP クライアントのライフサイクル管理に起因するスレッド増加問題とその解決策を解説します。 なお、本文中のサンプルコードは Kotlin で記載していますが、問題の本質は言語に依存しません。 背景:スレッドが増え続ける OCR エンジンの API 呼び出し処理の負荷試験として、50 並列で OCR API を呼び出す構成に対して 500 ファイルを同時にアップロードしました。 すると CPU やメモリには大きな問題がないにもかかわらず、JVM のライブスレッド数だけが直線的に増加し、最終的には 1,000 を超える状態に達しました。 調査 最初に疑ったのは外部 API の遅延やハングでしたが、Thread Dump を確認すると RUNNABLE 状態の短命スレッドが大量に存在しており、この仮説は否定されました。 さらに Thread Dump を詳細に解析したところ、 java.net や org.apache.http に関連するスレッドが多数存在していることが分かりました。 これらは HTTP クライアントの内部スレッドであり、RestTemplate の利用に伴うものです。 HttpClient-2-SelectorManager@19,900 in group "main": RUNNING HttpClient-3-SelectorManager@19,902 in group "main": RUNNING HttpClient-32-SelectorManager@19,942 in group "main": RUNNING HttpClient-34-SelectorManager@19,944 in group "main": RUNNING HttpClient-35-SelectorManager@19,946 in group "main": RUNNING HttpClient-36-SelectorManager@19,949 in group "main": RUNNING HttpClient-37-SelectorManager@19,950 in group "main": RUNNING ... ... ... 解決策:HTTP クライアントの再利用 採用した方針は、 HTTP クライアントを再利用可能な形で管理すること です。 具体的には以下を実施しました。 RestTemplate を シングルトン Bean として定義 呼び出し側での build() 呼び出しを廃止し、DI 渡しのインスタンスを利用 Before:毎回生成していたケース この場合、リクエストのたびに HttpClient が新規生成され、内部で SelectorManager や Worker スレッドも作られるため、スレッド数が累積していきます。 class OcrServiceFactoryImpl { fun createRestTemplate(): RestTemplate { // 毎回 build() を呼び出して新しい HttpClient を生成 return RestTemplateBuilder() .setConnectTimeout( Duration .ofSeconds( 5 )) .setReadTimeout( Duration .ofSeconds( 30 )) .build() } fun callOcrApi(request: OcrRequest): OcrResponse { val restTemplate = createRestTemplate() return restTemplate.postForObject( "https://example.com/ocr" , request, OcrResponse :: class .java) !! } } After:シングルトンで再利用するケース この構成では RestTemplate がアプリケーション全体で 1 インスタンス共有されるため、内部の HttpClient も再利用され、スレッド数が増え続ける問題が解消される。 @Configuration class RestTemplateConfig { @Bean fun restTemplate(builder: RestTemplateBuilder): RestTemplate { return builder .setConnectTimeout( Duration .ofSeconds( 5 )) .setReadTimeout( Duration .ofSeconds( 30 )) .build() } } @Service class OcrService( private val restTemplate: RestTemplate ) { fun callOcrApi(request: OcrRequest): OcrResponse { return restTemplate.postForObject( "https://example.com/ocr" , request, OcrResponse :: class .java) !! } } 検証 検証目的 RestTemplate をシングルトンに変更した構成で、HTTP 通信が直列化していないか(並列性を維持しているか)を確認する 併せて、以前発生していた「スレッド数が通信ごとに増加する問題」が解消されているかを確認する 検証方法 以下を観測しました - RestTemplate の通信ログ(DEBUG)によるリクエストの並列性 - Grafana の jvm_threads_live_threads メトリクスによるスレッド数の挙動 - IntelliJ の Thread Dump によるスレッドの状態(処理中と処理完了後の2タイミング) 検証結果 スレッド数の挙動 修正前:アップロードのたびに HttpClient-SelectorManager が増加し、 jvm_threads_live_threads が400超に 修正後: RestTemplate の使い回しにより、スレッド数は一定値(100前後)で安定し、増加し続ける挙動は再現されなかった Thread Dump 通信中は HttpClient-1-SelectorManager が RUNNABLE 状態で非同期処理を担当 通信後も同一スレッドが残存していたが、新規増加は見られず再利用が確認された 並列性 通信ログのタイムスタンプを比較すると、複数のスレッドが同時にリクエストを発行しており直列化はされていない レスポンス順序もランダムで、リクエストが並列で処理されていることを確認 // リクエスト開始ログ 2025-04-15 10:49:26.204 DEBUG 1 --- [pool-5-thread-6] o.s.web.client.RestTemplate : HTTP POST https://example.com/ocr 2025-04-15 10:49:26.204 DEBUG 1 --- [pool-5-thread-7] o.s.web.client.RestTemplate : HTTP POST https://example.com/ocr 2025-04-15 10:49:26.204 DEBUG 1 --- [pool-5-thread-4] o.s.web.client.RestTemplate : HTTP POST https://example.com/ocr 2025-04-15 10:49:26.204 DEBUG 1 --- [pool-5-thread-5] o.s.web.client.RestTemplate : HTTP POST https://example.com/ocr ... // レスポンスログ 2025-04-15 10:49:31.756 DEBUG 1 --- [pool-5-thread-7] o.s.web.client.RestTemplate : Response 200 OK 2025-04-15 10:49:31.929 DEBUG 1 --- [pool-5-thread-5] o.s.web.client.RestTemplate : Response 200 OK 2025-04-15 10:49:32.029 DEBUG 1 --- [pool-5-thread-6] o.s.web.client.RestTemplate : Response 200 OK 2025-04-15 10:49:32.871 DEBUG 1 --- [pool-5-thread-4] o.s.web.client.RestTemplate : Response 200 OK 結論 RestTemplate をシングルトンにしたことで、内部の HttpClient も共有され、 通信スレッドの再利用が有効に働いた その結果、 スレッド数が通信ごとに増加する問題は解消 HttpClient-1-Worker-* および HttpClient-1-SelectorManager のスレッドが再利用されていることが Thread Dump により確認され、リソースの安定性が確保された まとめ 今回の事例、 HTTP クライアントのライフサイクル管理不足がスレッド増加の原因になり得る という点が明らかになりました。 RestTemplate をシングルトン化し用途ごとに分離することで、リソースの再利用・安定性・性能の維持を実現しました。
アバター
はじめに こんにちは。メールディーラーAI開発課のmarronです。エンジニアブログ初投稿となります。よろしくお願いします。 私が所属しているメールディーラーAI開発課では、主にメールディーラーに搭載されるAI機能の開発を担当しています。 現在は10月にリリース予定の回答自動生成エージェントの開発を進めています。 この機能を開発するにあたって、新たにベクトルDBを利用したナレッジの検索機能が必要となりました。 本記事では、ベクトルDBでの検索精度を上げるために導入したハイブリッド検索についてご紹介します。 はじめに ベクトルDBの選定 ベクトルDBとは メールディーラーで採用したベクトルDB 密ベクトルを用いた検索 Qdrantでの密ベクトル検索 密ベクトル検索の欠点 疎ベクトルを用いた検索 疎ベクトルとは Qdrantでの疎ベクトル検索 両方の検索結果を組み合わせるハイブリッド検索 密ベクトルと疎ベクトルの両方を活用する Qdrantでのハイブリッド検索 まとめ 参考文献 ベクトルDBの選定 ベクトルDBとは そもそも「ベクトルDBとはなんぞや」という方もいらっしゃると思いますので、簡単に説明させていただきます。 開発中の機能では、過去の対応履歴やFAQをもとに作成したナレッジから問い合わせの回答に必要となる情報を検索します。 ナレッジの検索には全文検索を利用したキーワード検索を用いても良いのですが、キーワード検索の場合は問い合わせに含まれるキーワードがナレッジに含まれるキーワードと少しでも異なると情報がヒットしません。 この問題を解決するために、ナレッジや問い合わせを数値ベクトル化してベクトルの近さによる検索を行います。この数値ベクトルは、文章全体がどういった意味を示しているかを多次元で表したものになります。 検索時はベクトル同士の距離を測ることで、距離が近い = 意味が似ているデータを見つけることができます。ベクトル化(埋め込み表現)については参考文献もご参照ください。 このベクトルデータを保存するのに利用するのがベクトルDBになります。ベクトルDBはベクトルデータを保存することに特化しており、膨大なベクトルデータ同士の距離計算を効率よく高速に行ってくれるものになります。 メールディーラーで採用したベクトルDB メールディーラーでベクトルDBを利用するのは2回目なのですが、前回採用したChromaDBでは今回の機能を提供するにあたってパフォーマンス面で不安がありました。 そのため、別途ベクトルDB専用のサーバを構築することにしました。 利用するDBを選定するために以下のような条件を満たす製品を探すことにしました。 オンプレミス環境で動作すること マルチテナント構成に対応できること 複数台サーバを用いた負荷分散が行えること この条件を満たす製品として「Milvus」「Qdrant」「PGVector」を候補として、パフォーマンスや使いやすさを比較しました。 結論としてはタイトルにもある通り、Qdrantを採用することにしました。理由は下記の通りです。 Rust製で、高速に検索が行えることを謳っている Dockerコンテナだけでなく、単体バイナリとしても配布されており、オンプレミスのサーバに導入しやすい マルチテナントでの運用方法がドキュメントに記載されており、インデックスの最適化方法まで記載されている 簡単な設定で分散環境を構築することができる 利用するベクトルDBが決定したので、実際に利用してみます。 密ベクトルを用いた検索 Qdrantでの密ベクトル検索 最初に説明した文章全体の意味合いを示したベクトルデータを密ベクトル(Dense Vector)と呼びます。まずはこの密ベクトルを利用した検索を行ってみます。 ベクトルデータを投入するためにQdrant上にコレクションを準備します。 今回のサンプルコードはすべてPythonで記載しています。また、Qdrant公式のDockerイメージを利用して環境を構築しています。 from qdrant_client import QdrantClient, models qdrant = QdrantClient(url= "http://localhost:6333" ) qdrant.create_collection( collection_name= "dense_collection" , vectors_config=models.VectorParams(size= 1536 , distance=models.Distance.COSINE) ) size にはベクトルデータの次元数を指定します。今回はOpenAIのEmbeddings APIによるベクトル化を行い、モデルに text-embedding-3-small を利用するため、1536次元を指定しています。 distance にはベクトルデータの距離計算に利用する方式を指定します。今回はテキストの類似度を調べるのに最適とされるコサイン類似度を指定しています。 コレクションが作成出来たら、検索対象のデータを保存します。今回はChatGPTを利用して、5つの猫種の特徴を20件ずつ文章にしてもらい、計100件のデータを投入しました。 アメリカンショートヘアは筋肉質である。 スコティッシュフォールドは耳が折れている猫である。 メインクーンは世界最大級の猫である。 シャムは社交的な猫である。 ペルシャは長毛の猫である。 ... from qdrant_client import QdrantClient, models from openai import OpenAI qdrant = QdrantClient( "http://localhost:6333" ) openai = OpenAI() with open ( "cat.txt" , "r" , encoding= "utf-8" ) as f: for idx, line in enumerate (f): line = line.strip() response = openai.embeddings.create( input =line, model= "text-embedding-3-small" ) vector = response.data[ 0 ].embedding qdrant.upsert( collection_name= "dense_collection" , points=[ models.PointStruct( id =idx, vector=vector, payload={ "text" : line} ) ] ) Qdrantではベクトル以外のデータをpayloadという形式で保持します。今回はベクトル化対象の文章をpayloadに保持するようにしています。 準備が出来たので、投入したデータに対して検索を行ってみます。 from qdrant_client import QdrantClient, models from openai import OpenAI qdrant = QdrantClient( "http://localhost:6333" ) openai = OpenAI() query = "穏やかな性格の猫" response = openai.embeddings.create( input =query, model= "text-embedding-3-small" ) vector = response.data[ 0 ].embedding search_result = qdrant.query_points( collection_name= "dense_collection" , query=vector, with_payload= True , limit= 5 ) for point in search_result.points: print (f "Score: {point.score}, Text: {point.payload['text']}" ) 実行結果がこちらになります。 Score: 0.6045555, Text: メインクーンは落ち着いた雰囲気を持つ猫である。 Score: 0.59054977, Text: ペルシャは優雅な雰囲気を持つ猫である。 Score: 0.565565, Text: ペルシャは静かな生活を好む猫である。 Score: 0.55805016, Text: ペルシャは穏やかな性格である。 Score: 0.5490287, Text: スコティッシュフォールドは静かな環境を好む猫である。 無事似ている文章を検索することが出来ました。 このときのスコアはベクトルの類似度を示しており、コサイン類似度を利用した時は値が大きいものほど似ていることを示しています。 密ベクトル検索の欠点 密ベクトルを利用した検索では文章が似ているかどうかに着目して検索を行います。 このとき、あくまで類似度に着目して検索を行うため、全く同じキーワードを含んでいるかには着目していません。これが弱点となるパターンがあります。 例えば、「○○ではAボタンを決定として使う」と「××ではBボタンを決定として使う」というナレッジがあったとします。 このときに「○○ではどのボタンが決定ですか?」という問い合わせがあった場合に前者の情報を使いたいのにもかかわらず、後者の情報を取得する可能性があります。これでは回答文として利用できません。 そこでキーワード検索と同じ仕組みをベクトル検索でも行えるようにします。 疎ベクトルを用いた検索 疎ベクトルとは キーワード検索を行うためには文章内にどのような単語が含まれているかを知る必要があります。そこで利用するのが疎ベクトル(Sparse Vector)になります。 密ベクトルではベクトル内の値が0以外であることが多いのですが、疎ベクトルでは単語の頻出度や決まった単語との類似度を示すため、ベクトル内の値が0であることが多いです。そのため、値がスカスカのベクトルという意味で疎ベクトルと呼ばれます。 疎ベクトル同士を比較することで単語ごとの頻出度を調べ、検索したいキーワードが多く含まれる文章を取り出すことが出来ます。 Qdrantでの疎ベクトル検索 Qdrantでは1つの文章に対して、密ベクトルと疎ベクトルの両方を保持することが出来ます。 ただし、既存のコレクションに対して、保持するベクトルの個数や形状を変更することができないため、新たにコレクションを作成します。 from qdrant_client import QdrantClient, models qdrant = QdrantClient(url= "http://localhost:6333" ) qdrant.create_collection( collection_name= "sparse_collection" , vectors_config={ "dense" : models.VectorParams(size= 1536 , distance=models.Distance.COSINE)}, sparse_vectors_config={ "sparse" : models.SparseVectorParams()} ) 次に密ベクトルと一緒に疎ベクトルを投入します。 密ベクトルはOpenAI APIを利用することで生成することが出来ますが、疎ベクトルを生成するAPIは提供されていません。 そのため、疎ベクトル化は自ら行う必要があります。 また、今回疎ベクトル化にはQdrantが提供しているライブラリを採用したのですが、このライブラリは日本語のトークン化(文章の単語を切り分ける処理)に対応していません。そのため、トークン化の処理を自前で実装する必要があります。 疎ベクトル化の処理は参考文献を元に実装しています。今回のサンプルプログラムではこの疎ベクトル化の処理については省略させていただきます。 密ベクトルのところで利用した100件のデータから作成した密ベクトルと疎ベクトルを投入します。 from qdrant_client import QdrantClient, models from openai import OpenAI qdrant = QdrantClient( "http://localhost:6333" ) openai = OpenAI() # TextEmbedderの実装については省略 embedder = TextEmbedder() with open ( "cat.txt" , "r" , encoding= "utf-8" ) as f: for idx, line in enumerate (f): line = line.strip() response = openai.embeddings.create( input =line, model= "text-embedding-3-small" ) dense_vector = response.data[ 0 ].embedding sparse_vector = embedder.embed_query(query_text=line) qdrant.upsert( collection_name= "sparse_collection" , points=[ models.PointStruct( id =idx, vector={ "dense" : dense_vector, "sparse" : models.SparseVector( indices=sparse_vector.indices.tolist(), values=sparse_vector.values.tolist(), ) }, payload={ "text" : line} ) ] ) 疎ベクトルだけを使って検索を行ってみます。 from qdrant_client import QdrantClient, models from openai import OpenAI qdrant = QdrantClient( "http://localhost:6333" ) openai = OpenAI() query = "穏やかな性格の猫" # TextEmbedderの実装については省略 embedder = TextEmbedder() sparse_vector = embedder.embed_query(query_text=query) search_result = qdrant.query_points( collection_name= "sparse_collection" , query=models.SparseVector( indices=sparse_vector.indices.tolist(), values=sparse_vector.values.tolist() ), using= "sparse" , with_payload= True , limit= 5 ) for point in search_result.points: print (f "Score: {point.score}, Text: {point.payload['text']}" ) 実行結果がこちらになります。 Score: 2.0, Text: スコティッシュフォールドは穏やかな性格である。 Score: 2.0, Text: ペルシャは穏やかな性格である。 Score: 2.0, Text: アメリカンショートヘアは穏やかな性格である。 Score: 2.0, Text: メインクーンは穏やかな性格である。 Score: 1.0, Text: メインクーンは子どもと仲良くできる猫である。 単語単位で似ている文章が取り出せていることが分かります。 このときのスコアは似ている単語がどの程度文章に含まれているかを示しています。 両方の検索結果を組み合わせるハイブリッド検索 密ベクトルと疎ベクトルの両方を活用する これで文章の類似度による検索とキーワードを利用した検索を行えるようになりました。 この2種類の検索方法は互いの弱点を補うものですので、検索結果を統合することで精度を上げることが出来ます。 問題はこの2つの検索結果をどうやって統合するかです。それぞれの検索結果を元に類似度が高い文章を取り出したいので、それぞれのスコア(順位)から再度スコア計算を行う必要があります。 この仕組みをハイブリッド検索と呼びます。ハイブリッド検索を簡単に行える方法をQdrantが提供していますので、実際に使ってみます。 Qdrantでのハイブリッド検索 Qdrantでハイブリッド検索を行う場合、まず prefetch という機能で先に密ベクトル、疎ベクトルのそれぞれの検索結果を作成しておきます。 その後、検索結果を統合するために検索クエリに fusion を指定します。このとき、統合する方法にはRRF手法とDBSF手法を利用できます。 RRF手法は検索結果の順位に基づいて新しいスコアを計算します。一方、DBSF手法は検索結果そのもののスコアを利用して新しいスコアを算出します。 RRF手法は順位ベースのため、異なる性質を持つベクトル(今回の場合は密ベクトルと疎ベクトル)を比較する際に有効です。そこで今回はRRF手法を採用しました。 逆に、同種のベクトルで内容が異なる複数の検索結果を統合する場合には、DBSF手法の方が適していると考えられます。手法の詳しい内容については参考文献をご参照ください。 では、ハイブリッド検索を実際に行ってみます。コレクションは疎ベクトルの時に作成したものを利用します。 from qdrant_client import QdrantClient, models from openai import OpenAI qdrant = QdrantClient( "http://localhost:6333" ) openai = OpenAI() query = "穏やかな性格の猫" response = openai.embeddings.create( input =query, model= "text-embedding-3-small" ) dense_vector = response.data[ 0 ].embedding # TextEmbedderの実装については省略 embedder = TextEmbedder() sparse_vector = embedder.embed_query(query_text=query) search_result = qdrant.query_points( collection_name= "sparse_collection" , prefetch=[ models.Prefetch( query=dense_vector, using= "dense" , limit= 5 ), models.Prefetch( query=models.SparseVector( indices=sparse_vector.indices.tolist(), values=sparse_vector.values.tolist() ), using= "sparse" , limit= 5 ) ], query=models.FusionQuery(fusion=models.Fusion.RRF), with_payload= True , limit= 3 ) for point in search_result.points: print (f "Score: {point.score}, Text: {point.payload['text']}" ) 検索結果を統合するため、prefetchで取得する件数は最終的に必要な件数より大きくしておく必要があります。prefetchの取得件数が少ないと統合した際にどちらかのベクトルに偏ったデータも取得されてしまいます。 実行結果がこちらになります。 Score: 0.53333336, Text: ペルシャは穏やかな性格である。 Score: 0.5, Text: メインクーンは落ち着いた雰囲気を持つ猫である。 Score: 0.5, Text: スコティッシュフォールドは穏やかな性格である。 文章の類似度と単語単位での類似度を元に文章が取り出せています。 このときのスコアはそれぞれのベクトルでの順位を元に算出されたものとなります。 まとめ Qdrantを利用したハイブリッド検索を活用することで、ナレッジの検索精度を向上させました。 みなさんもRAGのような文章検索を行う場面がありましたら、ぜひハイブリッド検索を利用した精度向上を行ってみてください。 参考文献 atmarkit.itmedia.co.jp qdrant.tech qiita.com dev.classmethod.jp
アバター
はじめに こんにちは。楽楽明細開発チームのtkktです。 楽楽明細は2013年のサービス開始以来、10年以上の運用を続け、現在では1万を超えるお客様にご利用いただいています。 しかし、この成長の裏側では、長年の機能追加や複雑化による技術的負債が蓄積し、 新機能追加のたびに調査やテスト工数が増大するなど、サービスの成長スピードを阻害する課題に直面していました。 今回は、その課題を乗り越えるために取り組んだシステム刷新の一部をお話ししたいと思います。 目次 刷新の背景 実際の取り組み リリース後の課題と改善 成果と効果 今後の展望 まとめ 刷新の背景 長年の運用により、システムには以下のような課題が生じていました。 古いフレームワーク利用によるリスク サポート終了が迫り、セキュリティリスクが高まっていた 周辺のミドルウェアやライブラリのバージョンアップも妨げられていた 開発効率の低下 度重なる機能追加によりコードが複雑化 影響調査やテストに多くの工数が必要 本番環境での障害やインシデントも少なくなかった 当初の開発メンバーが離職しており、仕様把握が難しくなっていた 顧客数増加による影響 操作の多様化でこれまで出なかった不具合が顕在化し、障害対応工数が増加 クラスタ数の増加でリリース時間も長くなっていた さらに、手動テスト中心だったため、開発全体の工数に占めるテスト工数の比率が大きくなり、改善活動に時間を割けない状況もありました。 こうした背景から「今後の安全性・開発効率を確保するには刷新が必須」となり、プロジェクトが動き出しました。 実際の取り組み 刷新の第一歩として、利用者が限定的な一部機能を対象にしました。 セキュリティリスクが高く、既存システムからの切り離しが容易だったためです。 移行は二段階で実施しました。 第1弾 :既存アプリ内の処理を新フレームワークに書き換え、まずは安定稼働を実現 第2弾 :本体アプリから切り離して独立稼働させ、フロントで受けたリクエストを新アプリに振り分ける構成に変更 段階的なシステム刷新のイメージ この二段構えにより、障害や不具合発生のリスクを抑えつつ、新基盤への移行を進めることができました。 リリース後の課題と改善 第1弾リリース直後には、想定外の問い合わせや不具合対応に苦労しました。 特に、利用者環境に依存する問題(ブラウザ拡張機能やセキュリティソフトの影響など)が発生し、リクエストがアプリに届かないケースでは原因調査に時間を要しました。 チームでは、問い合わせいただいたお客様に協力いただき、スクリーンショットやコンソールログを取得して原因を特定するなど、地道な調査を重ねました。 その経験を踏まえ、以降はフロントエンドの操作状況やエラーを分析できる仕組みを導入。さらに次の段階では、システムの監視基盤を強化し、不具合の早期発見と原因特定をしやすくする取り組みを進めています。 成果と効果 刷新の効果は、コード品質やテスト体制の改善に顕著に表れています。 コードの複雑度が大幅に改善 刷新前は数十クラスで「変更すると誤修正を招きやすい」と評価される状態 刷新後はそうした箇所がほぼ解消され、多くのクラスが低い複雑度に テスト体制の強化 リリース前はテストの大半が手動で、カバレッジは全体で30%程度 刷新部分では自動テストを整備し、カバレッジが80%を超える水準に向上 フロントエンドとバックエンドを分離したことで、テストのしやすさも格段に向上 刷新直後は不具合対応が発生しましたが、マイナーリリースを重ねて早期に収束。現在ではアプリケーション起因の不具合は減り、安定性が高まっています。 今後の展望 刷新はまだ道半ばです。 今後は、サポートが終了していくフレームワークやライブラリを計画的に置き換えるとともに、アーキテクチャの刷新にも取り組んでいきます。 機能や要件によっては、新しいサービス基盤への移行も視野に入れています。 また、アプリケーションの稼働環境についても改善を進め、より柔軟かつ効率的に運用できる仕組みを整備する予定です。 さらに、組織全体としてもAIを積極的に活用しており、刷新の過程でも開発効率化や品質向上に役立てていく方針です。 まとめ 今回紹介した取り組みは、まだ刷新プロジェクトの一部に過ぎません。 今後も継続して改善を進め、お客様により安心して利用いただけるシステムを目指すとともに、開発者にとっても挑戦しがいのある環境を築いていきます。
アバター
こんにちは、株式会社ラクスでデザイナーをしているかっつです。 今回は私が所属しているプロダクトデザイン3課でデザインレビューを始めることになった話をご紹介します。 デザインレビューをする文化がなかったところからなぜ始めることになったのか、 上手く行っていること・行かなかったことなどお話しします。 これからデザインレビューをチーム内で始めようとしている方の参考になれば嬉しいです。 1. デザインレビューを始めるきっかけ 2. どう始めたか いきなりレビューではなく、まず輪読会から レビュー用フォーマットの導入 3. 上手くいったこと 議論が建設的になった 副次的にチームの課題を解決できた 4. 課題とこれから 5. まとめ 1. デザインレビューを始めるきっかけ ラクスのデザイナーはそれぞれが担当するプロダクトを持ち、デザインを進めています。 その状況もあり、プロダクトをまたいだレビューの機会はあまりありませんでした。 ただ最近、課内で案件の進捗を共有する時間が設けられるようになり、そこで偶発的に「そのデザイン、こうしたらもっと良さそう」と意見を言い合ったり、議論が生まれるようになってきました。 また、採用が進んでメンバーが増えてきたこともあり自然と「レビュー」の必要性が高まっていきました。 とはいえ、お互いに「レビュー」に対する認識が揃っていなかったので、フィードバックがしづらかったり、受け取り方にズレが出てしまうこともありました。 そこで、私たちは課として「デザインレビュー」を正式に始めることにしました。 目的は大きく2つあり、 1つ目は楽楽シリーズ全体のデザイン品質を高めること。2つ目はレビューを通してお互いに学び合い、スキルを高めていくことです。 2. どう始めたか いきなりレビューではなく、まず輪読会から 「レビュー」に対する認識やお作法をそろえるために、まずは 『みんなで始めるデザイン批評』 という本を使って輪読会を始めました。 みんなではじめるデザイン批評―目的達成のためのコラボレーション&コミュニケーション改善ガイド 作者: アーロン・イリザリー , アダム・コナー ビー・エヌ・エヌ新社 Amazon 輪読会の目的は、本の内容を理解することよりも以下を重要視しています。 みんなが何に関心を持っているか どんなところでつまずきやすいか 「レビュー」という言葉をどう解釈しているか こうした違いを理解して、お互いの認識のズレを解消することを意識しました。 本という共通のオブジェクトがあることで、「Aという事例を見て自分はこう解釈した」と話せるので、議論がとてもスムーズになります。これがないと、同じ言葉を使っていても実は違うイメージで話している…なんてことが起きてしまいます。 輪読会では何を議論したいかをグルーピングして議論していきます 実際に輪読会をしてみると、 「レビューって承認のことだと思っていた」 「人柄がわからない相手には意見しづらい」 「デザインレビューは手段にすぎなく、担当外のスプリントレビューに他デザイナーも入るで良いのでは?」 「ファシリテーションスキルが大事になる。どうしたら伸ばせる?」 など、想定していなかった課題や施策も見えてきました。これらは輪読会の時間の中で一つずつ解決を試みました。 輪読会で議論した様子 ※輪読会の効果や具体的な進め方は別の記事で紹介しようと思います。 レビュー用フォーマットの導入 輪読会を重ねる中で「仕組み化した方がいいよね」という流れになり、レビュー用のフォーマットを作ることにしました。 このフォーマットは、輪読会で出てきた「これだけは大事にしたい」という要素を集めて型化したものです。 レビュールールとフォーマット また運用ルールも作成しました。 事前にNotionに書き込んでチャットで連絡 週2回レビュー用の時間を確保して、利用しても良い時間にする Notionの起票場所 私たちのレビューの特徴は、 承認フローではなく「意見交換の場」として位置づけていること です。 最終的なオーナーシップはあくまでデザイナー本人にあり、レビューはより良くするためのヒントを持ち寄る場としています。 3. 上手くいったこと 実際にデザインレビューを始めるにあたり、いくつかのことが改善されました。 議論が建設的になった 今までは案件の共有の中でデザインレビューが偶発的に行われていたので、論点があっちこっちに行っていました。 それがレビューフォーマットを導入したことや、レビューへの概念が認識統一されたことで、コミュニケーションが建設的になりました。 結果として、レビューを依頼する人は欲しい情報を持って帰れるようになりました。 副次的にチームの課題を解決できた 前述した通り、デザインレビューをする前段の部分である相互理解、そもそものファシリテーションスキルをどう高めるかといった部分まで議論ができ、それに向けてアクションをすることができました。 特に相互理解の部分は、お互いの過去の経験や得意なこと・苦手なことなどを知る良い機会となり、チームで協業する土台を作ることができました。 ※『実際にあなたのチームは機能していますか』という本では、信頼の欠如がチームの機能不全となる要因と書かれており、お互いの歴史や強みを知ることは効果的とされています。 あなたのチームは、機能してますか? 作者: パトリック・レンシオーニ 翔泳社 Amazon 4. 課題とこれから もちろん、課題もまだあります。 一番大きいのは、 レビューが任意であるため、参加や活用にばらつきがあることです。 困ったときに声をかけやすくなったという良い変化はあるものの、「楽楽シリーズ全体のデザイン品質をどう高めるか」という視点で見ると、デザイナー個人の意思に依存してしまっているのが現状です。 ただし、レビューは「チェックの門番」ではなく、あくまで品質を高めるための一つの手段だと私たちは考えています。 強制力を持たせるとスピードも落ちてしまい、本来の目的からずれてしまう恐れがあります。 だからこそ、課としてデザイン品質をどう担保していくのか方針を決めて、デザインレビューの位置付けを決めていく必要があります。 最終的には、レビューという時間の意識もなくなり、気軽に相互に聞いて改善する意識が根付いていくとより良いなと感じています。 5. まとめ まだ始めたばかりで試行錯誤の連続です。完璧なレビュー文化は一朝一夕には作れませんが、小さく試して改善していくことを目指しています。 課題もたくさんありますが、それも含めてチームで取り組んでいることが、私たちのチームらしさだと思っています。 こういう文化を大切にしているチームで一緒に働きたい人はぜひお声がけください! career-recruit.rakus.co.jp
アバター
こんにちは。40代インフラエンジニアのAと申します。 今回は今さらながら、 Kubernetesを勉強し始めた エンジニアのポエムになります。 あまり技術的な内容はありませんがご容赦ください。 経歴 手作業のインフラの時代 新しい時代の幕開け、そして焦り 重い腰を上げ下げしてようやくKubernetesへ 金はかけるがコスト感をもつ (参考)AWSのマニュアルにあるゲーム(2048)をデプロイしてみる 難しく考えず、実は根本はあまりかわらないよ おわりに 経歴 私はエンジニア歴20年以上の世間では「ベテラン」といわれるインフラエンジニアで 経歴としてはSIerでOSインストールや機器設定を現場でがむしゃらにこなす所から始まり、 SaaS業界で運用を経て、昨今はオンプレ機器の導入・設計をリードする立場で働いてまいりました。 また、現在の会社は在籍年数も10年以上と長く、何やらベテラン臭のする、 「発言ばかりが目立つベテラン社員」に何となく居座っている状況でありました。 手作業のインフラの時代 少し時代をさかのぼりますが、20年前のインフラは手作業と物理作業が当たり前でした。 データセンターで徹夜のサーバチューニング、手動でのシステム再起動、 無駄に長いストレージのビルドを待ちながらの仮眠。 エンジニアのとてつもない長時間労働によって、システムの安定稼働が支えられていた時代です。 しかし、そんな私が長年培ってきた「手作業のインフラの時代」は、 多様な選択肢の中から最適なソリューションを設計することが求められる時代になっていました。 これまで自分が拠り所としてきた経験そのものが、 時代遅れになってしまうのではないかという不安 を抱かせるには十分すぎる変化でした。 新しい時代の幕開け、そして焦り グローバルクラウドが席巻したかと思えばコンテナが時代の旗手となり 世の中はIaC(Infrastructure as Code)の時代の幕開けとなっていました。 作業の自動化、人的ミスのない再現性、バージョン管理、 我々が苦労して手動で支えてきた内容が、 今ではきれいにコードで完結 するようになってきました。 新しく業界に入ってくる若者たちはこれが当たり前かのように周りにある時代、刷新された知識で業務をこなし始めていきます。 そんな中でベテランと名の付く座に安座しているのであれば、 偉そうにこれらの知識も「どや顔」で弁舌しなければメンツを保てないわけで、 ChatGPTとかで非常に表面的に「コンテナのメリットとは?」みたいに調べて知った気になって、 「何となくどこでも動かせるポータブルな技術だよね。お前ら、まだ手動でやってんのか?」 と「どや顔」で言ってはいるものの、 実は自分は何も動かしたことがない虚構の存在になりつつある自分がいました。 そんな自分に嫌気がさし、夜中にふと目が覚めると、「コンテナ 初心者」「IaC やり方」と検索窓に打ち込んでは、溜め息をつく日々。 ただ、物理の世界で生きてきたおじさんにはこのコンテナというものが、 どうにも宙に浮いた、つかみどころのない幻のように感じられたのでした。 重い腰を上げ下げしてようやくKubernetesへ 「石の上にも三年」といいますが、重い腰を上げるのに5年かけてようやくKubernetesを勉強する気になりました。 このきっかけといえば、実は異動になって業務で使うことになったことも大きいですが、何よりも、 自分よりも年上のベテランエンジニアがKubernetesを使っていたことが、大きな精神的な転換点 でした。 若い世代に負けることよりも、自分よりも人生の先輩たちが軽々と新しい技術を使いこなしていることに驚きを覚えたのです。 それは、自分自身が長年の経験に胡坐をかき、新しい時代の変化を傍観していたことへの強烈な否定でした。 いつのまにか、自分の得意なインフラは、主流の座を新しい技術に明け渡し大きく様変わりしていました。 若いエンジニアたちの軽快なフットワークについていけない自分を、心の中では「仕方ない」と割り切ろうとしていたのです。 しかしその先輩の姿は、そんな言い訳を打ち砕きました。 積み重ねた経験からくる自信と、新しい知への探究心がそこには見えました。 その時、私はこのままではいけないなと強く感じたのでした。 重い腰は上がりました。そして、Kubernetesという、今まで手をつけてこなかった新しい世界の扉を叩くことにしました。 別に40代からでも遅くはないのです。今からでも大丈夫。 同じような不安や焦りを抱えている方々にとって、少しでも勇気を与えられる存在になれたら幸いです。 金はかけるがコスト感をもつ 細かい技術の話をしてもあれなので私が今も続けられている勉強方法について記載します。 まずは、多少お金をかけることです。 これはジムと同じ理屈で、無料のサービスだけではどうしても甘えが出てしまいます。 多少でもお金を払うことで、「せっかくお金を払ったんだから、元を取るぞ」という気持ちが生まれるからです。 あと、重い本を何冊も買うよりもマシに思えたからです。 ただし、コスト感は徹底的に意識しています。 無駄な出費は避け、できる限り節約するのが自分のルールです。 そんな中で選んだのが、AWSのマネージドサービスである EKS(Amazon Elastic Kubernetes Service) でした。 グローバルクラウドのサービスに触れられるので、まさに一石二鳥。 EKSの裏側にある難しいコントロールプレーンのことは一旦忘れて、まずはとにかく Deploymentを動かしてみる。 そこに重きを置いて、手を動かして遊んでみることにしました。 ※ちなみに、油断するとすぐに1万円に到達してしまうので、かなりの注意が必要です。 常にコストをモニタリングし、不要なリソースはすぐに削除する癖をつけなければなりません。 手始めにやったのは、「Hello, World」のコンテナを動かすことです。 まずは、シンプルなアプリケーションを動かすための Podと、そのPodを管理する Deploymentを作ってみました。 YAMLファイルにたった数行のコードを書くだけで、いとも簡単に立ち上がる。 その瞬間の感動は今でも忘れられません「おお、動いたわ~・・」。 次に、そのコンテナに外部からアクセスできるように Ingress、Serviceを設定しました。 この一連の流れを体験したことで、これまで漠然と「宙に浮いた話」に感じていたコンテナの世界が、 少しずつ現実のものとして手触り感を持つようになりました。 (参考)AWSのマニュアルにあるゲーム(2048)をデプロイしてみる HelloWorldが動かせたら、次は実際にAWSが公開しているサンプルアプリをデプロイしてみると面白いです。 docs.aws.amazon.com アプリのDeploymentはたったこれだけです。ほかにServiceとIngressはありますが、その十数行でkubernetesで実際にゲームが動きよりリアルなイメージとなってきます。たったそれだけで。 ※読むだけではコードの羅列ですが動かすと世界が変わります apiVersion: apps/v1 kind: Deployment metadata: namespace: game-2048 name: deployment-2048 spec: selector: matchLabels: app.kubernetes.io/name: app-2048 replicas: 5 template: metadata: labels: app.kubernetes.io/name: app-2048 spec: containers: - image: public.ecr.aws/l6m2t8p7/docker-2048:latest imagePullPolicy: Always name: app-2048 ports: - containerPort: 80 resources: requests: cpu: "0.5" このYAMLをapplyすればOKです。 kubectl apply -f 02-deployment.yaml あとはブラウザから確認すればゲームが動きます! 難しく考えず、実は根本はあまりかわらないよ 物理インフラで培った経験は、決して無駄ではありません 。 なぜなら、目に見える物理的な機器から、コードという抽象的な概念に変わっただけで、 サービスを安定稼働させるという本質は何も変わらない からです。 むしろ「ベテラン」は昔ながらの苦労を乗り越えてきたからこそ、新しい技術の効率性や便利さにより深く感動できる。 そう気づいた時、「 時代遅れになってしまうのではないか 」という焦りではなく、新しい知識を手に入れた喜びで満たされていました。 おわりに ということで終始ポエムな記事で物足りなかったかもしれませんが、たまにはこういう記事もありなのかなと。。 現在はGitHubにソースを上げるとGitHub ActionsでECRにイメージが自動で作成されるようになっており、 次はこれ以降のCICDでも作ろうかなと思っています。 わからないことは今やAIにガンガン聞けますし そして何より、 わからないことを恥ずかしがらずに行動することこそが、これからのエンジニアに必要な姿勢 なのだと、あらためて感じています。 もしこの記事が、 少しでも「やってみようかな」と思っている方の背中を押せたなら 、うれしい限りです。
アバター
こんにちは!!ラクス技術広報担当です。 2025年8月7日(木)に、オンラインにて「RAKUS Tech Conference 2025」を開催いたしました。平日にもかかわらず、多くの皆様にご参加いただき、大盛況のうちに幕を閉じることができました。登壇者、関係者の皆様、そして何よりご視聴いただいた皆様に、心より感謝申し上げます。 本イベントの開催目的は、私たちラクス開発本部が最も大切にしている 「顧客志向」 という概念を多くの方に知ってもらうことでした。参加後アンケートの結果から、9割の視聴者の方に「ラクスが顧客志向な開発組織であるという印象が伝わった」という回答をいただき、イベントの目的が果たせたことは大変良かったと思います。 各セッションでは、ラクスのサービスが日々どのように顧客と向き合い、その価値を技術で実現しているのか、7つのセッションを通じて開発の裏側にある「強み」や「想い」をお届けしました。 また、クロージングトークではラクス開発本部のAIの取り組みについてご紹介しました。 本記事では、各セッションで語られた内容をダイジェストでご紹介します。 各セッションの紹介 1. 『楽楽電子保存』開発チームが挑む「AI駆動開発」の全貌 2. 数字と感情で語るスクラム導入効果。『楽楽勤怠』開発チームの変革の軌跡 3. 分割と統合で学んだサイロ突破術—『楽楽販売』開発組織10年の軌跡と持続的成長の仕組み 4. 『メールディーラー』へのAI機能実装─”20年”の歴史を持つ製品への導入プロセス 5. 新サービス『楽楽請求』!何を作るかより“なぜ作るか” 顧客価値から逆算する開発現場のリアル 6. なぜ、成熟市場で”売上120%成長”を続けられるのか?『配配メール』の顧客志向型プロダクト開発戦略 7. 『楽楽精算』15年の進化と未来への挑戦 〜経理の”楽”から、すべての働く人の”楽”へ〜 クロージングトーク:AI開発の最前線と未来 おわりに 各セッションの紹介 1. 『楽楽電子保存』開発チームが挑む「AI駆動開発」の全貌 登壇者:楽楽明細開発部 開発2課 小栗 朗、フロントエンド開発課 伊藤 彪我 電子帳簿保存法の改正により市場が3年で3.5倍に拡大する中、『楽楽電子保存』開発チームは、激化する競争を勝ち抜くために「AI駆動開発」による開発プロセス全体の刷新に挑んでいます。 セッションでは、まず設計フェーズにおいて、PMM・PdM・開発者間で分散していたドキュメントをGoogle Docsに一元化し、AIが読み取りやすいよう構造化。AIに設計ドラフトの作成やレビューをさせることで、設計期間を平均30%以上短縮することに成功しました。実装フェーズでは、DevinやGitHub Copilotといった複数のAIツールをタスクに応じて戦略的に使い分け、平均30%の工数削減を実現。さらに、ラクスベトナムとのグローバル開発体制においても、AIによる翻訳やレビュー支援がコミュニケーションコストの削減や業務のボトルネック解消に繋がり、開発力を大きく向上させている事例が紹介されました。 speakerdeck.com 2. 数字と感情で語るスクラム導入効果。『楽楽勤怠』開発チームの変革の軌跡 登壇者:楽楽勤怠開発部 開発1課 加藤 祐也 働き方改革を追い風に市場が成長する一方、圧倒的なマーケットリーダーが不在で競合がひしめく勤怠管理システム市場。後発サービスである『楽楽勤怠』がシェアを拡大するためには、開発スピードとボリュームの向上が必須でした。 そこで白羽の矢が立ったのが、ラクスではまだ主流ではなかった「アジャイル(スクラム)開発」の導入です。本セッションでは、スクラム導入後の具体的な成果が「数字」と「感情」の両面から語られました。数字の面では、リリース案件数が導入後に大幅に増加し、受注件数も過去最高を記録。感情の面では、エンジニアの満足度は10段階中平均8ptと高く、「コミュニケーション頻度が上がった」「チームで助け合いが出来る」といったポジティブな声が多く挙がりました。プロセスの導入だけでなく、失敗を恐れず変化を楽しむマインドの醸成が成功の鍵であることが示されました。 speakerdeck.com 3. 分割と統合で学んだサイロ突破術—『楽楽販売』開発組織10年の軌跡と持続的成長の仕組み 登壇者:楽楽販売開発部 部長 藤井 高志、同 テックリード 山内 覚 年間売上高55億円を超え、SaaS型販売管理システムでシェアNo.1を達成した『楽楽販売』。そのプロダクトの成長を支えてきたのは、10年間にわたる開発組織の変革の歴史でした。 セッションでは、7名体制だった10年前から24名体制の現在に至るまで、組織がどのように変化してきたかが語られました。当初は全員が全ての領域をカバーしていましたが、組織の拡大に伴い、企画、要件、実装といった職能別のチームに分割。しかし、これがチーム間の連携を妨げる「サイロ化」という新たな課題を生み出しました。この課題を乗り越えるため、再び要件から実装、技術負債改善までを一気通貫で担うチームへと統合。日々の接点が多い作業は同一チームで推進すべきであるという学びや、改善の取り組みをチームで推進し、暗黙知を共有する重要性が共有されました。 speakerdeck.com 4. 『メールディーラー』へのAI機能実装─”20年”の歴史を持つ製品への導入プロセス 登壇者:メールディーラーAI開発課 神山 賢太郎、メールディーラー開発課 廣部 知生 2001年に販売開始され、16年連続シェアNo.1を誇る『メールディーラー』。この歴史あるレガシーシステムに、いかにしてAIという新しい技術を迅速に実装したのか、そのプロセスが語られました。 「世はまさにAI戦国時代」 という市場の変化に対し、ビジネスサイドからは「うかうかしているとディスラプトされる」という強い危機感が示される一方、開発サイドではビジネス価値への懐疑的な見方もあり、当初はスピード感にずれがありました。しかし、展示会でAIエージェントへの注目度の高さを目の当たりにし、危機感を共有。ウォーターフォール型開発が主流だった組織の中で、AI開発に特化した課を新設し、完全アジャイル開発にシフト。PMM、PdM、デザイナーが密に連携し、顧客ヒアリングを週1ペースで行いながら高速でPDCAを回すことで、開発スケジュールを大幅に短縮し、価値提供を早めた事例が紹介されました。 speakerdeck.com 5. 新サービス『楽楽請求』!何を作るかより“なぜ作るか” 顧客価値から逆算する開発現場のリアル 登壇者:楽楽請求開発部 開発1課 巽 隆氏、庄禮 有佑 2024年10月にサービスを開始した新サービス『楽楽請求』。ゼロからイチを創り出す過程で直面した、数々の成功と失敗がリアルに語られました。 リリース当初は、ドメイン知識ゼロの状態から書籍や競合サービスの機能分析を基に仮説を立てて開発を進めました(仮説ドリブン)。しかし、リリース後、実業務にそぐわない仕様や、顧客が本当に求めていた機能とのズレが明らかになりました。この経験から、開発プロセスを全面的に見直し、営業やサポートが収集した顧客の声(VoC)を起点とする「VoCドリブン」へと大きく舵を切りました。現在は、2000件を超える要望DBを基に、「何を作るか」よりも「なぜそれが必要なのか」という顧客課題の深掘りを徹底し、顧客が本当に求める価値を提供できる開発体制を築いています。 speakerdeck.com 6. なぜ、成熟市場で”売上120%成長”を続けられるのか?『配配メール』の顧客志向型プロダクト開発戦略 登壇者:ラクスクラウド開発部 配配メール開発課 西尾 敬太 サービス開始から18年目を迎え、国内市場が成熟期にある中で、年間売上成長率120%超を達成し続ける『配配メール』。その力強い成長の源泉は、徹底した「顧客志向型プロダクト開発戦略」にありました。 配配メールは、単なるメール配信ツールから、リード獲得・育成・商談化というマーケティングプロセス全体をカバーするプラットフォームへと進化を遂げてきました。この戦略を支えるのが、「迅速かつ柔軟に価値を届ける」リリース戦略と、「開発者全員が深く顧客を理解する」ための取り組みです。新機能は価値の単位で分割して段階的にリリースし、顧客からのフィードバックを迅速に反映。開発チーム自らが製品を日常的に利用するドッグフーディングや、PMM主催の勉強会を通じて、全部門一体で顧客理解を深める文化を醸成しています。 speakerdeck.com 7. 『楽楽精算』15年の進化と未来への挑戦 〜経理の”楽”から、すべての働く人の”楽”へ〜 登壇者:楽楽精算開発部 開発2課 課長 高波 顕二郎 15年以上の歴史を持ち、導入社数1.9万社を超えるまでに成長した『楽楽精算』。その成長は、電子帳簿保存法やインボイス制度といった法制度ニーズへの迅速な対応によって加速してきました。しかし、その長い歴史は150万行を超えるコードベースや700以上の画面といった技術的負債も生み出し、開発スピードの低下という課題に繋がっていました。 本セッションでは、これまで注力してきた「経理担当者の楽」の実現に加え、今後は経費精算に不慣れな「申請者の楽」も実現すべくUI/UXの根本的な改善に着手していることが語られました。さらに、AIエージェントが自律的に経費精算を行う未来を見据え、レガシーな開発から脱却するための技術戦略として、モダンな新基盤の構築とAI駆動開発を両輪で進める挑戦が紹介されました。 speakerdeck.com クロージングトーク:AI開発の最前線と未来 登壇者: 大阪開発統括部 統括部長 矢成 行雄、東京開発統括部 プロダクト部 副部長 稲垣 剛之、AIエージェント開発課 課長 石田 浩章 イベントの最後には、AI開発を牽引する3名によるクロージングトークが行われました。 ここでは、各プロダクトへのAI機能の実装や、開発本部全体でのAIツール活用など、セッション本編では語りきれなかったテーマについて深掘りしました。 AI開発の組織体制について、ラクスでは単一の部門が集約的に開発するのではなく、各事業部の事情に合わせて多様なスタイルで取り組んでいることが語られました。 例えば、プロダクトマネージャーとデザイナーが所属するプロダクト部では、複数製品を横断する形でAIのロードマップ策定に関与しています。 一方で、新設されたAIエージェント開発課では、事業部直下に開発・営業・CSが一体となったコンパクトなチームを組成し、意思決定のスピードを重視した開発を進めています。 AIの進化に伴いエンジニアに求められるスキルについて、「審美眼」「適応力」「言語化能力」の3つが挙げられました。 AIが生成したアウトプットが本当に正しいかを見抜く力、変化の早い技術や常識を常にアップデートしていく力、そしてAIが理解できる形でコンテキストを的確に伝える力が、今後ますます重要になるとの展望が語られました。 おわりに 改めて、「RAKUS Tech Conference 2025」にご参加いただいた皆様、そしてご協力いただいた関係者の皆様、本当にありがとうございました。 今回のカンファレンスを通じて、ラクスの各プロダクト開発チームが、それぞれの事業フェーズや市場環境の中で、いかに「顧客志向」を貫き、それを実現するために組織や開発プロセスを柔軟に変化させ、新しい技術に挑戦し続けているか、その一端を感じていただけたなら幸いです。 今後もラクスは、「顧客志向のSaaS開発組織」として、お客様の期待を超える価値を提供できるよう、真摯にプロダクト開発と向き合ってまいります。引き続き、ラクス開発本部の活動にご注目ください!
アバター
はじめに こんにちは。新卒3年目のymyhero7です。 メールディーラーという自社開発プロダクトの開発チームに所属しています。 入社してすぐの頃は、実装やテストの工程を担当していましたが、新卒2年目から徐々に要件定義を任されるようになりました。もともと就職活動の面接段階から、「どうすればお客様にとって本当に価値のある機能を作れるか」といった上流工程への関心が強く、そうした業務に携わることを希望していました。 そのため、2年目という比較的早い段階から要件定義に関われるようになったときは、非常に嬉しかったのを覚えています! しかし、意気揚々と始めた要件定義の業務は、想像以上に難しく、苦労の連続でした。作成した要件定義書はレビューで指摘を受けることが多く、大幅な手戻りが発生してしまうことがしばしばありました。 本記事では、そうした経験を通じて学んだ要件定義の進め方のコツや「顧客理解」の重要性をご紹介します。 はじめに 苦戦した要件定義と、繰り返される手戻り チームで取り組んだ改善 顧客ヒアリングを通じて得られた気づき 実践している3つの工夫 おわりに 苦戦した要件定義と、繰り返される手戻り 私の所属する開発チームでは、製品企画チームが作成した要求定義書をもとに、「要望をどのような機能に落とし込むか」を要件定義で検討します。 要件定義を担当し始めた当初、私は「要求定義書に書いてあることをそのまま機能として具体化していけば問題ないだろう」と安易に考えていました。 しかし、実際に書いた要件定義書は何度もレビューで差し戻されました。 特に多かったのは、 「そもそもその機能、本当に必要?」 「他にもっと良いアプローチがあるのでは?」 といった、本質を問う指摘です。 「確かにその通りだ」と納得する一方で、「なぜ最初から気づけなかったのか」と悔しさが込み上げました。さらに、手戻りによって開発が2週間以上遅れることもあり、チームに迷惑をかけてしまったことへの申し訳なさも強く感じました。 振り返ると、その原因のひとつは、要求を表面的にしか理解できておらず、ユーザの本当の困りごとやユースケースを自分の言葉で説明できない状態だったことにあります。 “何を作るか”ばかりに意識が向き、“なぜ作るのか”という視点が欠けていたのです。 この状態では、いくら丁寧に要件定義書を作成しても、ユーザの課題を解決できる良い機能を作ることはできません。 結果として手戻りが発生し、開発の遅延を招き、ユーザへの価値提供も遅れてしまいます。 チームで取り組んだ改善 そんな中で支えになったのが、周囲のチームメンバーの存在です。 失敗に落ち込んでいた私に対し、先輩たちは「まずは製品企画チームに要求の背景を聞いてみよう」「最初にチーム内で機能の方向性をすり合わせるミーティングを開こう」など、具体的で実践的なアドバイスをくれました。 ある先輩エンジニアからは、「完璧にしてから出すのではなく、途中でもいいから一度レビューを依頼してみよう」と助言をもらい、「しっかり仕上げてからでないと見せてはいけない」と思い込んでいた自分の固定観念が変わりました。 また、チームの振り返りミーティングでは、「どうすれば手戻りを減らせるか」について皆で何度も話し合いました。その中で、要件定義に入る前にチーム内で要求を読み合わせ、疑問点を洗い出したり、要件の方針をすり合わせたりすることが、開発プロセスとして明文化されるようになりました。 顧客ヒアリングを通じて得られた気づき あるとき、特定の機能要望について製品企画チームに質問したところ、「それなら実際にお客様に聞いてみよう」と、要望を挙げてくださったユーザに直接ヒアリングする場を設けてくれました。 普段はユーザと直接やりとりする機会がなかった私にとって、ユーザの声を生で聞くことができるのは初めての経験でした。 直接お話を伺う中で、「ああ、これが本当に困っていることなんだ」と心から腑に落ちました。また、製品に対する強い期待や信頼を寄せていただいていることも実感し、より一層の責任感が芽生えました。 それまで私は、製品企画チームは別部署ということもあり、「どこまで相談して良いのか」と遠慮してしまうことがありました。ですが、こうして顧客ヒアリングに同席させてもらえたことで、「分からないことは積極的に相談して、一緒に解決に向かって進めていけばいいんだ」と認識が大きく変わりました。 実践している3つの工夫 こうした経験を通じて、私は以下の3つのポイントを意識しながら要件定義を進めています。 製品企画チームに質問して、ユーザの解像度を上げる 「なぜこの要望があるのか?」「実際にどんな場面で困っているのか?」といった背景を把握するため、製品企画チームに積極的に質問するようにしています。要求を深掘りし、ユーザの抱えている課題を自分の言葉で語れるようになることを目指しています。 まず方針をすり合わせる 要件定義書を書き始める前に、「こういう背景があって、こういう方針で考えています」とチーム内で方向性を相談しています。すぐに要件定義書を書き始めるのではなくて方針が定まってから手を動かすようにしています。また、要件定義書を書き始めてからも、課題があればその都度相談し、徹底的に認識合わせをするように意識しています。 6割の完成度でレビュー依頼を出す 要件定義書は、完璧を目指すよりも6〜7割程度の段階で一度レビュー依頼を出すようにしています。そのほうが早期に改善点を洗い出すことができ、結果として手戻りを減らすことができます。 おわりに 弊社の開発チームでは、「顧客志向」を非常に大切にしています。ユーザへの理解を深め、どのような機能であれば真に価値を届けられるのかを考えることは、その顧客志向の姿勢そのものだと感じています。 また、ユーザへの理解が深まることで、結果的に要件定義工程での手戻りも減り、早く価値を届けられるという好循環が生まれると考えています。 もちろん、要件定義は今でも難しいと感じることがたくさんあり、すべてが順調に進むことはありません。それでも、一つひとつのユーザの課題に真剣に向き合っていくことが、より良いプロダクトづくりにつながると信じています。 最後までお読みいただき、ありがとうございました。
アバター
はじめに こんにちは。フロントエンド開発課でチームリーダーをしています、北嶋です。 私が所属する開発部では、開発の 「スピードUP」と「生産性の向上」 を今年度の大きなテーマとして掲げています。 そこに向けて、私のチームでは開発プロセスの中でAI活用を実践していく 「AI駆動開発」 を推進することに、積極的に取り組んでいます。 本記事では、今年度から本格的にAI活用に取り組み始めた私たちが、どのようにAI活用を進めて、どのような成果や学びを得たのか、具体的な事例を交えながらご紹介できればと思います。 まだまだ発展途上ではありますが、私たちが実践してきた取り組みが、開発業務でAI活用をしていきたい方への、何かヒントになれば幸いです。 はじめに どのようにAI駆動開発を進めてきたか ステップ1:KPIの設定 ステップ2:個人での利用とアイデアの共有 ステップ3:チームでの標準化 例①:DevinのAPIを活用したプルリクエストの自動レビュー 例②:Github Projectsによるプロジェクト管理の効率化 背景 AI連携方法 AI連携を試してみた結果 得られた学び おわりに どのようにAI駆動開発を進めてきたか AI駆動開発と聞くと、何か特別なノウハウや技術が必要だと思われるかもしれませんが、私たちのチームでは比較的シンプルに、以下のステップで取り組んできました。 ステップ1:KPIの設定 はじめに、通期でチームとしてどのような状態を目指すかの、KPIの設定を行いました。 最低限でもAI活用方法がチーム内で共有されている状態、更には開発フローに組み込まれている状態をイメージし、以下のようにKPIを設定しました。 チームとして共通のKPIを設定したことで、AI活用の方針にブレが生じにくくなり、取り組むべきアクションも明確になったため、AI活用するに当たってこのようなKPI設定は非常に重要なステップであると感じました。 ①AIツールによる開発効率化で以下の時間短縮を実現していること ・詳細設計:30%以上短縮 ・実装:30%以上短縮 ・単体テスト:40%以上短縮 ②マージされたプルリクエストの50%がAIエージェントが開発したものになっていること ③AI活用のノウハウを標準化して以下の開発フローにプロセス組み込みできていること ・詳細設計:API仕様書作成、画面仕様書作成 ・実装:コードレビュー ・単体テスト:Unitテスト, Integrationテストのテストコード作成 ・結合テスト:E2Eのテストコード作成 ステップ2:個人での利用とアイデアの共有 次に、開発業務でチームメンバーが個々で様々なAIツールを実際に試すことから始めました。 利用した生成AIやAIツールは、ChatGPT, Gemini, Github Copilot, Codex, Devin, 最近だとClaude Codeなど。 その中で 「こんなことができた」「このツールは〇〇が得意そうだ」「こういうことができたら嬉しい」 といった実例や意見、アイディアが次々に出てきたので、それらをカジュアルに共有する場(チャットツール上にチャンネル作成や、対面でのミーティング)を設けて、積極的に情報交換を行うようにしました。 変化の早いAIの流れについていくために大切なのは、いきなり完璧な活用法を求めるのではなく、 「まずは使ってみる」「それを共有してみる」 という文化を醸成することなのかな思いました。 ちなみに私のチームでは、情報共有する際には以下の共通フォーマットで記載してもらうようにしています。 フォーマットを作っておくことで、人によって情報をブレなく共有できるので、これも効果的な取り組みの一つだと実感しています。 ■試してみたこと ①概要 ②利用したAIエージェント(モデル)は何か ③入力(資料やルール等)は何か ④プロンプトは何か ■結果 ①出力結果はどうか ②実用的か ■工夫した点 ■標準化検討 ■参考記事(あれば) ステップ3:チームでの標準化 個人の試行錯誤から有益なアイデアが生まれてくると、次にそれをチームとして 「標準化」 して運用に載せたいよね、という話が出てきました。 現時点で、実際に運用されている事例はいくつかあるのですが、ここでは2つを取り上げて紹介したいと思います。 例①:DevinのAPIを活用したプルリクエストの自動レビュー 私たちのチームで最初に大きな成功を収めたのが、DevinのAPIを活用したプルリクエストの自動レビューです。 GithubのPR上にUserScriptで 「PRレビューを依頼する」 のボタンを配置し、このボタンを押下するだけで、Devin APIを発火させてコードレビューを依頼できるというものです。 (ボタンを画面上に設置してしまう辺りがフロントエンドチームらしいなと思ったりしました笑) 実際にDevinがレビューコメントを付けてくれた一例が、以下の画像です。 プロンプトを工夫することで、インラインでコメントしてくれたり、imo,mustなどの接頭語も適宜付与してくれたり、修正の提案(suggestion)をしてくれたりと、非常に分かりやすく指摘してくれていることが分かるかと思います。 運用としては、実装者が人にコードレビューを依頼する前に、Devinへのコードレビューを一度挟むことで、実際に人がレビューする工数は大幅に削減できたと感じています。 こちらが上手くいった背景には、 もともと「レビュー観点」や「コメントルール」がある程度明文化されていた ことが大きく影響していると、個人的には考えています。 AIは自然言語化された明確なルールや指示があれば、その能力を最大限に発揮してくれるのだなと実感する、良いきっかけになりました。 また、 開発フローの1つの作業を標準化がすることができた という成功体験が生まれたことで、チームとしてAI駆動開発に取り組もうとする姿勢がより一層高まったように思います。 AI活用によって「こんなに便利になるんだ」という体験を実際にすることが、メンバーのAI活用への積極性を駆り立てる原動力になるのだな、身を持って実感しました。 例②:Github Projectsによるプロジェクト管理の効率化 こちらは私が主導して検証を行い、最近運用に乗せたばかりの、GitHub ProjectsとAIを連携させたプロジェクト管理の効率化についての紹介です。 背景 これまでは、Googleのスプレッドシートでプロジェクト管理を実施していましたが、タスク分割や工数計算などで、多くの手作業が発生していました。 セルの計算式が気付かない内に壊れていることも多く「これをAI活用で楽にできないかな」と考えたのが、この取り組みのきっかけです。 Github Projectsでプロジェクト管理を行う方法は様々あると思いますが、まず作りたい機能の詳細を書いておく親のissueの作成を行い、それを実際に必要な作業ごとに子のsub-issueへと分割し、sub-issueを元に実際の作業を進めるというイメージで考えました。 機能issueの作成 タスクsub-issueへの分割 工数の見積もり入力 実装から単体テストの実施 これらの作業をAIにある程度任せられないかと考え、検証を行っていました。 AI連携方法 この頃には、チームではClaude Codeの活用が進められており、 「標準化できそうな作業が見つかれば、カスタムスラッシュコマンドを作成して共有する」 という流れがありました。 ここでも作業をほとんど、カスタムスラッシュコマンド化しています。コマンドの中身の詳細については、社内の情報もあるため載せられないのですが、以下のような流れで実作業を行なっています。 1. 機能issueの作成 以下のコマンドを実施すると、GitHubプロジェクトに新しい機能issueを作成されます。必要なカスタムフィールドについてもAIが自動で設定を行います。 ※ただし、機能の内容については、今は人の手でissueに詳細に記入を行なっています(ここもいずれAI活用をしたい部分です) /create-main-empty-issue <機能名> 2. タスクsub-issueへの分割 以下のコマンドで、作成した機能issueを元に、調査・実装・テストコード作成といった、具体的な作業タスクをsub-issueとしてAIが自動で切り出します。 この時に、AIが判断した「タスク種別」や「重み」を、カスタムフィールドを自動で設定します。 /create-sub-issues <機能IssueのURL> コマンドを実行すると、機能issueの下にタスクsub-issueが分割されて登録され、以下のような状態となります。 3. 工数見積もり 各sub-issueの「タスク種別」や「重み」を元に、あらかじめ定義したルールに従って作業工数・レビュー工数・総工数を算出し、カスタムフィールドに自動で設定します。 /estimate <機能issueのURL> コマンドを実行すると、以下のように見積もり工数に数字が入力されます。これを利用して、今は人がガントチャートの作成を行なっています。 4. 実装〜単体テスト 最後にissueのURLをAIに渡して、実装と単体テストを実施させるという流れになっています。 (ここのやり方は個々に任せている段階なのですが、今後標準化に向けて動いていきたい部分です) AI連携を試してみた結果 結論から言うと、Github ProjectsとのAI連携は、非常に実用的でした。 手作業でissueを作成したり、ラベルを付けたり、工数を見積り入力する手間は確実に削減できました。 ただし、改善点はまだまだ山積みという状態です。 人の目の介入は不可欠 特に実装フェーズでは、AIが途中で意図しない方向に進んでしまうことがあります。 現状では、大きなタスクを丸投げするのではなく、sub-issue単位で一つずつ実行を依頼し、都度人間が確認する必要がある状態です。 インプット(ルール)の質がアウトプットの質を決める タスク分割や見積もりの精度は、まだまだ粗削りなものでした。これは、私たちがAIに渡しているルールや定義がまだ曖昧だからという要因が正直大きいです。 逆に言えば、ルールが明確に自然言語化・整備されているチームほど、AI活用の恩恵をスムーズに受けられるのだろうなと感じています。 検証が終わって実運用を始めたばかりの段階なので、改善点は多くありますが、プロジェクト管理をAIと連携しやすいGitHub Projectsに移行し、運用するための土台は作れた状態となりました。 得られた学び これらの取り組みを通じて、技術的な知見以上に、チームや文化に関する大きな学びがありました。 AI活用の士気を高めるのは「実用的な成功例」 机上の空論ではなく、「これ、便利だよね」と誰もが実感できる実用的な成功例が一つ生まれると、チーム全体のAI活用に対する士気が一気に高まります。 私のチームでは、PRの自動レビューは、まさにその大きなきっかけとなりました。 AI活用は「ルールを明文化する」絶好の機会 AIにタスクを任せるためには、これまで「暗黙の了解」で済ませていた作業手順や判断基準を、誰もが理解できる自然言語で明文化する必要があります。 このプロセスは、チームの属人性を排除し、開発プロセスそのものを洗練させる良い機会になっていると感じます。 AIはあくまで作業者、判断は人がするべき AIに全てを任せようとするのは時期尚早です。AIが出したアウトプットを鵜呑みにせず、要所要所で人間がレビューし、方向性を修正することが極めて重要です。 AIを便利な「作業者」として活用する姿勢が、現時点では賢明かなと、個人的には考えています。 おわりに 私のチームでのAI駆動開発の推進は、正直まだまだ始まったばかりの段階です。 刺激的なアイデアを次々と試す若手メンバーを見ていると、「AIネイティブ世代」の台頭を肌で感じ、私自身も大いに刺激を受けています。 AIの分野は情報の変化が非常に早いので、 「まず使ってみる」という探究心と、「こんなことに使えるかも」というアイデアが勝負 の世界なのかもしれない、とも個人的には感じていました。 この記事が、皆さんのチームでAI活用を始めるための一歩を踏み出すきっかけになればと思います!
アバター
自己紹介 こんにちは、株式会社ラクスでプロダクトマネージャー(以下PdM)をしている 柴 と申します。 楽楽精算のPdMを経て、現在は楽楽精算モバイルアプリ・楽楽明細・楽楽債権管理・AIリーン開発と複数のプロダクトでPdMを担当しています。 (PdM積極採用中です!!) 今回はPdMという役割を経験して私が感じてきたことを記事にしてみます。 PdMを目指している方やPdMという役割にもやもやしている方の参考になると幸いです。 はじめに 「隣の芝が青く見える」——この言葉が、私のPdMキャリアの最初の数年間を象徴していました。 SNSで目にする「戦略を描くPdM像」、イベントで語られる「PMFを達成したPdMの話」、そして「経営に貢献するPdM」の事例。 それらと比較して、私は「自分のやっていることは、本当にプロダクトマネジメントと言えるのだろうか?」と疑問を持っていました。 そんな中でも派手ではないけれど確かに意味のある仕事を続けた結果、今は複数のプロダクトのPdMを担当させてもらっています。 この記事では、過去のモヤモヤや迷いも含めながら、「自信がない中でも前に進み続ける」ためのマインドや行動習慣をお伝えします。 比べることに疲れたジュニアPdMに、ちょっと肩の力を抜けるようなヒントを届けられたら嬉しいです。 1. ジュニアPdMが感じる"理想像"のプレッシャー SNSやイベントで語られる「理想的なPdM像」に圧倒される PdMとしてのキャリアを歩み始めた頃、私はSNSやイベントで語られる「理想的なPdM像」に圧倒されていました。 戦略を描くPdM、PMFを達成したPdM、経営に貢献するPdM——これらの情報を見るたびに、「自分は全然できていない」と感じていました。 外部から得られる情報と自分の日常業務を比較して、いつも「もっと大きなことをやらなければ」と焦っていました。 ただ今振り返るとこれらはすべて結果(成果)であり、そこまでの道のりは皆同じように日々の業務の積み重ねであるということに気づきました。 2. 実録:同じ会社でも、PdMの仕事はこんなに違う 楽楽精算・楽楽精算モバイルアプリ・楽楽明細・楽楽債権管理・AIリーン開発、それぞれでのPdM業務の違い ラクスに入社して、実際に複数のプロダクトを担当したり、他社のPdMと直接交流する中で気づいたことがあります。 それは同じ会社でも・会社によっても、プロダクトによっても、PdMの役割や期待が全く違うということです。 以下が私が各プロダクトの参画当時に求められているなと感じ、実行したことの概要です。 (市場環境やAI技術の発達などの外部環境や内部の組織変革によって常に変化していますのでその点はご留意ください。また現在も携わっているプロダクトもありますが統一感のためにあえて過去形で書いています。) 楽楽精算(経費精算システム) 成熟期を迎えた楽楽精算では、PdM/PMMともに他のプロダクトと比較して人数が多く、役割分担も明確な中で、新規参画したPdMには個別の案件(課題)への深い入り込みと主体的な推進が求められました。各案件は影響範囲や難易度が高く、課題の本質を見極め、進め方を組み立てる力が特に求められる環境でした。複雑な課題を整理し、仕様策定とエンジニア・ビジネスサイドの合意をリードする業務が中心で、この時期は「課題解決と合意形成に徹する日々」でした。 楽楽精算モバイルアプリ 成長期かつ今後重要な成長ドライバーになるべきモバイルアプリでは、課題はあるが、何を優先すべきか、どういった順番で進めるかの整理がされていない状態であり、モバイル開発チームとしてしっかり成果をあげる必要がありました。ビジョンから体制づくりまで支援し、安定した開発を実現することが求められ、この時期は「チーム安定化とビジョン実現に徹する日々」でした。 楽楽明細(請求書発行システム) 成熟期の楽楽明細では、エンジニアのキーマンに様々な業務の推進/意思決定が依存している状態でした。また、ジュニアPdMが先行して参画しており、成果物のレビューや業務のサポートが必要な状態でした。スケールに向けた属人化からの脱却と同時にチームの成果を守ることが求められ、この時期は「チームサポートと成果保護に徹する日々」でした。 楽楽債権管理(債権管理システム) 導入期の楽楽債権管理では、0→1フェーズであり、最速でのPMFを目指すために市場や顧客を深く/広く理解して、優先して解くべき課題を発見する能力が求められる環境でした。役割分担も明確に決まっておらず、自発的かつ積極的に行動することが求められ、この時期は「市場理解とPMF追求に徹する日々」でした。 AIリーン開発 AIリーン開発では、市場ニーズの検証とプロトタイプの作成が主な役割でした。AI技術の検証、プロトタイプの作成・テスト、事業貢献の可能性探索など、将来の事業拡大を見据えた技術検証業務が中心でした。この時期は「技術・ニーズ検証に徹する日々」でした。 上記のようにプロダクトの規模やフェーズによって、ビジネス側との関係性やPdMに特に求められる役割も大きく異なります。楽楽精算・楽楽明細のような大規模(ステークホルダー、売上)プロダクトでは、1人のPdMでは対応しきれません。PdM内でも長期的なビジョンとロードマップを策定や、個別機能の仕様策定・開発管理、ユーザー対応・要望収集を行うというテーマ単位での役割分担が必要になります。 3. 他人比較をやめる:隣の芝は青く見えるけど、それでよい プロダクトのフェーズ・体制・文化で"青さ"の基準は違う 「隣の芝が青く見える」という感覚は、プロダクトのフェーズやチーム体制、組織文化によって生まれています。導入期、成長期、成熟期で求められる役割が違いますし、チームの人数やスキルレベル、経験値でできることも違います。また、組織の意思決定の速さやリスク許容度、イノベーション重視度も影響します。 「今の自分が、目の前のお客様やチームに何を提供できるか」を軸にする 他人と比較するのではなく、お客様にとって今のプロダクトで何が改善できるか、チームにとって今の自分が何をサポートできるか、事業にとって今の状況で何が貢献できるかを考えるようにしました。 「求められていること」に目を向ける 各プロダクトで「求められていること」は異なります。完璧なジョブディスクリプションがある場合はそれに準ずることができますが、多くのプロダクトマネージャーは間に落ちるボールを拾う役割を担うケースが多いと思います。プロダクトの成功のために組織として何が求められているか?に常に目を向けるようにしました。 小さな信用を積み重ねて、信頼を得る 大きな成果を一度に出すのではなく、小さな信用を積み重ねることを意識しました。期限を守ることや品質を保つこと、進捗を共有して課題を早期発見すること、小さな問題も真摯に向き合うこと、分からないことは素直に聞くことなど、一つ一つの行動が信頼につながっていきます。 その信頼によって大きな仕事を任されるようになります。 4. それでも見失ってはいけない"PdMの本質" 各プロダクトでの役割が違っても、目指すべきはプロダクトの成功 具体的には、ユーザーの課題解決や使いやすさの向上といったユーザー価値と、売上向上やコスト削減、効率化といった事業価値の両立を目指すことです。 タスクに追われて目の前しか見えなくなる中でも、定期的に「この仕様が誰の課題を解決して、どう売上につながるのか?」を問い直す 日々の業務に追われていると、目の前のタスクしか見えなくなります。それを防ぐために、以下のような習慣を持ちました。 週次振り返り 今週やったことの意味を考えること、ユーザーにとっての価値を確認すること、事業への貢献を言語化することが重要です。 月次振り返り プロダクトの方向性が正しいか確認すること、優先度の見直しを行うこと、長期的な目標との整合性を確認することが必要です。 PdMの自信は「正しい問いを持ち続けること」からも生まれる 以下のような問いを常に持ち続けることが重要です。ユーザー視点では「この機能は誰の課題を解決するのか?」、事業視点では「この改善はどう売上につながるのか?」、技術視点では「この実装は適切な技術選択なのか?」、チーム視点では「この進め方はチームにとって最適なのか?」といった問いを繰り返し考えることで、PdMとしての自信が育まれていきます。 5. どう育てるか:PdMとしての自信をつくる3つの行動 「誰の役に立てたか」に目を向ける 身近な「ありがとう」を信じることが重要です。 営業からの感謝 「この機能のおかげで商談が進んだ」や「顧客の要望に迅速に対応してくれて助かった」といった声 CSからの感謝 「ユーザーの問い合わせが減った」や「問題の原因を特定してくれて助かった」といった声 開発からの感謝 「仕様が明確で開発しやすかった」や「優先度が明確で計画が立てやすかった」といった声 顧客からの感謝 「使いやすくなった」や「業務効率が向上した」といった声 「プロダクトを前に進めた感覚」を言語化する 小さな進歩でも、それを言語化することで自信につながります。 仕様が決まった 「曖昧だった要件が明確になった」や「関係者の認識が揃った」といった感覚を言語化することで、小さな進歩でも自信につながります。 優先度が決まった 「開発リソースの配分が最適化された」や「ユーザーにとって重要な機能が優先された」といった感覚を言語化することで、プロダクトを前に進めた実感を得られます。 リリースが完了した 「計画通りにリリースできた」や「ユーザーからの反応が良かった」といった感覚を言語化することで、成果を実感できます。 「学んだことを振り返る」習慣を持つ 定期的な振り返りが成長につながります。 週次振り返り 今週学んだことや改善できたこと、次週への課題を整理することで、小さな成長を実感できます。 月次振り返り 今月の成果や学んだスキル、次月の目標を整理することで、より大きな成長を実感できます。 1on1での報告 成長した点や課題となっている点、サポートが必要な点を整理して報告することで、上司との対話がより充実したものになります。 ラクスのPdM組織では各プロダクトのPdMが集まって行う週次・月次の定例会が実施されるともに、上長やビジネスサイドのキーマンとも1on1を実施しており、 上記のような振り返るや課題のすり合わせを行う場が設けられています。 6. おわりに:歩き続けることで育つキャリア 正直に言うと、他人と比較して落ち込むことは、今でもあります。でも、それは自然なことだと受け入れられるようになりました。 プロダクトマネジメントは、常に変化し続ける分野です。完璧な状態は存在せず、常に改善の余地があります。だからこそ、今の一歩に集中することが重要です。 小さな行動でも、誰かのために動いたその行動は、確かに価値を生んでいます。それを信じて、一歩ずつ前に進み続けることが、PdMとしての成長につながります。 今、自分なりに育ててきた芝が、少し青く見えるようになってきた——それが、伝えたかったことです PdMキャリアを通じて、私は自分の足元に目を向けることができるようになりました。 他人と比較するのではなく、自分の現場と向き合い、目の前の課題に真摯に向き合うことの大切さを学びました。 今、自分なりに育ててきた芝が、少し青く見えるようになってきました。 それは、完璧な状態になったからではなく、自分の価値観と向き合い、一歩ずつ前に進み続けた結果です。 まとめ:同じモヤモヤを抱えているPdMへのメッセージ 他人と比較しない プロダクトによって役割が違いますし、フェーズによって求められることも違います。自分の現場に集中することが重要です。 小さな価値を積み重ねる 約束を守ること、コミュニケーションを大切にすること、問題解決に真摯に向き合うことが、小さな価値を積み重ねることにつながります。 定期的に振り返る 週次・月次での振り返りや学んだことの言語化、成長の実感を定期的に行うことで、継続的な成長が可能になります。 正しい問いを持ち続ける ユーザーにとっての価値や事業への貢献、技術的な適切性について、常に正しい問いを持ち続けることが重要です。 隣の芝が青く見える世界で、自分の足元に目を向けられるようになるまで。 それは、他人と比較するのではなく、自分の価値観と向き合い、一歩ずつ前に進み続けることです。 あなたの芝も、きっと少しずつ青くなっていきます。焦らず、一歩ずつ、歩き続けていきましょう。 [Appendix]PdM・デザイナー積極採用中! ラクスでは様々なフェーズのプロダクトに携わることができます。 興味を持った方は是非カジュアル面談からお申込みください。 カジュアル面談のお申込みはこちら
アバター
こんにちは、フロントエンド推進課の水野です。 普段はWebフロントエンド領域を中心に、商材開発や技術支援、開発改善に携わっています。 自動化・標準化、開発プロセスの変遷に関心があり、作るものだけではなくその過程や運用設計を意識して取り組んでいます。 note.com 最近、自分の中でコードレビューのやり方が変わったなと感じています。 GitHub CopilotやClaude Codeのようなツールが当たり前になり、構文エラーやコーディング規約のチェック、命名規則の統一のような作業はほぼ自動化できてしまいます。 成果物の出てくるスピードと規模感も桁違いで、レビューだけで1日が溶ける日もたまにあります。 その中で、改めて「自分は何をレビューすればいいんだろう」「コード以外に見るべきものはなんだろう」と考えることが増えました。 個人的にコードレビューや開発現場に関する話が好きで、ブームが再燃しているからというのもあります。 www.shoeisha.co.jp www.shuwasystem.co.jp 添削作業の消失 答えを出すことによる機会損失 「なんで?」を大事にしている 設計の話 運用の話 開発チームの変化 知見の民主化 非同期で作る 今後 おわり 添削作業の消失 コードレビューにおいて、おそらく以下のようなコメントを見かけたことがあるでしょう。(私は今でも見ます) 「このif文はearly returnした方がよくないですか?」 「命名がcamelCaseではなくsnake_caseになっています!」 「変数名が抽象的すぎるのでもうちょっと分かりやすくしてください」 「外から参照する型定義は *.interface.ts に定義しましょう!」 などなど。 既に答えを知っているメンバーが答案用紙に赤ペンを入れて、実装者がそれに従って修正するという表現が近いかと思います。これはこれで大事で、勿論コードの品質は保たれるのですが、なんだか一方通行だなあと思うことはありました。 今は開発周辺ツールがそこら辺をカバーしてくれます。AIサービス含め、Linter, Formatterがあれば人間の出番はほとんどありません。そうなると、「コードレビューの存在意義って何?」という哲学的な問いに直面することになります。哲学的というか、自分自身の存在に対する危機感でもあるというか...。 答えを出すことによる機会損失 「こう書いてください」ではなく「こういうケースの考慮が必要になりませんか?」と聞いてみることが増えました。直接答えをポンと提示するのではなく、一緒に考える時間を作るように意識しています。とは言っても「なんでこうしたんですか?」「この実装のどこに問題があるでしょうか?」みたいなネチネチした詰め方はしませんが。 APIリクエスト処理を書く時に「リクエスト前後でこういう処理が必要になりませんか?」と聞いてみたり、UIコンポーネントを作る時も「このコンポーネントってどの画面でどういうパタンで使われますか?」と実装前に一度考える時間を作ったり。 そうすると、次に同じような問題が出てきた時や別の人のレビューを行う際に自分で判断したり、別の改善案を考えたりできるようになっていきます。 「なんで?」を大事にしている 機械がコーディングをアシストする場面が増え、構文的には正しく効率的なコードが出てきやすくなりました。しかし、「なんでその設計にしたの?」のような部分の責任は依然として人間にあります。 設計の話 「このコンポーネントの共通化の粒度、後で機能追加する時に耐えられますか?」 「この関数だけ責任範囲が広すぎませんか?」 「これ、3ヶ月後に見てもウッてなりませんか?」 「テスト書きにくくないですか?」 運用の話 「この実装は別のプロダクトでも何箇所か見かけたのでライブラリのAPIに閉じてしまって良さそうですね」 「デザインシステムや他プロダクトとの整合性は取られていますか?」 「前にも似たようなもの作っていませんでしたっけ?」 機能的には問題無くても時系列的な整合性が無かったり客観性に乏しかったりすると、負債になりやすいと考えます。そういうものをまあまあ見落としがちで、後からテコ入れしたり実装背景が後付けされることもありました。 なので、単純に「動くか動かないか」ではなく「長く使っていけるか」「変更に強いか」「チームにとってプラスか」のような視点で話すことが増えました。 AIが生成するコードは特に「なんでこうしたの?」が抜けていることが多いので、「前提条件って何でしたっけ?」「こんなケースは考えました?」を掘り下げてコンテキストを補足する作業が大切だと思っています。 開発チームの変化 知見の民主化 以前は「コードが書ける人」「コードレビューができる人」でなんとなく別れるようなことが多かったのですが、今は流動的になってきたと感じます。コーディングの敷居が下がった結果、より多くの人が実装に参加できるようになり、逆にレビューにおいては各々の専門性・経験値が活かされるようになってきました。 自身の周りの話ですが、業務ドメインに詳しいエンジニアがロジックを実装してアーキテクチャに強いエンジニアが別の観点からレビューしたり、フロントエンドエンジニアが実装したUIコンポーネントをマークアップ・Webアクセシビリティに精通したメンバーがチェックしたりといった協業は自然と生まれてきています。 非同期で作る これまでは「作る→レビュー→直す→またレビュー...」を繰り返していましたが、現在は事前に相談する(相談できるようにする)ことが増えてきました。「なんでこの方法?」「他の選択肢は?」「今後の運用は?」のような話を作る前にしておくことで、実装時のレビューはその確認作業に近くなり、大きな手戻りも発生しにくくなりました。 一人がコンポーネントを実装しながら、別の人がリアルタイムで画面の開発を進める、みたいな動き方も出来るようになってきました。多少複雑なインタラクションや状態管理も非同期で考えながら進められるので、完全に作り終わってからの考慮漏れは格段に減ったと感じています。 今後 生成AI含め、技術の進化は止まりません。近いうちに「なぜこの実装を選んだのか」の前後も含めて実装プロセスが圧縮されるかもしれません。そうなったとき、人間の役割はさらに抽象的、例えば「そもそもこの機能は必要か」「体験として最適なのか」「プロダクトとの親和性は」「人間もAIも守っていない実装ルールは捨てるべきでは」といった、より戦略的な判断軸に移り変わるだろうと予想しています。 だからといって人間の価値が下がるわけではなく、末端実装の細部まで気を払う必要が無くなることで、より本質的な価値創造を追求できるようになったと考えています。 おわり 人間以外にコードを書かせる技術が一般化した今のコードレビューは、表面上の正確性から人間的な洞察へとシフトしています。 単純なコードの良し悪しではなく、実装の本質的な価値と持続可能性を見極めるために、AIが生成したコード含め全てのアウトプットを『人が作り上げるシステム』という文脈で評価し、プロダクトの価値提供への貢献は勿論、開発チームの成長にも結びつける。 ...みたいな思想が当てはまるのだろうと思います。 正直な所、自分がレビューにかける時間は長くなったと感じています。純粋に実装単位のボリュームと実装速度が上がって物理的な負担が上がったのもそうですし、技術的な側面だけではなくもっと広い視点でレビューすることが増えました。 毎回疲弊しないためには、事前の相談を大事にしたり背景をドキュメントにしたりなどの工夫をする必要があります。 その一方で、開発チーム内の知識共有やコミュニケーションが活性化したり、「本来こうあるべき」のような話をやりやすくなったという効果は確実に得られています。 何より、単純作業から解放されて抽象度の高い課題解決に割ける時間が多くなったのは嬉しいことです。まだまだ頑張れることがたくさんありそうで、それはそれで楽しみでもあります。
アバター
自己紹介 ラクスでPdMをしております。 @keeeey_m と申します。 現在の担当商材は、楽楽シリーズ(楽楽精算、楽楽明細、楽楽電子保存、楽楽債権管理)を担当しており、個人としては楽楽精算×AIの担当、楽楽明細・楽楽電子保存・楽楽債権管理PdMチームのリーダーをしております。 はじめに 前回までの記事では、ジョブ理論とノーススターメトリックそれぞれの重要性について詳しく解説しました。第1回では顧客の真のニーズを理解する鍵としてのジョブ理論、第2回では組織全体の方向性を統一する鍵としてのノーススターメトリックについてお伝えしました。 しかし、これらを単独で活用するだけでは、真の事業成長を実現することは困難です。本記事では、ジョブ理論とノーススターメトリックを組み合わせることで生まれる相乗効果についてまとめました。 自己紹介 はじめに 相互補完的な関係 単独での限界 相互補完的な役割 相乗効果のメカニズム 因果連鎖の構築 相互依存関係 具体的な相乗効果 市場変化への柔軟な対応 ジョブ理論による柔軟性 Netflixの事例 実際の取り組み事例:両者の組み合わせ効果 顧客と企業双方にとっての持続的価値創造 顧客にとっての価値 企業にとっての価値 相互価値の創出 戦略的示唆と今後の展望 プロダクト開発のパラダイムシフト 今後の展望 まとめ 相互補完的な関係 単独での限界 ジョブ理論とノーススターメトリックは、それぞれ単独でも価値のあるフレームワークですが、単独で活用する場合には限界があります。 ジョブ理論単独の限界 顧客の真のニーズを理解できても、組織全体で追求しにくい 定性的な洞察を定量的な指標に変換しにくい 組織全体の方向性統一が困難 ビジネス成果への結びつきが曖昧 ノーススターメトリック単独の限界 表面的な数値に留まるリスク 顧客の真のニーズを深く理解できていない 指標設定の根拠が曖昧 短期的な改善に終始する可能性 相互補完的な役割 ジョブ理論とノーススターメトリックは、プロダクト開発の成功において互いを補完し合う、不可欠なフレームワークです。 ジョブ理論の役割 顧客の真のニーズ、つまり「片付けたいジョブ」を定性的に深く理解 プロダクトが提供すべき「顧客価値」の核心を明確化 イノベーションの方向性を指し示す ノーススターメトリックの役割 明確化された顧客価値を定量的に測定 組織全体をその目標達成に向けてアライン 継続的な改善の指針を提供 相乗効果のメカニズム 因果連鎖の構築 両者を連携させることで、単独で適用する以上の相乗効果が生まれます。 因果連鎖 ジョブ理論で顧客の真の課題と価値を特定(定性的フレームワーク) 適切なNSMを選定(その価値提供を定量的に測る顧客中心の先行指標) 組織全体がNSMに集中 持続的なビジネス成長が実現 相互依存関係 ジョブ理論とノーススターメトリックは、相互依存的な関係にあります。 ジョブ理論がなければNSMは表面的な数値に留まる NSMがなければジョブ理論の深い洞察はビジネス成果に結びつきにくい 両者が組み合わさることで、定性的な洞察と定量的な測定が統合される 具体的な相乗効果 1. より深い顧客理解 ジョブ理論による顧客の真のニーズの理解 NSMによる顧客価値の定量的測定 顧客の行動と価値の関係性の明確化 2. より効果的な指標設定 ジョブ理論に基づいたNSMの選定 顧客価値を中心とした指標設計 長期的な成長につながる指標の設定 3. より強い組織アラインメント 顧客の真のニーズに基づいた組織目標の設定 全従業員の共通理解の促進 部門間連携の強化 市場変化への柔軟な対応 ジョブ理論による柔軟性 ジョブ理論を基盤とした企業は、市場の変化に柔軟に対応できます。NSMと組み合わせることで、この柔軟性を組織全体で活用できます。 柔軟性の源泉 1. ジョブ中心の視点 製品の寿命に縛られない 顧客の「ジョブ」の変化を捉える 新たな「ジョブ」の出現を発見 2. 継続的なイノベーション 既存製品の改善点を発見 全く新しい製品カテゴリを創出 顧客の未解決のジョブに焦点を当てる 3. 戦略的柔軟性 製品が衰退期に入っても、その背後にある「ジョブ」を解決する新たなソリューションを開発 ビジネスの継続性を確保 長期的な成長軌道を維持 Netflixの事例 Netflixは、ジョブ理論とノーススターメトリックを組み合わせた成功事例として知られています。 不変のジョブ : 「質の高いエンターテイメントコンテンツを手軽に楽しむ」 時期 ビジネスモデル ノーススターメトリック 初期 DVDレンタルサービス 月間レンタル数 中期 ストリーミングサービス 月間視聴時間 現在 オリジナルコンテンツ制作 月間アクティブユーザー数 この事例から分かることは、顧客の「ジョブ」は時代を超えて存在し続ける一方で、それを測定するNSMは技術やビジネスモデルの変化に応じて進化するということです。 実際の取り組み事例:両者の組み合わせ効果 楽楽精算では、ジョブ理論とノーススターメトリックを組み合わせることで、単独では実現できない相乗効果を生み出す取り組みを開始しています。 両者の組み合わせによる実践 1. ジョブ理論による顧客理解 経費精算における顧客の真の「片付けたいジョブ」を深く理解 表面的な業務効率化ではなく、根本的な課題解決に焦点 2. NSMによる定量的測定 理解した顧客価値を「1社あたり申請から承認までの全作業時間」として定量的に測定 組織全体が統一された目標に向かって取り組む 3. 相乗効果の実現 定性的な顧客理解と定量的な測定が統合される 顧客の真のニーズに基づいた組織目標の設定 全従業員の共通理解の促進 取り組みの方向性 この組み合わせにより、楽楽精算では以下の相乗効果を目指して取り組みを進めています。 顧客にとっての価値 : 真のニーズを満たすソリューションの提供 企業にとっての価値 : 持続的な成長と競争優位性の確立 組織にとっての価値 : 部門間連携の強化と効率的なリソース配分 ロードマップ作成への貢献 ジョブ理論で顧客の真のニーズを理解し、それをNSMとして定量的に測定することで、組織全体が統一された方向性で効率的なロードマップを作成できるようになりました。これにより、短期的な機能追加ではなく、顧客価値の向上に焦点を当てた持続的な成長戦略を実現に取り組んでいます。 www.rakurakuseisan.jp 顧客と企業双方にとっての持続的価値創造 顧客にとっての価値 ジョブ理論とノーススターメトリックの導入により、顧客にとっての価値が最大化されます。 顧客にとっての価値 真のニーズを満たすソリューションの提供 機能的価値を超えた情緒的・社会的価値の享受 長期的な関係性と信頼の構築 生活の質の向上 企業にとっての価値 企業にとっても、両者の組み合わせにより大きな価値が生まれます。 企業にとっての価値 持続的な成長と収益の確保 競争優位性の確立と維持 顧客ロイヤルティの向上 イノベーション能力の強化 相互価値の創出 両者の組み合わせにより、顧客と企業双方にとっての持続的価値創造が実現できます。 相互価値の創出 顧客の成功が企業の成功につながる 企業の成長が顧客により多くの価値を提供 長期的なパートナーシップの構築 持続可能なビジネスモデルの確立 戦略的示唆と今後の展望 プロダクト開発のパラダイムシフト ジョブ理論とノーススターメトリックの導入は、プロダクト開発におけるパラダイムシフトを意味します。 項目 従来のパラダイム 新しいパラダイム 開発アプローチ 機能中心の開発 ジョブ中心の開発 価値創造 短期的な売上追求 長期的な顧客価値創造 競争優位性 競合との機能競争 顧客の「ジョブ」解決能力による競争優位性 顧客理解 顧客の表面的な要求への対応 顧客の真のニーズへの深い理解 今後の展望 技術革新との融合 AI・機械学習による顧客行動の深い理解 データドリブンなジョブ特定 リアルタイムでのNSM測定と改善 まとめ ジョブ理論とノーススターメトリックの戦略的な導入と運用は、企業が顧客の真のパートナーとなり、変化の激しい市場において持続的な成長と競争優位性を確立するための、強力な武器となります。 現代の競争が激しい市場において、プロダクト開発の成功には、単独のフレームワークでは不十分です。ジョブ理論とノーススターメトリックを組み合わせることで、企業は 顧客の真のニーズを深く理解し、それを定量的に測定できる 組織全体が統一された方向性で顧客価値の向上に集中できる 短期的思考から脱却し、長期的な持続的価値創造を実現できる この相乗効果により、企業は変化の激しい市場においても確実な成長軌道を確立し、競争優位性を維持することができます。技術革新との融合への配慮など、今後の展望においても、両者の組み合わせは、企業が持続的な価値創造を実現するための基盤として、ますます重要な役割を果たすことでしょう。
アバター
はじめに 私たちのモバイルアプリ(Android/iOS)開発チームでは、2024年頃から段階的にAIツールを導入し、開発プロセスの改善に取り組んできました。プロセス改善とチーム体制の強化も相まって、PR作成数などの指標で大幅な改善を実現しています。 本記事では、私たちがどのようにAIツールを活用して開発効率を向上させているか、具体的な取り組みをご紹介します。 はじめに 生成AI活用の文化づくり 生成AI情報共有会の開催 多様なAIツールの活用 独自MCPサーバーによる開発環境の革新 MCPとは 1. GoogleDrive MCP 2. Redmine MCP 3. 検証環境 MCP 4. GitHub PR/Issue MCP 5. Figma MCP 6. ファイル編集 MCP 具体的な活用事例 開発プロセス全体での活用 ナレッジの蓄積と共有 導入効果の測定 PR作成数の推移(1日あたり) CI実行回数の推移(2025年分 iOSのみ) 取り組みの中での失敗 現在取り組んでいる課題 1. 処理速度の最適化 2. 効果測定の精緻化 3. 適用範囲の拡大 まとめ 生成AI活用の文化づくり 生成AI情報共有会の開催 私たちのチームでは「生成AI情報共有会」を隔週で開催しています。この会では以下のような内容を行っています。 新しいAIツールの情報と使用感 効果的なプロンプトエンジニアリングのテクニック 実際の開発での成功事例と失敗事例 AIツール活用のベストプラクティス ツールの使用方法デモ、ハンズオン この定期的な情報共有によりチーム全体のAIリテラシーが向上し、新しいツールや手法の導入がスムーズになっています。 多様なAIツールの活用 現在チームでは以下のAIツールを利用可能な環境が整っており、メンバーそれぞれが利用したいツールを申請して利用している状態です。 Claude Code (メインツール:実装の40〜90%をAIで生成) Cursor GitHub Copilot Devin Codex JetBrains AI Gemini タスクの性質や個人の好みに応じて、最適なツールを選択できる環境を整えることで、開発者それぞれが最も生産的に作業できるようになっています。 また弊社では上記ツール以外でも使いたいと言えば、費用面も含めて検討して下さる開発横断組織もあり、直近だとKiroも連絡して1日後には利用可能リストに入れて下さいました。 このように非常にスピーディに対応して頂けていることも、AIツール活用して生産性向上が出来ている一つの要因となっています。 独自MCPサーバーによる開発環境の革新 MCPとは MCP(Model Context Protocol)は、AIツールに外部システムの情報を提供するためのプロトコルです。 私たちは開発効率を向上させるため、以下の独自MCPサーバーを開発・運用しています。 1. GoogleDrive MCP 機能 要件定義書、設計書、テスト項目書の参照・更新 文言一覧の読み取り(英語文言の自動反映など) 効果 ドキュメントとコードの整合性が向上し、仕様変更時の対応速度が大幅に改善しました。 2. Redmine MCP 機能 Redmineの情報取得、更新の自動化 効果 チケット管理の効率化により、開発者がタスク管理に費やす時間を削減できました。 3. 検証環境 MCP 機能 SQL自動実行による環境設定変更 テスト時の手動設定時間の削減 効果 環境構築やテストデータの準備にかかる時間が大幅に短縮されました。 4. GitHub PR/Issue MCP 機能 PR自動作成 コードレビューの支援 バックログ作成の効率化 AIへのコンテキスト提供 効果 PR作成からレビューまでの一連のプロセスが効率化され、開発サイクルが高速化しました。 5. Figma MCP 機能 デザインデータの読み取り AIへのコンテキスト提供 効果 デザインと実装の乖離が減少し、UIの実装精度が向上しました。 6. ファイル編集 MCP 機能 Claude Codeのファイル編集速度の改善 効果 大規模なリファクタリングや複数ファイルの同時編集が高速化されました。 具体的な活用事例 開発プロセス全体での活用 私たちのチームでは以下のような場面でAIツールとMCPを活用しています。 1. プルリクエスト(PR)作成 コミット内容からPRの説明文を自動生成 変更内容の要約と影響範囲の明記 2. コードレビュー コード差分、PRコメント、影響範囲コードを総合的に分析してフィードバック 潜在的な問題点の事前検出 3. テスト自動化 テスト環境でのSQL実行とcurlを組み合わせた自動テスト 手動テストの工数削減 4. その他の活用場面 脆弱性診断対応 ソースコード、DB定義の検索 Obsidianを使用した情報の記録、検索 マージ済みPRのレビューコメント分析 片手間で新機能PoC作成 要件定義からPBI(Product Backlog Item)作成 実装時のコンテキスト収集(Issue、Figma、Google Drive) ナレッジの蓄積と共有 実装ナレッジの再利用・形式知化 AIとのチャット履歴から有益な情報を抽出 良かった点をMarpでスライド化して共有 アプリ開発用ハンドブックへの記載 AI駆動開発のワークフロー作成 導入効果の測定 PR作成数の推移(1日あたり) AI導入段階 iOSアプリ Androidアプリ AI導入前 0.346 0.221 ChatGPT 0.313 0.487 Copilot(サジェストのみ) 0.638 0.576 Copilot(Edits/Agent)※2月 0.737 0.842 Cursor※4月 1.313 1.506 Claude Code※7月 3.059 2.235 ※1〜2月頃にプロセス改善も実施、3月頃にiOSチームメンバーが1名増員しています。 CI実行回数の推移(2025年分 iOSのみ) 1月:187回 2月:144回 3月:270回 4月:245回 5月:245回 6月:310回 7月:415回 これらの数値はAIツールの導入だけでなく、プロセス改善やチーム体制の強化も寄与した成果です。 取り組みの中での失敗 もちろんこれらの成果は一直線に得られたわけではありません。AIの出力が期待と異なったり、自動化が逆に非効率になったりと大小の失敗は常に経験しています。 小さな仮説検証を高速で回して常に失敗しているような状態ではありますが、チームが進化し続けている証だと考えています。 現在取り組んでいる課題 1. 処理速度の最適化 Claude Codeで時間がかかる部分の改善に取り組んでいます。特に大規模なコードベースでの処理速度向上が課題です。 2. 効果測定の精緻化 AIでのコード生成率の正確な計測 各ツールのROI(投資対効果)の可視化 品質指標との相関分析 3. 適用範囲の拡大 実装だけでなく設計フェーズへのAI活用を検討しています。要件定義から設計、実装、テストまでの一貫したAI支援の実現を目指しています。 まとめ 私たちのモバイルチームでは、AIツールの導入とプロセス改善を組み合わせることで、開発効率の大幅な向上を実現しました。特に独自開発したMCPサーバー群により、AIツールがプロジェクトの文脈を深く理解し、より精度の高い対応ができたり、手動作業を省力化できました。 重要なのはAIツールを単に導入するだけでなく、チームや組織の文化として定着させることです。定期的な情報共有会や独自ツールの開発により、チーム全体でAIを活用する文化が醸成されています。 今後も新しい技術やツールを積極的に取り入れながら、開発者がより創造的な作業に集中できる環境づくりを進めていきます。AIは開発者を置き換えるものではなく、開発者の能力を拡張するパートナーとして、私たちの開発プロセスに欠かせない存在となっています。
アバター
自己紹介 ラクスでPdMをしております。 @keeeey_m と申します。 現在の担当商材は、楽楽シリーズ(楽楽精算、楽楽明細、楽楽電子保存、楽楽債権管理)を担当しており、個人としては楽楽精算×AIの担当、楽楽明細・楽楽電子保存・楽楽債権管理PdMチームのリーダーをしております。 はじめに 前回の記事では、ジョブ理論の重要性について詳しく解説しました。顧客の真の「ジョブ」を理解することの重要性と、それが企業にもたらす競争優位性についてお伝えしました。 しかし、顧客の真のニーズを理解したとしても、それを組織全体で効果的に追求していくためには、もう一つの重要な要素が必要です。それが「ノーススターメトリック(North Star Metric: NSM)」です。 本記事では、ノーススターメトリックの重要性と、組織全体の方向性を統一する鍵としての役割についてまとめてみました。 自己紹介 はじめに 従来の指標設定の問題点 短期的思考の罠 楽楽精算での経験 顧客の属性と職種範囲 ノーススターメトリックの本質的な価値 顧客価値を起点とした先行指標としての役割 北極星の比喩が示す重要性 組織全体の目標統一と方向性の明確化 NSMの最大の価値 部門間の連携強化 KGI/KPIとの戦略的関係性 指標の階層構造 3つのバランス 長期的価値創造のアプローチ 短期的思考からの脱却 先行指標としての重要性 変化の激しい市場での成長軌道確立 現代ビジネス環境の特徴 NSMによる成長軌道確立 実際の取り組み事例 まとめ 従来の指標設定の問題点 多くの企業では、従来のKPI(Key Performance Indicator)やKGI(Key Goal Indicator)を設定して事業を推進しています。しかし、これらの指標には根本的な問題があります。 従来の指標の問題点 短期的な売上目標に囚われがち 顧客価値よりも事業価値に偏重 組織全体の方向性が統一されない 各部門が異なる指標を追求する結果、バラバラな方向に進む 短期的思考の罠 多くの企業が短期的な売上目標に囚われ、長期的な価値創造を見失いがちです。 短期的思考の問題 プロダクト価値の向上が後回し 顧客に提供できる価値の総量が変わらない 一度成長が止まってからの立て直しに膨大な時間と労力が必要 持続的な競争優位性を失う このような状況では、企業は「泥沼サイクル」に陥り、持続的な成長を実現することが困難になります。 楽楽精算での経験 楽楽精算では、AI活用の成果指標としてノーススターメトリックを設定することにしました。この導入のきっかけとなったのは、合議で機能仕様を決めていく中で、それぞれの役割において、第一想起するお客様が異なるという事象でした。特にラクスでは機能別組織体制を選択しているため、この事象がより顕著に表れていました。 職種による顧客の時間軸の違い 職種によって顧客と言われて第一想起する属性が異なります。営業部門やマーケティングは未検討・導入検討中の顧客、CSは導入準備中や運用中の顧客、企画部門や開発部門(開発・デザイナー)は未検討・導入検討中・導入準備中・運用中と現在から未来にかけての時間軸が分かれています。 顧客の属性と職種範囲 結果として生じた事象 顧客のペインの本質的な解決にて価値をもたらすのか、それともビジネス的に即効性のあるインパクトを求めているのか、この判断によって解決策が変わってきます。しかし、各部門が異なる指標を追求する結果、顧客像や達成したいことがバラバラになり、仕様決定に何度も苦労する経験をしました。 このような経験を通じて、全員と前提をそろえる指標が必要だと考えるきっかけとなり、ノーススターメトリックの導入を検討することになりました。 ノーススターメトリックの本質的な価値 顧客価値を起点とした先行指標としての役割 ノーススターメトリック(North Star Metric: NSM)は、プロダクトをより確実に成長させるための先行指標として設定されるものです。 NSMの定義 顧客へ提供する価値を明確に表し、かつ計測可能な指標 企業全体の正しい方向性を全部署が把握できる唯一無二の指標 北極星が地上のどこから見ても常に変わらない位置にあり、方向性を示すように機能 北極星の比喩が示す重要性 北極星は、地上のどこから見ても常に変わらない位置にあり、方向性を示す星として知られています。NSMも同様に、組織全体が目指すべき方向性を明確に示す指標として機能します。 北極星の特徴 常に一定の位置にある 誰から見ても同じ方向を示す 迷った時の指針となる 長期的な航海の道しるべ NSMの特徴 顧客価値を中心とした指標 組織全体で共有できる 事業の方向性を明確にする 長期的な成長の指針となる 組織全体の目標統一と方向性の明確化 NSMの最大の価値 NSMの最大の価値は、組織全体の目標を統一し、方向性を明確にすることにあります。 組織統一の効果 企業全体が同じ目線で目標に向かう 全従業員、全部署での目標達成における意識の統一 チーム間やメンバー間の連携の取りにくさを解消 バラバラな方向への進行を防止 部門間の連携強化 従来の指標設定では、各部門が異なるKPIを追求する結果、組織全体としての方向性が曖昧になりがちでした。NSMの導入により、この問題を解決できます。 従来の問題 営業部門:売上目標 開発部門:機能リリース数 マーケティング部門:リード獲得数 カスタマーサクセス部門:解約率 NSM導入後の効果 全部門が顧客価値の向上に集中 部門間の連携が自然と生まれる 組織全体の効率性が向上 顧客にとっての価値が最大化 KGI/KPIとの戦略的関係性 指標の階層構造 NSMは、従来のKGI(Key Goal Indicator)やKPI(Key Performance Indicator)と密接に関連しつつも、異なる戦略的な位置づけを持ちます。 戦略的位置づけ NSMはKGIとKPIの間に設定される傾向 KGIやKPIが経営視点の指標であるのに対し、NSMは顧客視点を取り入れた指標 事業の結果(売上など)に対して「先行指標」として設定 NSMが適切に設定され、改善されることで、遅行指標である成果(売上や利益など)が自然と生まれる 3つのバランス NSMは、以下の3つの要素のバランスを取った指標として機能します。 3つのバランス ビジョン : 企業が目指すべき未来像 顧客価値 : 顧客に提供する価値 事業価値 : 企業が得る価値 このバランスが取れた状態を目指すことで、プロダクトの成功に直結した指標として機能します。 長期的価値創造のアプローチ 短期的思考からの脱却 NSMの導入により、企業は短期的思考から脱却し、長期的なビジネス価値の実現を目指すことができます。 長期的価値創造のアプローチ 顧客の真の価値提供に焦点 顧客価値の向上を最優先 持続的なイノベーションの実現 長期的な顧客関係の構築 先行指標としての重要性 NSMは、事業の結果に対する「先行指標」として機能します。これは、NSMの改善が将来的な事業成果につながることを意味します。 先行指標の特徴 現在の行動が将来の結果に影響する 早期に問題を発見できる 改善の機会を早期に把握できる 長期的な成功の予測が可能 具体例 NSM : 月間アクティブユーザー数(MAU) 結果 : 売上・利益の向上 関係性 : MAUの増加が売上向上につながる 変化の激しい市場での成長軌道確立 現代ビジネス環境の特徴 現代のビジネス環境は、技術革新の加速、市場のグローバル化、顧客ニーズの多様化により、かつてないほどの速さで変化しています。 市場環境の特徴 技術革新の加速 市場のグローバル化 顧客ニーズの多様化 競争の激化 NSMによる成長軌道確立 このような環境において、NSMは企業が確実な成長軌道を確立するための強力な武器となります。 成長軌道確立のメカニズム 1. 戦略的明確性 組織全体の方向性を明確化 リソースの最適配分を実現 顧客価値の向上に集中 2. 実行効率性 無駄な開発を排除 本質的なKPI設定 組織全体のアラインメント 3. 継続的改善 顧客価値の向上を継続 市場の変化に対応 イノベーションを加速 4. 競争優位性の維持 顧客価値の向上を継続 競合との差別化を維持 持続的な成長を実現 実際の取り組み事例 楽楽精算では、ジョブ理論で特定した顧客の真の「ジョブ」を基に、ノーススターメトリックを設定しました。 NSM設定の背景 楽楽精算のAI活用の方針は「経理業務の本質的な課題解決をするためにAIも活用する」ことです。もちろんAIの精度は大事ですが、それに加えAIを活用することで、お客様に本質的な価値を提供できていることを定量的に計測することで、早期に問題を発見し、改善の機会を把握できます。これにより全員が本質を見失うことなく取り組むこともできます。 具体的なNSM設定 ジョブ理論で特定した経費精算における顧客の真の「ジョブ」を基に、「1社あたり申請から承認までの全作業時間」をNSMの実行KPIの一つとして設定しました。プレスリリースでも「1社あたり申請から承認までの全作業時間の約60%削減を目指す」と宣言をしました。 組織統一の効果 このNSM設定により、開発部門、営業部門、CS部門など、全ての部門が「顧客の作業時間削減」という統一された目標を共通認識として持つことができました。 www.rakurakuseisan.jp まとめ ノーススターメトリックの導入により、企業は組織全体の方向性を統一し、顧客価値の向上に集中できるようになります。これにより、短期的思考から脱却し、長期的なビジネス価値の実現を目指すことができます。 NSM導入の効果 NSMの導入により、組織全体の目標が統一され、顧客価値の向上に集中できるようになります。これにより、長期的な成長軌道を確立し、競争優位性を維持することが可能になります。 成功の鍵 NSMの成功には、顧客価値を中心とした指標設定が不可欠です。組織全体での理解と実践を徹底し、継続的な改善サイクルを確立することで、長期的視点での取り組みが実現できます。 次回は、ジョブ理論とノーススターメトリックを組み合わせることで生まれる相乗効果について詳しく解説します。両者を連携させることで、単独で適用する以上の価値を生み出す方法についてお伝えします。
アバター