エス・エム・エスのブログ - TECH PLAY

TECH PLAY

エス・エム・エス

エス・エム・エス の技術ブログ

282

この記事は株式会社エス・エム・エスAdvent Calendar 2025 vol.1の12月4日の記事です。 qiita.com エス・エム・エスで全社SREというロールで活動しているSecurity Hub芸人の山口( @yamaguchi_tk )です。おすすめのAWSサービスは営業です(いつもお世話になっています)。 はじめに 私が所属している全社SREチームで監視基盤の入れ替えを行った際、そのタイミングで監視設定自体も見直しました。 その見直しの中で、 脅威モデリング の考え方をインフラレイヤーの監視設計に応用して整理を行いました。 本記事では、そのときに実施した手法をできるだけ具体的に言語化し、同じように監視を見直したい方の参考になることを目指して紹介します。 背景 オンプレからAWSにLiftした際にオンプレと同じ構成でAmazon EC2を構築し、監視もZabbixを利用してオンプレと同じ構成で構築しました。 Zabbix自体のアップデートやAmazon EC2、Amazon RDSのアップデートを何度か実施した結果、アップデートの検証工数やZabbix自体の運用工数が課題になってきたため、フルマネージドサービスであるAmazon CloudWatchへの移行を行いました。 監視設定の整理の目的 監視設定自体はZabbixの基本テンプレートをベースに一部をカスタマイズして利用しており、特にメトリクスベースのアラートがシステムの実態と合っておらず 無駄なアラートが発生している 状況でした。 無駄と判断した監視設定は、発生のたびに削除したり閾値や監視するメトリクス自体を見直ししたりしていましたが、発生都度の対応ではどうしてもいたちごっこになってしまいます。 そこで、Amazon CloudWatchへの移行を機に方針を決めて監視設定を整理することにしました。 インフラレイヤーの監視設定への応用 インフラレイヤーの監視設定に脅威モデリングの手法を応用できないか検討し、実際に行ってみました。 これは古典的なセキュリティ原則の「可用性(Availability)」にフォーカスして脅威モデリングを実施した、と言えるかもしれません。 脅威モデリングについて 脅威モデリング(Threat Modeling)は、システムやアプリケーションのセキュリティを設計段階から考慮するための手法です。 アダム・ショースタック氏の以下のフレームワークが有名です。 Shostack’s Four Question Framework for Threat Modeling 何に取り組んでいるのか? What are we working on? 何が問題を引き起こす可能性があるか? What can go wrong? それに対して何をするのか? What are we going to do about it? 十分によい対応をしたか? Did we do a good job? 具体的には、DFD等でシステムの構成要素を可視化し、「起こったら困ること」という視点で脅威を特定します。 特定した脅威をSTRIDE等でカテゴリ分けし、その発生確率をアタックツリーで分析し影響度と併せてリスク評価することで、セキュリティリスクを事前に把握し、適切な対策を検討することができる手法です。 実施手順 ここからは、実際に行った手順を紹介します。 発生したら困ることを洗い出す まず、AWSの構成図を作成します。 1つ目の構成図(EC2版)には、オンラインWebサービスと同じインスタンスで処理されるバッチ処理が含まれています。 2つ目の構成図(AWS Fargate版)には、オンラインWebサービスとバッチ処理、非同期処理が含まれています。 AWSの構成図を見ながら、 起こったら困ること を基準に付箋などを張ったりして洗い出していきます。 例示したAWSの構成図の場合だと、以下のようになります。 オンラインサービス系 オンラインサービスが応答しない オンラインサービスの応答が遅延している バッチ系 バッチが処理されない 非同期処理系 非同期処理が処理されない 非同期処理が遅延している 処理フローを可視化する 洗い出した 起こったら困ること に対して、その処理(オンラインサービス系/バッチ系/非同期処理系)がどのようなシステムフローで実行されているかを、AWS構成図ごとに可視化していきます。 作成したAWS構成図から必要な処理フローを抜き出して構成します。 以下に上で例示したAWS構成図での可視化例を示します。 オンラインサービス系(EC2) バッチ系(EC2) オンラインサービス系(Fargate) バッチ系(Fargate) 非同期処理系(Fargate) 発生要因を分析する 洗い出した 起こったら困ること に対して、処理フロー図を見ながらその発生要因を抽象度高めで洗い出していきます。 ここでは「xxxというエラーでyyyが発生して処理が異常終了する」という詳細な記載ではなく、「処理が正常終了しない」といった抽象度高めの粒度で洗い出しを行います。 洗い出した例を図で示します。 オンラインサービス系発生要因(EC2) バッチ系発生要因(EC2) オンラインサービス系発生要因(Fargate) バッチ系発生要因(Fargate) 非同期処理系発生要因(Fargate) 直接的に監視できるところを探す 分析で洗い出した発生要因に対して、 一番直接的に観測できる箇所・監視内容 や、 処理の急所(ここを監視すればシステムフローの下流の異常が検知できる箇所・監視内容) を処理フローから探します。 洗い出した例を図で示します。 オンラインサービス系監視ポイント(EC2) バッチ系監視ポイント(EC2) ハートビート系処理でログを監視する場合は、ハートビート系処理をどこで動作させるのか、バッチ処理のログをどこに出力するのか、といった点もあわせて考慮する必要があります。 オンラインサービス系監視ポイント(Fargate) バッチ系監視ポイント(Fargate) 非同期処理系監視ポイント(Fargate) バッチ系監視ポイント(Fargate)では、以下の理由でAWS Step Functions以降を監視することで全体をカバーしています。 Throttlingが発生する可能性がある場合は通常Amazon SQS等を挟むため、このシステムはThrottlingが発生する状況になることは少ないと考えられる。 Amazon S3とAmazon EventBridge間でThrottlingが発生してもAWS Step Functions自体は起動することを期待している。 Amazon EventBridgeの定時処理は少なくとも1回は起動することを期待している。 まとめ 監視設定の整理に脅威モデリングの手法を応用することで、以下の効果が得られました。 システムの実態に合った 最低限必要な監視設定 が可能になります。 「起こったら困ること」を起点にすることで、無駄なアラートを削減できます。 処理フローを可視化することで、監視ポイントの選定根拠が明確になります。 この手法は既存の監視設定の見直しだけでなく、新規システムの監視設計にも応用できると考えています。
この記事は株式会社エス・エム・エスAdvent Calendar 2025 12月3日の記事です。 qiita.com 介護/障害福祉事業者向け経営支援サービス「カイポケ」のソフトウェア開発者の空中清高(@soranakk) です。 本記事ではカイポケのバックエンド開発で取り入れている、スキーマからのコード生成に焦点を当てて取り組みや工夫を紹介したいと思います。 カイポケのシステム概要 まずはこちらの図をご覧ください。 こちらはカイポケのシステム概要図となっています。 バックエンドにはいくつかのサーバーが存在していて、それぞれのサーバーはGraphQL APIを公開しています。 そして、それらをGatewayで1つのGraphQL APIにまとめて、フロントエンドに公開しています。 またそれぞれのバックエンドはSpring Bootで構成されていて、KotlinとSpring for GraphQLを利用して開発しています。 さらにそれぞれのバックエンド毎にデータストアとしてPostgreSQLのデータベースを持っている構成になっています。 本記事ではこれらのバックエンド開発のコード生成に焦点を当てて紹介したいと思います。 コード生成を利用している箇所 コード生成は主に2箇所で利用していて、1つ目はGraphQL Schemaからのコード生成です。 それぞれのバックエンドで公開しているGraphQL SchemaからKotlinのコードを生成して利用しています。 もう1つはデータベースアクセスでPostgreSQLのスキーマからKotlinのコードを生成して利用しています。 GraphQL Schema からのコード生成 カイポケのバックエンドではSpring for GraphQLを利用してGraphQL APIの開発をしているのですが、Spring for GraphQLにはコード生成の機能が存在しません。 そのため、カイポケではDGS Framework (Domain Graph Service)というライブラリのコード生成を利用しています。 DGS frameworkはNetflixが提供している、Spring BootでGraphQLを開発するためのライブラリです。 リンク: https://netflix.github.io/dgs/ DGS frameworkにはコード生成のためGradleプラグインが用意されていて、それを使うとKotlinのコードを生成することができます。 ちなみにSpring for GraphQLの開発においてコード生成でDGS frameworkを利用することは公式ドキュメントでも触れられていますので、半分ぐらい公式的な方法です。 リンク: https://docs.spring.io/spring-graphql/reference/codegen.html データベーススキーマからのコード生成 カイポケのバックエンドではjOOQというORMを利用してデータベースアクセス層の開発をしています。 jOOQにはデータベーススキーマからのコード生成プラグインが提供されているので、それを利用しています。 jOOQを使ったデータベースアクセスは、例えばソースコードはこのような感じになります。 by公式ドキュメント: https://www.jooq.org/doc/3.20/manual/sql-building/dsl-api/ val result: Result <Record?> = create.select() .from(AUTHOR) .join(BOOK).on(AUTHOR.ID.eq(BOOK.AUTHOR_ID)) . where (AUTHOR.YEAR_OF_BIRTH.gt( 1920 )) .and(AUTHOR.FIRST_NAME.eq( "Paulo" )) .orderBy(BOOK.TITLE) .fetch() この時に利用するテーブル名やカラム名、View名やRecord型などがjOOQによって生成されたコードとなっています。 生成するときはデータベースのスキーマを直接参照して生成することになるので、DockerなどでPostgreSQLを起動しておいたり、 TestContainersを使ったりしてPostgreSQLを起動した状態でコード生成します。 コード生成のメリット:GraphQL GraphQLのコード生成によってリクエストやレスポンス型のdata classを自分で書く必要がなくなります。 これらはGraphQL Schemaに合わせて定型的な型を定義して利用するだけなので、コード生成できると楽です。 さらにGraphQL Schemaからコード生成されるため、GraphQL Schemaを修正すれば自動的にコードへ反映されるようになります。 そのためGraphQL Schemaを更新したけどコードへ反映が漏れていた、みたいなことにコンパイルエラーで気づくことができます。 ユニットテストやCIでも気づくことはできるのですが、やはり修正してすぐに手元のエディタで気づけるほうが開発者体験として良いです。 コード生成のメリット:データベース データベースのスキーマは何らかのマイグレーションツールを使って管理していると思います。 カイポケではgolang migrateというGo言語で作られたマイグレーションツールを利用しています。 リンク: https://github.com/golang-migrate/migrate こちらのツールではデータベースの更新をSQLファイルを使って管理します。 そのためデータベースのスキーマを管理するSQLとアプリケーションコードのKotlinで変更を同期しておかないと、データベースは更新したのにアプリケーションが発行するSQLは古いままでエラーになってしまう、みたいなことが発生しがちです。 そこでデータベーススキーマからコード生成することで、自動的に同期できるようになります。 なのでGraphQLの時と同じく、データベースを更新したけどコードが古いままになっていた、みたいなことにコンパイルエラーで気づくことができます。 CI での活用 スキーマとコードのズレにコンパイルエラーで気づける、という話をしましたがそれでも漏れてしまうこともあります。 そこでGraphQL SchemaやデータベースのマイグレーションのSQLが追加された時などをトリガーにしてCIでコードの自動生成を行なって、変更がコードに反映されているかどうかをチェックしています。 手元で修正漏れがあったとしてもPRのCIでチェックされるので、整合性が取れていない場合はマージされることもありません。 このような自動化が行えることも自動生成の利点だと思います。 まとめ 本記事ではカイポケのバックエンド開発で取り入れているコード生成に焦点を当てて紹介しました。 コード生成を活用することで外向けのインターフェースと内部のソースコードの整合性のチェックが自動化できたり、開発者がコンパイルエラーで不整合に気づけるというメリットがあります。 DGSのようにコード生成部分だけ利用するってケースもありかなって思っています。 また、本記事の内容はKotlin Fest 2025やJJUG CCC 2025 Fallのカンファレンスのエス・エム・エスのブースでも紹介していました。 ブースでは実際のソースコードも見せながら色んな工夫を話すことが出来たので、今後もエス・エム・エスのブースを見かけたら立ち寄ってもらえると嬉しいです。
この記事は 株式会社エス・エム・エス Advent Calendar 2025 の12月1日の記事です。 qiita.com  みなさんこんにちは。Analytics & Innovation推進部の井手です。あっという間に今年も12月。心の準備も済まぬ間にカウントダウンが始まる時期に突入です。そして今回の記事はAdvent Calendar 2025の記事の一つでありしかも1日目とのこと。華々しい幕開けとなれるかどうか。はてさて。 RecSys2025に参加してきました  前回の 私の記事 でも書きましたが、私は現在求職者と事業者に対してリコメンドを提供するシステムの作成に関わっています。そしてインプットの一環として、だいぶ過日となってしまいましたが、秋にチェコはプラハで開催された RecSys というリコメンドシステムの国際カンファレンスに参加してきました。開催地域である中央ヨーロッパの国々を中心に、アメリカ、中国、イギリス、フランスなど世界各国からリコメンドシステムに関わる研究者や実務者が集まり、研究が共有されました。また、Music, Travel, News, HRといったドメインごとのワークショップも開かれ、実用的な観点での学びも多分にありました。 今回のRecSys 簡単に前置き  あまりこの界隈に馴染みのない読者の方も多くいらっしゃると思いますので簡単に前置きをいれておきます。ここで言うリコメンドシステムとは、ECサイトではおなじみの「あなたへのおすすめ」と表示されて自動的に商品が提案されるような、過去のデータを利用してターゲットとなるユーザーの好みやニーズを推測し、それにマッチするアイテム(群)を抽出するシステムのことを指します。リコメンドアイテムを決定するアルゴリズムは「自分の行動と似た行動をとっているユーザーのパターンを参考に決定する」「自分が高評価したアイテムの中身と似たコンテンツのものを探し決定する」などのアプローチの側面があり、またそれらの側面から、クラスタリングアルゴリズムの適用、行列分解、ディープラーニングを利用した手法などを用いてアイテムの決定がなされます。特に最近は、精度や柔軟性の高さから、ディープラーニングを用いた手法が中心となっており、今回のRecSysの発表の傾向も同様でした。 ドメインごとにみたRecSys   RecSysでは様々なドメインでのリコメンドについて扱われていますが、ここでは大きく「リコメンドシステムが成熟してきているドメイン」と「新たなドメインへのリコメンドシステムの適用」という2側面で今回のカンファレンスの特徴をまとめてみたいと思います。 成熟してきているドメインでのリコメンドの深化  E-commerceや音楽、映画、オンライン広告など、すでにリコメンドシステムが多数のユーザーが利用するサービスに取り込まれ、アーキテクチャーの実績がすでにある分野では、エンベディングの頑健性や安定性を高める取り組み、あるいはリコメンド結果の多様性に焦点をあてている研究などが多かったように思えます。例えばMetaのスタッフを中心とした Zhengらの発表 では、広告表示のリコメンドに関連する課題を解決するための提案でした。SNSで表示される予定の広告は、量が膨大なのはもちろん、一方で表示される広告とそうでない広告の差が激しく分布が歪んでいたり、広告の入れ替わりが激しくIDドリフトが生じやすいなどの点でエンベディングが不安定になりやすい。それを解決するために、似た意味を持つ広告をクラスタにして情報を共有するSemantic IDを用いる手法を提案しています。  また、新規ユーザーのように、該当サービスにほとんど過去の情報を持っていない中でリコメンドを行うコールドスタート問題については、今回も複数の研究発表がありました。クロスドメインやマルチモーダル等、入力のバリエーションを増やすことで解決する提案が多かったように思え、これは近年の傾向と言えるでしょう。コールドスタート状態における情報の補完を、他ドメインあるいは他メディアで補完する場合、いかにそれらの情報を目標とするドメインで利用できるフォーマットに変換するかが課題となります。マルチモーダルの例だと、イメージ情報、または音声情報をテキストのエンベディングに変換するのは今までであればかなりハードルの高いタスクでした。しかしLLMが登場し、この部分をLLMが担うことで、ハードルが劇的に下がり各ドメインへの適用結果の報告がかなり増えてきました。LLMは適用が容易ですので、今後多くのドメインでコールドスタートのリコメンドの質が改善されていくことでしょう。 新たなドメインへのリコメンドシステムの適用  一方、リコメンドシステムを新たな領域に適用しようという動きも多く見られました。例えば Bereket らは、アートセラピーにおける、絵や音楽のリコメンドに関する手法。既存研究では絵の刺激に対するクライアントの反応からリコメンドのモデルを学習させていたところを、音楽のモデリングも含めた双方からのクロスドメインで行うという研究を報告していました。また、オンラインコースのリコメンドでは、受講者の興味をモデリングする手法が既にありましたが、これは受講者の興味がシフトしたタイミングを把握できないという欠点が指摘されてきています。この課題に対して両方を達成するためのモデルの提案が Li らによってなされ、その効果と有効性が主張されていました。こういった領域は今後しばらくは様々な側面からのリコメンドアーキテクチャが提案されていくなかで、徐々にデファクトの方法が定まり、現在のe-commerceの領域のように深化していくのだろうなという印象を受けました。  また、本のリコメンドに関する研究や実装はすでに珍しくなくなっておりますが、リコメンド対象を子供に限定し、さらに既存のリコメンドで前提となるプロフィール情報やインタラクションログなどが(privacy lawなどで)取得できないという制限された状況でのリコメンドエージェントを作成するという Hillら による発表は非常に目新しく、そして大変興味深かったです。子供の各年齢がどのような感情パターンを持つかをグルーピングしたものと、リコメンド対象の本を感情的側面でベクトル化したものでLLMをファインチューニングしてエージェントを作成するという手法で、その有効性を主張されていました。発表者は今後の課題点など挙げられており、確かに今後改善するポイントは多くあるのかもしれないとは思ったものの、それ以上に発表者(学生さんたちでした)の「子どもたちにもっとたくさん本を読んでもらいたい」という研究のきっかけとなったモチベーションは素晴らしく、とても魅力的な研究であるなと感じました。 個人的に特に気になった研究  どのドメインの発表も興味深く聞くことができたのですが、上記全体を通して一番印象に残った研究は、NetflixのZielnickiらによる、 Orthogonal Low Rank Embedding Stabilization というタイトルの発表でした。  実際のサービスでリコメンドシステムを運用するにあたり、日々更新されるデータからの再学習は避けては通れません。ただし、再学習を行うにあたっては計算負荷や、再学習されたモデルから生成されるエンベディングが今までのものと変化してしまうという問題が大きな課題となります。この再学習で生成されたエンベディングの計算負荷や不安定性に対し、QR分解とSVDを用いて次元を下げた後に、プロクラステス回転を行い前の行列に近づけるというアプローチを提案しています。彼らはNetflixの実際のデータ(基準日および基準日から数週間後の日)をこの方法で学習させ比較し、両者の間に強い類似度が生じていることを確認したと報告していました。  通常、あるモデルを利用して検索用のベクトルインデックスを構築している場合などは、再学習でモデルを作り直すと、インデックスも作り直すことになります。データが膨大な場合にはモデルの学習と合わせてかなりの時間がかかることになります。今回提案された方法は、モデル学習のみならず、軸をプロクラステス回転で過去の軸に合わせることでインデックスの作り直しを避けることができる(可能性がある)点で非常に魅力的で、参考になりました。 RecSys in HR  RecSysでは、メインの研究発表とは別に初日と最終日にワークショップがあります。ワークショップなので、メインの研究発表よりもさらに領域特化した感じのトピックになりますが、基本的には研究発表がメインという点は同じです。いくつか参加しましたが、ここでは本業であるHRに関するワークショップ(RecSys in HR)について簡単に紹介します。  今回の発表は7件ほどあったと思うのですが、AI(特に生成AI)が生み出すバイアスに注目する研究が多かった印象です。LLM登場直後の、ジェンダーや人種などに対する極端なバイアスではなく、文脈がより多様化した中でのバイアスが扱われていました。例えば、 Hoffmannらの発表 では、職業のマッチングについて、そのマッチングがどの程度適切かをLLMに評価させた際のバイアスについて報告していました。それによると、アラビア系国籍の人はヨーロッパ系国籍の人に比べて、経験が少ないことをより大きなペナルティと判断したなど、細かい部分にバイアスが見られたということでした。  このような、細かいところに見え隠れする小さなバイアスというのは、ときに誰かを大きく傷つける可能性があります。LLMが持つ数多くの偏りに常に注意深くあることは、とりわけ我々のような、数多くの人に利用していただくサービスにAIを適用しようと考えている者にとっては非常に重要なことです。  ワークショップの最後には組織内でAIを利用するリスクとその対策について、研究者、実務者、弁護士を含めたパネルディスカッションが行われました。そこでも話題の中心は、LLMが持つバイアスについてであり、バイアスについて注意深くあること、そしてバイアスがあることを前提としたレギュレーションを明確に敷いていくことは絶対に必要であるし、国際的な流れでもあるという話がなされていました。これは大変手間のかかる作業ではあります。ただ、今後AIを使わないという未来はないことを考えれば、いつかは絶対にやらなくてはいけないことです。私たちの準備はどうであるか、今一度考えるとてもいいきっかけになりました。 自身の領域を改めて考える  さて、こうやって今回参加したRecSysのメインカンファレンスおよびHRのワークショップを振り返り、改めて私が目下取り組んでいるテーマや領域について考えてみたときになにを強く思うかというと、やはりHR領域でのマッチング課題というのは、他ドメインのマッチング課題とは課題構造が少なからず異なるなということです。  HR領域におけるリコメンドは、多くの場合コールドスタート問題を抱えています。転職希望者のなかの多くは、転職をするのが初めての求職者です。そして転職が当たり前の時代になっているとはいえ、総回数はe-commerceなどにおける買い物などとは比較にならないほど少ない。つまり過去の履歴はあったとしてもかなり少ない。インタビューなどを通じて把握した、求職者のニーズだけを頼りに適切なマッチングを行っていく必要があります。また、リコメンドモデルを作成するのに利用する過去の求人情報は、ほとんどの場合現在はすでにありません。希望の求人が満たされた時点でなくなってしまいます。学習時に成立した求人と、類似した求人を探す必要が出てきます。すると、リコメンドされる求人は「現在の求職者さんと似たニーズを持つ人にマッチしたものと、似た求人」と、だいぶ誤差の範囲の広いおすすめになってしまう可能性があります。  また、求職者のニーズというのは、他領域のリコメンドにおける「好み」とは異なり、制約に近いニュアンスを持ちます。好みであれば、多様性で許容されるかもしれませんが、制約となるとより強い条件をリコメンドシステムに課すことになります。しばしばジョブマッチングは、問題構造をデートのマッチングのアナロジーとして取り扱われることもありますが、私はこの好みと制約の違いから、デートマッチングとも大きく異なると考えています。つまり、RecSysで発表されるような研究をはじめリコメンドに関する研究は世の中に数多くあるものの、HR領域への効果的な適用を考えていくと、領域特化して考えなくてはならない部分が多分にあるのではないかと感じるようになっています。参考になるもの、そして独自に考えなくてはならないもの、それをきちんと切り分けながら課題を設定し、解決していく必要があります。考えてみると割と当たり前のことなのですが、様々な領域の話を聞くと、この点が輪郭を持って浮き上がってきます。すごい大事なことなんですよね。その気付きも含めて、実りの多いカンファレンスでした。  RecSysへの参加、自分ではもちろん意義があることだと思っていたけど、それをうまく伝えられるかなーなんて少し不安に思っていたのですが、上司である田辺さんに相談したところ、快諾してくださいました(勉強だけじゃなくせっかくだから楽しんできてください!とまで言ってもらえました)。自身の成長の背中をぽんと押してくれるのは、田辺さんはもちろんこの会社全体の文化なんだなあと大変ありがたく思っています。  というわけでこの経験を成長につなげ、日々の仕事に還元してまいります。求職者、そして事業者が最も欲しているリコメンドができるよう、引き続き精進していきます。 皆さんにも「いいものができたよ!」と報告できる日を楽しみに、アドベントカレンダー2日目にバトンを渡したいと思います。それではまた!!
こんにちは、 豊濱 です。 現在は、プロダクト開発部で ウェルミージョブ 、 シカトル 、 カイゴジョブアカデミー のエンジニアリングマネージャ(EM)を担当しています。 この記事では、現在ウェルミージョブで取り組んでいることについてご紹介します。 少し自己紹介 まだ20世紀だったころにソフトバンクに入社し、2日目に子会社のヤフーに出向ののち正式に転籍、そこから約16年働いていました。 21世紀に入ったあたりから、インターネットの急速な普及、大容量回線によるコンテンツの進化、スマートフォンの台頭など、業界や市場の成長とともにエンジニアとして自分も成長させてもらったな、運が良かったな、と今でも思います。その後、Web/IT系の企業に何社か転職、テックリード・アーキテクト・CTOなどを経験し、2024年にエス・エム・エスに入社して今に至ります。スタートアップ企業の技術顧問・アドバイザーやカメラマンもやってます。 今でも使える技術スタックだとPHP/Laravelぐらいです。COBOLも書けます。 ここ数年はEMやプロダクトマネジメント(PdM)と呼ばれる領域にウェイトを置くことが多いです。 ウェルミージョブとは 2025年7月に、 “カイゴジョブ” からリブランディングを行ったものが “ウェルミージョブ” です。 2025年3月期 決算及び会社説明資料より カイゴジョブはブランド名の通りもともとは介護中心の求人情報でしたが、介護・医療・障害福祉・保育の求人サイト「ウェルミージョブ」として、今後は職種横断のダイレクトリクルーティングプラットホームとして拡大・成長を実現するプロダクトになりました。 エス・エム・エス的に言うと、ウェルミージョブはキャリア事業という領域の中の1つですが、ナース専科転職やカイゴジョブエージェントはそれぞれ専任のキャリアパートナー(CP)が、就職・転職先を探している従事者へ働き方や条件に合う事業所を紹介したり、事業所からどういう人材が欲しいかの要望もヒアリングします。 それに対し、ウェルミージョブはCPがおらず、従事者は自分で事業所に応募する形、事業所も求人票を自分で記述して掲載するという形になっています。その分採用時にいただく料金もお安くなっている、という仕組みになっています。 課題抽出・仮説の設定 CPを介してヒアリングや紹介を行うサービスのことを、エス・エム・エスでは人材紹介と呼んでいます。 上述したとおりウェルミージョブはCPがいないぶん、基本的には従事者も事業所の双方に自律自走が求められます。 従事者目線で転職するとなると、いまの職場で働きつつ、どういう場所でどういう職場で働きたいのか、を自分で決めて見つけて、スケジュールを調整して面接をこなしていく必要があります。 事業所目線でいうと、小さな介護施設などは専任の採用担当もおらず、マネージャも現場での業務をこなしつつ採用もやらなきゃいけない状況であることが多いです。 当然ですが、従事者はウェルミージョブのサイトに来たときが一番モチベーション高く職場を探している状態です。事業所も求人票を掲載したいと思っているタイミングが一番人材がほしい状態になります。そこから実際に従事者が事業所に入職するまでの手間と時間をいかに減らすか、究極 “ゼロ” が理想、ということになります。 それらの要望を叶えるために、現在の状態を正しく把握する必要が出てきました。 企業は採用したいと思ったときから入職するまでに、なににどれぐらい手間と時間をかけているのか 求職者は就職・転職したいと思ったときから入職するまで、なににどれぐらい手間と時間をかけているのか そのなかから課題の大きさや重要さから、仮説検証すべき領域やフェーズのはなんなのか そのために成果物として作るべきものはなんなのか 現状分析から課題抽出した結果、それらを検証するためにスコープを絞ってMVP(Minimum Viable Product)を作る必要があるという判断をしました。 チームで議論しているときは「契約ってしないとだめなんだっけ?」「人が文章書かないといけないんだっけ?」「なにかモノを作らないといけないんだっけ?」といった、現状や常識に縛られない話も出てきました。もちろん契約や成果物が必要なのはわかってますが、角度を変えて見ることで新しいアプローチが見えたりと非常に有意義だったなと思います。 どのようにプロジェクトを進めるか このMVPでは、不確実性が高い状況で仮説検証を小さく素早く回す必要があったため、アジャイル的なアプローチを取ることにしました。 アジャイルで進めるということは、「いつまでに何ができるのか」を最初から明確に示せない、途中で方向転換する可能性がある、投資対効果の見通しが立ちにくい、といった特性があります。 組織にとっては、計画の不確実性を受け入れることになるため、慎重にならざるを得ない進め方です。 それでも、エス・エム・エスはこうした挑戦を許容してくれる環境です。 「なぜこのアプローチが必要なのか」「何を検証しようとしているのか」といった意義をしっかり説明すれば、会社として変化を受け入れ、任せてくれます。 不確実性の高い状況であっても、納得のいく説明さえできれば前に進める。そういった環境で、やりがいと責任を持ってプロジェクトを進められることを、日々感じています。 まとめ 今回は、ウェルミージョブで取り組んでいるMVP開発の事例を通じて、以下のような実践をご紹介しました。 従事者と事業所の入職までの手間と時間を減らすという課題に対し、現状分析から仮説を立てる 不確実性が高い領域では、スコープを絞ったMVPで検証サイクルを回す アジャイルアプローチを取ることで、計画の不確実性を受け入れながら前に進める こうした取り組みを進める上で大切なのは、「なぜこのアプローチが必要なのか」を説明し、組織の理解を得ることです。 エス・エム・エスでは、不確実性の高い挑戦であっても、その意義をしっかり伝えれば前に進める環境があります。役職や役割に関係なく議論でき、「サービスを通じて社会に貢献したい」という共通の価値観があるからこそ、こうした挑戦ができるのだと感じています。 さいごに エス・エム・エスに入社したのは、昔の同僚が声をかけてくれたのがきっかけでした。もちろん紹介は紹介でしかなくて、面接や面談でしっかりと情報交換をしていったのですが、会う人会う人全員が、立場や役割関係なく「社会のために我々は何をしていくべきか」を軸にお話をしていたのが非常に印象的でした。 弊社が以前から取り組んでいる、少子高齢、人口減少による生産年齢人口の減少という未来と、AIをはじめとした技術革新と、それを享受する社会や人類の情報リテラシーの変化の中で、 我々はなにをどう形にして世の中に価値を提供するのか を考え続けられる会社です。 そんな我々は一緒に働ける仲間を大・大・大募集しています!ここまで読んでくださったみなさんは、多少なりともエス・エム・エスという会社に興味を持っていただけてるはずです。まずは話だけでも聞いてみませんか?以下からご連絡お待ちしています! 最後まで読んでいただきありがとうございました。
こんにちは。2025年6月にエス・エム・エスに入社した柴山です。現在は介護/障害福祉事業者向け経営支援サービス「カイポケ」のリニューアルプロジェクトでQAエンジニアとして働いています。 プライベートでは1歳と4歳の子供を育てるワーキングマザーでもあります。今回は、多くのワーキングマザーが直面する「育児とキャリアの両立」という課題に私自身がどう向き合ってきたか。その「戦い方」と、新たな挑戦の場としてエス・エム・エスを選んだ理由についてお伝えします。 私自身の経験に基づく、かなり生々しい話も含まれますので、あらかじめご容赦いただけますと幸いです。 また、最近は男性育休の取得も増加傾向にあり(弊社でも取得報告は多く、非常に喜ばしいことです)、子育てとキャリアの両立は必ずしも女性に限った課題ではないと認識しています。それでもあえて今回は 女性のキャリアにフォーカス してお伝えできればと考えています。 育児とキャリアの両立に対する課題意識 子育て中の皆さん、仕事と家事と育児、どうですか?うまくいってますか?朝は子供のお世話や保育園の登園でへとへと、日中はなんとか仕事して、夜は寝かしつけや家事を終えてぐったり。残業する体力もないし、勉強会は大体アーカイブ配信を見るのみ……みたいな感じじゃないですか?少なくとも私はそうです。生活リズム、物事の優先度、仕事の向き合い方やキャリアの考え方。子供が生まれる前と後では全てが大きく変わりました。母親になって4年経ちますが、その変化には未だ困惑しています。 その中で、ここ数年私が悩んでいたのは、産休・育休による「キャリアの断絶」そして「マミートラック」でした。 キャリアの断絶 子供を妊娠・出産し、職場復帰するまでの期間は 最短でも7か月 *1 、長ければ2年 *2 に及びます。しかもこれは単純な休職期間の話。実際には妊娠初期の悪阻に始まり、食欲不振、頭痛、眠気、こむら返り、動悸、息切れなど様々な不調が伴います。そんな状態で、通常業務をこなして更にはスキルアップを目指すのは極めて困難です(少なくとも、私にはかなり厳しいものでした)。これは私の体感ですが、妊娠発覚直後からパフォーマンスは落ち始めます。ホルモンバランスの乱れもありますし、正直に言えば「流産が怖い」「禁忌事項が多すぎる」といったストレスも大きいのです。 そのため、職務経歴書上の経験年数と実務が一致しないといった事態も十分に起こります。私自身もエンジニア歴は10年ですが、2回の産育休を挟んでいるため、実務の期間は7〜8年ほどでしょう。同じ経験年数の人と比較したとき「若干スキルが劣るのでは?」と見られる可能性があります。それならば休職中にスキルアップを目指したり、復職後にバリバリ働いてギャップを取り戻そう、と考えるかもしれません。しかし、それもあまり現実的な解決策ではありません。なぜなら、前述の通り妊娠中は著しくパフォーマンスが下がるうえ、子を産んで復職すれば仕事と家庭の両立という正解のない課題が待っているからです。 マミートラック 子供を育てながら働く女性にとって、一度は聞いた単語かもしれません。出産した女性が本人の意欲とは関係なく、昇進から遠いキャリアコースに乗せられてしまう状態を指す言葉です。要するに、子供が生まれる → 短時間勤務や早退遅刻で仕事にかける時間が減る→スキルアップや重要な仕事に取り組めない → キャリアが停滞、あるいは下降する、という流れですね。 パートナーや親族を頼って時間を捻出すれば、このようなマミートラックは回避できるかもしれません。しかし近年共働き核家族化の影響で、自分たちだけで仕事も家庭もまわす必要があります。私もそうです。 特にIT業界は、技術の進化が非常に速いという特性があります。 1年、あるいは数か月で技術トレンドは移り変わり、休職前に使っていた技術がレガシーになることも珍しくありません。常に新しいOSSや設計・開発手法を学び続ける必要があり、近年はAIの発展によってそのスピードはさらに加速しています。 限られた時間の中で通常の業務と並行してスキルをアップデートし続けるのは容易ではありません。 このような要求の高い環境は、「キャリアの断絶」や「マミートラック」という課題をより一層深刻なものにします。 そして、「今の会社を離れることになった時、自分に市場価値はあるのだろうか」「このままITエンジニアを続けられるのだろうか」という、キャリアに対する強い不安に繋がっていくのです。 産休・育休後のキャリアチェンジという選択 この課題にどう向き合うべきか考えた末に、私が選択したのはキャリアチェンジでした。変化の速いIT業界でスキルが陳腐化するリスクと戦うよりも、全く新しい専門性を身につけることで仕事の幅を広げようと考えたのです。 私は現在QAエンジニアですが、それ以前はフロントエンドエンジニアとしてプロダクト開発に関わっていました。一人目の育休から復帰した際、休職による知識のギャップや開発環境の激しい変化に私は強い衝撃を受けました。仕事のスピードについていくだけで精一杯、「このまま最前線で戦い続けるのは難しい」と痛感したのです。そんな中、前職でQAエンジニアというポジションが新設されることになり、開発経験とテスト工程への理解があった私に声がかかりました。 正直、当時は未知の領域でしたが、これは 新たな専門性を築くチャンス だと感じました。特に、今後のテスト自動化などを推進する上では、これまでの 開発経験が大きな強みになる と確信し、キャリアチェンジを決意しました。 この選択によって私はマミートラックに陥ることなく、IT業界で生き抜く新たなスキルを手にしました。しかし、一人QAという環境では、どうしても自分の成長に限界を感じるようになります。ライフステージの変化に左右されず自身のキャリアを実現するためには、継続的にスキルアップできる環境に身を置くことが最善だと考えました。それが、今回の転職を決意した理由です。 とはいえ、転職活動を開始した矢先に妊娠が発覚したため、実際は出産後の育休中に転職活動を再開しました。この辺りの経緯はJaSST nanoでお話ししています。 エス・エム・エスに入社した決め手 子供がいる私にとって、転職活動では仕事内容だけでなく、働く環境も同じくらい重要視しました。いくつかの条件を軸に企業選びを進める中で、特にエス・エム・エスに入社を決めた3つのポイントをご紹介します。 働き方の柔軟性:リモート勤務を前提とした組織づくり 保育園に入園した途端に起こる「保育園の洗礼」、誰しも経験があると思います。保育園入園直後に子供が発熱や下痢症状を起こし、頻繁にお迎えの電話がかかってくる、療養のためしばらく保育園をお休みする、といった状況のことですね。こういった急な呼び出しにもすぐ対応できる、子供を自宅看護しながら最低限仕事ができる、という理由からリモート勤務を希望しました。また将来的な地方移住も視野に入れ、長く働ける環境というのも1つのポイントでした。そのため、地方在住者が所属しているかも条件に加えました。 私が所属するプロダクト推進本部では、リモートワークを基本としながらも、出社するか在宅するかを選択できる体制が整っています。入社初日のオリエンテーションや総会などで出社が必要な場合も、事前に家庭内で調整して参加しています。 組織内には関東圏外の在住者も多く(私の知る限り、北は北海道から南は九州まで)、チーム内にも京都からリモートで働くメンバーがいます。場所が離れていてもチームのコミュニケーションに不都合を感じないのは、オンラインで円滑に連携できる組織づくりがされているからだと感じています。こうした柔軟な環境であれば、将来的に移住といったライフステージの変化にも対応できそうだと感じました。 専門性を高める環境:QAチームの存在 前職においてはQAエンジニアが一人という関係上、QA同士で業務相談ができない、という課題がありました。勉強会の内容をシェアしたり、品質に対する議論をしたり「他のQAチームはどのように工夫しているのだろう?」といった情報交換ができなかったのです。そのため、QAチームが存在すること、具体的には3名以上QAが在籍していて、横断的活動やコミュニケーションの場があることを条件に転職活動をしました。 エス・エム・エスでは、複数のQAエンジニアが所属しており、各プロダクトの品質向上活動を行なっています。同じプロダクトの別チームの様子も聞けるし、別プロダクトのQAエンジニアにお話を伺う機会もあるので、情報共有や交換がとても活発です。 また、組織としても勉強会やカンファレンスの参加を推奨しています。先日行われたJaSST Niigataも、メンバー間で活発な意見交換が行われていました。私は現地参加でしたが、他の方々はオンライン参加でした。いつかチームメンバーと現地参加できることを楽しみにしています。 相互理解と文化:面接で感じたフィット感 転職活動終盤、ありがたいことに2社内定を頂きました。私が希望する上記の条件はどちらも満たしていたので、どう決めようかと相当悩んだのを覚えています。その時に最終的な決め手となったのが、エス・エム・エスのオファー面談における誠実さと熱量、フィット感でした。 エス・エム・エスのオファー面談で印象に残ったのは、自分の強みだけではなく弱みまで伝えられ、それが自分の理解と一致していた(=私に対する解像度が高かった)こと。そして、入社後に活かすべきスキルと期待される活動が、かなり具体的かつ明確に示されたことでした。 そのおかげで入社後のイメージをより強く持つことができ、入社を決めました。 入社後に感じた、子育てと両立しやすい環境 ここからは、実際に入社して4か月で感じた「子育てと両立しやすい環境」についてお伝えします。 カルチャーと周囲の理解 まず、入社して特に重要だと感じたのは、会社のカルチャーです。 私が所属する組織には子育て世代が多いということもありますが、それに関わらず、お互いのプライベートを尊重し、仕事上でサポートし合う文化が根付いています。家族や自身の体調不良に関しても、仕事の調整が非常にやりやすく助かっています。 また、子供の体調不良などで自宅保育しながら勤務せざるを得ない状況もあります。そういった場合にもチームメンバーは業務調整など快くサポートしてくれます。実際私も転職したての頃は何度か子供を保育しながら仕事をしていましたが、ミーティングに子供が映り込んでしまうようなアクシデントも、温かく受け入れてもらえました。 柔軟な勤務を支える制度 私が所属するプロダクト推進本部では、コアタイム(12:00〜16:00)ありのフレックスタイム制度を導入しています。このコアタイムに勤務していれば、始業・終業時間は個人の裁量で柔軟に調整することが可能です。 そのため、朝の時間を活用して8時から業務を始めるメンバーもいれば、午前中に用事を済ませてからコアタイムが始まる12時に合わせて勤務を開始するメンバーもいます(もちろん、月当たりの定められた労働時間を満たすことが前提です)。 私自身もこの制度を活用し、普段は子供を保育園に送った後の9時頃から、お迎えの時間に合わせて18時頃まで勤務しています。もちろん、子供の通院などで日中の勤務が難しい日もあります。そういった場合は、コアタイム以外の時間を調整することで対応しています。 また、時間単位の休暇制度もあり、1時間単位で休暇を取得できます。子供の予防接種や役所での手続きなど、短時間の離席が必要な際にこの制度を活用することで、業務への影響を最小限に抑えつつ家庭の用事にも対応でき非常に助かっています。 これらの制度やカルチャーに助けられながら、仕事と子育てに奮闘している状況です。 仕事と子育てに追われる一日のスケジュール ここでは私のとある平日のスケジュールをご紹介します。出社や子供の通院などがある日は変動しますが、普段は概ねこのような流れで一日が過ぎていきます。 我が家は夫婦共にリモートワーク(旦那はたまに出社)かつ保育園が近所なので、フルタイム勤務でギリギリ家庭を回している状態です。これが1つでも欠けていたら絶対に無理だろうな〜と日々思っています。 06:00 起床・朝の準備 08:30 保育園登園 & 業務開始 12:00 昼食 17:50 業務終了・お迎え 18:30 帰宅・夕食 19:00 お風呂 21:00 寝かしつけ・残りの家事 子供たちがいない間はほぼ勤務時間なので、家事は昼休みや隙間時間にねじ込んでこなしています。やはり家事に手間をかけられないので、食器洗浄機やロボット掃除機、ドラム式洗濯機は必須です……。 特にご飯を作る時間(食材調達から食材管理、献立、調理、後片付け含む)が圧倒的にないので、我が家では つくりおき.jp *3 を活用しています。とてもおいしくて経済的で時短にもなります。でもママの作った料理じゃなくてごめんねっていう謎の罪悪感に駆られるんですよね。これが地味にメンタルに来るんだよなあ〜。とはいえフルタイム勤務しながら夕食を作るのは(私には)絶対に無理です。時間のない中作ったご飯を残されても悲しいしね。 おわりに:ライフステージの変化とキャリア形成 ここまで、産育休と女性のキャリアや仕事と子育ての両立について語ってきました。決して偉そうに語れる立場ではなく、そんなに上手く立ち回れているわけでもない、というのが正直なところです。「子育てを言い訳に仕事を諦めたくない」という気持ちと、「とはいえ仕事に全力投球して家庭を顧みないのは、家族として健全ではないよね」という現実との間で今も毎日のように葛藤しています。 子供がまだ未就学児で保育園に助けられている部分もあるけど、小学生に上がったらどうなるんだろう、学童に行ってもらう?夏休みはどう乗り切ろう?といった先の心配で頭がいっぱいです。まあでも正直なるようにしかならないんだろうな、と最近は割り切るようになりました。子供や家庭に何か大きな変化があった時、会社員を続ける選択ができるよう、少しずつでもキャリアを積み上げていきたいです。 現在はQAエンジニアとして、主にPlaywright(コードベースのE2Eテストツール)を用いたテスト自動化の推進に取り組んでいます。この活動はこれまでの開発経験を大いに活かせる領域です。他にも開発者視点でテストの課題や改善点を見つけ出し、それを解決していくプロセスを通じて、QAエンジニアとしての専門性を高めていけたらと考えています。 私自身、特別要領が良いわけでも体力があるわけでもありません。たぶんどこにでもいる普通のワーキングマザーです。だからこそ、この記事が同じ境遇で働く方々の支えになれたらと願っています。 こうしたライフステージの変化はキャリアを諦める理由ではなく、働き方や自分自身を見つめ直す最高の機会なのかもしれませんね! *1 : 10月ごろに出産し、0歳児クラスに生後5か月で預けるパターン。産前休業が出産予定日の1か月前なので9月に休職、4月に保育園入園と同時に復職する想定。 *2 : 0歳児クラスで入園できなかったパターン。2歳の誕生日前まで育休の延長が可能。 *3 : 数日分の食事を宅配で届けてくれるサービス。おかずのみが冷蔵で届くので、ご飯と汁物さえ用意すれば栄養バランスの整った食卓が実現できて助かっています。おいしいし。忙しい家庭におすすめ!
こんにちは。介護・医療・障害福祉・保育の求人サイト、ウェルミージョブのQAを担当している林です。 ウェルミージョブは、2025年7月にカイゴジョブからリブランディングしてサービス提供を開始しました。 私は先日Kaigi on Rails 2025に参加してきました。私はQAエンジニアでProduction Readyなコードは書けませんが、開発系のカンファレンスに興味があり、今回生まれて初めて参加しました。会場ではセッションを聴講したり自社ブースでの対応をおこないまして、感想としては、控えめに言って すごくすごくよかった です!このブログでは、コードが書けないQAエンジニアの私が、開発系カンファレンスで何を感じ、開発とQAの意外な「共通点」をどう見つけたのか?具体的な学びとともにお伝えします。 自己紹介 QA歴は10数年で、2021年5月から現ウェルミージョブ(当時のカイゴジョブ)の開発チームへ、専属QAの一人目としてJOINしました。当時は人生初の一人目QA・育休明け・初のリモートワーク・コロナ禍における様々な影響などにより多くの困難がありましたが、アジャイルな開発チームの中で、持ち前のコミュニケーション能力と「握ったボールは自分でやり切るor誰かに渡す」の精神で乗り切ってきました。  私の開発系技術スペックはこんなかんじです。 大学はバリバリの文系で、開発系技術とは無縁 新入社員時代、必須受講のC言語研修にて、ポインタで挫折して泣いた(ほんとうに) QAエンジニアとして業務をしながら、2016年に基本情報技術者(FE)に合格。開発系の資格はこれのみ所有 過去には「仕様書がない・触れるシステムもまだない」案件で、ER図からがんばってテスト設計をやり遂げた経験あり SQLやAPIについて積極的には実行しないが、幸いにも年1回程度は触ったり勉強したりする機会に恵まれている アジャイルな開発チームにて日々、開発メンバー同士の会話を横で聞いている。そのため、テーブル・データ・モデル・処理などが大まかにイメージできている なぜ「Kaigi on Rails 2025」へ参加したのか? Kaigi on Railsは、「初学者から上級者までが楽しめるWeb系の技術カンファレンス」をコアコンセプトとした技術的な学びの場であり、多様な人々が交流できるイベントです。 kaigionrails.org エス・エム・エスはKaigi on Rails 2025へGoldスポンサーとして協賛し、スポンサーブースにてウェルミージョブのソースコードを公開しました。 このKaigi on Rails 2025へなぜQAの私が参加したかというと、2つの目的があったからです。 @moro さんの基調講演を聴くため :ウェルミージョブの開発をリードする@moroさんがKeynote Speakerとして登壇して基調講演を務める運びとなり、私もそれを現地で聞きたいと思いました。普段からチーム内に共有されている@moroさんの考えが、多くのエンジニアに響くのを肌で感じたいと思いました。@moroさんが楽しそうな様子で準備しているのを身近で見ていたこともあり、私を含め多くのチームメンバーがワクワクしていました。さらに、開発チームのメンバーから「林さんも一緒に現地で楽しもう」とお誘いがあったことも参加の後押しになりました。 開発エンジニアの考えや課題感を知るため : セッションの視聴やブースでの交流によって開発エンジニアのことが知れると、それが開発とQAの相互理解を深める土台となって、より強い連携を築けるのではという期待がありました。   参加してわかった!セッションからの学び 特に印象に残った2つのセッションについてご紹介します。  1. 基調講演:dynamic! speakerdeck.com 要約 なぜ動的/dynamicにしたいのか :この発表では「動的/dynamic」とは「継続して変化し続けること」を指します。不確実性の高いプロダクト開発において「初めから正解を選ぶ」のは難しいため、一度に正解を目指すのではなく、良い方向を目指して少しずつ変わることを大事にしたいです。そしてそれは、楽しいことです。 フィードバックから得られる価値 :「最もシンプルで、うまくいく」ものは何かを見極めて、作ってみて動かして、フィードバックをもとに変化させ続けます。動かすことで、開発者だけでなくデザイナーやQAエンジニアなどがそれぞれの職能を発揮できます。企画者も、事業活用の計画を判断できたり見直せたり、ドキュメントではなく動くソフトウェアをベースにコミュニケーションを円滑におこなえます。 あらゆるものを動的に習熟していく :見極めたり、一度作ったものを変えるのは簡単ではありません。そのため、コード・プロダクト・プロセス・チーム・自分自身も含めてあらゆるものを少しずつ動的に習熟していきます(※1)。変わることを楽しみましょう! (※1) 所感 現地で聞けて良かった! :会場では多くの賛同のリアクションや拍手が起こり「良いプロダクトを作りたい」と願う人々の心が一つになったような感動を覚えました。講演の内容は、ウェルミージョブ開発の中で@moroさんが日々体現されていることをそのまま資料に落としたようなものでした。改めて、魅力あるプラクティスに日々トライできることへの喜びを感じました。 変化に対応するQAの課題感と、それを解決する可能性 :QAエンジニアとして日々変化についていくのは容易でなく、高頻度に発生する追加のテスト設計・実施を軽やかにおこなうための工夫が必要です。ここで私は「忍者式テスト」を思い出しました。( 忍者式テストの講演資料はこちら )忍者式テストとは深谷美和氏・関将俊氏によって提唱されるプラクティスで、反復開発の中で「増分だけでなく、プロダクト全体を都度テストする」というものです。忍者式テストでは、開発者もテストを実行してプロダクトから学び、修正や改善を積極的にできるようになるメリットがあるそうです。私は、忍者式テストへの挑戦も含めて、今後さらに軽やかに変化対応できるようトライしていきたいです。 不安を軽減するコミュニケーションの重要性 :動的に開発が進むことにより、例えば企画者は「最終決定がいつ頃になるのか見通せない」と不安を覚えるかもしれません。そんな場面では、ステークホルダーが必要とするものが何かを知り、より相互にコミュニケーションをとり、必要なドキュメントはシンプルに残すなどして困り事や不安を取り去ることが大事になりそうです。 変わるのは、楽しいこと。変えられるのは、ハッピーなこと! :課題もありますが、不確実性の高いプロダクト開発において動的に物事を進めることのメリットは多大です。私もQAエンジニアとしてあらゆる変化を楽しみながら、よりよいプロダクト開発に尽力したいです!    2. Railsによる人工的「設計」入門 speakerdeck.com 要約 設計を体得する・教えることの課題感 :「設計」を体得したり教えるのは難しいことです。一方で、今後はAIが普及して設計の機会が減り「場数を踏んで体得する・させる」のが難しくなりそうです。さらに、AIを使いこなすためには設計できる能力が重要です。そのため、設計を教える人が「設計を教えられる」ようになっている必要があります。  手順から逆算して考えるアプローチ :設計ができない人は「コードを書くとシステムができる」と考えがちですが、設計とはコードとは違って、抽象的なレベルで考える活動です。「コードを意識しないで設計する」ように導くのに「システムができる手順から逆算して考える(※2)」というアプローチが有効でした。まず「完成したシステム」を思い浮かべ、もっとも実現したい本質的な事柄を「ゴール」と定めて、その実現に必要なことを段階的に考えるというステップで、抽象的なレベルで設計していきます。  (※2) 「名前付け」の重要性 :抽象化する作業において「名前を付ける」ことは重要です。長い概念を適当に省略してしまうと、本質から外れたところにミスリードされてしまいます。名前付けに苦手感がある人も、勇気を出して、本質を表す名前を自分の裁量でつけましょう。 所感 「抽象化する能力」の課題感はQAも同様 :QAにとっても抽象化する能力は重要です。例えばテスト分析という過程で「何をテストするか」を定義する際、抽象化が苦手な人はテストケースなどの細かい粒度で考えてしまってテスト全体を捉えられません。さらに、体得する過程における課題感も開発と同様、AIの普及で体得する機会が減りそうです。そのため、QAにとっても「人工的に抽象化を体得させるメソッド」はとても役に立ちそうです。 「逆算して全体像を考える手法」はQAにも適用可能 :先述した「システムができる手順から逆算して考える(※2)」の文脈で、私は、西康晴氏によって提唱されたVSTeP(「何をテストすべきか」という観点を図で整理し、抜け漏れなく効率的にテストを設計するための手法)( VSTePの講演資料はこちら )を思い出しました。VSTePでは、「テスト要求分析」「テストアーキテクチャ設計(コンテナ設計・フレーム設計)」などの工程を経てテスト全体をアーキテクトします。このうちの「テスト要求分析」の際にテスト観点(テストすべき要素)を整理するにあたり、逆算の手法を適用してみると、以下のステップで進められそうです。 「完成したシステム全体」を思い浮かべる 中核的な「実現したいこと」にフォーカスする 「実現したいこと」に対して「ユーザーに使ってもらって大丈夫、となれるには何の確認が必要か?」を順々に考えていって、全部考えた状態にする QAも「勇気を出して名前付けをしよう」 :名前付けの重要性や課題感もQAに共通するところだと感じます。名前付けがしっくりこないときは「大事なものの見極め」がうまくいっていないサインですし、間違っていればチームメンバーがそれを教えてくれ、より正しく抽象化ができるようになります。「勇気を出して、本質を表す名前を、自分の裁量でつけよう」というメッセージを、多くのQAエンジニアにも届けたいです。  開発・QAが類似課題を共有して解決できる可能性 :開発・QAの類似課題について、開発・QA両者が情報や知恵を出し合えると、よりよい解決の方向性が見出せると思います。さらに、VSTePの講演資料の「テスト開発プロセスの基本的考え方(※3)」において「テストケースを開発成果物と捉え、ソフトウェア開発プロセスとソフトウェアテスト開発プロセスを対応させよう」とあるように、開発とQAは様々なプロセスでリンクしています。設計のタイミングだけでなく、多くのプロセスにおける開発・QAの連携が期待できそうです。 (※3)出典: VSTePによるソフトウェアテストの開発 ブース対応で感じたQAの可能性 今回はスポンサーブースに立ち、来訪者への対応をおこなう機会もありました。具体的な実装に関する受け答えができないので不安でしたが、いざやってみると、QAならではの強みを発揮できたと感じています。 プロダクトの「体験」を提供 :テスト用端末を使って来場者に実際にプロダクトを触ってもらうことで、コードだけでは伝わらない魅力を伝えることができました。 多様な情報提供 :テックブログやウェルミーマガジンなど、プロダクト以外の情報も提供することで、来場者との会話を広げることができました。 QAの魅力を発信 :開発チームの中でQAがアジャイルに活躍していることを開発メンバーからも話してもらえて、QAの存在や魅力がより伝わったかと思います。また、ウェルミージョブの開発チームが「異なる業種間のコミュニケーションが良好なチーム」であるという魅力が発信できた点も有意義でした。さらに、来訪者の方にはQAの話に興味を示してくれる方もおり、QAからの情報発信の場として開発系カンファレンスは有効な場所となる可能性を感じました。  たくさんの人との出会い・関わり 2日間のセッション聴講やスポンサーブース対応を通じて多くの方々と関わることができました。開発業務が主担当ではない私の参加を歓迎していただき、また、QAという領域にも興味を持っていただくことができました。いずれの方も、カンファレンスへの参加や交流を心から楽しんでいる姿がとても印象的でした。 運営メンバー ブース対応を共におこなった開発チームメンバー ブースの来訪者 他社ブースの方、本屋さんやコーヒーなどを提供してくださった方 現在一緒に業務している方、過去に業務でご一緒した方 開発チームメンバーの方の紹介があって出会えた方… また、私が身に着けているエス・エム・エスのロゴを見た多くの方から「○○さんの会社の」と声をかけていただきました。これらの出会いは、エス・エム・エスで活躍する人のつながりによって生まれた貴重なもので、私もそのつながりを大事に紡いでいきたいと思います。  一方で、普段とは違って多くの人と関わる場面のため、意識して気を付けようと思ったことがあります。それは「人を尊重すること」です。 安心して気持ちよく過ごせるために :アンチハラスメントポリシーはもちろん遵守します。さらに、そこからもう一歩踏み込んで「お互いが気持ちよく安心して過ごせるためのマナー」も大事にしたいと思いました。 楽しいからこそ要注意! :楽しさから気が緩んでしまったり、一体感や高揚感から「このくらいの言動は大丈夫だろう」と判断を誤ってしまうかもしれません。「普段から私は気を付けているから大丈夫」と過信せず、一呼吸おいて判断することが大事だと思いました。 尊重する相手は「すべての人」 :尊重する相手は、お客様にあたる立場の方・運営メンバー・自社のチームメンバー・友人知人・会場や廊下などでたまたま物理的に距離が近づいた人と多岐に渡ります。そして(私の個人的な感覚かもしれませんが)「自分自身」もその対象に入れると、自然に「すべての人を尊重する」が実行できるような気がします。そのため、自分自身も大事にしたいなと思いました。 まとめ 今回の開発系カンファレンス参加を通じて、開発エンジニアとQAエンジニアは「 よりよいプロダクトを作りたい 」という同じ気持ちを強く持っていることを再確認しました。 「 dynamicにシンプルに 」プロダクト開発を進めることは容易ではありませんが、関わる人と相互理解のもとコミュニケーションをとって 楽しんで 実現していけると確信しています。 QAが開発系のカンファレンスに参加する意義は、自身のスキルアップだけでなく、 QAの存在や意義を広く知ってもらうこと や 開発・QAの相互理解からの連携強化 にも繋がります。開発エンジニアのみなさんにも、ぜひ品質保証に関するカンファレンスに参加していただけたら嬉しいです! 「コードが書けないQAが開発系カンファレンスに参加する」、2回目のチャレンジを目指して現在鋭意調整中です!  お知らせ スポンサーブースで大好評だった ウェルミージョブのソースコード公開 は、カジュアル面談にておこなうことも可能です。「カンファレンスへの参加が叶わなかった」「時間がなくてブースに行けなかった」「ブースでコードを見てみたが、もっと見たい」という方がいらっしゃいましたら、ぜひ、カジュアル面談しましょう! @moroをはじめとしたウェルミージョブの開発メンバーが(ご要望あればQAメンバーも)、みなさんとお話できるのを楽しみにしています。  
はじめに こんにちは。プロダクト開発部の髙木です。先日、弊社のブログでテックブログの入稿システムについて紹介しました。このシステムは、ブログ記事の作成から投稿まで、これまで手作業で行っていた工程を大幅に自動化し、記事執筆に集中できる環境を提供するものです。 tech.bm-sms.co.jp このシステムを運用している中で、サムネイル画像生成機能において、一部の文字が太字にならないという問題が発覚しました。調査・修正を行う過程で、技術的な問題を解決するだけでなく、チーム開発において非常に重要な「どうしてこうしたんだろう?」を考えるきっかけを得られました。 問題の発見と原因の特定 サムネイルの文字が太字にならない 今回問題となったのは「絆」という漢字でした。通常、サムネイル作成システムによって生成される画像では、すべての文字が統一された太字フォントで表示されるはずです。しかし、ある記事のサムネイルを確認したところ、「絆」という文字だけが細字で表示され、他の文字と視覚的に異なる状態になっていました。 この現象を詳しく調査したところ、リポジトリに内包していたフォントファイルにその文字が含まれていないことが判明しました。システムは存在しない文字を代替フォントで表示していたため、視覚的な違いが生じていました。技術的な挙動の原因は特定できましたが、そもそもなぜそのような問題が起きる状態になっていたのか、その背景や経緯については不明でした。 最初のアプローチ:Google Fontからのダウンロード 問題の根本的な解決を図るため、まずはGoogle FontsからNoto Sans JPのフォントファイルをダウンロードし、既存のフォントファイルと置き換えることにしました。この新しいフォントファイルを使用してサムネイル生成をテストしたところ、期待通り「絆」という文字も正しく太字で表示されるようになりました。 問題が解決したと安心して、この修正をコミットしてリモートリポジトリにプッシュしようとしたところ、予想外のエラーが発生しました。これまでそのような大きなファイルを扱った経験がなかったため、Gitでは約1MBを超えるファイルをプッシュしようとするとサイズ制限によってエラーが出ることを、このときに初めて知りました。 サブセット化という解決策 バッファサイズ変更よりも良い方法 最初は、Gitの設定でバッファサイズを上げて大きなファイルをプッシュできるようにすることを検討しました。しかし、調べている過程で、フォントファイルのサブセット化という、より根本的で効率的な解決手法があることを知りました。 サブセット化とは、フォントファイルから実際に使用しない文字を排除して、必要最小限の文字セットのみを含むフォントファイルを作成する技術です。今回のブログのサムネイル生成という用途を考えると、日本語のすべての文字を含む必要はありません。そのため、ファイルサイズを大幅に削減できるサブセット化の方針の方が、長期的に見てもメンテナンス性やパフォーマンスの観点から適切だと判断しました。 「絆」が含まれなかった理由 今回使用していたフォントファイルに「絆」が含まれなかった理由を考えてみました。結構身近に感じていた漢字でしたが、この漢字が常用漢字に含まれないことがわかりました。たしかに子ども頃に習った記憶はない気がする…。 今後も常用漢字以外の漢字をタイトルに使用する可能性があります。そのため、ある程度使用される可能性のあるフォントはサブセット化する際に含めておく方が安全であること考えました。 常用漢字以外の文字の選定 使用される傾向のある常用漢字以外の漢字は、文化庁の資料から抽出しました。 常用漢字表の字体・字形に関する指針(報告)について(報告) | 文化庁 こういったPDFから抽出するコードをさっと作ってくれるのは、LLMの良いところだなと改めて思いました。 結果と成果 それらの文字を含めたフォントファイルを作成したところ、1MB未満となりコミット、プッシュすることができました。 先駆者の行動をリスペクトする 「なぜそうしたのか」を理解する 記事のタイトルに戻りますが、おそらくこの問題は、このシステムを担当した方も全く同じことを考えたのだと思います。フォントファイルを入れてみたら1MBを超えていて、ファイルサイズを減らすために常用漢字のみを入れたフォントファイルを作成したのだと思います。 想像力と知識の不足を認める 日常的に「どうしてそうしなかったんだろう」と思うことは多いですが、自分が同じ立場に立つと「だからこうしたんだな」となることが多いです。それは自分の想像力が足りていないこともありますが、知識が足りていなくてそのような結論になってしまうことが多いと感じています。 先駆者の行動はリスペクトを持って分析し、その上で「こうした方が良さそう」にもっていくことは、同じチームとして活動していく仲間として大切な考え方です。技術的な問題を解決することは重要ですが、その過程で過去の意思決定を否定するのではなく、理解し、その上で改善を提案することが建設的だと考えています。 おわりに 今回のフォントファイルのサブセット化を通じて、技術的な問題解決だけでなく、チーム開発において重要な視点について改めて見直す良いきっかけになりました。「絆」という漢字にぴったりのテーマだったということもあり書いてみました。 自分の知識が深まれば深まるほど、自分の考えが適切であると考えることが増えていくと思います(その考えが間違っていることもたくさんありますが…)。そのような状態でも、先駆者の行動の理由を理解し、リスペクトを持って改善を進めることは、自分の知識も深めつつ良いチームになっていくうえで必要なことだと改めて思いました。自分だけの話ではなく、一緒に働いている人とやりやすく仕事をしていくうえで大切にしていこうと思います。
はじめに こんにちは!カイポケのリニューアルプロジェクトを担当しているエンジニアのNobです。 普段はWebのフロントエンドが中心ですが、最近はモブプロをとおしてバックエンドのタスクにもチャレンジさせてもらっています。 プライベートでは2歳になったばかりの息子の子育てに奮闘中です。最近は話せる言葉が増えて少し会話が成り立つようになってきたり、遠くへの外出でも泣かなくなってきました。子育ては大変ですが、それ以上に子供からたくさんの笑顔と幸福感をもらっています。 さて、今回はESLintに追加されたMultithread Lintingについて、私が携わっているプロジェクトのCIへの導入を検討したので共有します! Multithread Linting 機能の概要 ESLint v9.34.0で追加されたこの機能は、その名のとおりESLintによるチェック処理を並行して実行することによって高速化するものです。リリースとともに 公開された Blog によると、1.3倍から3倍ほど高速化した例があるようです。大規模なコードベースで開発している我々としても高速化が期待できそうなので試してみることにしました。 concurrency オプションの設定値 concurrencyに指定可能な値は以下のいずれかです。 正の整数: 最大のスレッド数。任意の数を指定。 auto : CPUのコア数と対象ファイル数に基づいてESLintに並列数を決定させる。 off : Multithread Linting機能を無効にする。デフォルト。 auto がうまく機能しそうであれば、実行環境に合わせて値の調整をしなくて済むので手間が省けそうです。なので、まずは auto から試してみることにしましょう。 初回ベンチマーク: off vs auto 現在の私の開発端末のスペックは以下です。 MacBook Pro: 14インチ、 Nov 2024 CPU: Apple M4 Max メモリ: 64GB この端末で現在私が開発に携わっているプロジェクトを対象に、どのくらい処理速度に変化があるのか見てみましょう。まずはESLintの処理速度の変化を検証したいので、 ESLintのキャッシュを利用しない状態で比較してみます。 ベンチマークには hyperfine というコマンドラインベンチマークツールを使用します。 hyperfine --warmup 1 --runs 3 -L concurrency off,auto " pnpm exec eslint --concurrency {concurrency} './**/*.{ts,tsx,graphql}' " Benchmark 1: pnpm exec eslint --concurrency off ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 62 . 363 s ± 0 . 257 s [ User: 74 . 000 s, System: 10 . 615 s ] Range ( min … max ) : 62 . 110 s … 62 . 624 s 3 runs Benchmark 2: pnpm exec eslint --concurrency auto ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 76 . 222 s ± 1 . 714 s [ User: 262 . 973 s, System: 138 . 288 s ] Range ( min … max ) : 74 . 245 s … 77 . 297 s 3 runs Summary pnpm exec eslint --concurrency off ' ./**/*.{ts,tsx,graphql} ' ran 1 . 22 ± 0 . 03 times faster than pnpm exec eslint --concurrency auto ' ./**/*.{ts,tsx,graphql} ' 試した結果、期待とは違って --concurrency auto を指定した場合の方が1.22倍時間がかかるようになってしまいました。なぜこのような結果になってしまうのか少し調べてみましょう。 auto モードの並列数決定ロジック まずは --concurrency auto を指定した場合、並列数がどのような処理で決定されるのか調べてみます。 concurrency というキーワードでgrepしてESLintのコードを眺めてみると、どうやら このあたりの処理 で判断しているようです。 case "auto" : { workerCount = Math . min ( availableParallelism() >> 1 , Math . ceil (fileCount / AUTO_FILES_PER_WORKER), ); break ; 周辺コードも含めて少し噛み砕いて見ていくと availableParallelism() >> 1 この availableParallelism() はNode.jsの標準ライブラリの os.availableParallelism() であり、その実体は libuv の uv_available_parallelism() 。OSやCPUによる細かな違いはあるものの、シンプルに言えばプロセスが利用可能なCPUのコア数を返す。 availableParallelism() の結果を1ビット右にシフト(2で割って小数を切り捨て)した値となる。 Math.ceil(fileCount / AUTO_FILES_PER_WORKER) fileCount は対象ファイル数。 AUTO_FILES_PER_WORKER は 35 という定数 。 この値はヒューリスティックな値であり、将来的により適切な値や算出処理に改善される可能性がある。 のように読みとることができます。最終的にはそれぞれの値のより小さい方が並列数として使用されることになります。 これを思い切って単純にすると Math.min(CPU のコア数の半数, ファイル数 / 35) となります。 ではここで ファイル数 / 35 が実際にどのくらいの値になるのか考えてみましょう。 100 / 35 => 2.8… 300 / 35 => 8.5… 500 / 35 => 14.2… のようになり、この値の比較対象がCPUのコア数の半数であることを考慮すると、対象ファイルが500以上あるような比較的大規模なプロジェクトではCPUのコア数の半数が並列数になると考えることができます。 検証端末での並列数計算結果 前述のとおり、並列数の算出にはCPUのコア数と対象のファイル数が関係してくるのでした。今回検証に使っているプロジェクトには4,000ファイル以上が存在しています。対象ファイル数が十分に多いため、並列数はCPUのコア数で決まると考えることができそうです。 検証に使っている開発端末のCPUはApple M4 Maxであり、この環境で availableParallelism() が返す値は16です。 node -p " require('node:os').availableParallelism() " 16 この値を2で割った値、つまり8が並列数として利用されることになります。実際に並列数として使用された値はESLintの実行時に --debug オプションを指定することで出力されるログからも確認することができます。 eslint:eslint Linting using 8 worker thread ( s ) . ここでApple M4 Maxのコアの内訳を見てみましょう。 12個がPerformanceコアで4個がEfficiencyコアです。 Performanceコアは高いクロック周波数で動作するCPU集約的なタスクが向いているコアで、 Efficiencyコアは低消費電力で動作する電力消費効率を重視したコアです。 一方Node.jsが利用しているlibuvの uv_available_parallelism() ではこれらのコアの違いを知ることはできません。 16個のうちの4個が他のコアよりも性能が低いことを考慮すると、 8という並列数は実際のスペックよりも高い値なのかもしれない、という仮説をたてることができます。 最適な並列数の探索 それでは実際に8以下の並列数で改めて検証してみましょう。 hyperfine --runs 1 -L concurrency off, 2 , 3 , 4 , 5 , 6 , 7 ,auto " pnpm exec eslint --concurrency {concurrency} './**/*.{ts,tsx,graphql}' " Benchmark 1: pnpm exec eslint --concurrency off ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 64 . 260 s [ User: 75 . 702 s, System: 11 . 435 s ] Benchmark 2: pnpm exec eslint --concurrency 2 ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 51 . 809 s [ User: 108 . 378 s, System: 22 . 637 s ] Benchmark 3: pnpm exec eslint --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 48 . 950 s [ User: 135 . 421 s, System: 35 . 065 s ] Benchmark 4: pnpm exec eslint --concurrency 4 ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 49 . 328 s [ User: 163 . 220 s, System: 50 . 156 s ] Benchmark 5: pnpm exec eslint --concurrency 5 ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 52 . 281 s [ User: 187 . 664 s, System: 67 . 241 s ] Benchmark 6: pnpm exec eslint --concurrency 6 ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 59 . 303 s [ User: 216 . 758 s, System: 91 . 124 s ] Benchmark 7: pnpm exec eslint --concurrency 7 ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 67 . 345 s [ User: 236 . 109 s, System: 113 . 020 s ] Benchmark 8: pnpm exec eslint --concurrency auto ' ./**/*.{ts,tsx,graphql} ' Time ( abs ≡ ) : 72 . 838 s [ User: 263 . 605 s, System: 133 . 785 s ] Summary pnpm exec eslint --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' ran 1 . 01 times faster than pnpm exec eslint --concurrency 4 ' ./**/*.{ts,tsx,graphql} ' 1 . 06 times faster than pnpm exec eslint --concurrency 2 ' ./**/*.{ts,tsx,graphql} ' 1 . 07 times faster than pnpm exec eslint --concurrency 5 ' ./**/*.{ts,tsx,graphql} ' 1 . 21 times faster than pnpm exec eslint --concurrency 6 ' ./**/*.{ts,tsx,graphql} ' 1 . 31 times faster than pnpm exec eslint --concurrency off ' ./**/*.{ts,tsx,graphql} ' 1 . 38 times faster than pnpm exec eslint --concurrency 7 ' ./**/*.{ts,tsx,graphql} ' 1 . 49 times faster than pnpm exec eslint --concurrency auto ' ./**/*.{ts,tsx,graphql} ' どうやら私の端末では明示的に --concurrency 3 を指定することで off の場合よりも1.31倍、 auto の場合よりも1.49倍高速なようです。 concurrency auto を指定すると遅くなってしまうものの、適切な並列数を明示的に指定することで良いパフォーマンスを得ることができそうです。 キャッシュ有効時の性能比較 これまではESLintのキャッシュが無効な状態で検証をしてきました。次はESLintのキャッシュが有効な状態はどのような結果になるか試してみます。 hyperfine --warmup 1 --runs 3 -L concurrency off, 3 " pnpm exec eslint --cache --concurrency {concurrency} './**/*.{ts,tsx,graphql}' " Benchmark 1: pnpm exec eslint --cache --concurrency off ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 2 . 516 s ± 0 . 044 s [ User: 2 . 006 s, System: 0 . 578 s ] Range ( min … max ) : 2 . 470 s … 2 . 557 s 3 runs Benchmark 2: pnpm exec eslint --cache --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 4 . 574 s ± 0 . 037 s [ User: 6 . 710 s, System: 2 . 061 s ] Range ( min … max ) : 4 . 540 s … 4 . 614 s 3 runs Summary pnpm exec eslint --cache --concurrency off ' ./**/*.{ts,tsx,graphql} ' ran 1 . 82 ± 0 . 04 times faster than pnpm exec eslint --cache --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' 今回の検証ではすべてのファイルに対するキャッシュが有効な状態で試しているので極端な例ではありますが、この場合は直列で実行したほうが良い結果を得ることができました。 ここまでの整理のために、同じオプションに加えてキャッシュが無効な場合も含めて比較してみましょう。 hyperfine --warmup 1 --runs 3 -L cache --cache,--no-cache -L concurrency off, 3 " pnpm exec eslint {cache} --concurrency {concurrency} './**/*.{ts,tsx,graphql}' " Benchmark 1: pnpm exec eslint --cache --concurrency off ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 2 . 417 s ± 0 . 026 s [ User: 1 . 886 s, System: 0 . 534 s ] Range ( min … max ) : 2 . 391 s … 2 . 442 s 3 runs Benchmark 2: pnpm exec eslint --cache --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 4 . 508 s ± 0 . 031 s [ User: 6 . 682 s, System: 2 . 051 s ] Range ( min … max ) : 4 . 473 s … 4 . 530 s 3 runs Benchmark 3: pnpm exec eslint --no-cache --concurrency off ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 59 . 652 s ± 0 . 536 s [ User: 73 . 527 s, System: 10 . 505 s ] Range ( min … max ) : 59 . 221 s … 60 . 253 s 3 runs Benchmark 4: pnpm exec eslint --no-cache --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' Time ( mean ± σ ) : 49 . 708 s ± 0 . 678 s [ User: 134 . 778 s, System: 34 . 085 s ] Range ( min … max ) : 48 . 982 s … 50 . 323 s 3 runs Summary pnpm exec eslint --cache --concurrency off ' ./**/*.{ts,tsx,graphql} ' ran 1 . 86 ± 0 . 02 times faster than pnpm exec eslint --cache --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' 20 . 56 ± 0 . 35 times faster than pnpm exec eslint --no-cache --concurrency 3 ' ./**/*.{ts,tsx,graphql} ' 24 . 68 ± 0 . 34 times faster than pnpm exec eslint --no-cache --concurrency off ' ./**/*.{ts,tsx,graphql} ' この結果から、今回の環境では キャッシュが有効なら直列のほうが速い キャッシュが無効なら並列のほうが速い ということが言えそうです。 CI 環境への適用判断 このプロジェクトではCIでESLintを実行しているので、最後にCIでESLintの concurrency オプションを追加するべきか検討してみます。 前提として、このプロジェクトはTurborepoが導入されています。Turborepoは複数のパッケージからなるモノレポにおいて、ビルドやテストなどのタスクを効率的に実行するツールです。修正したファイルの範囲によりますが、このプロジェクトは最大で9つのパッケージに対してESLintが実行されることになります。Turborepoでそれぞれのパッケージへのコマンドを並列実行することになるため、 ESLintの concurrency オプションを使うと過剰な並列数になってしまい、良いパフォーマンスを得られない可能性がありそうです。 実際に試してみましょう。以下ではturboコマンドを経由してfmtコマンドを実行していますが、これは概ね eslint --cache --fix './**/*.{ts,tsx,graphql}' であると思っていただいて構いません。 hyperfine --warmup 1 --runs 3 -L concurrency off, 2 , 3 " pnpm exec turbo run --cache local:w,remote:w fmt -- --concurrency {concurrency} " Benchmark 1: pnpm exec turbo run --cache local:w,remote:w fmt -- --concurrency off Time ( mean ± σ ) : 4 . 561 s ± 0 . 290 s [ User: 2 . 431 s, System: 0 . 870 s ] Range ( min … max ) : 4 . 376 s … 4 . 895 s 3 runs Benchmark 2: pnpm exec turbo run --cache local:w,remote:w fmt -- --concurrency 2 Time ( mean ± σ ) : 6 . 291 s ± 0 . 075 s [ User: 5 . 689 s, System: 1 . 793 s ] Range ( min … max ) : 6 . 208 s … 6 . 353 s 3 runs Benchmark 3: pnpm exec turbo run --cache local:w,remote:w fmt -- --concurrency 3 Time ( mean ± σ ) : 6 . 322 s ± 0 . 012 s [ User: 7 . 296 s, System: 2 . 287 s ] Range ( min … max ) : 6 . 315 s … 6 . 335 s 3 runs Summary pnpm exec turbo run --cache local:w,remote:w fmt -- --concurrency off ran 1 . 38 ± 0 . 09 times faster than pnpm exec turbo run --cache local:w,remote:w fmt -- --concurrency 2 1 . 39 ± 0 . 09 times faster than pnpm exec turbo run --cache local:w,remote:w fmt -- --concurrency 3 やはり直列で実行したほうがより良いパフォーマンスを得ることができそうです。 これらの処理はGitHub ActionsでGitHubのPull-Requestに対して実行されるようにしていますが、ほとんどのPull-Requestでは一度に大量のファイルを修正することはありません。つまり多くのケースではESLintのキャッシュは大多数のファイルで有効な状態であると考えることができます。 またこのワークフローはUbuntuの4コアで実行するようにしていますが、コア数が少ないためさらなる並列化によってより良いパフォーマンスが得られる見込みは薄そうです。 実際にこのワークフローでベンチマークした結果が以下です。 hyperfine --warmup 1 --runs 3 -L concurrency off, 2 , 3 , 4 ,auto " pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency {concurrency} " Benchmark 1: pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency off Time ( mean ± σ ) : 13 . 241 s ± 0 . 038 s [ User: 41 . 594 s, System: 5 . 830 s ] Range ( min … max ) : 13 . 204 s … 13 . 280 s 3 runs Benchmark 2: pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency 2 Time ( mean ± σ ) : 31 . 019 s ± 0 . 075 s [ User: 104 . 797 s, System: 13 . 536 s ] Range ( min … max ) : 30 . 954 s … 31 . 102 s 3 runs Benchmark 3: pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency 3 Time ( mean ± σ ) : 39 . 606 s ± 0 . 037 s [ User: 136 . 718 s, System: 17 . 224 s ] Range ( min … max ) : 39 . 568 s … 39 . 643 s 3 runs Benchmark 4: pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency 4 Time ( mean ± σ ) : 48 . 413 s ± 0 . 007 s [ User: 169 . 105 s, System: 21 . 288 s ] Range ( min … max ) : 48 . 406 s … 48 . 420 s 3 runs Benchmark 5: pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency auto Time ( mean ± σ ) : 27 . 108 s ± 0 . 056 s [ User: 91 . 045 s, System: 11 . 620 s ] Range ( min … max ) : 27 . 063 s … 27 . 170 s 3 runs Summary pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency off ran 2 . 05 ± 0 . 01 times faster than pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency auto 2 . 34 ± 0 . 01 times faster than pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency 2 2 . 99 ± 0 . 01 times faster than pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency 3 3 . 66 ± 0 . 01 times faster than pnpm exec turbo run --cache local:w,remote:w fmt -- --cache-strategy content --concurrency 4 どうやらこのプロジェクトのESLintには concurrency オプションは追加せず、Turborepoによる並列化のみに留めたほうがよさそうです。 まとめ 以上、 ESLintのMultithread Lintingの導入を検討する際に検証したことでした! 今回検証したプロジェクトのCIには concurrency オプションの追加は見送りましたが、一定の条件下であれば concurrency オプションを使うことでESLintの処理を高速化することができます。しかしその効果は、対象のファイル数、実行環境、キャッシュの有無などによって大きく異なります。導入する前に対象の環境や用途に合うか検証することをオススメします。 他にもチーム内ではESLintの一部のルールを oxlint に置き換えて高速化を試みる動きもあります。良い結果が出てより高速なCI環境が手に入るといいですね! それでは!
はじめに こんにちは、カイポケのリニューアルプロジェクトを担当しているエンジニアの菅原です。2023年12月に入社し、現在はフロントエンドエンジニアとして機能開発を行っています。 最近、Claude CodeやGitHub CopilotなどのAIエージェントが注目されており、弊社でも活発にAIエージェントを活用した開発が行われております。 私が所属しているチームでも、AI活用の取り組みの一環として、 フロントエンドの実装自動化 に挑戦しました。具体的には、二週間のスプリント期間内で実施するすべてのフロントエンドタスクを、AIエージェントによる自動実装で完成させることを目標とした実験を行いました。 結論から申し上げると、完全な自動化には至らなかったものの、適切な仕組みを整備することで実装プロセスの大幅な効率化を実現することができました。 本記事では、この取り組みを通じて得られた知見と課題、そしてAIエージェントによる実装自動化の現実的な可能性について紹介させていただきます。 取り組みのモチベーション カイポケのリニューアルプロジェクトでは、開発手法としてLeSS(Large Scale Scrum:大規模スクラム)を取り入れており、隔週でスプリントを回しています。LeSSのイベントである、リファインメントを通じて、複数チームに跨ったPBI(ブロダクトバックログアイテム)の分割や曖昧な要求を詳細化することで、スプリント活動中にチームが担当するPBIの不確実要素が下がった状態を実現できています。 また、スプリント期間中もチーム内でモブプログラミングや実例マッピングといった手法を活用して、チームが担当するPBIの要求をより詳細化していき、SBI(スプリントバックログアイテム)というPBIを完了させるために取り組む必要があるタスクのリストに分割しています。スクラムのプラクティスの1つとして、SBIを1日以内に終わる単位で分割することが推奨されており、開発者が実装するタイミングでは仕様が明確になっているため、スムーズに開発できるケースが多くなっています。 このような状況の中で、私はAIエージェントを活用しつつ日々の開発に取り組んでいましたが、要求が明確なため実装後に期待するアウトプットのイメージが持ちやすく、ある程度はAIエージェントに実装を任せても十分な品質のコードを出力できていると感じていました。 そのため、弊プロジェクトで採用しているLeSSによるPBIの不確実性を下げる取り組みと、AIエージェントによる自動実装には強い親和性があるという仮説を持ちました。そこで思い切って、私が担当する一スプリント内のすべてのタスクをAIエージェントにより実装させることで、 実装をどこまで自動化できるか という挑戦を行うことにしました。 LeSS導入時の経緯は過去記事をご参照ください。 自動化の概念図 今回の取り組みでは、スプリント期間中のすべての開発プロセスを自動化するのではなく、初期の実装とPRレビューの指摘事項への修正を対象に自動化することとしました。 自動化対象のイメージは以下の概念図を参照してください。 取り組み内容 1. 設計ドキュメントからAIエージェントがdraft PRを自動作成 まず、AIエージェントによる実装自動化の第一歩として、FigmaのコンポーネントURLと「このコンポーネントを実装して」のような簡潔な指示を出して、AIエージェントに実装を任せてみることから始めました。 しかし、このアプローチでは以下のような問題が発生し、生成されたコードは一見動作するものの、期待値を満たしておらずに大幅な修正が必要になるという結果になりました。 デザインシステムとの不整合 : デザインシステムのコンポーネントやカラー、フォントサイズなどの定義を無視した、独自の実装になってしまう インタフェース定義の不備 : 他のコンポーネントとの連携に必要なProps定義やGraphQLスキーマの型定義が不適切になってしまう 振る舞いの実装ミス : UIの細かな状態変化やユーザー操作に対する振る舞いが期待値と異なる実装になってしまう これらの問題を解決するため、スプリント活動でアウトプットした設計ドキュメントを基に、実装時に必要な情報を構造化して提供する方針にしました。 MCPを活用してデザインシステムに準拠 デザインシステムとの不整合を解消するため、弊社の内製Figma MCPとデザインシステムMCPを活用したアプローチを採用しました。これにより、AIエージェントは以下のような情報を参照しながら実装を行えるようになりました。 デザイントークン : カラー、スペーシング、フォントサイズなどの基本的なデザイン要素を参照 コンポーネント定義 : 各UIコンポーネントで定義されたPropsを参照 この仕組みにより、AIエージェントが生成するコンポーネントは、デザイナーが意図した見た目と動作に近い状態で実装できるようになりました。 弊社内製のMCPの実装については以下記事で詳しく解説しているので、併せてご参照ください。 インタフェース定義の標準化 実装するコンポーネントのインタフェース定義やGraphQLスキーマの定義が曖昧な状態では、AIエージェントは柔軟に実装してくれます。しかし、この「柔軟性」が問題となり、毎回異なる結果を出力してしまうことから、実装予定の他のコンポーネントとの連携が取れない実装になってしまうという問題がありました。 この問題を解決するため、スプリント活動の設計フェーズで明確になった仕様を基に、事前にインタフェース定義を固定し、AIエージェントへのインプット情報として明示的に提供するようにしました。 以下はインプットとして提供する情報の例です。 コンポーネントを実装するディレクトリの例 src/services/careReceivers/tableRow/TableRow.tsx にコンポーネントを実装 コンポーネントのPropsの例 type Props = { id : string ; name : string ; } ; 利用するGraphQLスキーマの例 fragment CareReceivers on User { id name } UIの振る舞いの構造化 AIエージェントが生成したコンポーネントは、見た目は正しく実装されているものの、ユーザーの操作に対する反応や状態変化が仕様と異なることがありました。 この課題に対しては、スプリント活動の実例マッピングで整理したUIの振る舞いを、Given When Then形式で構造化し、AIエージェントにテスト駆動開発で実装させる方針を採用しました。 具体的には、以下のような流れで実装を行います。 振る舞いの構造化 : 実例マッピングの結果をGiven When Then形式で記述 テストの実装 : AIエージェントがその仕様に基づいてテストコードを実装 コンポーネントの実装 : テストがパスするまでコンポーネントを繰り返し修正 UIの振る舞いの例(Given When Then形式で記述) Given : 利用者一覧画面が表示されている状態で When : 利用者のチェックボックスをチェックすると Then : ヘッダーにチェックした利用者件数が表示されること このアプローチにより、AIエージェントが生成するコンポーネントは、見た目だけでなく動作も仕様通り実装されるようになりました。 プロジェクト固有のコンテキストの提供 上記の主要な課題への対策に加えて、AIエージェントがプロジェクトの既存実装パターンを理解し、一貫したコードスタイルで実装できるよう、以下も補完情報として加えました。 リファレンス実装のディレクトリパス コーディングガイドラインのファイルパス これらの構造化されたインプット情報を整備した結果、AIエージェントによる実装品質が安定するようになりました。 2. インラインレビューによるAIエージェントの自動修正 上記のアプローチにより、実装品質が安定したものの、インプットの内容の不備やコンテキストの欠落により、AIエージェントが生成したdraft PRをそのまま商用環境に適用することは厳しいことがわかりました。 そこで、draft PRで不十分な箇所については、人手でのPRレビューにより修正する方針としました。 最初のアプローチとして、AIエージェントが GitHub CLI を活用してPR reviewの内容をチェックして修正するようにしていましたが、以下の課題がありました。 すでに解決済みのレビューコメントも取得してしまい、フィードバックの回数が増えると適切な修正が行われなくなる レビューコメントに対して、AIエージェントが修正した内容をチェックするのに手間取り、指摘内容が適切に修正されているか確認しづらい そこで、効率的なPRレビューを実現できるように GitHub GraphQL API を活用して、以下のツールを持つ簡易的な自作GitHub MCPサーバーを作成し、レビューコメントの修正を行うようにしました。 get_pull_request_review_comments : 未解決かつ参照元のコードが最新のレビューコメントのみを取得するツール reply_to_fixed_commit_in_pull_request_review_thread : レビューコメントに対して修正内容の完了と修正した対象のコミットハッシュを通知するツール これらのツールを活用することで、AIエージェントが以下のプロセスでインラインレビューの指摘事項を修正することができたため、コードを期待する品質まで改善させることができました。 レビューコメントの取得 : get_pull_request_review_comments でPRの未解決コメントを一括取得 修正内容の特定 : AIエージェントがコメントの内容を解析し、必要な修正を特定 コードの修正 : 指摘事項に基づいてAIエージェントが自動でコードの修正を実行 修正完了通知 : reply_to_fixed_commit_in_pull_request_review_thread で修正コミットと修正内容を報告 具体的なMCPツールの実装イメージは以下を参考にしてください。 MCPツールの実装イメージ 1. get_pull_request_review_comments PRのレビューコメントを構造化されたデータとして取得するツールです。 以下のコードブロックでは、現在の作業ブランチ(draft PRを作成したブランチ)を入力値として渡すと、未解決のレビューコメントのファイルパスとスレッドを返す仕組みを表現しています。 server.registerTool( "get_pull_request_review_comments" , { description : "Get comments from pull request review threads" , inputSchema : { branchName : z.string().describe( "Branch name of the pull request" ), } , outputSchema : { filePaths : z.array( z.object( { filePath : z.string().describe( "File path of the review thread" ), reviews : z .array( z.object( { threadId : z.string().describe( "ID of the review thread" ), startLine : z .number() .nullable() .describe( "Start line of the review thread" ), endLine : z .number() .nullable() .describe( "End line of the review thread" ), comments : z .array(z.string()) .describe( "Comments in the review thread" ), } ), ) .describe( "Reviews in filePath" ), } ), ), } , } , async ( params ) => { // 未解決のPRレビューコメントを構造化されたデータとして返却する処理 } , ); リクエストの例 branchName: 現在の作業ブランチ(draft PRを作成したブランチ) { " branchName ": " feature/current-branch " } レスポンスの例 filePath: レビュー対象のファイルパス reviews: レビューのスレッドID、コメントの範囲、コメントの内容 { " filePaths ": [ { " filePath ": " src/components/UserList.tsx ", " reviews ": [ { " threadId ": " threadId1 ", " startLine ": 15 , " endLine ": 20 , " comments ": [ " 型定義が不十分です。Propsの型を明確に定義してください。 ", " ユーザビリティの観点から、エラーハンドリングを追加したほうが良いです。 " ] } ] } ] } 2. reply_to_fixed_commit_in_pull_request_review_thread レビューコメントに対して修正完了の返信を自動で行うツールです。 以下のコードブロックでは、 get_pull_request_review_comments で取得したレビューのスレッドIDと修正したコミットハッシュ、修正内容を入力値として、対象のレビュースレッドに対して修正内容を通知する仕組みを表現しています。 server.registerTool( "reply_to_fixed_commit_in_pull_request_review_thread" , { description : "Reply to a fixed commit in a pull request review thread" , inputSchema : { threadId : z.string().describe( "ID of the comment to reply to" ), commitHashes : z .array(z.string()) .min( 1 ) .describe( "Array of commit hashes of the pull request" ), message : z.string().describe( "Custom message to include in the reply" ), } , outputSchema : { result : z.object( { success : z.boolean().describe( "Whether the reply was successful" ), body : z.string().describe( "Content of the reply" ), createdAt : z .string() .describe( "Timestamp of when the reply was created" ), } ), } , } , async ( params ) => { // レビューのスレッド単位で修正内容を返信する } , ); リクエストの例 threadId: レビューのスレッドID commitHashes: レビューコメントに対して修正したコミットハッシュ message: 修正内容 { " threadId ": " threadId1 ", " commitHashes ": [ " ea9f557c44b545b93d7f86fcc7cb796c77022367 " ] , " message ": " ご指摘いただいた点を修正しました。型定義を追加し、エラーハンドリングも実装しています。 " } レスポンスの例 threadIdで指定したスレッドに対して、レビューコメントを返す まとめ 本記事では、LeSSによってPBIの不確実性が低減された状況とAIエージェントによる自動実装に親和性があるという仮説のもと、スプリント期間中のフロントエンド実装自動化に挑戦した取り組みについて紹介させていただきました! 完全な自動化には至らなかったものの、この取り組みを通じて、以下の仕組みによりAIエージェントによる実装の大幅な効率化を実現できました。 スプリント活動でアウトプットした設計情報を、AIが理解しやすい形式に整理し、設計ドキュメントを構造化 独自のGitHub MCPを活用して、PRレビューコメントの自動取得と修正完了通知の仕組みを実装し、自動修正フローを構築 さらに、弊社内製のFigma MCPやデザインシステムMCPとの連携により、デザインシステムに準拠した実装を自動生成する体験も実現しました。 一方で、完全な自動化を実現するには、まだまだ以下のような課題があることもわかりました。 AIエージェントが安定した出力を行うための設計ドキュメントの構造化が必要 複雑なビジネスロジックや例外処理では、人手による詳細な指示やレビューが必要 AIが解釈しやすい形式でのコーディングガイドライン整備が必要 現状では「完全自動化」よりも「効率的な協働」が現実的であることがわかりました。今後はこれらの課題を解消しつつ、人とAIがより良く協働できる開発体験の実現を目指していきたいと考えています。
こんにちは。介護・医療・障害福祉・保育の求人サイト「ウェルミージョブ」のQAを担当している林です。 ウェルミージョブは、2025年7月にカイゴジョブからリブランディングしてサービス提供を開始しました。 私はアジャイルな開発チームの中で、テストをこなすだけでなく、開発チーム全体でプロダクト・サービス品質を向上すべく日々挑戦しています。 今回の記事では、QA担当の私が開発チームにポストモーテムを導入し、チームでの実践に至るまでの経緯と、その具体的な進め方についてお伝えします。 0. はじめに エス・エム・エスのQA組織では、Value(行動指針)として「チームで品質保証」を掲げています。 これは、介護/障害福祉事業者向け経営支援「カイポケ」のQAチームにて策定されたもので、ウェルミージョブのQAチームでも同じマインドを共有しています。 QA組織の行動指針を言語化した取り組みについては、以下の記事をご覧ください。 tech.bm-sms.co.jp 「チームで品質保証」の範囲はQAに留まらず、開発・デザイナー・PdM・事業メンバー・運用メンバーなどと幅広く協同することを想定しています。 横断的に「チームで品質保証」を実践している事例については、以下の記事をご覧ください。 tech.bm-sms.co.jp 1. QAの私がポストモーテムにチャレンジした経緯 チームでの品質保証活動における「3つの課題」 私はかねてより「チームで品質保証」のもと、開発チーム全体で質の高い原因分析をして再発防止に取り組みたいと思っていました。 しかしながら、以下のような課題感がありました。 QAが実施する不具合分析やインシデントの振り返りが、開発メンバーを巻き込んでの活動に繋げづらい 過去に開発メンバーでインシデント振り返りやポストモーテムを行った実績もあるが、経験値や関心度はメンバーによって差がある 同じ方向をむいて原因分析・再発防止を検討できる基盤がない 私をポストモーテムへの挑戦に導いた「3つの決め手」 課題を抱えていた私に、ポストモーテムについて触れる機会が次々とやってきました。 そして、以下の決め手により、ポストモーテムへ挑戦したい気持ちが固まっていきました。 チームで同じ方向を向ける「指南書」の存在 他チームの成功事例による「道しるべ」 「QAの業務」ではなく「チームの活動」にできる可能性 以下に、それぞれの決め手についてお話しします。 1. チームで同じ方向を向ける「指南書」の存在 同僚のQAエンジニアが作成したドキュメント中に、ポストモーテムの指南書ともいえるものを見つけました。 その中には「直接的原因・間接的原因・動機的原因」を切り分けた分析アプローチの例示と、フィッシュボーンチャートがありました。 私は「これを使えばチームで同じ方向を向いて活動できそう!」と直感しました。 「直接的原因・間接的原因・動機的原因」を切り分けた分析アプローチ 「原因」という言葉は意味が広く、人によってイメージするものが異なりがちです。「直接的原因・間接的原因・動機的原因」を分けて考えることで、チームメンバー間のイメージをすり合わせが容易になり、チームで同じ方向を向いて分析を進めることができます。指南書では、「直接的原因・間接的原因・動機的原因」について以下のように身近な例でわかりやすく説明されていました。 例:カロリーの摂りすぎで肥満になり、⚪︎⚪︎病(インシデント)になった 起きたこと -> 〇〇病 直接的原因 -> 肥満(hogehoge数値の増加) 間接的原因 -> カロリーの摂りすぎ 動機的原因 -> 日々の仕事でストレスがたまっており、過食の傾向があった フィッシュボーンチャート フィッシュボーンチャートは、ある問題(結果)とその原因の関係を、魚の骨のような形で整理・可視化するための図です。ある問題(魚の頭)は、どのような原因(骨)から起きているのか?をひと目で理解することができます。 2. 他チームの成功事例による「道しるべ」 他開発チームにおいて「ポストモーテムを重ねた結果、検討の観点・深さがよくなってきて、品質向上のプロセスが磨かれている」との情報をキャッチしました。これは、まさに私の目指したい姿です。 また、他チームにてポストモーテムのフォーマットが確立していることも確認できたため、フォーマットをそのまま流用して省コストでチャレンジできそうでした。 3. 「QAの業務」ではなく「チームの活動」にできる可能性 私は、チーム全体で活動をするにあたり「QA業務を開発メンバーに協力してもらう」ではないやり方を模索中でした。 ポストモーテムは、当時のウェルミージョブ開発チーム内では「QA(または開発)がやるもの」という概念がない状態だったため、「これならQAの業務ではなくチームの活動にできそう!」と感じました。 そして、ついにポストモーテムへ挑戦する日が訪れました。 2. ポストモーテム実施 初回チャレンジ ステークホルダへ原因や再発防止について報告が必要な状況となったため、私から「今回はポストモーテムにチャレンジしてみませんか?」と開発チームへ提案しました。 ポストモーテムについて、社内における他チームでの実績や参考にできる情報が多くあることを伝え、開発チームの賛同を得ました。 誰がファシリテートするかについてはもちろん、ポストモーテムへの挑戦にワクワクしている私が引き受けました。 以下、初回チャレンジのサマリです。 活動のステップ 資料たたき(ステータス・サマリ・タイムライン・影響・原因・対応・アクションアイテム)作成:QA(私) 読合せ会1:開発・QA・PdM・事業メンバー 読合せ会2:開発・QA・事業メンバー 改善アクション実行:開発・QA 大事にしたこと チーム全体で同じ方向を向いて原因分析に取り組むこと 効果的かつ実現可能な再発防止策を導き出すこと 次回以降、私ではない他のメンバー(特に、QAではなく開発メンバー)がチャレンジできるように敷居を下げること チャレンジ結果 【◎】「直接的原因・間接的原因を切り分けた分析アプローチ」によりチーム全体で方向性を合わせ、解像度を高めて効果的な分析ができた 【△】読合せ会が初動の話で盛り上がり、原因分析の話が十分にできなかったため、別日に読合せ会2を追加開催することになった 【△】後から資料を整理する時間がなく、資料が読みづらいままになってしまった 【◎】改善アクションを、QAタスクではなく開発チームのタスクとして進められている このように、ポストモーテム初回チャレンジは概ね成功といってよい形で実施することができました。 さて、このポストモーテムの活動を開発メンバーへ展開していきたい…と思っていた矢先、予想外に早く、その時は訪れてしまいました。 2回目チャレンジ 初回チャレンジから間を空けず、ポストモーテムの成功体験が記憶に新しいタイミングで、開発チームへ2回目のポストモーテム実施を提案したところ賛同が得られました。 「ぜひ開発メンバーにチャレンジしてほしい、私が伴走する」とファシリテーターについて持ち掛けたところ、ポストモーテム未経験の開発メンバーに立候補してもらえました。 以下、2回目チャレンジのサマリです。 活動のステップ 資料たたき(ステータス・サマリ・タイムライン・影響・原因・対応・アクションアイテム)作成:開発(伴走:QA) 原因分析の分科会:開発・QA(主要メンバーのみ) 読合せ:開発・QA・事業メンバー・運用メンバー 改善アクション実行:開発・QA 大事にしたこと 私はできるだけ裏方に徹すること チーム全体で同じ方向を向いて原因分析に取り組むこと 効果的かつ実現可能な再発防止策を導き出すこと チャレンジ結果 【◎】QAが行った品質活動に、開発メンバー主導でチャレンジした実績ができた 【◎】原因分析を分科会で事前に実施し、課題が一定クリアになった状態で読合せができた 【◎】ポストモーテム前提でインシデント対応中に時系列を記録できていたことで、情報収集の負荷が軽減できた 【△】同じ方向をむいて原因分析するために重要なフィッシュボーンチャート等がカットされてしまったため、私にて再掲 【△】ポストモーテムの形式にとらわれすぎて、読合せ会の前半が資料の読み上げになってしまった 【△】後から資料を整理する時間がなく、資料が読みづらいまま 【◎】改善アクションを、QAタスクではなく開発チームのタスクとして進められている このように、2回目のポストモーテムも概ね成功といってよい形で実施できたのではと思います。 特に原因分析について、分科会としてメンバーを絞って事前に実施したことで、必要十分な工数をかけて余計な圧などがない環境で議論ができ、より確度の高い分析ができたと感じています。 また、改善アクションについて、開発メンバーにて迅速に対応がなされて一部改善効果が出ており、効果的かつ実現可能な再発防止が進められています。 3. おわりに その後、報告書が必要となる大規模のインシデントは発生していませんが、小規模のインシデント対応においても開発チームのメンバーから「ポストモーテムしましょうか」と声が上がり、ポストモーテムの実施が定着しつつあります。 また、ポストモーテムを意識した情報整理も意識されるようになり、別のインシデント対応において他システムの開発チームとの連携にも役立ちました。 今回のポストモーテムへのチャレンジは、今後の更なる「チームで品質保証」への取り組みの礎となると大いに期待しています。 今回のチャレンジができたのは何よりも、日ごろから開発・QA・デザイナー・事業メンバーが一丸となってアジャイルなチーム開発を進めていることにあります。 チームメンバーである塩井さんの記事『社会課題に取り組みたいRuby大好きエンジニアがセカンドキャリアにエス・エム・エスを選んだ理由』の中で「開発に責任感を持って真摯に向き合い、ごく自然にお互いに助け合うチームメンバー」とあるように、ウェルミージョブの開発チームでは、チーム全体へ働きかける形での品質向上へのチャレンジが歓迎されています。 tech.bm-sms.co.jp これからも私は「チームで品質保証」のもと、異なる専門性を持つメンバーと協力してチーム全体で品質の向上を目指すべく、チャレンジを続けます。 告知! ウェルミージョブの開発をリードする @moro が、この度「Kaigi on Rails 2025」にて初日のKeynote Speakerを務めます。 一昨年のKaigi on Rails 2023、そして去年のKaigi on Rails 2024でも大好評を博した@moroの基調講演にどうぞご期待ください! Kaigi on Rails 2025 Keynote: dynamic! 昨年までの発表 Simplicity on Rails - RDB, REST and Ruby / MOROHASHI Kyosuke - Kaigi on Rails 2023 Identifying User Identity / MOROHASHI Kyosuke - Kaigi on Rails 2024
皆さん、こんにちは! エス・エム・エスの人材紹介開発グループでマネージャーをしている @kenjiszk です。私は2023年4月に入社し、気づけば3年目に突入しました。今回は、私たちのグループが新たに始めたオフラインイベントについてご紹介します。 なぜオフラインイベント? エス・エム・エスの開発組織はフルリモートで業務を行っているため、実はまだ一度も顔を合わせたことのないメンバーが多くいました。特に九州や関西地方など遠方に住んでいるメンバーもいるため、気軽にランチをするということすら難しい状況です。 このような状況下で、私たちのグループには「チーム間のつながりが希薄である」という課題がありました。各チームは、それぞれのサービスごとに少人数のエンジニアで構成されており、日常的な業務や開発についてはこのチームの中で解決することが多いです。各チーム内での会話や議論は非常に活発ですが、チームを跨いだ議論や交流はあまり多くありませんでした。 なぜ横のつながりを大事にしたいのか? 私たちのサービスは、看護師・介護職・保育士など対象とする従事者によってサービスとチームが分かれていますが、それぞれに求められる技術的な要件やアーキテクチャは似ている部分があります。チームに閉じずに、横断的なコミュニケーションが活発になることで、自分たちが困っていることは実は他のチームが解決してくれていた、とか、自分たちが行っていることが他のチームの助けになった、ということは往々にして起こり得ます。 オンラインで機会を作ってもなかなか難しい問題 オンラインでもチームを横断したような雑談の機会や、他チームのメンバーの人となりがわかるようなLT(ライトニングトーク)を企画していましたが、偶発的にチームを横断した雑談が生まれるような雰囲気の醸成はなかなか難しいと感じていました。 物理的な距離を越えて、心の距離を縮める試み この課題を解決するため、私たちはまず「物理的に会ったことのないメンバーをなくす」ことに焦点を当てました。そして、お互いの精神的な壁を低くすることを目指し、初のオフラインイベントを企画・開催しました! イベントでは、「マシュマロチャレンジ」というチームビルディングゲームを行いました。このゲームは、パスタ、テープ、ひも、マシュマロを使い、自立可能なタワーを作るというシンプルなルールながら、チームの創造性、問題解決能力、そしてコミュニケーション能力が試されます。最も高いタワーを作ったチームが勝利となります。 普段話す機会のないメンバー同士が自然に交流できるよう、チームはランダムに編成しました。初対面のメンバーも多い編成でしたがどのチームもお互いに協力しあいタワーを作りました。 今回一番成績の良かったチームは、71cmのタワーを完成させることができました(ちなみに世界記録は99cm)。 マシュマロ・チャレンジの概要は以下の動画で確認できます。 Build a tower, build a team | Tom Wujec チームリーダーによるパネルディスカッション マシュマロゲームで会場が温まった後には、各チームのリーダー4名によるパネルディスカッションを実施しました。ここでは、現在取り組んでいる課題や、今後挑戦していきたいことなどについてざっくばらんに語ってもらいました。 普段は聞くことのできない他のチームの取り組みやリーダーたちの熱い想いに触れることができ、参加者からは「とても刺激になった」「視野が広がった」といった声が上がりました。リーダー陣のリアルな声は、今後の業務へのモチベーション向上にも繋がったことと思います。 半年に一回の開催で継続していきます イベント後のアンケート結果は、概ね好評でした!「普段話さないメンバーと交流できて楽しかった」「他チームのことが知れてよかった」といったポジティブな意見が多く寄せられ、このイベントがチームの絆を深める上で非常に有効であったことを実感しました。 リモートワークが主流の今、オフラインでの交流はより一層貴重な機会となります。次回以降もメンバー間の交流を促進し、より強固なチームを築いていけるようなイベントを継続的に開催していく予定です。 今回はリモートワークのデメリットについてスポットライトを当てましたが、リモートワークにはメリットがたくさんあり今後も良い形で続けていきたいと考えています。この取り組みを通じて、私たちの会社がどんな会社なのか、少しでも皆さんに興味を持っていただけたら嬉しいです。
こんにちは!ブログ編集チームの @_kimuson です。 我々はエス・エム・エス テックブログをはてなブログで運用しており、従来はGoogle Documentやesa *1 で下書きを書いて入稿をしていました。 今回、はてなさんが公開している Hatena-Blog-Workflows-Boilerplate を一部利用しつつ、我々のワークフローに合わせてカスタマイズすることでブログの入稿やブログの公開に伴う様々な作業を自動化することで記事管理がかなり楽になったので事例を紹介させていただきます! これまでのフローのペイン 入稿フローの複雑さ 入稿は執筆者の好みでGoogle Documentあるいはesa(markdown)に書いてもらったものをレビューしていましたが、それぞれ入稿やレビュープロセスにペインがありました。 Google Documentの場合: 入稿時のセマンティックを正しく反映したMarkdownへ変換したり、見た目の調整をしたりが大変 esaの場合: エンジニアが慣れ親しんだmarkdownで書きやすいが、行レベルコメントが利用できないのでレビュープロセスが大変 markdownも方言が異なるのでそのまま入稿できることはほとんどない 執筆者が実際のデザインで記事を見られない 執筆者が記事を書いてから下書きとしてはてなブログに入稿されるまでにラグがあり 執筆者が自分のブログデザインの崩れに気づけない(気づくのが遅くなる) 実際に当てはめてみて読んでみることができない というペインもありました。 品質チェックの負荷 記事の公開前には常に広報ガイドラインに則ったチェックとフォーマットのチェックを手動で行っており、これも負担になっていました。 広報のガイドライン準拠チェック 英数字の前後空白など、スタイルルールの確認 チャットベースのLLMを活用した一部効率化は行っていたものの、コピペや修正の手間は依然として残っており大変でした。 アイキャッチ作成の手間 記事ごとにアイキャッチ画像(OGP画像)を作成して設定していましたが、これもKeynoteで調整して書き出しており労力がかかっていました。 適切な改行位置の決定 SNS投稿時の見切れを防ぐ文字サイズ調整 記事をリポジトリで管理することで、こういった面倒な作業を自動化しやすくなります。これらのペインを解消すべく取り組みました。 Hatena-Blog-Workflows-Boilerplate はてなブログ用の記事管理をリポジトリでやるなら、はてなさんが提供する hatena/Hatena-Blog-Workflows-Boilerplate を利用すると便利です。 このリポジトリをテンプレートにして記事管理リポジトリを作成することで、ボイラープレートに用意されているGitHub Actionsワークフローを利用できます。 create-draft: 手動実行でドラフト記事を作成 pull-draft: ドラフト記事をpushした際に、はてなブログ側へ変更を反映する pull: はてなブログから公開済みの記事のみを取得 push-draft: はてなブログから特定のタイトルの下書き記事を取得 push-when-publishing-from-draft: ドラフト記事を公開ステータスでpushすると公開 push: 公開済みの記事を更新し、 はてなブログに反映 すでに公開されている記事の同期から、新しいmarkdown記事の作成・入稿・公開まで一通りの機能がオールインワンで提供されており、基本的にはこれをそのまま使用すれば記事管理を行うことができます。 予約投稿機能が使えない 非常に便利なHatena-Blog-Workflows-Boilerplateですが、予約投稿機能を利用できないという点で困りました。 我々は記事の公開は基本的に予約投稿機能を利用しています。 しかしながら 予約投稿がサポートされていない frontmatterのdraftプロパティで公開/非公開が制御される 公開済み記事は draft_entries から entries ディレクトリへの移動される という仕様になっていました。 Hatena-Blog-Workflows-Boilerplateを利用した上で予約投稿も併用すると、予約投稿によって公開された記事が draft_entries に残り、他記事のリポジトリ操作ではてなブログ側へ意図しない状態変更が起きるリスクもありそうです。 解決アプローチ 考え方を少し変え、「記事の執筆から入稿・公開・公開後の修正まですべて管理する」のではなく、 「下書き記事の作成から入稿までを管理する」 という方針に変更しました。 我々のペインは入校後の記事管理にはほとんと存在せず、下書き記事の執筆から入稿までの間に集約されていました。 公開済みの記事管理までスコープを広げて変に複雑にするより、下書き記事の入稿までに振り切る方がシンプルで運用しやすいと考えたため、この方針を採用しました。公開した記事の内容を変更したり調整することもないわけではありませんが、頻度が多いわけではないので割り切っています。 具体的には以下のように実現します: draft_entries ディレクトリのみを使用し、公開済み記事は管理しない(entriesディレクトリ不使用) entriesに関連するワークフローは削除し、一部のワークフローのみ利用(create-draft, push-draftのみ) 記事PRマージ後にファイルを自動で削除する 公開済みの記事について編集する場合はリポジトリを介さずに調整する この方針により、下書きから入稿までの諸々の手間はリポジトリに寄せて自動化しつつ、下書き→公開のプロセスにはリポジトリは関与させないことで、責務を明確に分離できました。 機能が不足している予約投稿やカテゴリ設定といった公開に関するオペレーションは従来の方針を維持して運用できています。 親子アカウント非対応問題 Hatena-Blog-Workflows-Boilerplateのセットアップは基本的には公式READMEに従って簡単に設定できましたが、一部問題が発生しました。 はてなブログでは親子アカウント機能を利用でき、我々は強すぎる権限を持たせないようにしないため子アカウントを普段使いしています。 しかし、Hatena-Blog-Workflows-Boilerplateでは親子アカウントに対応しておらず、親アカウントのトークンが必要でした。 このため、初期設定時のみ親アカウントを使用してトークンを発行する必要がありました。 編集 URL の修正 Hatena-Blog-Workflows-Boilerplateでは create-draft ワークフローを利用することで記事の下書きファイルとPRを作成し、対応するはてなブログ上のエントリの作成・PR Descriptionにプレビューや編集のURLを添付するところまでやってくれます。 ただし、記事の編集URLがAtomPubのURL形式( https://blog.hatena.ne.jp/bm-sms/sms-tech.hatenablog.com/atom/entry/<id> )で生成されるのですが、これを参照するには親アカウントでないと閲覧できないという問題がありました。 これを解決するため、create-draftのワークフローを拡張し、後続のJobで通常の編集URL形式( https://blog.hatena.ne.jp/bm-sms/sms-tech.hatenablog.com/edit?entry=<id> )に変換するワークアラウンドを実装しました。 name : create draft on : workflow_dispatch : inputs : title : description : "Title" required : true jobs : create-draft : uses : hatena/hatenablog-workflows/.github/workflows/create-draft.yaml@ce4c0e01255ad9348842e5ce09809c3ec499e43d # v2.0.5 with : title : ${{ github.event.inputs.title }} draft : true BLOG_DOMAIN : ${{ vars.BLOG_DOMAIN }} secrets : OWNER_API_KEY : ${{ secrets.OWNER_API_KEY }} fix-edit-url : # 編集ページ URL が AtomPub ベースの URL になっていて編集チームでアクセスできないので、普段使っている URL 形式に変換する # before: https://blog.hatena.ne.jp/bm-sms/tech-bm-sms.hatenablog.com/atom/entry/<ID> # after : https://blog.hatena.ne.jp/bm-sms/tech-bm-sms.hatenablog.com/edit?entry=<ID> needs : create-draft runs-on : ubuntu-latest steps : - name : Checkout repository uses : actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name : Get PR number from create-draft job id : get-pr run : | # 記事タイトルをもとに該当するPRを検索し、最新のものを取得 PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --author github-actions[bot] --search "in:title \" ${{ github.event.inputs.title }} \" " --limit 1 --json number --jq '.[0].number' ) echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT env : GH_TOKEN : ${{ github.token }} - name : Update PR description with correct edit URL and issue link run : | # 現在のPRのdescriptionを取得 CURRENT_DESCRIPTION=$(gh pr view ${{ steps.get-pr.outputs.pr_number }} --repo ${{ github.repository }} --json body --jq '.body' ) # URLを置換(atom/entry/ → edit?entry=) UPDATED_DESCRIPTION=$(echo "$CURRENT_DESCRIPTION" | sed 's|/atom/entry/|/edit?entry=|g' ) # PRのdescriptionを更新 gh pr edit ${{ steps.get-pr.outputs.pr_number }} --repo ${{ github.repository }} --body "$UPDATED_DESCRIPTION" env : GH_TOKEN : ${{ github.token }} これにより、子アカウントを利用していても編集URLへアクセスできるようになりました。 不要なワークフローの削除とお掃除機能の実装 下書きの入稿までをスコープとするため、PRをマージした時点で下書き記事は削除を行います。 これはHatena-Blog-Workflows-Boilerplateではサポートされない独自のワークフローなので自前でGitHub Actionsを実装しました。 name : cleanup draft entries after merge on : pull_request : types : [ closed ] branches : - main jobs : cleanup-draft-entries : # PRがマージされた場合のみ実行 if : github.event.pull_request.merged == true runs-on : ubuntu-latest steps : - name : Checkout repository uses : actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with : # PRがマージされた後の最新のmainブランチをチェックアウト ref : main token : ${{ secrets.GITHUB_TOKEN }} - name : Get changed draft files id : get-changed-files run : | # マージされたPRで変更されたdraft_entriesディレクトリ内のファイルを取得 CHANGED_FILES=$(gh api /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files \ --jq '.[] | select(.filename | startswith("draft_entries/")) | .filename' \ | tr '\n' ' ' ) echo "changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT echo "Changed draft files: $CHANGED_FILES" env : GH_TOKEN : ${{ secrets.GITHUB_TOKEN }} - name : Delete draft files if : steps.get-changed-files.outputs.changed_files != '' run : | # 変更されたdraft_entriesディレクトリのファイルを削除 for file in ${{ steps.get-changed-files.outputs.changed_files }}; do if [ -f "$file" ] ; then echo "Deleting $file" rm "$file" else echo "File $file not found, skipping" fi done - name : Commit and push changes if : steps.get-changed-files.outputs.changed_files != '' run : | # Gitの設定 git config --local user.email "action@github.com" git config --local user.name "GitHub Action" # 変更をコミット git add -A # 削除されたファイルがある場合のみコミット if ! git diff --cached --exit-code > /dev/ null ; then git commit -m "chore: cleanup draft entries after merge of PR #${{ github.event.pull_request.number }}" git push origin main else echo "No changes to commit" fi 執筆・入稿作業の効率化 ここまでの対応でリポジトリを用いた記事管理ができるようになりました! 本来やりたかったのは「記事をリポジトリで管理すること」で、ローカル向けのツールやGitHub Actionsを用いた品質管理やレビュープロセスの効率化なので、実際に運用している効率化の仕組みも紹介させていただきます。 textlint を使った文章校正 人間によるレビューで発見される内容を極力減らすため、また「英数字の前後には空白を置く/置かない」と言った機械的なルールを適用するため textlint を導入しています。 日本語関係のルールや、フォーマットに関するルールを追加し、日々運用しながらルールを調整しています。 文法上の細かい指摘などはVSCodeで書くと同時にtextlintの拡張機能によりフィードバックされるので、一部の不適切な記述は執筆者が自分で修正できるようになりました。 GitHub Actions + actions/ai-inference を活用した広報ガイドラインチェック 我々はテックブログを公開するための広報ガイドラインを持っており、公開前に必ずガイドライン違反する記述や内容がないかを編集チームがチェックしています。 このプロセスの負荷を軽減するため、LLMを用いたガイドラインチェックを追加しました。 actions/ai-inference を利用することで、GitHub Actions上で手軽にGitHub ModelsのLLMを利用できます。PRがReady For Reviewになったらワークフローが起動し、LLMがガイドラインと記事の内容を照らし合わせて問題のある箇所をPR上にコメントしてくれるようになっています。 OGP 画像生成の効率化 記事のOGP画像の生成もコマンドラインツール化しました。 完全な自動化は適切な改行位置の設定をすることが難しいため、一部手動で変更するオプションを残した上で自動化をしています。 デフォルトの改行位置の決定には google/budoux を利用しています。budouxに記事ファイルのfrontmatterから取得したタイトルを食わせることで、タイトルを適切な改行可能な位置で分割してくれます。そして予め決めておいた文字数や行数の上限を超えないようにまとめます。 import { loadDefaultJapaneseParser } from "budoux" ; const MAX_CHARS_PER_LINE = 30 ; const MAX_LINES = 6 ; export const separateTitle = ( title : string ): string [] => { // BudouXを使って日本語文章を適切な位置で分割 const parser = loadDefaultJapaneseParser(); const segments = parser.parse(title); const lines: string [] = [] ; let currentLine = "" ; for ( const segment of segments) { // 現在の行に新しいセグメントを追加しても30文字以内の場合 if ((currentLine + segment). length <= MAX_CHARS_PER_LINE) { currentLine += segment; } else { // 30文字を超える場合、現在の行を確定して新しい行を開始 if (currentLine) { lines. push (currentLine); currentLine = segment; } else { // currentLineが空の場合(segmentが30文字を超える場合) currentLine = segment; } } } // 最後の行を追加 if (currentLine) { lines. push (currentLine); } // 行数制限の処理 if (lines. length <= MAX_LINES) { return lines; } // 6行を超える場合、最初の5行を取り、残りを最後の行にまとめる const result = lines. slice ( 0 , MAX_LINES - 1 ); const remainingLines = lines. slice (MAX_LINES - 1 ); const lastLine = remainingLines. join ( "" ); result. push (lastLine); return result; } ; 適切な改行位置での分解ができれば、あとはOGP画像を生成するだけです。これは前例となる記事がたくさん世に出ているので割愛しますが、 node-canvas を用いて、文字が見切れない横幅に収まる範囲で最大のフォントサイズが適用されるように実装しました。 例えば今回の記事タイトルを渡した場合、初回では以下のようになります。 今回に関してはやや文字が小さいので手動で調整します。 分割の情報はtemporaryなjsonファイルへ書き出すようにしており、これを変更して再実行することで区切り位置を変更します。 { "lines": [ - "Hatena-Blog-Workflows-Boilerplate を", + "Hatena-Blog-Workflows-Boilerplate", - "使って記事をリポジトリ管理し、レビュープロセスや入稿作業を", + "を使って記事をリポジトリ管理し、", - "効率化した話" + "レビュープロセスや入稿作業を効率化した話" ] } 再実行することで、再度生成されます。 良い感じになりました。 こういった形でOGPの画像も手間なく作成できるようにしました。 まとめ Hatena-Blog-Workflows-Boilerplateをベースに、我々の運用に合わせたカスタマイズを行うことで、テックブログの執筆・レビュープロセスを効率化した事例を紹介させていただきました! 予約投稿やカテゴリ・タグ設定といった公開に関する機能との兼ね合いで、あくまで下書きの入稿までを行う仕組みとして導入を行いましたが、かなり上手くワークしていると感じています。編集チーム内からの評判も良く、テックブログ運営が楽になりました。 ブログ編集チームは各々が開発チームに所属しながら有志として活動しているようなチームなので、こういった効率化を行って運用負荷を下げていくことは今後もやっていきたいなと考えています。 ブログ編集チームの取り組みについて紹介した記事も出ているので良ければ併せて御覧ください! *1 : 社内で利用しているMarkdownベースのナレッジSaaS
みなさんこんにちは! プロダクト推進本部の人事をしているまゆゆ( @mayuyu_desuyo ) です。 7/3 -7/4に丸の内で開催されたファインディ社主催の「 開発生産性Conference 2025 」にブース出展および登壇してきましたので今日はそのレポートブログです! まゆゆ 今回登壇したプロダクト推進本部カイポケ開発部エンジニアリングマネージャーのsoranakkさんに、登壇の振り返りをまずはしてもらおうと思います! soranakkさんどうぞ!!! 空中 はい、代わりました。 カイポケ開発部エンジニアリングマネージャーをしている空中清高 ( @soranakk ) です。 「開発生産性Conference 2025」での登壇の振り返りをしたいと思います。 登壇のテーマと背景 まずなぜ「失敗から再構築した開発推進チームの立ち上げ」というテーマで登壇することにしたのかについてお話しします。 登壇することが決まった時、テーマについてチーム内で相談したところ以下のような意見が出ました。 あえて失敗した話や現場の生の声を共有することは価値があるのではないか 失敗から学ぶことの重要性を伝えたい エス・エム・エスの文化として、失敗を恐れずに挑戦していることを伝えたい こういった意見があって「失敗から再構築した開発推進チームの立ち上げ」というテーマで登壇することにしました。 登壇の振り返り 実際に登壇してみた感触ですが、鄧皓亢(でんはおかん)さんが話した前半のパートで、エス・エム・エスで開発生産性のために組織として取り組んでいることをお話しできました。 特にドメインやプロダクト戦略に合わせた開発生産性向上のための専任チーム立ち上げという取り組みについて、組織として開発生産性に取り組みたいときの参考になると良いなと思います。 また私が話した後半のパートの開発推進チームの活動内容について具体的に紹介できたのも良かったと思います。 開発生産性を上げるという抽象的な課題に対して、具体的な取り組みを紹介できたことで、参加者の方々にとって何かのヒントになれば嬉しいです。 登壇の様子や資料については、スライドを公開していますので、ぜひご覧ください。 speakerdeck.com 登壇で話しきれなかったエピソード 登壇の時間が限られており、開発推進チームの全ての活動内容を話しきることができませんでした。 スライドではたくさんの活動内容を紹介しましたが、具体的に内容を話せたのはフロントエンドの開発生産性向上の取り組みの2つの例だけでした。バックエンドの開発生産性向上のための取り組みや、リリースとデプロイの改善活動など、他にもたくさんの取り組みがありますが、時間の都合で話しきれませんでした。 また開発生産性向上のためには品質保証もセットで必要だと考えているので、QAの一部自動化や効率化、本番環境のモニタリングの強化についての取り組みもあるのですが話しきれませんでした。 この辺りについて、興味のある方はぜひカジュアル面談等でお話できればと思います。この記事の末尾にカジュアル面談についてリンクを貼りますので、ぜひ気軽にお声がけください。弊社のカジュアル面談は本当に選考と関係ないカジュアル面談なので、気軽にお話しできると思います。 空中 では、登壇の振り返りについてはこの辺りにして、ブースの状況などについてまゆゆさんと交代したいと思います。まゆゆさん、よろしくお願いします。 まゆゆ soranakkさんありがとうございました!私からはブースの様子をお伝えします。 ブースの様子 エス・エム・エスはsoranakkさんとデンさんの登壇と共に7/4の1dayでブース出展をしました。 こちらのブログ記事 でもお伝えしたとおり、ブースは受付から入ってすぐのところでした! ブースでは、エス・エム・エスの事業や「カイポケ」のプロダクトについてご説明させていただきました。 今回のイベントテーマ「開発生産性」にちなみ、技術や開発をテーマにした「おみくじ」をコンテンツとしてご用意。 「カイポケ」の事業ドメインである「介護」について少しでも立ち止まって考えていただくきっかけになればと思い、ブース内にこんな問いかけを設置しました。 「将来あなたに介護が必要になった時、どんな社会になっていて欲しいですか?」 以下の3つの選択肢から、ご自身の考えに近いものや共感できるものを選んでいただき、そこにおみくじを結んでいただくという企画です。 A:AIやロボットなど介護のIT化が進む社会 B:高齢者の社会参加が重視され生き生きと過ごせる社会  C:在宅医療や介護がより充実する社会  結果としてはAが最も多く、エンジニアが多く参加するイベントということもあり、テクノロジーによる課題解決への関心の高さがうかがえました! 選択肢を眺めながらご自身の体験談などをお話しくださった方などもいらっしゃり、正解が1つではなく、多様な未来の可能性があることについて、来場者の皆様と対話ができた大変貴重な機会でした! また、ブースでは終日デモも行なっていて、デザインシステムMCP化のデモをご用意しました。 デモは終日行なっていましたが、soranakkさんとデンさんの登壇の中でデモをやっていることをお伝えしたところ、たくさんの方にブースへお越しいただき、おかげさまで大盛況でした! 中には一度ブースでデモを体験してくださった方が、同じチームの方と一緒に再度ブースへ来てくださるという大変嬉しい一幕も。 デザインシステムMCP化についてのアウトプットはこちらですので是非こちらもご覧ください。 zenn.dev speakerdeck.com 当日は予期せぬハプニングなどもありましたが、参加メンバーで協力し合いながら無事にカンファレンスを終えることができました!今後の活動にも活かしていきたいと思います!
Who I am みなさまはじめまして。2025年6月よりAnalytics&Innovation推進部(通称A&I)に入りました井手と申します。 肩書としてはデータサイエンティストというくくりで仕事をしてきております。統計分析や自然言語処理にかかわる学問領域を修めて社会に出たあと、データを集めるところから、それを加工し、分析を行いモデルにするまで幅広くデータ周りに関するお仕事に関わってきました。過去にはECサイトの分析基盤構築と分析業務、直近前職では社内インフラデータの分析基盤構築やそれを用いたデータ利活用推進業務、機械学習を用いたエンジニアHR業の業務マッチングシステムの構築などに携わってきておりました。 When I decided to change 前職での仕事はやりがいもあり特に大きな不満もなかったのですが、関わっていたプロジェクトが落ち着いたタイミングで先のことをぼんやり考えるようになりました。私は大学にいた期間が長かった関係で、社会人経験で言うと同年代同世代の人たちと比べるとそこまで多くないんです。ぺーぺーです。ぺーぺーなのですが、社会人経験の長さにかかわらず皆平等に年をとっていきます。私の残りの社会人人生はそこまで長くない。環境を変えるならそろそろ最後かなっていう思いが、私の背中を押しました。 Why I’m here Motivation 環境を変えるとして何がしたい? これについては私はひとつ、いつか医療や介護に関わる人達のための仕事に自分の能力を役立ててみたいという方向性を持っていました。人間歳を取ってくると、自分や家族が医療介護のお世話になる機会が増えてきます。私もその例に漏れず家族が随分とお世話になる経験がありました。そして私たちは大変幸運なことに素晴らしい方が担当をしてくださり、頼もしい想いや安堵を感じたことをよく覚えています。これは、担当してくださった方の才能はもちろんのこと、その職掌が現場においてまさに適材適所だったからこそなのだと私は思っています。適材適所っていうのは、難しい問題です。それでも、適材適所になる確率を少しでも高めることはできないか、そして私たちのような想いをする人を一人でも多くできるように自分の能力を活かせないかという気持ちを長らく抱いておりました。 看護介護の人材マッチングを柱の一つとするエス・エム・エスは、私のチャレンジの舞台としてはまさに理想的でした。 The Determinants もちろん看護介護のマッチングを提供する会社は他にもあります。その中で、私がエス・エム・エスを選んだ要因。今一生懸命思い出してみるとたくさんあります。たくさんありますが、常にぱっと思い浮かぶのは以下の2点。どちらも全然ロジカルではなく、すごい感覚的なのですが、まあ、意思決定なんてそんなものですよね。 ① 選んでもらえて誇らしかった 転職をするにあたって、もちろん候補となる企業はいろいろ調べます。企業HPをみたり、転職サイトの口コミ見たり社員のみなさんがやっているブログを読んだり。エス・エム・エスも、私が目指したいゴールは十全に共感できるものの、そこに向かう、一緒に働く方々はどういう人達なんだろうっていうことも気になってだいぶ調べました。エス・エム・エスの皆さん、エンジニアはもちろんキャリアパートナーとして働く人もみな志が高く実力者。ああ、皆さんレベルが高いんだな私の力が通用するかなって少し不安になるほど。選考も緊張の連続。冷や汗だらだら。それでも無事に内定をいただき、その後再び内部のみなさんとお話をする機会にて改めて志の高さを確認。そのような方々に選んでいただけたことを大変に誇らしく思い、入社の決め手の一つとなりました。 だから今も私、すごく誇らしい気持ちで働いています。 ② 田辺さん 本部長の田辺さん。一次面接を担当してくれました。私、もう、めちゃくちゃ緊張していたんですね。オンラインだけどちゃんとスーツ着て、ちゃんと3分前くらいには入室して言おうと思っていることをつっかえずに言えるかなって頭の中で何度もリハーサルして。 そしてついに登場した田辺さん。私が事前に想像していた「本部長の田辺さん」とは随分異なり、なんでしょう。カジュアルというか。登場するなり私の緊張を察してか、2、3言ことばをかけていただいて。私も緊張していたのであまり覚えていないのですが、その言葉で肩の力が抜けた気がして。 なんでしょうね。面接には関係のないほんのささいな言葉だったし、いま思い出してもこの会話にどんな情報量が詰まっているか未だにわからないんですよ。でも、この瞬間に、あ、ここでぜったい働きたい。田辺さんといっしょに働きたいって思うんだから人間って不思議ですよね。本質的にはロジカルな生物ではないんでしょうね。人間。 結局①も②も根底は似ているのかな。いいなって思った方々に選んでいただけた。それがすごく誇らしいです。今も。 What I’m doing now いくつかの業務を担当させていただいておりますが、メインはキャリアパートナー向けのサービス改善です。キャリアパートナーのみなさんが現在利用している、求職者とのトランザクションを管理するシステムを、より機能的にスケーラブルで使いやすいものへと刷新する中で、私は特に、求職者と事業者のマッチング確率を計算してリコメンドを生成する部分で関わらせてもらっています。 一般的なマッチングあるいはリコメンドの手法は言うに及ばず、HR領域においても、国内海外を見渡してみると盛んに手法が提案されてきています。ただ、データの持ち方や取得できるデータの性質はビジネスのスタイルによって大きく変わります。今一番効果的だと謳った手法を採用し、手元のデータに適用しようとしてもさっぱりということはざらです。とりわけ私達の場合、マッチングに際して間にキャリアパートナーという人間が介在し、キャリアパートナーの情報も利用する必要があります。そうすると問題構造が、研究が盛んに行われている単純なResume-Jobマッチングと大きく異なってきます。既存の技術だけではどうにもならないぞ、と少し不安はありますがそれでもこのチャレンジングな課題に大きなやりがいを見出しており、なんとかクリアしようと奮闘中です。 Where I want to go 「高齢社会に適した情報インフラを構築することで人々の生活の質を向上し、社会に貢献し続ける」が、エス・エム・エスのミッションです。 私はこれに共感して入社しています。だから、私の大きな目標はただ一つ。自分が定年になって退職し、そして高齢社会の一員になったとき、そして社会を見渡したときに「あ、エス・エム・エスで頑張ってよかったな」って思えるようにするということです。世間の報じられ方からすると、特に若年層の人から見ると、高齢社会というのは一種のディストピアのように見えてしまっているかもしれません。大きな重荷に見えているかもしれません。確かにやりたいこともできず、他人の世話をしなくてはいけない世界というのは明るいとは言えません。ただ、高齢者がいて、その高齢者の周りには個々の力が適材適所で発揮できる場所が存在するのだとしたら、その社会は重荷でしょうか。やりがいのある社会とは言えないでしょうか。私はそういう社会になるよう貢献したいと思っています。 とはいえちょっと漠然としすぎた目標なので、もうちょい自分の能力に引き寄せた目標を立てると、まずは上述したマッチング計算のアルゴリズム。未踏な部分が多いですが、やり遂げたいと思っています。そして過程で得られる様々な知見については、できる限り発信していきたいと思っています。少子高齢化は、遠くはイタリア、近くはお隣韓国など、日本以外の様々な国でも問題になってきており世界の喫緊の課題です。日本のみならず世界の人々と知識をシェアし、よりよい解決策を皆で検討できるようになれたらと思っております。 How I’ll get there なんかえらそうなことを延々書いてきてしまいましたが、私の力はまだまだ足りません。全然足りません。ともすると定年退職の当日まで成長しなくてはいけないくらい足りないかもしれません。 だいぶ長く生きてきて、そうすると自分の能力についてもだいぶ把握できてくるのですが、自分は小さな頃に信じていたほどのスーパーマンにはなれませんでした。いや、ちょっとのスーパーマンにもなれていません。誰かが1回でできることは、私は3回かかります。いま書いていて思いましたが、スーパーマンとか持ち出しましたが本当はどんくさいのかもしれません。ごめんなさい盛りました。 ただ少なくともスーパーマンではない私、3回繰り返すことはできるんです。3回でできなくても5回繰り返すことはできるんです。この才能は心から親に感謝しています。私の座右の銘は本当に月次で陳腐だと思うのですが「継続は力」です。これは本当。そして私の唯一の武器です。 高く掲げた目標、1回挑戦してだめなら10回やります。いつかきっとできます。いつかきっとできるんだけど、もしかしたらそれは定年の日を超えちゃうかもしれない。間に合わないかもしれない。まあでも、やらないって選択肢はないですよね。誇りをもって、進んでいきます!
こんにちは、カイポケの開発組織責任者の酒井 ( @_atsushisakai )です。 事業会社で働くソフトウェアエンジニア、特にプロダクト開発に関わる人にとって、個人の目標設定に関する悩みはよく話題に上がるテーマです。「どう立てればいいのかわからない」「立てたはいいものの形骸化してしまう」「目標を達成しても思ったように評価されない」といった悩みを聞くことが多くあります。 以前、私自身の目標設定の考え方を社内でまとめたところ反応がよかったこともあり、改めて「目標」と「評価」の関係性を整理し、形骸化しにくく、成果と成長につながる目標設定の考え方を紹介したいと思います。 目標設定に関するよくある悩み これまで複数社で主にエンジニアのマネジメントをやってきて、目標設定が難しいと感じる理由にはいくつかの共通点があるように感じています。 形だけ立てて終わる とりあえず何かを書かないといけないから、無難な内容にしてしまう。 達成しても評価が思い通りにならない 「やったことはやったのに、なぜ評価が上がらないんだろう」とモヤモヤする。 そもそも目標に何を書けばいいかわからない 「なりたい自分像」や「理想のキャリア」がはっきりしないと、目標が浮かばない。 こうした悩みを抱える人は少なくないと思います。また、目標を一緒に立てていくマネージャーにとっても、成熟した考え方が身についていないと、このようなメンバーの問題を解決するのは結構難しいことだと思います。 目標と評価の関係性 これまでに何度もメンバーから「目標設定」に関する相談を受けてきました。その度に、前提として目標と評価の関係性をしっかりと認識してもらうためのコミュニケーションを取っています。 目標と評価について、私の考え方を整理すると次のようになります。 目標と評価は直接紐づくものではない エス・エム・エスのエンジニア評価は「成果評価ではなく能力評価」という手法をとっています (詳しくは、 エンジニア採用ページ の記載をご覧ください)。この評価手法において、目標は「これを達成したから等級UPする」「達成できなかったから評価が上がらない/下がる」というものではなく、あくまで自分がどの課題にチャレンジするのかを表明するものと位置付けています。 目標の本質は成長のための仮説立て 目標は評価のためではなく、達成することを通じて自己成長を実現するためのガイドツールです。評価されるのは「どのような意味のある成果を生み、その過程でどういう成長を遂げたのか」という結果に対してであり、目標を達成した/しなかったというそれ自体ではありません。 評価は組織ごとのマネジメントポリシーに依存する どれだけ目標を達成し成長できていると言っても、それが会社から期待されている役割や等級の範囲を超えていなければ評価に反映されにくいこともあります。それぞれの組織にはその組織のマネジメントポリシーに沿った評価軸が存在し、その評価軸に照らし合わせて下されるものです。 つまり、目標は「成果を生むためにどの課題に取り組むかを明確にするためのツール」として活用し、評価については評価の意思決定を行うマネージャーとその評価軸をすり合わせておくことが大切だと考えています。 私自身の体験と学び 私自身も目標設定にはかなり苦労してきました。自分がどんなエンジニアやマネージャーを目指したいのか、明確なロールモデルを持っていたわけではなく、最初は「何を書けばいいかわからない」という感じでしたし、それゆえ目標設定という作業はとても苦手でした(今も得意ではありません)。 そんな中で気づいたのは、「なりたい自分像」から逆算して目標を立てるのは必ずしも必要ではないということです。むしろ、自分が今いる環境やプロジェクトの中で、 どんなゴールが組織やプロダクトにとって意味があるのか そこに向かう中で何が課題になるのか その課題を解決するために、自分はどんな貢献ができそうか その貢献は自分にとって十分チャレンジングなものか を考える方が、現実にフィットするし、プロダクト開発を主軸とするエンジニアである自分は目標を作りやすいと感じました。 ここ最近、私は目標を立てる際はいつも、 まずは少し先の「ゴール(組織やプロダクトについて、こうなっていたら嬉しい状態)」を考える そこに向かう上での課題を多面的に洗い出す 特に重要度が高い課題を選ぶ その課題をどう解くか、課題を解くためにはどんなステップがありそうかを考える というステップを踏んでいます。 これを繰り返すうちに、「目標を立てる」こと自体は苦手ではあるがやるべきことだとも感じられるようになり、周囲にも説明しやすく、評価にもつながりやすい形に自然となっていったと思います。 「目標設定テンプレート」の紹介 こうした体験を踏まえて「もっとシンプルに、形骸化しにくい目標を誰でも作れる形にしたい」と思い、今回あらためて整理したのが、ここから紹介する「目標設定テンプレート」です。 このテンプレートの大きな特徴は、「まずは事業やプロダクトのゴールを解釈し、そのゴールから逆算して課題を見つけ、そこに挑む中で成長を得る」という順序にあります。「なりたい自分像」ありきではなく、現実の課題から出発してチャレンジを設計するという考え方です。ただし、このテンプレートはプロダクト開発に関わるエンジニア向けに作っており、職種や役割によっては当然合わない部分もあるかもしれません。必要に応じて、自分の役割に合わせて調整して使ってください。 テンプレートの構成 テンプレートは大きく次の5ステップで構成しています。 ゴール 現状と課題 テーマ ステップとチャレンジ 目標 (Objectives) テンプレートの中身と意図 テンプレートの各項目の意図と、どういう考え方で埋めると良いかを簡単に説明します。 1. ゴール まずは、ビジネスやプロダクトの戦略、長期的な目標を踏まえて目指したい状態・達成した成果を書きます。 2. 現状と課題 このゴールに向かう上で、現在立ちはだかっている問題について言語化してください。チーム、組織、プロダクト、プロセス、自分のスキルやマインドなど多面的に洗い出しましょう。最終的に、この期間に解決すべき特に重要・緊急な課題は何かを明示してください(フォーカスすることを重視したいので最大3個程度に絞りましょう)。 3. テーマ 選んだ課題に対して、自分が取り組む際のテーマを明確化します。なぜこの課題解決を自分が担うことに意味があるのか(貢献・成長の視点)、その課題が解決された状態はどのようなものなのかについて言語化してください。 4. ステップとチャレンジ 課題を解くために、どのようなステップが必要だと考えていますか?ステップを踏んでいく中で、あなたにとって予想されるハードルやチャレンジはどんなものありますか? 5. 目標(Objectives) フォーカスすることを重視するので、2〜3個に絞って設定してください。定性的でもOKで、ゴールや成果を示すだけでなく、ありたい姿や取り組み方に焦点を当ててもよいです。また、自身の現在の等級や役割における期待を踏まえた上で、「その目標は水準として妥当か」を見立てる意識を持つことが重要です。 この順序で整理すると、「最終的な組織全体が目指す成果を生むために今期自分自身はどの課題にチャレンジするのか」が自然と言語化できると考えています。 テンプレート活用の工夫 テンプレートを最大限活かしつつ、目標を形骸化させないために、いくつか工夫を加えると良いかもしれません。 例えば以下のような工夫を交えながら目標設定という作業に向き合うと、単なる儀式的な作業にならず、現実の課題と向き合うツールとして長く活かせるものになるはずです。 目標設定作業を1人で抱え込まない 目標は自分だけで完璧に作るものではありません。マネージャーやチームメンバーともオープンな会話ですり合わせながら、課題の優先順位やゴールの解像度を段階的に一緒に確認すると、より現実に即した内容になります。 定量化に縛られすぎない 目標を全部数字で表そうとすると、逆に本質からズレてしまうこともあります。「どういう状態を目指すのか」「どんな姿勢で取り組むのか」といった定性的な要素も、成長を示す大事なポイントです。 達成できなくてもOK 目標は「やることの宣言」ではなく「こういう仮説をもってチャレンジする」という表明です。仮に目標が達成できなくても、その過程で何を学び、未達成の原因を内省・追求し、次にどうつなげたかを言語化することができれば十分に意味のある作業です。 まとめ プロダクト開発を担うソフトウェアエンジニアが事業成果を起点に考える目標設定をどのようなステップで行うか、その背景にある評価の考え方について紹介しました。目標は「評価のためのコミットメント」ではなく、「今どの課題にあえて挑戦するのか」を言語化し、成長と成果を結びつけるツールだと私は考えています。 もし、目標が形骸化しがちであったり、何を書けばいいかわからないなどの悩みがある場合には、ぜひ一度このテンプレートを参考にしてみてください。
はじめに こんにちは、介護/障害福祉事業者向け経営支援サービス「カイポケ」のリニューアルプロジェクトでモニタリングやオブザーバビリティ周りを担当している加我 ( @TAKA_0411 ) です。 私が携わっているカイポケのリニューアルプロジェクトではオブザーバビリティのツールとしてDatadogを活用しています。そしてこの度Findy様からのお声がけで、DatadogのレビューをFindy Toolsに寄稿しました。 findy-tools.io Findy Toolsについて 「Findy Tools」は、開発ツールに特化したレビューサイトです。第三者の視点で実際にツールの選定を行った企業の生の声を集めることで、ツール選定に関する不安を解消し、導入検討に必要な情報を提供します。 「Findy Tools」を開発ツールの導入検討をしているユーザーが利用すると、実際にツール選定を行った大手企業やメガベンチャー企業の技術責任者やエンジニアによるレビューを集めることができ、導入検討がスムーズになります。また、開発ツールを掲載するベンダーには、実際の利用企業の声を活かしたコミュニティマーケティングによる新規顧客の獲得や、認知向上をご期待いただけます。 findy.co.jp レビューの寄稿に至った経緯 以前、弊社のエンジニアが別のツールに関するレビューをFindy Toolsに寄稿したことがありました。その時のご担当者様が 私のブログ記事 を見て「Datadogの活用ノウハウについてのレビューを寄稿してみませんか」とお声がけいただいたのがきっかけでした。 実はお声がけいただいたタイミングが非常に良く、社内でも「オブザーバビリティのツールの技術選定についての意思決定をADR (Architecture Decision Record) として残しておいた方がよいのでは」という議論がありました。これにより、関連するADRを整備し、それに沿ってレビュー記事を執筆することで無事に寄稿できました。 レビューの注目箇所 オブザーバビリティのツールは多く存在しますが、利用する組織の規模やプロダクトの特性によって最適解が異なります。ツールの導入にあたり「実運用をしっかりイメージすること」「特定の人やチームに属人化させないこと」「より多くの開発者に利用してもらえること」が重要だと私は考えています。特に「より多くの開発者に利用してもらえること」は私たちのリニューアルプロジェクトでも重要な判断軸です。 それを踏まえて以下の内容をご覧いただくと、理解が深まると思います。 私たちがツールを導入する前にどのような課題があったのか ツールを導入することでどのような状態を目指していたか 比較検討したツールと比較の軸 導入の成果 特に最後の導入の成果は私のイチオシです。オブザーバビリティのツールを導入することでどのような問題が解決できるようになったのかという話は、現場のエンジニアだけではなく導入を判断する立場のマネージャーにとっても気になるポイントだと思います。私たちのサービスは開発途中のため、現時点での成果が気になる方も多いでしょう。ぜひみなさまの目で確かめてみてください。 最後に Findy ToolsへDatadogに関するレビューを寄稿した話でした。今後オブザーバビリティのツールを導入しようと考えている読者のみなさんはぜひ参考にしてみてください。 今回のレビュー寄稿にあたり、当時からドキュメントを残しつつ丁寧にDatadog導入をリードしてくれたSREチームの @okazu_dm さんと小笠原さんには感謝が尽きません。特に小笠原さんは今回のレビューの寄稿を行うにあたり、過去のやり取りの取りまとめやADRの整備を率先して進めていただき非常に助かりました。 もしレビューの内容について詳しく聞きたいという方がいましたら下記のイベントやTwitter (X) 等で気軽にお声がけください。 datadog-jp.connpass.com
はじめに みなさん、こんにちは!! 株式会社エス・エム・エスの川名と申します。 私は2024年7月にエス・エム・エスに入社し、人材紹介事業の業務基盤を開発する「BPR推進部 キャリア横断開発グループ」でテックリードを務めています。 この記事では、BPR推進部におけるテックリードのミッション、そして日々の課題にどのように向き合いながら事業貢献に紐づけているのかを、具体的な事例を交えながらご紹介したいと思います。 この記事を通してエス・エム・エスで働くことのやりがいや現在抱えている課題なども共有することで、皆さんが当社で活躍いただくイメージを持つ一助となれば幸いです。 我々のエンジニア組織については、弊社及川の記事『 Team Topologies で社内ユーザ向け業務システムを開発する組織を再設計してみた 』をご覧いただくことで、よりイメージが具体的になるかと思いますので是非ご覧ください。 自己紹介 簡単に私の経歴についてお伝えさせてください。 私はエンジニアになる前、工業製品の生産部門で1工程を担当していたのですが、製造にはある程度の型があり、その基準通りに生産する事だけが成果となっている事に個人的に違和感がありました。 生産数や品質をキープしながら、継続的にアウトプットし続ける仕事の大変さや重要性を理解する一方で、どのようにすればより良いアウトプットになるのか?そのための仕組み作りや設計に楽しさを見出し、それが実現できそうなソフトウェアエンジニアの道に進みました。 ソフトウェアエンジニアとしては、SIerのWebエンジニア、事業会社(小売)の情報システム担当、SaaS企業のコーポレートエンジニアとキャリアを積んできました。 コーポレートエンジニアになってからは、経営や事業部からの要求を直接ヒアリングし、要求を技術でどう解決するかに注力してきました。具体的には、Salesforceを中心としたCRM/SFAのカスタマイズや外部システム連携による業務プロセスの自動化、GCPやAWSを活用した連携基盤の構築、各種SaaSの導入・運用サポートによる生産性向上などが主なミッションでした。 単にシステムを導入/開発するだけでなく、それがビジネス価値にどう繋がるかを常に意識し、最適な技術選定やアーキテクチャ設計、コミュニケーション、DevOpsなどが得意な領域です。 私が感じるコーポレートエンジニアの魅力 職歴の中でも特にエンジニアとしての楽しさがより増したのが、コーポレートエンジニアとして活動し始めた頃です。SIer時代は開発するものが概ね決まっている事が多く、本質的には「どのような型や基準を作るべきなのかを考える事」がほとんどハンドリング出来なかったように思います。 コーポレートエンジニアというロールの魅力はエンジニアリング面からビジネスのOps改善を事業部と一緒に進められたり、より良いアーキテクチャを自分たちで考えたりしながらビジネスに貢献していける点です。 コーポレートエンジニアはステークホルダーと近い距離でコミュニケーションをとりながら、技術的な解とビジネス要求のバランスを取る難しさと面白さがあると感じています。 エス・エム・エスに入社した理由 上記のようにやりがいのある日々を過ごしていましたが、そんな中でも転職しようと思ったきっかけは、自分自身がまだまだ成長出来ると感じた事でした。 よりチャレンジングな環境で自分を成長させながら、それを事業成長に繋げられる事が実感できればより有意義なキャリアになると考えたのです。 転職活動を開始し、幸いなことにいくつかお声がけをいただく中で、最終的にエス・エム・エスに入社を決めた理由は以下です。 社会貢献度の高い事業且つ業界におけるシェアが大きい 規模感が大きい+エンジニア組織へのコミットメントから、「自身が最も成長できそうな環境」だと感じた オファー面談のメッセージに感銘を受けた 事業規模についてですが、エス・エム・エスは医療介護領域の人材紹介事業において大きく社会に貢献しているプレーヤーだと感じました。これほどの規模の事業を支えるエンジニア組織の成長に興味があったというのが最初のきっかけでした。 その後、Team Topologiesを利用した組織構造の改変や組織ミッションの見直し、アジャイルな組織への変革を行なっていることを伺い、この規模でありつつモダンな取り組みを行なっている事がとても魅力的だと感じ、結果的に自分の次の成長を実現するフィールドとして最適だと感じたのです。 所属する組織とミッションについて 当社エス・エム・エスには、全社の業務改善を推進する「BPR推進部」があります。その部内に、医療・介護業界の人材不足を解決する社内業務システムを開発する「キャリア横断開発グループ」が設置されています。私はその一員として、従事者様と事業者様をつなぐことを価値とした機能開発を担当する、「マッチングチーム」のテックリードを務めています。 キャリア横断開発におけるテックリードの役割 事業部やBA(ビジネスアーキテクト)といったロールのメンバーと日々コミュニケーションを取りながら、バックログアイテムの整理、最適なアーキテクチャ設計、リアーキテクティング、レビュー、リリース調整、運用、場面によって自ら実装を行うなど、開発ライフサイクルにおける全体を見ながら推進する役割になります。BAやチームリーダーがWhat/When/Who/Whyなどに重きをおき、テックリードとしてはHowを主軸にWhat/Whyも深掘りしていきます。 参考までに弊社のビジネスアーキテクトについては西田の記事を、チームリーダーに関しては井上の記事をご紹介させていただきます。 ビジネスアーキテクト × Salesforce:改善だけで終わらない、戦略推進と戦術実行を追求する BPR推進部の開発リーダーとしての取り組み テックリードの具体的な活動 ここからは私がチームの中で日々どのような観点で仕事をしているのか、さらに課題感や今後の展望などについてシェアさせていただければと思います。 私たちのチームではスクラムを用いてプロダクト開発を行っているので、今回はスクラムのイベント(プランニング、デイリースクラム、スプリントレビュー、レトロスペクティブ)を軸に活動をシェアできればと思います。 スクラムイベントへの関わり方 スプリントプランニング プランニングでは新たなスプリントでのゴール設定、取り組むべきバックログアイテムをチームで決定していきます。優先順位についてはチームリーダーやBAと会話をしながら調整し、開発視点で実現可能なラインを決定していきます。タスクの規模感についてはリファインメントという設計の時間を設けていて、そこでアーキテクチャなどをチームで共有しながら事前に算出する作業を行っています。アーキテクチャ検討時には既存のコードベース、技術的負債やスケジュールなど、トレードオフを考慮しながら、最終的にどこまでやるべきかを考えながら決定しています。ここがとても難しいところではありますが、醍醐味でもあると感じています。技術的にあるべき姿を考えながら具体化していく活動は、エンジニアにとってとてもやりがいのあるミッションだと思っています。 デイリースクラム 毎朝行っているデイリーでは主に開発メンバーから出たブロッカーについて確認するようにしています。テックリードという立場としては技術的観点で方向性について改めて議論が必要になった場合にスプリントゴールの達成に向けて各種調整を行なっていきます。私はデイリーだけでなくタスクを進める上で困ったことがないか?などをMTGの最後などに軽く聞くなどして発信しやすい環境づくりを心がけています。そうすることで1人だけでタスクをこなしているという感覚から、チームミッションとして捉え、全員でゴールに向かって動けるとメンバーに感じて欲しいからです。 スプリントレビュー スプリントレビューではチーム内で「受け入れ要件」と「完了の定義 / Definition of Done (DoD)」の確認を行い(プロダクトレビュー)、ステークホルダーのレビューはスクラムイベント外で実施しています。この時、当初の見積もりと異なっていた点や改善出来そうな点や疑問点などをチームでディスカッションしながら次のプランニングに向けて改善内容を確認していきます。またリリース後については事業部メンバーに利用状況などをヒアリングする場面もあります。 レトロスペクティブ スプリント終了時の振り返りはKPTを利用してディスカッションしています。また今期からFour Keysを軸とした開発生産性指標のメトリクスをFindy Team+で確認する取り組みを開始しました。コミットからオープンまでのリードタイムやオープンからレビューまでのリードタイムなど各種KPIをスプリント間で比較しながら、要因の深掘りをすることでより良い開発体験を実現するための情報収集やファシリテーションを行なっています。 上流での関わり方 テックリードという立場は基本的に「How」に責務を持っています。「こういうものが欲しい」という要求があって、どう実装すべきかという「How」を考えて具体に落とし込む作業です。 しかしながらエス・エム・エスでは何を作るべきなのか?という事業部やBAとのディスカッションにも関わることができる楽しさがあると思います。 時間的な制約もあるので全ての会話に入ることは難しいのが現実ですが、大規模なテーマの改善においては開発者として参加することができ、「エンジニアだから事業の事は分からないだろう」といった空気感もなく、分からない事も丁寧に教えていただく事が出来る点がとても助かっています。これは各自が弊社の 理念 を大切に思い、「情熱」「誠実」をもって「プロフェッショナル」であることを追求する という考え方を基本としていることから生まれている文化だと思います。 開発生産性向上に向けた取り組みとその意義 今期、私たちのチームおよび組織全体では「開発生産性の向上」を重要テーマとして掲げ、さまざまな取り組みを進めています。 私たちが担当するモノレポは、10年以上にわたり機能追加と改修を重ねてきた結果、現在では認知負荷の高さや技術的負債の蓄積が課題となっています。こうした背景の中で、いかにして継続的に価値を届け続けるか、どのように開発生産性を高めて変化に強い開発体制を築くかが、私たちにとって喫緊のチャレンジです。 このような取り組みを通じて、 「高齢社会に適した情報インフラを構築することで人々の生活の質を向上し、社会に貢献し続ける」 というエス・エム・エスのミッションを、より高い次元で実現していけると確信しています。 なお、開発生産性向上の取り組みについては、エス・エム・エス BPR推進部にて導入している、 経営と開発現場をつなぐ戦略支援SaaS「Findy Team+」 をぜひご参照ください。 We are hiring!!! 私が考えるエス・エム・エスで働く魅力は、社会が抱える大きな課題の一つである高齢化社会の領域で貢献していけることにあると思っています。 同時にとても難易度が高い領域であるとも感じていまして、まだまだエンジニアの手が足りていない状況です。 今回の記事を読んで共感いただけた方、共に成長しながら社会に貢献していきたいと思ったエンジニアの方、ぜひ一度カジュアル面談などでお話しましょう! open.talentio.com
はじめに @emfurupon777 です。エス・エム・エスに入社したのが2022年1月なので、3年ちょっとたちました。ようやくエス・エム・エスで働いているのだという実感も得始めているところで、これまでに経験してきた環境とは実感の仕方が異なることに面白みを感じ始めています。 この感覚をもって、Slackに戦略コンサル出身の経営陣が作り上げた前々職での実感を『変態的に優秀な人たちに引っ張り上げられつつ搾り取られ続けているような感覚』(※これは最大限の賛辞のつもりです)と表現したところ、プロダクト組織の責任者である @sunaot からも『奇遇ですね。私も以前の職場(私の前々職とは同じ戦略コンサル出身の別人による経営)のときはそういう感覚でしたw』と返ってきたので、妙な納得感がありました。一方で、「なるほど @sunaotも異なる実感がありそうなので、やはりエス・エム・エスで求められることはこれまでの経験と異なるのだなー」と再認識し、マネージャーとして考えていることをポエムとして書いていきます。(あくまで一社員としての私見ですので、その点はご容赦ください) 視座をあげるということ VUCAなどという小難しい表現を用いるまでもなく、変化の激しい現代において。目の前にある今イシューだと見えているものに正面からぶつかって、砕けて、を繰り返していくだけでは、なかなか前に進むことができなくなる状況はまま発生し、『視座を上げて見つめ直してみて』(意訳ですが)と、1on1などの場で伝えたり、伝えられたりした経験を持つ方は多いのではないでしょうか。 マネージャーとしてはチームに求めるべきことだと理解はできるものの、視座という言葉の必要性をうまく言語化し、説明することに難しさを感じていました。受け手側も、『それはマネージャーであるあなたに必要なものであって、自分には関係ないのでは?』と咀嚼しきれないのではないでしょうか。(私自身、かつてそう感じた一人です) チームへの役割期待 少し話は変わりますが、ここで前提を2点おさえておきます。 1点目は、社内の”チーム”定義です。 エス・エム・エスにおけるチームは短期と中長期、主戦場と周辺、時間軸に対する成長へどう取り組むかを考えていくのが役割になっていて、担うことが期待されているのは主にこのような事です。 固有の文脈の解釈・評価 今期、半期の目標とKPI、そこへのプラン おや、、一般的に言われるマネージャーの役割と認識されている事の相応の内容が、エス・エム・エスでは、一般的にマネージャーの役割とされる内容の多くが、チームへの期待として明文化されていますね・・・ アウフヘーベン(止揚) つづいて2点目は、上位グレードに対する期待値です。 弊社プロダクト責任者の @sunaotが書いた社内ドキュメントの中にこんな記載があります。 答えがなく選択肢複数の中でアウフヘーベンするのが上位グレードのイメージ あれ?おやつの話ですか?あ、違った。 Google日本語辞書より引用 ある命題(テーゼ)と対立関係にある命題(アンチテーゼ)を統合し、より高い次元の命題(ジンテーゼ)を導き出す止揚(アウフヘーベン)の考え方を土台とした思考法があり、これを弁証法というそうです。 重要なのは、対立する2つの命題(テーゼとアンチテーゼ)に優劣はなく、片方がもう片方を打ち消すのではなく、統合され進化していくという点です。なるほど。 一見、矛盾や対立する要素を統合し、より高次の価値を創出するための重要な手法で、この考え方は、利益追求と社会貢献、短期的な目標と長期的なビジョンなど、経営における多くの課題に適用されるとのこと。 (一般的に)マネージャーとはなんなのか マネージメントとは「なんとかすること」というのはよく言われることで、その任にあたっている人は感覚的にもこの表現はしっくりくる気がしています。 ところが、「うちの会社のEM / PdM / PjMって何をする人なんですか?」という、特定のアクションによってマネージャーの役割が定義されているかのような質問を投げかけられることが多いように感じています。 なぜそう感じるのか。試しにAIにマネージャーの果たす役割を尋ねてみると・・・ 業績管理と目標設定 人材管理と育成 コミュニケーションと連携 モチベーション管理 etc. なるほど、確かにこれをやる人がマネージャーという感じの答えが返ってきて、確かに表層でわかりやすく観測できるのはこういうことかもしれないという気はします。 エス・エム・エスにおけるマネージャーとは エス・エム・エスのプロダクト組織でもEMという表現をすることや、プロダクトマネージメントグループが存在するため、それを担う人という意味で共通認識を持つためにPdMといった表現をすることはそれなりにあるのですが、各人が担う期待は均一ではなく、事業遂行に必要な能力と、それぞれの得意・不得意などによってグラデーションがついています。(あたりまえのことを言っていますね) 普段の業務では、『EMだからこのアクションをする』『プロダクトマネージャーだからこのアクションをする』といった職種に縛られた考え方はしていません。マーケットに向き合う上で必要なことを自らのスタンスで取捨選択し、優先順位をつけながら推進していくことが求められています。(もちろん、全てのタスクを自分一人で実行するのではなく、仲間の力を借りて実現していく必要があります)。 この役割は一般的な企業であれば『経営層』や『ボードメンバー』、場合によっては『役員』といった、会社上の機関として位置づけられる立場の者が担う割合が多いと感じます。しかし、エス・エム・エスは役員が少ない経営体制であることからも推測できるように、それぞれの社員に明確な権限移譲が行われている組織です。 この移譲を受けて事業を推進する主体がマネージャーなのだと私は解釈しています。エス・エム・エスでは組織階層の中でのポジショニングを表す表現は必要としていない実情があります。たとえば、最近多く使われるようになってきた印象の表現に”VPoE”がありますが、社内で議論をしていく中で、「なんか誰もVPoEを名乗る必要性を感じてないね・・」となる瞬間があったりします。 どういう取り組みが必要なのか 私個人の経験では『社長意識』、@sunaotの経験では『2ランクアップ』、そしてエス・エム・エスでは経営層との縦横の連携など、優れた経営を行っている組織では、何らかの形で視座を高める取り組みが推奨されていると感じます。 表現の違いはあれど、行き詰まったり迷ったりした際は、意識的に自身の視座を上げるか、あるいは(無理にでも)視座を上げてくれる人に積極的に関わっていく(例えば1on1を申し込むなど)ことで、アウフヘーベンを体現するための新たな視点が得られるのではないでしょうか。。 もちろん良書を読んでインプットするといったことも重要だとは思いますが、組織として事業を推進していくにあたって、対話を重ねていくのは必要不可欠です。この対話を疎かにせずに行動し続けることができるのであれば、それぞれ得意領域は違えどマネージメント適正はあり、経営的思考を歩んでいくことにも繋がっていくと考えています。 組織が成長する中で、時には矛盾や対立構造が生じることがあります。そんな時こそアウフヘーベンを意識し、それぞれのチームが発揮している価値を尊重した上で統合していく、そうした戦略的な役割を担う意識を持つことが最重要であると考えます。。 おまけ 最後に @sunaotの記載を紹介しておきます。 ここでいうマネジメントというのが、EMなのかアーキテクトなのかPdMなのかデザインマネージャーなのか、実情でいくとこれはどれでもいいなあというのが今の状況で、職種的適切さよりも個人能力依存の限界のほうが早く来ている印象がある 問題に取り組み、前へ進めることができているのならば、それは良いマネジメントでありバックグラウンドの選別をしている余裕はない いや、マジで余裕はないですw すべての事業領域で仲間を求めていて、求人票の表現としては例えばEMといった一般的な表現はとっていますが、細かい表現にこだわる必要はありません。実体として今回記載させていただいたように、”事業を推進するマネージメント”に興味がある方はぜひカジュアル面談で意見交換したいです!というくらい、私たちは仲間を求めています。
みなさんこんにちは! プロダクト推進本部の人事をしている まゆゆ です。 エス・エム・エスはファインディ社主催の「 開発生産性Conference 2025 」にブース出展および登壇することになりました! 開催日程は7/3 - 7/4の二日間で開催方式はハイブリット形式、オフライン会場は東京丸の内のJPタワーホール&カンファレンスとなっています。 エス・エム・エスはシルバースポンサーとしてブース出展をするとともに、7/4に弊社開発部のメンバーが登壇します。 今日はその内容について少しお伝えさせてください。 登壇について 介護/障害福祉事業者向け経営支援サービス「カイポケ」のリニューアルプロジェクトを行なっている中で、開発者の生産性を向上させる取り組みとして技術戦略チームを発足し運営しております。 今回はその取り組みの成功事例・・・ではなく敢えて「失敗談」をお伝えさせてもらえたらと思っています! タイトル:「失敗から再構築した開発推進チームの立ち上げ」 登壇日時:7/4 (金) 15:25〜 オフライン登壇会場:ホールB 登壇者紹介:2名 タイムテーブルはこちら 👉 https://dev-productivity-con.findy-code.io/2025/detail/aDlc4Phu ※ 大変ありがたいことにオフライン会場は満席となり、現在はオンライン参加のみのお申し込みを受け付けているとのことです!お申し込みをお待ちしています! 登壇者1 : 鄧 皓亢(でん はおかん) 株式会社エス・エム・エス プロダクト推進本部 カイポケ開発部 アーキテクト/PdM データサイエンティスト、データエンジニア、フルスタックエンジニアを経てCTOに就任し、技術戦略と開発文化を推進し、海外・新規事業の立ち上げやレガシーシステムのリファクタリングなどもやってきました。 エス・エム・エスではカイポケリニューアルプロジェクトのアーキテクト兼開発推進チームのPdMに就任して分析を前提としてシステム設計と開発組織の効率化を推進しています。 飼っている猫がとっても可愛いです!ジーパンを育てること、木工家具のメンテが趣味です! 登壇者2 : 空中 清高(そらなか きよたか) 株式会社エス・エム・エス プロダクト推進本部 カイポケ開発部 エンジニアリングマネージャー Webフロントエンドエンジニア→Webサーバーサイドエンジニア→Androidアプリケーションエンジニアという経緯でソフトウェアエンジニアをやってきて今に至ります。 DroidKaigi と iOSDC Japan、PHPerKaigi のコアスタッフをしています! PCゲームやボードゲームが好きで、日本酒やウイスキーを嗜みます。 ブース出展について エス・エム・エスのブースでは、当社の事業内容やエンジニアリングに関する取り組みをご紹介します。 ブースではみなさんにデモ画面を触っていただき、日頃の取り組みについて少しでもお伝えできたらと思っています! またささやかではありますが、ちょっとしたコンテンツや、ノベルティをご用意してお待ちしております。 季節柄、アイスクリームスプーンをご用意する予定です。 尚、数に限りがございますためなくなり次第終了となります。 またエス・エム・エス登壇の後はブースでAsk The Speakerの時間があります。 おしゃべり大好きなメンバーばかりなので、どんな些細なことでも気になることやご質問などがあったら是非お立ち寄りください:) ブースの場所は受付入ってすぐです! (オレンジの丸あたり) フロアマップ 👉 https://dev-productivity-con.findy-code.io/2025#floormap それでは当日ブースでたくさんの方とお話しできるのを楽しみにしています!
はじめに はじめまして。 人材紹介開発グループでweb履歴書作成サービス『履歴書できるくん』の開発を担当している松尾と申します。 2020年に新卒入社し、昨年度よりスタートしたweb履歴書プロジェクトでwebの開発を担当させていただいております。今回はそんな新規サービスの立ち上げからリリースまでの経緯と振り返りについてお話しできればと思います。 プロジェクト発足 転職活動において、履歴書の作成は転職活動の内定を左右する大変重要なプロセスです。それ故に多くの労力を必要とします。たくさんの文字を書かなければいけなかったり、少し難しい文章を考えないといけなかったり。さらに、弊社の人材紹介サービスを利用いただく場合は、転職活動をサポートするキャリアパートナーに作成した履歴書の画像を送付し、その画像に対してキャリアパートナーが添削を行うというフローで履歴書作成が行われておりました。 これにより、質の高い履歴書の作成は実現できていた一方で、システムがない中での運用は多くの時間と手間を必要としていたため、よりスムーズな転職活動のご支援に向けた改善が求められていました。 今回のプロダクトでは、上記の課題を解消し、求職者とキャリアパートナーの双方にとってより良い体験を提供することを開発の軸に据えました。 プロダクトでの解決 本プロジェクトでは履歴書作成から添削までを一貫して行えるWebサービスを開発しました。このプロダクトは、求職者がスムーズに履歴書を作成・提出できるだけでなく、キャリアパートナーとのやりとりも簡潔かつ効率的に進められるよう設計されています。 具体的な機能は以下の通りです。 自動入力機能と豊富な例文 住所検索APIを用いた住所の自動入力や、生年月日から学歴の入学・卒業年を自動算出する機能、弊社人材紹介サービスで取り扱う職種に最適化された資格一覧や例文一覧を取り揃え、履歴書作成にかかる様々な手間を削減しています。また、添削にかかるリソースも大幅に削減できる見込みです。 データの自動保存 履歴書は自動的に保存されるため、途中で編集を中断しても安心です。プライベートとの両立の中で、忙しい日常の隙間時間に履歴書の作成を進めることができます。 キャリアパートナーとのスムーズな連携 作成された履歴書は、キャリアパートナーに自動連携されます。通知を受け取ったキャリアパートナーはWeb上で履歴書を閲覧でき、リアルタイムで添削ができます。 PDFダウンロード 完成した履歴書はPDFとしてダウンロード可能です。電子書類としての提出のほか、コンビニでプリントアウトすることもできるため急な提出にも即座に対応できます。 これにより、求職者の作業負担を大幅に軽減しつつ、サービス全体としてのサポート品質を向上させることができました。 大変だったこと プロジェクトを進めるにあたって、いくつかの困難にも直面しました。特に印象的だったのは、不確実性の高い課題への向き合い方とプロジェクト状況に応じた意思決定です。 不確実な課題にどう取り組むか 今回の開発チームは私含め比較的キャリアの浅いメンバーで構成されています。そのため、ゼロからプロダクトを立ち上げるという経験が不足しており、「何から手をつけるべきか」「どこまで決めれば開発に進めるのか」といった基本的な判断に迷う場面が多くありました。 そのような中で意識していたことは、「不確実性の高い領域から優先して取り組む」でした。最も見通しが立っていない部分から調査・検証を行うことで、その後の判断や設計の前提となる材料を早い段階で得るように心掛けていました。 また、判断の精度を高めるため、シニアエンジニアとの壁打ちやステークホルダーとのコミュニケーションを積極的に行い、プロジェクトのフェーズに応じて「今私たちがやるべきことは何か」をチーム内で意識的にすり合わせるようにしていました。 このような試行錯誤を繰り返す中で、チーム全体が「完璧な見通しがなくても、小さく進めて調整すればよい」と考えられるようになり、不確実性を前提に前進できる自走力が徐々に育っていったと感じています。 スコープ調整と意思決定 こうした不確実性の高い課題に対して優先的に向き合いながらも、プロジェクト全体を前に進めるには、状況に応じた柔軟な意思決定が求められました。 実際にプロジェクトを進める中で、当初の計画にはなかったタスクや新たな課題が判明し、当初想定していたスケジュールでのリリースは現実的ではないという判断に至りました。そこで私たちは、現時点で実現できる最も価値のあるプロダクトとは何かを考え、リリースブロッカーを洗い出すことで、機能の優先順位を見直しながらスコープの調整を行いました。 結果的に、限られた時間とリソースの中で価値のあるリリースを実現できたということが、チームの大きな自信につながりました。 最後に リリースから間もない段階ではありますが、早速次のような成功事例が寄せられています。 履歴書の作成が心理的なハードルになっており、なかなか転職活動に踏み出せなかった求職者の方が、このツールを使って履歴書を提出してくださった 他社の人材紹介サービスと併用していた求職者が、履歴書作成までサポートする一貫したサービス提供を理由に、最終的に弊社を通じて転職を決めてくださった またキャリアパートナーからは、当初予定していた完璧なリリースができなかったことに対して 「自分たちが活用して意見を出していける、自分たちによってよりよいサービスになる」 機能追加をきっかけに、中長期的なご支援や定期的なフォローアップが可能となり、より一人ひとりに寄り添ったサポートができるようになった といった前向きなフィードバックをいただいています。 当初の計画からスコープを絞り込んでのリリースでしたが、限られたリソースと不確実性の中で「何を作り、何を作らないか」を判断し、プロダクトの価値を最大化するという経験ができたことは、今回のプロジェクトを通じて得られた最大の学びでした。 今回得た学びを活かしながら、求職者、キャリアパートナー双方の課題に向き合い、価値あるプロダクトを届けられるように引き続き取り組んでいきたいと思います。