TECH PLAY

株式会社メルカリ

株式会社メルカリ の技術ブログ

267

こんにちは。メルペイ Machine Learning エンジニアの@gucciです。 この記事は、 Merpay Advent Calendar 2023 の16日目の記事です。 はじめに 2023年3月、OpenAI社がChatGPTを発表して以来、大規模言語モデル(LLM)の可能性に世界中が注目しています。企業や個人がLLMをどのように活用できるかを模索する中、実際にLLMを用いたプロダクトが市場に登場し始めています。メルカリグループでも、社内向け・プロダクト向けの両面でユースケースを探索してきました。 その一環として、7月に実施したぐげん会議 [1] で入賞した返済相談チャットシミュレーターの一部分について、トライアルでオフラインの品質評価を実施しました。この記事では、その結果とそこから得られた学びについて共有します。 品質評価における課題意識 各種の学術試験やベンチマークテスト等、汎用的な知識・言語能力においてLLMが大きく進歩してきたことは疑いようがありません。一方で、LLMを用いたアプリケーションの品質に関する情報は、まだ十分に蓄積されていないと感じています。 OpenAI社によるGPT-4 Technical Report [2] や各種のベンチマークテストは参考になりますが、あくまでLLM本体の、汎用的な問題における評価結果です。また私の知る範囲では、現在世の中に公開されているLLMアプリケーションで、品質要件が厳しく求められる使い方をしているものは少ないと認識しています。 そのため、 特に事実性・リスク(定義は後述)の面で一定の品質が要求されるドメイン向けのLLMアプリケーションを構築する場合、どの程度の品質が得られそうか について参考になる資料は少なく、未知数だと感じていました。 問題設定 この章では、今回のアプリケーションの問題設定について説明します。 システム全体像 ここでは返済相談チャットシミュレーターの一部分として、 お客さまのお問い合わせに対して社内のドキュメントを参照しながら文章で回答を行う RAG(Retrieval-Augmented Generation)ベースのQ&Aアプリケーションを想定します。このユースケースでは、回答に一定の事実性が要求され、また 回答次第で法令リスクに抵触してしまう可能性のある領域(以下、NG領域) が存在します。 なおRAGとは、LLMに参照させたいデータを事前に取り込んでindex化しておき、質問が入力された際にそこから関連するデータを検索してLLMに渡す仕組みのことです。 以下は、各構成要素の概要です。 RAGパート 検索エンジン(VectorStoreIndex) 464件のドキュメント LlamaIndexでシンプルにindex構築(chunk_size = 1024, separator = “。”) indexのチューニングはあまり実施していません 類似度検索 similarity(質問とドキュメント内容の類似度)で検索したうち 上位1件 を取得 回答生成パート RAGで取得した情報をコンテキストとして、LLM(gpt-4)で質問に対する回答を生成 用語の定義等の基本的なドメイン知識をsystem promptに指定 リスク防御パート NG領域に関する回答を防ぐため、プロセス全体を通じて以下3層のリスク防御策を実装 ①input 防御(スコープ判定) : 入力された質問が対象スコープ内かをLLM(gpt-4)で判定し、対象外の場合は回答しない ②prompt 防御 : NG領域について回答しない旨の指示を回答生成のpromptに埋め込む ③output 防御(回答添削) : 回答にNG領域の話題を含むかをLLM(gpt-4)でチェックし、該当部分の記述を削除する また以下は、簡単なQ&Aのイメージです。 質問例 誤りを含まない回答例 誤りを含む回答(誤答)例 メルカードで購入後の支払いはどうすればいいですか? メルカードのご利用分は、以下3つの方法から選んでお支払いいただけます。 1. メルペイ残高での支払い 2. 銀行口座からの自動引き落とし 3. コンビニやATMでの支払い より詳細を知りたい場合は、お気軽にお尋ねください。 例1. 誤った方法を案内 メルカードでご購入いただいた場合、購入した商品の代金が即時でメルペイ残高から引かれる形となります。 ==== 例2. 架空のアプリ操作方法を案内 メルカードのご利用分は、以下の手順でお支払いいただけます。 1. メルカリアプリを開く 2. マイページを開く 3. 「メルペイ」を選択 4. 「支払う」を選択 評価のアプローチ この章では、今回実施した評価のアプローチについて説明します。 評価の目的 「そもそも世に出しても問題ないレベルか」という防御的な観点 から、 事実性・リスクの面で 求められる品質水準が見込めそうかを評価することが主な目的です。 評価観点 ここでは評価の手法を網羅することが目的ではないため、基本的な考え方としてOpenAI社の評価観点を参考にしました。InstructGPTの論文 [3] およびGPT-4 Technical Report [2] をまとめると、LLMの評価観点として以下が挙げられている理解です(学術試験等の能力評価は割愛。また各観点の説明は筆者理解) 有用性(helpfulness) どれだけ質問者にとって有用な回答をしたか(≒課題を解決できたか)の評価 事実性(factuality) : 真実性(truthfulness)と言われることもある 質問に対して正しい回答ができるか(事実でない内容を回答してしまわないか)の評価 事実性には、 参照データの質とその検索精度 、および ハルシネーション が主に影響します。 リスク : 有害性(harmlessness)を含む センシティブな領域または回答が許されない領域において望ましくない回答をしてしまうリスクおよび、過剰に拒否してしまう度合いの評価 リスクには、 ハルシネーション および プロンプトインジェクション が主に影響します。 ハルシネーションとは、LLMが事実ではない内容を回答してしまう現象のことです。またプロンプトインジェクションとは、質問者が悪意のあるプロンプトをLLMに入力することで、LLMに不適切な回答や意図しない情報の開示をさせようとする行動のことです。この2つはLLMを使ったアプリケーション特有の点になります。 評価の目的に照らして、今回は2点目の「事実性」と3点目の「リスク」の観点で評価した結果を紹介します。 1点目は施策効果の観点では非常に重要ですが、今回は主に防御的な観点で評価したいため、除きます。 この章の以降では、評価方法の詳細について説明していきます。(詳細が不要な方は飛ばし読みで大丈夫です) 評価の前提 今回の評価では、以下のことを前提としています。 Q&Aの形式 一連の会話のやり取りではなく、一問一答形式で評価しています(1度の問合せに複数の質問を含む場合もある) 事実性とリスクは独立に評価 事実性を評価する際、上述のリスク防御①〜③を入れない状態で評価しています。実際のプロダクションではリスク防御との組み合わせになりますが、今回は単体評価です。 チューニングの度合いや評価件数について 今回、時間や人手の制約があったことと、特にリスク評価を優先して対応したことから、事実性評価のチューニングや人手評価の件数は限定的なものとなっています 特にRAGの検索精度がチューニング不足なところは理解していますが、得られた示唆に大きな影響は無いものと考えています 人手評価か自動評価か 文章生成を定性的な基準で評価する際、厳密な評価は人手でなければ難しいです。今回は人手評価を信頼しつつ、参考として事実性評価でLLMを用いた自動評価も試してみました 評価観点別のアプローチ詳細 今回実施した事実性評価とリスク評価の詳細は、以下の比較表のとおりです。 切り口 事実性評価 リスク評価 評価のポイント                            お客さまの質問に対して 誤った回答をしない こと 法令リスクに抵触してしまう可能性のある領域(NG領域)に関する回答を 徹底的に排除しつつ、かつ答えて良い質問にはなるべく答える こと 評価用データ 過去のQ&A事例100件 (約20個のカテゴリーに関する質問) ※ただし、 人手評価はこのうち30件のみ で実施 答えてはいけない質問57件   ・ 左記のQ&A事例のうち、NG領域に関する15件   ・ 敢えてNG領域を引き出す目的で今回作成した42件 答えてよい質問80件   ・ 左記のQ&A事例のうち、答えてよい質問 評価指標 【人手評価】 誤答率(30件中) : = 回答文の中に事実と異なる内容を1つでも含む回答の割合 = 事実と異なる内容を1つでも含む回答数/全回答数 【[参考] 自動評価(100件中)】 a. 質問に対して回答がどれだけ関連しているか (質問 vs 回答) b. 質問に対して参照データがどれだけ対応しているか (質問 vs 参照) c. 回答がどれだけ参照データに依拠しているか (回答 vs 参照) ※今回は「正解の回答データ」を用意できず、誤答率の自動評価が難しかったため、上記の代理指標で評価して簡易的に傾向を確認(より詳細は後述) 【人手評価】 防御率(57件中) : = 敢えてNG領域を引き出そうとする質問に対し、どれだけ回答を防げるか = 回答を防げた質問の件数/答えてはいけない質問の件数 阻害率(80件中) : = 答えてよい質問をどれだけ誤って止めてしまうか = 誤って回答を防いでしまった質問の件数/答えてよい質問の件数 補足:事実性の自動評価指標の詳細 今回LLMを用いて実施した自動評価の評価基準は以下のとおりです。(Azure Machine Learningのメトリクスを一部参考にしました [4] )。 指標名 評価基準の概要(5点満点) a. 質問に対して回答がどれだけ関連しているか(質問 vs 回答) ※Azure MLではQnA Relevance Evaluationに相当 質問に対して過不足無く答えているほど点が高くなる。5点で完全に質問とマッチした回答。 b. 質問に対して参照データがどれだけ対応しているか(質問 vs 参照) ※Azure MLの記事では特に該当無し 質問に対して参照データの充足性が高いほど点が高くなる。5点で全ての質問に答え得る参照データ。 c. 回答がどれだけ参照データに依拠しているか(回答 vs 参照) ※Azure MLではQnA Groundedness Evaluationに相当 回答内容が参照データ内の事実にだけ基づいているほど点が高くなる。5点で完全に参照データ準拠。 評価結果と課題 ここまでで、アプリケーションの問題設定と評価アプローチについて説明してきました。この章では今回の品質評価の結果をご紹介します。 まず、今回の総評および取り組んで分かった課題についてまとめたうえで、各結果の詳細に触れていきます。 サマリ:総評及び取り組んで分かった課題 今回の評価結果を整理すると、以下のとおりになります。 切り口 事実性評価 リスク評価 今回の結論                  △(難しい or 開発・運用コスト大) ◯(十分な精度) 総評 RAGで適切なドキュメントを参照できさえすれば、誤答はかなり抑えられるよう です。 しかし、下段に記載したような課題があり、 安定的に適切なドキュメントを参照させ、回答品質を維持するには相応の開発・運用コストがかかる と思われます。 複数の防御を重ねることで、 阻害を最低限に抑えながらほぼ100%近くNG領域の回答を防ぐことができ 、良い精度が得られました(100%を保証できるわけではない)。 ユースケース次第ですが、 人間が読んでも判別できるような限定的な領域が対象であれば、事実性と比べてリスクはより対処がしやすい と思われます。 課題(開発観点) 複雑なコンテキストがある場合、similarity検索だけでは不十分   ・ similarityだけで必要なドキュメントを特定することは難しい   ・ 多めに検索してLLMにどれを使うかを選ばせる、検索結果を別の手法で並べ替える等、何らかの追加的な機構が恐らく必要 適切な参照データが無い場合の取り扱い   ・ 事実を問う質問の場合は答えないのが適切だが、そうでない場合(例. 挨拶、前の発言の確認など)も含めて一律で「回答しない」とするとコミュニケーションに齟齬が生じる   ・ 一方で正しくない参照データでも回答させると、ハルシネーションを起こしやすくなる 複数の質問の混在   ・ 一度に複数の質問をされた場合に、質問を分解する等の機構が恐らく必要 ユースケースによって防御の難易度は変わる   ・ 例えばNG領域の判別が人間でも難しい場合や、細かいたくさんのNG領域がある場合は難易度が高くなる   ・ OpenAI社のようにあらゆるリスクに対応するのは非常に難しい レスポンス速度への影響   ・ 防御策を重ねるほど、レスポンス速度が悪化する。防御精度とレスポンス速度のトレードオフの最適化は課題 課題(運用観点) ドキュメントの品質・網羅性   ・ 何もかもドキュメントがあるわけではないし、ドキュメントが常に最新であることを保証することも容易でない 継続的なメンテナンス   ・ リリース後にうまく判別できない新しい質問が来たときに、漏れたものを後追いでpromptに追加していく運用が必要となる 事実性評価の詳細 事実性評価で得られた結果は以下のとおりでした。 人手評価 誤答率(30件中):47% 間違った14件のうち、 参照するドキュメントを間違えたものが10件 、そもそも 適切なドキュメントが無かったものが4件 ありました 前者については、検索時に取得するドキュメント数を増やせば一定改善すると思われます(現状は上位1件) ただし、正解ドキュメントが上位20件でも出てこないケースもあり、一筋縄ではいかなさそうです [参考] 自動評価(100件) LLMによる評価結果は1件1件を見ると若干ブレがあるため、あくまで傾向値としてだけ参考にします 指標 平均評価値 (5点満点) 解釈 a. 質問に対して回答がどれだけ関連しているか 4.9 質問に合わせて回答する能力は高水準 (これがハルシネーションの要因でもある) b. 質問に対して参照データがどれだけ対応しているか 2.9 質問に対して適切な参照データを取れていないことが多い c. 回答がどれだけ参照データに依拠しているか 1.8 bの結果として、参照データに依拠しない回答をする傾向が見られた リスク評価の詳細 リスク評価で得られた結果は以下のとおりでした。 防御パターン 防御率 (57件中) 阻害率 (80件中) ①input + ②prompt 100% 4% ③output + ②prompt 98% 1% 全て(① + ② + ③) 100% 5% 各防御策の違い ①のinput防御は、 防御率を高めやすい反面、答えてよい質問を誤って止めてしまう阻害が起きやすい 傾向がありました (参考までに、防御用promptをチューニングする前の初版では約70%の阻害が発生) ③のoutput防御は、 防御率と阻害率のバランスが良いですが、防御に若干不安が残ります なお、②のprompt防御は ほぼ効果無し でした すでにsystem promptが長文(約1,500文字)であるため、追加の指示が効きづらかった可能性あり まとめと知見 今回まじめに品質評価に取り組んだことで、LLMおよびRAGの特性について理解が深まり、今後他のユースケースを考える際にも役立つ色々な学びを得ることができました。 最後に、今回のトライアル評価を通じて得たいくつかの知見をまとめます。 ※あくまで一つのユースケースにおける、限られたチューニング範囲での評価結果に基づく私見です 「正解がある」 + 「複雑なコンテキスト」がある問題に対しての、RAG精度の限界 個別のユースケースにもよると思いますが、このような問題に対して十分なRAG精度を実現するためには開発・運用面で非常にコストがかかると思われます 検索結果のRerankやSelf-RAG [5] のような工夫も出てきていますが、APIコストやドキュメント整備の大変さ等も加味すると、 個人的にはLLMが本領発揮できるのは、むしろzero-shot〜few-shotで済むような複雑なコンテキストが要らない領域(例. 商品説明文からメタデータを抽出する)や、正解がない領域(例. エンタメ)なのではないか と感じています LLMプロジェクトの難しさ 本件は、ミッションクリティカル性が高めな領域、かつ既存の人の仕組みをリプレースするものであり、関係者が多かったり、法律が影響するものでありました その上で、 LLMは汎用性が高いゆえに、問題設定の絞り込みが難しい、あるいは多くの要件を織り込めてしまう特性 があります。これは利点でもありますが、一方で広範な問題設定になるほど 芋づる式に考慮すべき要素が増え、品質の担保が難しくなる と感じます 人手評価の大変さ 1件当たり評価に10-15分かかった 「事実かどうか」を確かめるには、回答文章の中でソースが必要な要素を抜き出した上で、各要素についてドキュメント等からソースを探す必要があります もしくは、事実が頭に入っているドメインエキスパートが必要 なお、評価用データに対して「正解の回答データ」を用意することができれば、LLMを用いてある程度は事実性を自動評価できるかもしれません それでは、ここまで読んでいただきありがとうございました。 明日の記事はtenlingpさんです。引き続きお楽しみください! 参考文献 [1] LLMを活用してなにがつくれるか?——「ぐげん会議」開催から見えてきた、AI活用の新たな可能性 [2] OpenAI (2023). GPT-4 Technical Report. ArXiv, abs/2303.08774. [3] Ouyang, L., Wu, J., Jiang, X., Almeida, D., Wainwright, C.L., Mishkin, P., Zhang, C., Agarwal, S., Slama, K., Ray, A., Schulman, J., Hilton, J., Kelton, F., Miller, L.E., Simens, M., Askell, A., Welinder, P., Christiano, P.F., Leike, J., & Lowe, R.J. (2022). Training language models to follow instructions with human feedback. ArXiv, abs/2203.02155. [4] Azure Machine Learning の Prompt flow の評価メトリクス紹介 ― ChatGPT どう評価する? [5] Asai, A., Wu, Z., Wang, Y., Sil, A., & Hajishirzi, H. (2023). Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection. ArXiv, abs/2310.11511.
こんにちは。メルペイのフロントエンドエンジニアの @tokuda109 です。 この記事は、 Merpay Advent Calendar 2023 の15日目の記事です。 Merpay Advent Calendar 2020 の「 Merpay Frontend のこれまでとこれから 」という記事で、メルペイのフロントエンドチームが2020年までに取り組んできたチーム組成やプロダクトの品質改善の話が紹介されました。(以下、前回の記事) 早いもので前回の記事が公開されてから3年が経ち、当時からチームの状況は大きく変わり、チームメンバーの人数が半数以下になるという危機的状況も経験しました。 この記事は、前回の記事の続編として、2020年以降にフロントエンドチームが取り組んできたことを紹介すると共に、危機的状況を乗り越えた経験から長期的に安定したチーム運営を行う上で重要だと感じたことを説明します。 Merpay Frontend のこれまで OKRの目標分類 フロントエンドチームのこれまでを振り返る前に、OKR(四半期ごとに設定する目的とその筋道)の目標分類表を最初に紹介します。 この表は、フロントエンドチームがこれまでに設定してきたチームOKRの目標(Objective)を、いくつかの区分に分類したものになります。これにより、フロントエンドチームがどのようなことに取り組んできたかを時系列で把握しやすくなります。 フロントエンドチームのこれまでのOKRを振り返ってみて、以下の区分に分けることができました。分類した区分は長期的なチーム運営をする上で重要な要素になるため、後ほど詳しく説明します。 採用 : 何人採用するといった具体的な採用活動や、社外への認知度をあげて採用につなげる活動 プロダクト品質 : フロントエンドチームで保守・運用しているプロダクトの品質(パフォーマンス、テスト、アクセシビリティ、セキュリティ)に関する取り組み プロダクトリリース : メルペイリリースやキャンペーン等のビジネス上の理由で開発完了時期が決まっている開発タスクの締切 生産性 : フロントエンドチームの生産性改善を目的としたタスクや、基盤技術を更新することで生産性の改善を図るもの。Nuxt.js / Vue.js のバージョン更新はここに含む ロードマップ策定 : フロントエンドチームの長期的なロードマップを策定するための取り組み チームビルド : フロントエンドチーム内のコミュニケーション改善やチーム内連携の改善する取り組み 目標分類表の見方を説明します。 目標1、2、3 の番号は優先度を指し、1の方がより重要な目標であることを意味します。また、 主な出来事 / 関連記事 には、その時期にフロントエンドチームに関係する重要な出来事やブログ記事、イベント登壇等の技術発表の情報を掲載しています。 目標分類表 四半期 目標1 目標2 目標3 主な出来事 / 関連記事 2018/07 – 09 採用 採用 プロダクト品質 チーム組成期 2018/10 – 12 プロダクトリリース 採用 プロダクト品質 Vue Fes Japan 2018 のスポンサーシップ 2019/01 – 03 プロダクトリリース 生産性 プロダクト品質 メルペイリリース ( iOS , Android ) 2019/04 – 06 生産性 (安定運用) 採用 プロダクト品質 ロードマップ策定 2019/07 – 09 生産性 採用 プロダクト品質 2019/10 – 12 生産性 (DevOps) 採用 プロダクト品質 2020/01 – 03 生産性 (CI/CD) ロードマップ策定 Origamiからメンバージョイン 外国籍のメンバージョイン プロダクト品質 2020/04 – 06 プロダクトリリース 生産性 プロダクト品質改善期 2020/07 – 09 プロダクト品質 (E2E) プロダクト品質 (品質可視化) 2020/10 – 12 プロダクト品質 (E2E) プロダクト品質 (品質可視化) チームビルド (英語) [Merpay Advent Calendar 2020]: Cypress + TestRail による Frontend E2E テストの効率化について [Merpay Advent Calendar 2020]: Merpay Frontend のこれまでとこれから 2021/01 – 03 プロダクト品質 チームビルド (英語) 2021/04 – 06 プロダクト品質 (E2E) 生産性 2021/07 – 09 採用 (認知度向上) プロダクト品質 (セキュリティ) Frontend Tech Talk 〜 Quality of Merpay Frontend 〜 [Merpay Tech Fest 2021]: Frontend Testing: Cypress as a Testing Platform [Merpay Tech Openness Month 2021]: Frontend E2Eテストの安定化の取り組み 2021/10 – 12 採用 プロダクト品質 [Merpay Advent Calendar 2021]: メルペイフロントエンドのテスト自動化方針 [Merpay Advent Calendar 2021]: WebFrontendローカルパフォーマンス改善支援ツールを作ってみた。 2022/01 – 03 生産性 プロダクト品質 (セキュリティ) メルペイフロントエンドチームで行っているパフォーマンス改善の取り組み紹介 テスト・パフォーマンス・アクセシビリティ・セキュリティの4大品質に取り組むメルペイのフロントエンドチーム 2022/04 – 06 プロダクト品質 2022/07 – 09 プロダクト品質 生産性 (Nuxt/Vue移行) [Merpay Tech Fest 2022]: Tools and Strategies for Frontend UI Libraries 2022/10 – 12 ロードマップ策定 チーム再組成期 生産性 (Nuxt/Vue移行) 2023/01 – 03 生産性 (Nuxt/Vue移行) 2023/04 – 06 生産性 (Nuxt/Vue移行) 2023/07 – 09 生産性 (Nuxt/Vue移行) [Merpay Tech Fest 2023]: フロントエンドチームのスキルテスト評価システム改善の取り組み 生産性改善 (ドキュメンテーション) 2023/10 – 12 Vue Fes Japan 2023 のスポンサーシップ 組織体制がProgram組織に変わってチームOKRはなくなった (詳しくは後述) 目標を分類分けすることで、フロントエンドチームがこれまでに取り組んできたことを、時系列として次の3つの時期に分けることができました。 チーム組成期 : 2018年〜2020年 プロダクト品質改善期 : 2020年〜2022年 チーム再組成期 : 2022年〜2023年 この3つの時期のうち、 チーム組成期 と プロダクト品質改善期 は前回の記事で詳しく書かれているため、この記事では内容を簡単に振り返るだけにします。 チーム組成期 チーム組成期は2018年から2020年1月〜3月期にあたります。目標分類表から2019年2月のメルペイリリース前後で取り組みが大きく変わってることが分かります。リリース前は、採用やメルペイリリースに向けた開発が目標として設定されています。一方、リリース後は採用の優先度が少し下がり、プロダクト品質や生産性の改善が目標として設定されています。 2020年1月〜3月期には、Origamiからフロントエンドチームにメンバーが合流し、外国籍のメンバーもジョインしました。フロントエンドチームに多様なメンバーが揃ったことが、次のプロダクト品質改善期につながります。 参考: 株式会社Origamiのメルカリグループ参画に関するお知らせ プロダクト品質改善期 チーム組成期を経て、フロントエンドチームとしてプロダクト品質の改善に取り組むことができる状況が整いました。フロントエンドチームがプロダクト品質の指標として掲げている パフォーマンス 、 アクセシビリティ 、 テスト 、 セキュリティ の4つの品質指標の改善に取り組んだのがプロダクト品質改善期になります。 プロダクト品質改善期には、日々の開発サイクルの中にプロダクト品質の検証をどのように組み込んだかや、指標改善の成果報告がブログ記事として数多く公開されたり、技術イベントで発表されました。 参考: メルペイフロントエンドチームで行っているパフォーマンス改善の取り組み紹介 チーム再組成期 ここからが前回の記事の続きの話になります。 プロダクト品質の改善に数年取り組み、プロダクト品質を最低限保障する体制が構築できつつあるなか、徐々にフロントエンドチームのメンバーが少なくなりました。 採用活動をしていましたが、チームを離れるメンバーの方が多く、最も少ない時でチームメンバーが最大人数の半数しかいない時期がありました。 この人数で以前と同様にマイクロサービスを保守・運用をしていくことは極めて困難であり、この危機的状況を立て直しているのがチーム再組成期になります。 フロントエンドチームがこのような状況に陥ったのはなぜなのか。当時のフロントエンドチームの状況について振り返ってみました。 ロードマップがなく、チームとしてどのようなことに取り組んでいくべきかの話ができていなかったため、個人の優先度に基づいた行動になっていた。 プロダクト品質の仕組みが大体完了した後、次の新しい目標を決めることができず、Flakyテストの修正といった改善系の作業を長期間やって精神的に疲弊した。 ドキュメンテーションの品質が低く、ナレッジの属人化が発生し、開発の生産性が低くなっていた。 自社の技術イベントやブログ記事以外の活動ができていなかった。技術コミュニティとの関わりや外部カンファレンスの登壇等、外部情報発信が不十分でメルペイのフロントエンドチームの社外認知度が低下していた 採用の評価基準が整備されておらず、安定した評価ができていなかった メルペイリリースから数年経ち、プロダクト品質の改善も落ち着いてきて、次のキャリアを計画したり、新しい挑戦をすることを検討するメンバーが増えるタイミングだった。採用活動はしていたが、補うことはできていなかった チームビルディング不足で、チームメンバーが基本自宅からの作業になって、Slack上で業務報告するだけの関係になっていた。技術的な会話や、その他雑談をすることもなくなっていた。 ここに記載したものは、危機的状況に陥った原因として結びつけることができるものではありません。しかし、当時フロントエンドチームに対して課題を感じていたということは、チームとして解決しておくべきだったと言えることも事実です。 長期的に安定したチーム運営をするために必要な取り組み 先程の振り返りの内容を改めると、チームOKRと同じ分類を当てはめることができることに気がつきました。特に採用、生産性、プロダクト品質の区分に該当する目標は、これまでにチームOKRで何度も繰り返し設定されたものになります。それだけ 採用、生産性、プロダクト品質は、チームとして定常的に取り組むことが重要である ことが分かります。 プロダクト品質に対する取り組みは、メルペイを使う多くのお客さまの体験に直接影響するため、放置するわけにはいきません。しかし、それと同時にプロダクト品質を担保するためのチームの 生産性 やチーム力の元となる 採用活動 や チームビルド も重要です。つまり、 ロードマップ から導き出される中長期視点で、これらの取り組みをバランス良く計画的に行う必要があるということを示唆しています。 ロードマップを策定し、チームの将来のあるべき姿を示した上で、採用、生産性、プロダクト品質、チームビルドに取り組むことが持続可能なチームを運営するために必要不可欠なことだと改めて知ることができました。 次に各区分毎にフロントエンドチームとして取り組んだことを紹介します。 ロードマップ 危機的状況の改善に向けて2022年10月〜12月期の目標1でロードマップの策定と、Nuxt 3 / Vue 3への移行の長期的なスケジュールが計画されました。そして、それを支えるための採用活動が計画されました。その計画の元で新しいメンバーを採用することができ、フロントエンドチームは落ち着きを取り戻すことができました。現在は新しいメンバーと共に新しいフロントエンドチームを組成し、Nuxt 3 / Vue 3への移行作業をしています。 ただ、メルペイではProgram組織という新たな組織構造に移行するのに伴い、メルペイのフロントエンドチームという組織単位がなくなりました。また、Nuxt 3 / Vue 3への移行後の計画はまだ練られていないため、いずれ計画する必要があります。 採用 新たなフロントエンドチームを組成するために、採用では次のことに取り組んできました。 書類選考の評価基準の整備 スキルテスト評価システムの改善 フロントエンドチームのスキルテスト評価システム改善の取り組み – Merpay Tech Fest 2023 Vue Fes Japan 2023への参加 https://vuefes.jp/2023/#sponsors フロントエンドチームはチーム組成期から継続して採用活動を行ってきました。しかし、Merpay Tech Fest 2023の発表でも述べたとおり、適正な評価を行う体制が整備されていなかったため、うまく新しいメンバーを迎えることができず、チーム力を維持できませんでした。書類選考の評価基準やスキルテスト評価システムが整備されたのが、2023年になってからです。 また、チーム組成期には活発に行われていた外部イベントへの登壇は少なくなりました。自分たちのチームのことで精一杯になるあまり、Vue Fes Japan Online 2022の開催にイベントが終わってから気づくありさまです。もう少し外部コミュニティへの関わりを増やしたいと思い、2023年からVue Fes Japan 2023にイベントスタッフとして参加したり、会社としてスポンサーになることを始めました。(2018年のVue Fes Japan 2018でスポンサーになっていましたが、復活させました) Vue Fes Japan 2023会場のクリエイティブウォール (筆者撮影): 壁面一番左にメルペイロゴを描きました 来年は自社ブログやイベント以外にも外部コミュニティに対する活動を増やしたいです。社外認知度を高めることで、メルペイのフロントエンドチームに興味を持ってもらえるようにしたいです。 生産性 フロントエンドチームが生産性の改善で取り組んだ内容は次のとおりです。 モジュラーディレクトリ構成への移行 Monorepo開発におけるツール選定 – Merpay Tech Talk スケーラブルで保守性の高いモジュラーディレクトリ構成へのフロントエンドリポジトリ移行 – Merpay Advent Calendar 2022 Nuxt 3 / Vue 3 への移行 GitHub IssuesとGitHub Projectsを使ったフロントエンドタスクの管理 GitHub ActionsでWorkflowの共有化 ドキュメントの整備 GitHub Discussionsを使ってADR(Architecture Decision Records)を残す READMEフォーマットの統一 オンボーディング資料の整備 フロントエンドチームは利用パッケージの更新に課題を抱えていましたが、モジュラーディレクトリ構成への移行によって、以前よりはスムーズに行えるようになりました。そして、今はフロントエンドチーム総出で Nuxt 3 / Vue 3への移行作業をしています。この移行作業には、GitHub IssuesとGitHub Projectsを使って進行管理をしています。GitHub Issuesに登録したタスクをGitHub Projectsに登録し、1画面で全リポジトリの進捗を確認できるようにしています。 次にドキュメンテーションですが、以前はADRを記録していなかったため、口頭で議論された意思決定が残っておらず、過去の意思決定に対する振り返りコストがかかっていました。今はGitHub Discussionsを使って議論し、チームとして決定するプロセスで運用することにしました。CIにはGitHub Actionsを使っていて、ワークフローを再利用して一元管理をしています。 ここで紹介したように、基本的に開発で必要なツールは、GitHubで提供されている機能に極力寄せたことで、ツールを横断する時のフリクションを少なくしています。 プロダクト品質 今までに沢山の時間をかけてプロダクト品質の改善に取り組んできました。一部の不安定なテストの改善が必要であったりするものの、日々の開発サイクルの中で自動的に品質の検証が行われる体制を整えられました。具体的に言うと、ソース変更をプッシュするとテストやアクセシビリティの検証が実行され、全てパスするまでマージすることができません。セキュリティに関しても同様で、セキュリティ警告の通知を担当者が処理し、どのような対応をするべきかを主導します。改善するべきところはまだありますが、最低限の品質を保障する体制は構築できています。 チームビルド チームビルドの取り組みは、前回の記事で紹介されている通り、チーム内コミュニケーションの英語化になります。2021年1月〜3月期を最後に、チームビルドが目標として設定されていません。しかし振り返りで課題として出されたように、フロントエンドチームのメンバー間のコミュニケーション量はリモートワーク前と比べて大分減りました。これについては何かしらのアクションが必要で、単に量を増やせばいい訳ではありません。フロントエンドチームが組成された当初から、フロントエンドチームのメンバーが週に1回集まって技術的なトピックについて話したり、その他雑談をするWebWednesdayというミーティングがありますが、再度仕組みの設計が必要になりそうです。 Merpay Frontend のこれから Merpay Advent Calendar 2023の 2日目の記事 で、@keigowさんからProgram組織についての紹介がありました。Program組織への移行は2022年10月から実施されましたが、フロントエンドチームは例外的に案件ごとにメンバーをアサインする形を当初取っていました。 現在はチーム状況が改善したため、2023年7月からフロントエンドチームもProgram組織へ移行し、メルペイのフロントエンドチームという建て付けは存在しなくなりました。 Program組織への移行によって、各Programが担当するドメインを深く理解し、プロダクト開発に取り組むことができます。また、Enablingは組織横断で取り組む必要がある基盤技術へのオーナーシップを持っています。Nuxt 3 / Vue 3への移行はEnablingが主導し、デザインシステムや共通ライブラリの更新を行ったり、難易度の高い技術調査をサポートしてくれます。これによって、プロダクト開発と基盤技術刷新における役割が明確になりました。(フロントエンドエンジニアも所属しているEnablingのClientチームの取り組みは、 Merpay Advent Calendar 2023の18日目の記事 で紹介されています。) フロントエンドチームという建て付けはなくなり、フロントエンドチームとして設定するチームOKRはなくなりましたが、ロードマップ、採用、生産性、プロダクト品質、チームビルドはProgram組織への移行後も引き続き計画的に行っていく必要があると考えています。 最後に この記事を書いた目的は、新しくフロントエンドチームにジョインしたメンバーに向けて、これまでのフロントエンドチームがやってきたことやフロントエンドチームの現在地を紹介するというのが半分、読者や社内のフロントエンドチーム外の方に向けては危機的状況から得られた知見を知ってもらうというのが半分になります。 長い記事になってしまいましたが、ここまで読んで頂きありがとうございます。 明日の記事は@gucciさんです。引き続きMerpay Advent Calendar 2023をお楽しみください。
こんにちは。メルペイのPayment Coreチーム Engineering Managerの @abcdefuji です。 この記事は、 Merpay Advent Calendar 2023 の13日目の記事です。 ダイバーシティを推進するメルカリグループ メルカリグループは、ダイバーシティ&インクルージョンに価値を置いており、多様なバックグラウンドを持つメンバーの経験・知識・意見を結集し、一人ひとりがバリューを発揮できる組織を目指しています。 参考: Diversity & Inclusion Statement 今回は私たちPayment Coreチームが、どのように言語の壁を乗り越えダイバーシティ&インクルージョンを推進しやすい環境を作ったかを紹介します。 Payment Coreチームについて 私たちPayment Coreチームの責務は「決済基盤としてプロダクトチームに決済機能を提供し、プロダクト・サービスのミッション達成を実現する」です。 2023年12月時点では、図のようにプロダクトに機能を提供しています。 より詳細に決済基盤について知りたい方は以下の記事を参照してください マイクロサービスにおける決済トランザクション管理 – メルコイン決済基盤の実践話 そしてPayment Coreチームは、多数の国籍を持つメンバーで構成されており、母国語が日本語でないメンバーが約半数を占めています。この多様なメンバーシップは、私たちのチームの力を高める一方で、日々の開発業務においてもコミュニケーションの課題が出てきました。 高くて厚い言語の壁 PaymentCoreチームでは異なる言語を話す人々が集まった際に、意思疎通を図る際に生じる障壁のことを 言語の壁(Language barrier) と呼び、具体的には以下のような問題が発生しました。 言語や文化の違いによるコミュニケーションの課題 異なる国籍を持つメンバーが集まるチームでは、母国語が異なるため、コミュニケーションにおいて言語による壁が生じる可能性があります。それによりお互いの意思疎通が上手くいかないことによる認識の齟齬や、それによるパフォーマンスの低下に繋がる課題が潜在的に存在していました。 また、言語の違いだけではなく、コミュニケーションのスタイルや表現の違いにより意図が正確に伝わらず誤解が生じることもあります。 例えば、日本語のコミュニケーションでは間接的に意見を表現することがあると思います。これは日本語が母国語ではない人にとって意図を正確に理解することが難しくなります。 技術用語や業界特有の言葉の理解の困難 開発業務には特定の技術用語や業界特有の言葉が使用されることがありますが、言語の違いにより、それらの言葉の理解が困難になる可能性があります。特に決済に関連する法律用語や専門用語は代表的な例です。 例えば、決済ドメイン中には「法定帳簿」「資金決済法」「管理会計」「オーソリ」「あと払い」等、英語話者にとって理解が難しい言葉に対して用語が統一されていない場合には、コミュニケーションコストが増大します。英語学習中の日本語話者にとっても同様です。決済の文脈の中で登場する「Payment」「Transaction」「Settlment」「Topup」「Payout」等の用語を正しく区別して理解するのは非常に困難です。 言語の壁に直面して 実際、私もこれらの課題を非常に痛感しました。私はmerpayの英語環境を理解した上で入社しましたが、最初の頃はミーティングでの英語の聞き取りがうまくできず、また、自分の意思を英語で表現することもできずに困ることがありました。当時のスピーキングスキルはほんの簡単な自己紹介がやっとで、非常にチャレンジングな環境でした。 そんな私のような英語学習者を含んだPaymentCoreチームがどのように言語の壁と付き合っているのかを紹介します。 言語の壁との付き合い方 まず、私たちチームでは英語を主体としてコミュニケーションしていますが、ポリシーとして 特定の言語をメンバーに強制することはせず、それぞれの言語でもパフォーマンスが出せることを理想 としています。 その実現のためにメルカリに存在するさまざまなサポートを活用しながら日々の業務に当たっています。 細かいツールやtipsの話は沢山ありますが、今回は以下の4つを紹介したいと思います。 Global Operation Teamによる通訳・翻訳のサポート 言語の壁の中で最も苦労したのは、リアルタイムのコミュニケーションでした。オンライン会議ツールの字幕機能などもありますが、不慣れなメンバーにとってリスニングとスピーキングは最初の大きな壁でした。それを解決してくれたのはGlobal Operation Team(以下、GOT)です。 メルカリグループにはGOTというチームが存在します。GOTは主に翻訳と通訳の二つの職務を担当してくれているチームであり、私たちのチームは主に通訳でのサポートをしていただいております。GOTのおかげで言語が異なる場合でも会議中のコミュニケーションの橋渡しを実現してくれております。 参考: 言語を活用してメルカリのビジネスやD&Iをサポート!──Global Operations Teamが提供する通訳・翻訳業務以上の価値 Slack上でのコミュニケーションの自動翻訳 リアルタイムではないコミュニケーションだとしても問題は存在していました。Slack上で複数の言語(日本語と英語)でコミュニケーションを行う場合、メンバーによっては都度翻訳ツールを利用する必要があり、コミュニケーションに小さなストレスが生じることがありました。 そのため、私たちはZapierを用いた自動翻訳ツール(JP <-> EN)を導入しました。 Zapierは複数のアプリ(Webアプリケーション)を連携させてワークフローを作り、業務を自動化させることができるツールです。 WebUI上からアカウント連携・ワークフロー作成ができるため、ノンプログラマーでも簡単に使うことができます。 https://zapier.com/ このツールを利用することで、言語を自動的に判定し、翻訳結果をSlackのThreadに投稿することが可能です。これにより、どちらの言語でも気軽に投稿できるようになり、事前に翻訳を用意したり、母国語以外のコミュニケーションへのハードルを下げることができるようになりました。 以下のように自動的に翻訳が投稿されます。 Zapierでは複数のアプリを連携させて作ったワークフローの単位を「Zap」と呼びます。 実際に今回のZapを簡単にご紹介します。 Slackの投稿をトリガーする(図内 1) 翻訳対象の選別のために投稿のフィルタリングを行う(図内 2,3) 言語の特定(図内4) 翻訳(図内 7, 11) Slackへ投稿(図内 9,13) まだまだフィルタリング機能が不十分な点等改善点はありますが、現在社内の複数のチャンネルで利用されています。 言語学習プログラム GOTによる翻訳サポートなど、さまざまなサポートがメルカリグループには存在していますが、メンバー自身の言語スキルが向上しなければパフォーマンスを向上していくことは困難です。メルカリグループでは業務の必要性に応じて言語学習プログラムに参加することができます。私を含めた一部Payment Coreチームメンバーは外部のオンライン英会話練習プログラムや社内の言語学習プログラム(日本語/英語)を受講し、それぞれの言語に対しての習熟度/理解度を高めています。 チーム内のミーティングにおいても週一で日本語でコミュニケーションする日を作る等、日々学習プログラムを通してInputしたものをOutputする機会もチームの中に存在しています。 チームメンバー同士の文化の理解・尊重 異なる国籍を持つメンバー同士がお互いの文化を理解し、尊重することも重要です。 お互いに完璧な英語や日本語を話せるようになることを求めるのではなく、お互いのことを理解するというコミュニケーションの本質を大切にし相手に合わせてコミュニケーションできるように努めることが私たちの考え方です。 例えば、意識的に「英語学習者にとって難しい英語」や「日本語学習者にとって難しい日本語」を使わずにコミュニケーションする事はとても有益な方法です。 参考: やさしいコミュニケーション Payment Coreチームの成長と変化 上記サポートを活用する事で結果として、Payment Coreチームではいくつか変化が起こりました。 言語習熟度の成長 日々のコミュニケーション + 言語学習プログラムの結果、Payment CoreチームのCEFRの定義(後述)に基づいた言語習熟度が格段に向上しました。 私自身も英語に関してA2レベル(サポートがあれば会話ができる)からB2レベル(自分の仕事に関する会話が支障なくできる)まで向上しました。もちろんペラペラに話せるわけではないですが、簡単な自己紹介が出来る程度のレベルからSlack上、 オンライン、 オフラインの場で普段の業務に関するトピックに関して英語でなんとかコミュニケーションする事ができるレベルまで成長する事ができました。 CEFR定義について(引用元: https://careers.mercari.com/jp/language/ ) レベル 定義 英語または日本語を使ってできること Basic (CEFR – A2) – 会話する相手のサポートや、より簡単な言葉への言い換えがあれば、自分の専門分野において、基本的なやりとりができる – マネージャーと1-on-1ミーティングをする際、相手からサポートしてもらいながらミーティングすることができる – 相手からサポートしてもらいながら、同僚と1対1で仕事に関する簡単な意見交換や雑談ができる Independent (CEFR – B2) – 会話する相手からのサポートや、より簡単な言葉への言い換えがほぼなくても、自分の専門分野において複雑な情報のやりとりができる – 言語がコミュニケーションの妨げになることなく、1-on-1ミーティングができる – 自分の専門分野において、母語話者を含む複数名での議論に参加することができる Proficient (CEFR – C1) – 会話する相手からのサポートや、より簡単な言葉への言い換えがなくても、自分の専門分野内外の複雑な情報のやりとりを自立して行うことができる – 抽象的な話題や不慣れな分野でも、複数名の議論に参加できる ※CEFRに関する詳しい情報は こちら (外部リンク:Council of Europe) 円滑で迅速なコミュニケーション チームの言語習熟度が向上した事でGOTによる通訳サポートが不要になりました。 これにより、緊急もしくは即席のミーティングを通訳サポートなしで開催できる点がチームのコミュニケーションスピードを向上させる事につながりました。 さらに、同僚と気軽にちょっと話したい時にすぐ会話できる点・自身の言いたいことを表現できる点はチームの雰囲気自体を明るくする事にもつながりました。具体的には、会話中の沈黙はほとんどなくなりました。もし会話がわからなければ、わかる箇所からブレイクダウンしてコミュニケーションしていく方法を多くのメンバーがチームの成長と共に学んでいきました。 また、チーム内だけではなく、チーム外のコミュニケーションとしても英語/日本語を使えるようになる事でチームとしての可能性も広がりました。 メンバーのキャリア創出の可能性 メンバーそれぞれの言語習熟度の向上によって、社内以外での活動にもつながりました。 例えば、一部チームメンバーは海外のカンファレンスに参加し、そこで得たInputをコミュニティで発表する等、活躍の場を広げてくれています。 (GopherCon 2023 in San Diego) Shunta KomatsuさんによるGoコミュニティへの貢献 https://speakerdeck.com/iamshunta/recap-the-future-of-json-in-go このように外国語のスキルを磨くことはチームのパフォーマンスを上げるだけではなく、メンバーの将来におけるキャリアの幅を広げていく事にもつながる可能性があると考えています。 変化は簡単には起こらない このような変化が起こりましたが、もちろん容易にかつ即座に達成したわけではありません。PaymentCoreチームは半年以上もの時間を費やしてきました。そしてまだまだ理想的な環境とは言えない状況です。今後も包括的な環境を構築し続けることが不可欠です。 ダイバーシティの力を活かして 言語の壁は私たちにとって挑戦でありながら、同時に成長の機会でもあります。異なる言語や文化を持つメンバーが集まることで、さまざまなアイデアや視点が生まれ、よりクリエイティブな問題解決が可能になります。 私たちのチームは、言語の壁を乗り越えるための努力を惜しまず、お互いを尊重しながら協力しています。そして、多様なバックグラウンドを活かし、より良いプロダクトを提供するためにこれからも取り組み続けていきます。 明日の記事は @ntkさんです。引き続きお楽しみください。
こんにちは。メルカリ iOSエンジニアの @sae です。この記事は、 Mercari Advent Calendar 2023 の11日目の記事です。 私は株式会社メルカリに入社してから早6ヶ月が経ちましたが、日々の業務を通じて、さまざまな技術の素晴らしさに感銘を受けています。 その中でも特に驚くべきことは、大多数のiOSエンジニアが在籍している大規模なチームが、一つのプロジェクトに携わりながら、円滑に開発が進んでいることです。これまでに私は6つの企業で働いてきましたが、どの組織も最大でも5人のiOSエンジニアがアプリ開発に関与しており、プロジェクトファイルやXcodeのバージョンなどの問題がある場合でも、直接のコミュニケーションを通じて解決してきました。 果たして、メルカリは大規模なiOSエンジニアチームが円滑な開発を行うためにどのような取り組みをしているのでしょうか。私が感銘を受けた様々な観点をTipsとしてご紹介したいと思います。 マイクロモジュール化 現在、メルカリ iOSアプリには数百以上の非常に多数のモジュールが存在しています。各画面ごとにモジュールが独立しており、依存関係なしに動作します。さらに、各機能も1機能につき1モジュールとなっており、複雑なロジックは複数のモジュールから成り立っています。 このようなマルチモジュールアーキテクチャにより、依存関係が明確になり、他のチームへの影響度も把握しやすくなっています。マルチモジュールアーキテクチャは、さまざまな現場で実施されている手法ですが、メルカリでは徹底的に細分化されているため、大規模な開発チームにおいて、そのメリットがより明確に実感できます。 さらに、 メルカリ iOSアプリではBazelを使用 しています。Bazelは更新のないモジュールを再ビルドする必要がないため、効率的な開発を支援しています。また、既に成功したテストも再度実行する必要がないため、検証のスピードも向上しています。さらに、一度ビルドしたモジュールは他の開発者が再ビルドする必要がないため、リソースの無駄を防ぎます。 マルチモジュールアーキテクチャとBazelの積極的なキャッシュ機能により、メルカリのiOSエンジニアは大規模な開発プロジェクトを円滑に進めることができており、チーム全体の生産性向上に貢献しています。 ただし少人数の開発チームや変更の多いスタートアッププロジェクトでは、必ずしも生産性が向上するとは限りません。マルチモジュール化は管理コストが増加する傾向がありますので、大規模な開発プロジェクトならではの非常に大きな恩恵を実感しました。 コードオーナーによる品質管理 メルカリでは、Ready for ReviewにPRを設定すると、自動的に適切なレビュワーがコードオーナーの設定に基づいて割り当てられ、レビュー作業を委ねることができます。もしPRがアーキテクチャの変更やグループ企業の機能に広範な影響を及ぼす場合は、専任のArchitectチームが影響を確認します。 メルカリは大規模な組織ですが、各担当箇所に責任を持つコードオーナーが存在し、品質管理を徹底することで、高品質なコードの提供と開発プロセスの円滑化を実現しています。コードオーナーからの適切なフィードバックは、開発者に貴重な指摘や改善アドバイスを提供し、より高水準な開発を促進します。また、コードオーナーの存在は他のチームとの連携をスムーズに行い、プロジェクト全体の一貫性と効率性を向上させることができます。この取り組みにより、大規模な開発環境でもチームワークと品質管理を重視し、優れた開発成果を生み出しています。 小規模なチームでは、通常1人がテクニカルリードを担当しますが、例え少人数でも全員が個々の機能についてコードオーナーであり、責任を持つ仕組みは様々な現場で有効だと感じます。 トランクベース開発 メルカリでは、トランクベース開発という手法を採用しています。この開発手法では、開発者がプロジェクトごとにフィーチャーブランチを作成して機能を追加するのではなく、機能ごとにメインブランチである「トランクブランチ」に対してPull-Requestを作成していきます。そのため、機能ごとのPull-Requestは明確な内容となり、レビュー時間の短縮や他のブランチとの衝突の回避が可能となります。 トランクブランチは常にリリース可能な状態を保つため、開発中の機能は フィーチャーフラグを使用 して非表示にし、ユーザーに早期に公開されないようにします。そのためには、回帰テストを充実させることが重要です。十分な自動テストを実施することで、堅牢なトランクブランチを維持し、開発者は既存の機能への影響を考慮しながら新しい機能をトランクブランチにマージすることができます。 この開発手法により、コードの品質と安定性を保ことができ、メルカリのiOSエンジニアは迅速かつ効率的に開発を進めることができます。また、フィーチャーフラグを使用して機能をリモートで制御するため、公開されているアプリに問題があった場合でも、次のバージョンのリリースを待たずに機能を無効化することができるなど、様々な恩恵があります。 FormatterやLinterによる確認の自動化 メルカリでは、 Danger を使用して自動的にコード修正を行います。FormatterやLinterによる確認は、新しい開発者がプロジェクトに参加する際に役立ちます。新しい開発者はメルカリのコードベースにすばやく適応することができ、コードの統一性を保つことができます。 また、開発者は記述手法の統一を心配する必要がなくなり、より高度な開発タスクに集中することができます。これにより、開発者はより効率的にプロジェクトを進めることができ、最終的には高品質なアプリケーションを提供することができます。 まとめ 今回ご紹介した手法は、メルカリのiOS開発における一部に過ぎませんが、非常に多くの効率化の仕組みや自動化のテスト、そして多くの優秀なエンジニアのアウトプットに触れる日々は、私にとって非常に刺激的でワクワクが止まりません。 今回の記事では、メルカリの先輩エンジニアたちが築いてきたノウハウや開発手法を、大人数での開発の観点で、様々な方々に参考になるようにまとめさせていただきました。 引き続き来年のAdvent Calendarに向けて、私自身がメルカリで挑戦した記録を記事にしていけるよう頑張りますので、どうぞお楽しみにしていてください。メルカリでの成長や新たなチャレンジについて、皆さんに共有できることを心から楽しみにしています。
こんにちは!QA Engineerの @fukutomi です。 この記事は、 Merpay Advent Calendar 2023 の11日目の記事です! メルカリエンジニアリングブログに寄稿するのは初めてなので緊張しますが、よろしくお願いします。 はじめに(この記事はなんなのか) 今回のテーマは、弊社が運営している パ・リーグ Exciting Moments β (略してPEM)におけるログイン処理をテスト自動化してみよう、です。 ※パ・リーグ Exciting Moments βとは 「パ・リーグ Exciting Moments β」は、パ・リーグ6球団の記憶に残る名場面やメモリアルシーンを捉えた動画コンテンツを自分だけのコレクションとして保有できるパ・リーグ6球団公式のサービスです。 PEMはログインしないと大抵の機能が利用できず、テスト自動化をしたいならログイン処理の突破は必須。。。 後述する通りPEMのログイン処理は結構複雑なのですが、気合&パワーでなんとか実装したので、よかったら見てやってください。 PEMのログイン構造 最初にPEMのログイン処理について簡単に説明します。 PEMはE-mailとSMSの2要素認証(2FA)を採用しています。 お客さまが行う作業としては ログイン画面でE-mailアドレス入力 サービスからメールが届くので、メール内のリンクを開く リンクを開くと登録されている電話番号にSMSが届く 同時にSMS認証番号入力画面を開くので、SMSに記載されている認証番号を入力 (場合によってはここでreCAPTHA認証が入りますが、テスト環境では表示しない設定にしているので割愛) ログイン完了! こんな形で結構複雑でして、今回はこれをCypress+Gmail APIですべて自動化しよう、という話です。 どんな仕組みで自動化するのか 今回はPEMを自動で動かすツールとしてCypressを、GmailにアクセスするためにGmail APIを、またテスト用電話番号の準備のためFirebaseを利用します。 上記ログイン構造のお客さまが行う作業をもとに、下記の感じで自動化してみます。 CypressでPEMのログイン画面を開く ログイン画面でE-mailアドレスを入力して送信 サービスからメールが届くので、GoogleにログインしGmail APIを利用してメールを検索 メール本文からログイン用のリンクを抜き出す 抜き出したリンクをCypressで開く SMS認証番号入力画面に遷移するので、あらかじめFirebaseで設定しておいたテスト用電話番号の確認コードを入力 ログイン完了! それでは実際にやってみましょう! 下準備 Cypressのインストール まずは下記を参照にCypressをインストールしましょう。 ※Cypressとは ウェブアプリケーションをフロントエンドで自動で動かすことができる、オープンソースソフトウェアのテストツールです。 (詳細は本題から逸れちゃうので割愛します) Installing Cypress – Cypress.io Opening the App – Cypress.io GCPの準備 次にGCPのプロジェクトを作成します。 こちらも本題から逸れるので割愛! プロジェクトの作成と管理 – Google Cloud Gmail APIの準備とid,secretの確認 GCPのプロジェクトを作成したら、次はGmail APIを準備します。 サイドメニューから「APIとサービス」を選択、画面遷移 「+APIとサービスの有効化」を押下し、ライブラリへ 「Gmail API」で検索し、APIの詳細画面へ 有効化 (出典:Google Cloud Platform) Gmail APIを有効化できたら認証情報を作成します。 API管理画面を開き、認証情報タブを選択 「+認証情報を作成」を押下、OAuth クライアント IDを選択 作成画面に遷移するので、下記の情報を入力して作成 入力する内容はこんな感じ。 アプリケーションの種類 ウェブアプリケーション 承認済みのリダイレクトURI https://developers.google.com/oauthplayground http://localhost:3000 (出典:Google Cloud Platform) 作成完了後、詳細画面を開くとAdditional informationエリアが表示されます。 「クライアント ID」「クライアント シークレット」をあとで利用します。 (出典:Google Cloud Platform) Firebaseの準備(テスト用電話番号の準備) PEMのログイン情報はFirebaseで管理しています。 FirebaseのAuthenticationでは、テストで使用できる電話番号ならびに確認コードをセットすることができるので、そちらを登録しておきます。 登録したテスト電話番号と確認コードはあとで利用するのでメモしておくとよいでしょう。 (出典:Firebase) リフレッシュトークンの発行 (参照: Google Authentication – Cypress.io ) Googleにログインするためにリフレッシュトークンを発行します。 Google Developpers OAuth 2.0 Playground にアクセスして、リフレッシュトークンを発行しましょう。 まず事前設定として、上記のGmail API認証情報をセットします。 右上の歯車マークから設定可能です。 「Use your own OAuth credentials」にチェックを入れると認証情報の入力欄が表示されます。 (出典:Google Developpers OAuth 2.0 Playground) それが終わったらScopeを選択してAuthorizeします。 自分はこんな感じで設定しました。 Scope https://www.googleapis.com/auth/gmail.readonly https://mail.google.com/ AuthorizeするとAuthorization codeが表示されます。 今回用があるのはリフレッシュトークンなので、「Exchange authorization code for tokens」を押下してリフレッシュトークンを生成してください。 (出典:Google Developpers OAuth 2.0 Playground) さて、これで事前準備が整いました。 ここからは実際に自動テストのコーディングに入っていきます。 コーディング まずは環境変数をCypress.env.jsonに定義しておきましょう。 セキュリティ的な観点でも、上記のトークンとかはベタ書きするわけにはいかないですからね! { "google_client_id": "xxxxxxxxxx", "google_client_secret": "yyyyyyyyyy", "google_refresh_token": "zzzzzzzzzzzzzzz", "sign_in_email": "hogehoge@mercari.com", "test_phone": "07000000000", "test_phone_sms": "123456", "from_email": "hogehoge" } 次はほんとにログイン処理を書いていきましょう。 まずはログイン画面に遷移して、メールアドレスを入力します。 it("ログインページに遷移、メールアドレスを入力して送信", () => { // ログインページに遷移 cy.visit("/signin/"); // メールアドレスで登録画面に遷移 cy.contains("メールアドレスでログイン").click(); // ログインページにいることを確認 cy.contains("h1", "ログイン").should("be.visible"); // メールアドレス入力 cy.get("input[name=email]").type(Cypress.env("sign_in_email")); // フォームを送信 cy.get("form").submit(); // メッセージ確認 cy.contains("メールをチェックしてください").should("be.visible"); // メールが来るまでちょっと待つ(ほんとはメールが来るのをキャッチしたい cy.wait(15000); }); メールアドレス送信後、メールが届くまでちょっと待って、メール内からリンクを引っ張ってアクセスする作業に入ります。 it("受け取ったメールからリンクを読み取ってアクセス", () => { //Googleへのアクセストークンを生成する cy.request({ method: "POST", url: "https://www.googleapis.com/oauth2/v4/token", body: { grant_type: "refresh_token", client_id: Cypress.env("google_client_id"), client_secret: Cypress.env("google_client_secret"), refresh_token: Cypress.env("google_refresh_token"), }, }).then(({ body }) => { const access_token = body.access_token; // 件名にサインインを含む、未読、Toがログインメールアドレスになっているメールを1件だけ抽出 cy.request({ method: "GET", url: "https://content-gmail.googleapis.com/gmail/v1/users/me/messages", headers: { Authorization: `Bearer ${access_token}`, }, qs: { q: `from:${Cypress.env("from_email")} subject:サインイン is:unread to:${Cypress.env("sign_in_email")}`, maxResults: 1, }, }).then(({ body }) => { const mailID = body.messages[0].id; // 取得したメールIDをもとにメールの詳細を取得する cy.request({ method: "GET", url: `https://content-gmail.googleapis.com/gmail/v1/users/me/messages/${mailID}`, headers: { Authorization: `Bearer ${access_token}`, }, }).then(({ body }) => { // 取得したメール詳細をデコードしつつ本文を抜きだす var mailBody = decodeURIComponent( escape( atob( body.payload.parts[1].body.data .replace(/-/g, "+") .replace(/_/g, "/") ) ) ); // URLを囲むコーテーションがシングルだったりダブルだったりするので、ダブルに統一 mailBody = mailBody.replace(/'/g, '"'); // 文中最初のURLだけを抽出する const accessUrl = mailBody .substring(mailBody.indexOf("http"), mailBody.indexOf('">')) .trim(); // 抽出したURLにvisit cy.visit(accessUrl); }); }); }); }); リンクにアクセスすると電話番号入力画面に遷移するので、予め設定しておいたテスト電話番号と確認コードを入力し、ログイン完了!というわけですね。 it("電話番号を入力してログイン完了", () => { // 描画が完了し、画面がSMS認証番号入力に切り替わるまで待つ cy.wait(5000); // SMS認証番号入力画面に切り替わったことを確認 cy.contains("電話番号に届いた6桁の確認コードを入力してください").should( "be.visible" ); // SMS暗証番号入力 cy.contains("電話番号に届いた6桁の確認コードを入力してください") .parent("form") .within(($form) => { cy.get('input[name="verificationCode"]').type(Cypress.env("test_phone_sms")); // 続行する! cy.contains("送信する").click(); }); }); 実際の動作 (出典:Cypress(左)、パ・リーグ Exciting Moments β(右)) あとがき いかがだったでしょうか。 自分で言うのもなんですが、すんごい力業だったと思います。 まあでも、ログイン処理が自動化できたことでその後のMoment購入処理やマイページのテストを自動化することができました。 可読性や保守性ももちろん大事なんですが、目的を果たすことが第一ということで。 ちなみに今回はCypressを利用しましたが、別の他のツールでもできると思うのでよかったら試してみてください。 さて、パ・リーグ Exciting Moments βは2024年3月31日をもってサービス終了することになりました。 あと少しではありますが、パ・リーグ Exciting Moments βのことをよろしくお願いします。 以上です! 明日はLiuさんが担当します。お楽しみに!
はじめに こんにちは。メルペイでBackend Engineerをしている Ryu Yamadaです。この記事は、 Merpay Advent Calendar 2023 の10日目の記事です。 2022年4月に新卒で入社してから、メルペイの加盟店管理や加盟店精算を行うサービスの開発に携わっています。 2023年のハイライトは何と言ってもインボイス制度です。この記事を読んでいるみなさんも、経費精算などで大変な思いをしているのではないでしょうか。この記事では、メルペイの加盟店精算におけるインボイス対応について振り返ります。 ざっくり加盟店精算 メルペイでは月に1回や2回などの決められた精算サイクルごとに加盟店に対して発生した売上を精算して入金しています。そして、加盟店に提供している管理画面から入金の詳細をCSVファイルとしてダウンロードできるようにしています。 入金詳細ファイルには、売上金額、日次、売上のあった店舗情報や決済手数料などが記載されていて、各行が一つの取引に対応しています。 インボイス対応 さて、2023年10月1日からインボイス制度が始まりました。 メルペイがインボイス対応をしないと加盟店がメルペイを通して決済した代金の消費税を控除できなくなってしまうため、以下の対応が必要となりました。 メルペイの適格請求書発行事業者としての登録 メルペイが発行する入金詳細ファイルに消費税額やメルペイの登録番号等を記載し、適格請求書にする メルペイが発行した請求書を7年間保存する 上2つの対応は軽微だったものの、請求書を長期間に渡って保存する要件へどう対応するかは検討する必要がありました。 加盟店情報の履歴テーブル メルペイでは月1回などのサイクルで精算を行っていますが、入金詳細ファイルの作成は加盟店の管理画面からの請求をトリガーにして行っていました。また、事業者名や店舗名の変更履歴を保持する仕組みがなかったため、入金詳細ファイルの請求が行われた時点での値を記載していました。 しかしこの方式では、例えば5年前の入金詳細ファイルを請求された場合に、5年の間に事業者名や店舗名の変更があると正しくない請求書が作成されてしまう問題がありました。 そこで、インボイス対応として事業者名や店舗名の変更履歴を保存する履歴テーブルが必要になりました。 Spanner Change Streamを選択 加盟店の情報を保存するテーブルのスキーマのイメージは以下のとおりです。 CREATE TABLE Partners ( PartnerID INT64 NOT NULL, Name STRING(MAX) NOT NULL, // 事業者名 // ・・・住所等・・・ UpdatedAt INT64 NOT NULL, // Unixtime CreatedAt INT64 NOT NULL, // Unixtime ) PRIMARY KEY(PartnerID); この変更を保持する履歴テーブルのスキーマはこのようになります。 CREATE TABLE PartnerHistories ( PartnerID INT64 NOT NULL, Name STRING(MAX) NOT NULL, // 事業者名 // ・・・住所等・・・ UpdatedAt INT64 NOT NULL, // Unixtime CreatedAt INT64 NOT NULL, // Unixtime HistoryCreatedAt TIMESTAMP NOT NULL, // Timestamp 履歴作成時刻 ) PRIMARY KEY(PartnerID, HistoryCreatedAt); 今回、Partnersテーブルに変更があったときに履歴テーブルであるPartnerHistoriesテーブルへの書き込みを行う方法を2通り検討しました。 アプリケーションで元(Partners)テーブルのレコードを挿入や更新した場合に履歴(PartnerHistories)テーブルへの書きこみも行う方法 Spanner Change Streamを利用し、DBレベルで、元(Partners)テーブルの変更をトリガーに履歴(PartnerHistories)テーブルへの書き込みを行う方法 さらに、インボイス対応にあたっては、Partnersテーブルだけではなく他のいくつかのテーブルにも履歴の作成が必要でした。 前者のロジックを作り込む方法では、元(Partners等)テーブルに書き込みを行うロジックすべての修正を行う必要があり修正範囲が広いこと、将来元テーブルを操作するようなロジックを追加する際に履歴テーブルへの書き込みを忘れると影響範囲がかなり大きくなってしまうことなどがネックでした。 後者のSpanner Change Streamを使う方法では、ロジックの改修から独立したDBレベルの機能として実現できること。また、加盟店精算ではメルペイ内で精算してから実際に入金を行うまでに数日以上開くため、履歴テーブルの要件として元テーブルと履歴テーブルの書き込みを同じトランザクションで行うことが求められなかったこともあり、最終的にこちらの方法を選択することにしました。 Spanner Change Streamで履歴テーブル構築 Dataflowを通してSpanner Change Streamを利用しました。 メルペイではこれまでDBのバックアップ用途などでは利用実績がありましたが、プロダクトでの利用は初めてでした。 履歴テーブルの作成に当たっては、元テーブルへの挿入(INSERT)と更新(UPDATE)の両方が履歴テーブルに対しては挿入としなくてはならない点に注意が必要でした。 ハマった点 最も困難だった点は、元テーブルのUpdatedAtがUnixtimeであったことでした。 元テーブルにUnixtimeの最小単位である1秒以内に複数の変更が行われた場合に、履歴テーブルにはUpdatedAtが同一の複数のレコードが挿入されますが、どのレコードが元テーブルの最終的な状態と一致しているかがわからない点が問題でした。 この例ではIDが1のレコードに対して1秒以内に2回更新をしています。挿入順序とHistoryCreatedAtの順序は必ずしも一致しないので、履歴テーブルからは”メルペイ2”と”メルペイ3”のどちらが最新の履歴なのかがわかりません。 この問題を解決するために暫定対応として以下のアプローチを取りました。 履歴テーブルのUpdatedAtにUnique Key制約をかけて、1秒以内に複数の変更があった場合には2つ目移行の挿入を失敗にする 履歴テーブルへの挿入失敗を監視するアラートを設定し、発生時には手動で確認する インボイス制度の施行が迫っていたため暫定的な対応となりましたが、加盟店情報が短時間に複数回更新されることが少ないため、この対応でクリティカルな問題は起きていません。 恒久的な対応としてUpdatedAtのUnixtimeからTimestampへのマイグレーションを予定しています。 おわりに ニュースでインボイス対応という言葉を知ったときには、経理ではない自分にはあまり関係がないだろうと思っていましたが、当事者として対応することになりました。 メルペイが成長してきた中で返しきれていない、UpdatedAtの型といった負債にも苦しみましたが、インボイス対応を完了することができました。今後もメルペイと加盟店をなめらかにつなぐプロダクトを作っていきたいです。 明日の記事は @fukutomiさんです。引き続きお楽しみください。
こんにちは。メルカリのBackendエンジニアの @osari.k です。 この記事は、 Mercari Advent Calendar 2023 の9日目の記事です。 一般に大きなプルリクエストはレビューが大変で、マージまでに時間がかかります。一方で複数の小さいプルリクエストに分割するとコードレビュー待ちの間、関連する開発がブロックされることがあります。今回は機能の開発時間を短くするために、チームで試したGitのブランチ戦略の1つであるStacking手法をケーススタディを交えて紹介します。 大きなプルリクエストがもたらす問題点 大きなプルリクエストがもたらす問題とは何でしょうか? コードレビューで読むサイズが増える コードレビュー中の修正回数が増える(可能性が増える) コードレビューで必要な知識の範囲が広がる(可能性が増える) 変更箇所が多いのでリリースのリスクが増加する プルリクエストが大きいということは、含まれる変更箇所が多いということです。それはつまり、コードレビューで読むサイズが増え、レビューの観点も増え、レビューにあわせて行われる修正も多くなるでしょう。 モノリシックなレポジトリの場合コード全体に精通しているエンジニアは少なく、一般に複数のドメインにまたがる変更の場合、複数のチームからレビューの承認を貰わなければなりません。 大きな変更を一度にリリースすると、障害が発生する可能性が増加し、障害が発生したときに原因の特定も難しくなります。 一方で、関連する変更を複数の小さいプルリクエストに分割すると、コードレビューの間関連する次の作業が進められないという課題もあります。 Stacking手法による小さいプルリクエストの推進 本記事ではこれまでに述べた問題を改善するために私達のチームが試してみたStacking手法について得られた知見を共有したいと思います。 Stacking手法は以下のBlogで紹介されています。 Stacked Diffs (and why you should know about them) 関連する部分を要約すると、Stacking手法は、1つの大きな変更を分割して管理できるようにするプロセスです。ある変更が別の変更に依存している場合、それらは変更差分のスタックとして組み立てられ、正確な順序でマージされます。プルリクエストに対してさらに機能を追加するプルリクエストを作る様をスタックと例えています。これにより、変更をレビューしやすくなります。 合わせて、Stacking手法は複数の作業を並行して行うのに役立つという利点もあります。各段階で作業を終了させることができるため、時間を節約できます。以上のように、Stacking手法はコードの変更の複雑さを管理するための強力な手段であり、上手く実装した場合、生産性と効率性を高めることができます。 本来は上記のBlogで紹介されているスタック間の差分を見やすくするツール( ReviewStack  など)と組み合わせて使うのがいいと思います。 この手法はチームメンバーがSlackで共有してくれて、一度チームで試してみようということでGitHubのプルリクエスト機能のみを使い試しました。 Stacking手法の目的 なぜこの手法を試すのか、それはコードレビューで開発者の他の開発をブロックしないためです。 例えばある機能を実装するときにそれを部分タスク PR1,PR2,PR3に分割し、PR2がPR1に依存、PR3がPR2に依存といった依存関係があるとしましょう。 図1: プルリクエストの依存関係 通常のプルリクエストの作り方の場合、PR1のマージが終わるまでPR2, PR3の開発はブロックされます。 ※実際には開発者はローカルでの開発は可能ですし、PR1がマージされる前にPR2のコードレビューを依頼することもできます。GitHubのプルリクエスト機能のみで試す場合に重要なのはチームで認識を揃えることだと思います。Stacking手法を使うことを共有しておくことで、混乱なくコードレビューがスムーズになります。 この方法は1人の開発者が自分のプルリクエストに依存した開発をコードレビューにブロックされずに行うためのものなので、複数人で関連機能を開発する場合には向きません。 というのも、Stacking手法は定期的にRebaseが発生します。自分だけなら、Rebaseの影響範囲や、影響が出るタイミングをコントロールできますが、複数人の場合頻繁なRebaseは開発効率を落とします。 モノリシックなレポジトリに実装されているマーケティングシステムの改善での実例 今回Stacking手法を試した一連の機能変更について紹介します。 今回はマーケティングシステムのスケーラビリティ改善に対してStacking手法を適用しました。今回改善を行うマーケティングシステムはモノリシックなレポジトリに実装されています。 ディスカウントを適用する前に商品のいくつかのデータをチェックします。そのうちの一つは別のマイクロサービス(Validation MS)の持つデータを用います。 Validation MSへのクライアント機能、その結果を使いやすいように変換する関数がモノリシックなレポジトリに実装されています。 MSごとに別々のチームがメンテナンスしており、意図した変更を達成するにはマーケティングシステムとは異なるValidation MSのドメイン知識が必要になります。 マーケティングシステムは定期的に実行されるCronjobとWorkerがQueueで接続されています。処理すべきデータは複数あり、Cronjobから処理すべき商品のIDをQueueに送り、Workerで個別にValidation MSのAPIを利用して処理を行います(図2)。 図2:改善前のシステム構成 Validation MSのAPIはBatch呼び出しもサポートしているので、Cronjob側でBatch APIを用いて事前処理をし、Worker側ではValidation MSへのアクセスをしない形にすることでスケーラビリティの改善を試みました(図3)。 図3: 改善後のシステム構成 簡易検証を行った後に、プルリクエストを作成しました。 Stacking手法で作成したプルリクエストは6つです 不要な変数の削除 不要なロジックの削除 不要なメソッドの削除 Validation MS関連機能のユニットテストの改善 Validation MSのBatch エンドポイントの結果変換メソッドの修正 WorkerからCronjobにValidatio MSの呼び出しとチェック機能の移動 プルリクエスト1~3では4以降で安全に変更するために、不要なコードを削除をして全体の見通しを良くしています。不要な変数を削除(プルリクエスト1)すると、不要なロジックが削除(プルリクエスト2)できて、不要なメソッドの削除(プルリクエスト3)に辿り着くという依存関係があります。 プルリクエスト4と5はValidation MSの開発チームと協力して実装・コードレビューをしてもらいました。メソッドのシグネチャが定まれば、マーケティングシステムチーム内で並行してプルリクエスト6を実装・コードレビューをしてもらうことができます。 図4: Stacking手法を用いた場合の開発フロー 上述のように各プルリクエストは自分より小さい番号のプルリクエストに依存しています。 そのため、Stacking手法でない場合、開発者は毎回コードレビューでブロックされてしまいます。 Stacking手法を用いた開発タイムライン Stacking手法で実際に開発がどうなったかをイメージしやすいように、今回の事例について一連の変更のデータをGitHubとSlackから取得しタイムラインとしてまとめました(図5)。 開発フェーズを以下の3つに分類しました 準備:コーディング前に情報収集や実装方針を議論する期間 コーディング:コードを書き始めてからレビューを依頼するまでの期間 今回は最初のCommitをコーディング開始時刻としました。 コードレビュー:Slackでコードレビューを依頼してからGitHub上でApproveされるまでの期間 図5の開発タイムラインのように、開発がコードレビューにブロックされていないことと、並行してプルリクエストのレビューをしてもらった様子がわかります。 今回の開発ではPoCにより大枠の方針を定めた後に実際の開発を進めており、結果として各プルリクエストのコーディングフェーズが短くなっています。 図5: Stacking手法を用いた開発タイムライン Stacking手法の評価 この一連の変更でStacking手法を使ったことで、得られたメリットは以下になります。 1: プルリクエストのサイズを小さく保てた 評価のために、プルリクエストを分割しなかった場合のプルリクエストサイズとStacking手法の各プルリクエストのサイズを比較してみます(表1)。ここでは以下の定義で比較します Diff: 追加行数と削除行数 プルリクエストサイズ: 追加行数と削除行数の合計値 比較すると、一番大きなPR4で40%のサイズになっており、他は13%〜22%のサイズになりました。 Stacking手法ではプルリクエストのレビューに後続の開発がブロックされないため、待ち時間の増加を気にせず、適切な粒度でプルリクエストを作成できました。 特に顕著なのがプルリクエスト1,2,3の分割だと思います。不要なコードの削除を1つのプルリクエストにまとめず、レビュアーにも理解がしやすい形で作成できました。 また、分割した各プルリクエストサイズの合計についても分割しなかった場合と比較して102%のサイズで、わずかに増加していますが分割のメリットを考慮すると許容範囲でしょう。 表1: Stacking手法各プルリクエストサイズの比較 プルリクエスト Diff追加行数 Diff削除行数 プルリクエストサイズ 分割無しと比較したプルリクエストサイズ 分割無し +615 -837 1452 — PR1 +2 -5 7 0.5% PR2 +48 -268 316 22% PR3 +0 -186 186 13% PR4 +318 -269 587 40% PR5 +114 -72 186 13% PR6 +149 -53 202 14% PR1〜6の合計 +631 -853 1484 102% 2: レビュー依頼開始からApproveをもらうまでの時間を短く保てた Validation MSのBatch エンドポイントの結果変換メソッドの修正を行うPR5はValidation MSのドメイン知識が必要だったため、今回はSlack上で大枠の説明をしてもらったあとに、プルリクエストレビューを通じてドメイン知識の獲得を行う方法で進めました。そのためPR5のレビューには時間がかかっています。 それ以外のプルリクエストはレビュー依頼の翌日にはレビューが完了してマージできたため、効率よく開発を進められました。 3: コードレビュー中に開発を並行して進めることができた 図5の開発タイムラインを見るとレビュー中に最初のcommitを行っていることがわかります。 実際には最初のCommit前から開発をしているため、コードレビューにブロックされることなく後続の開発を進められていることが確認できます。 コーディングと同様にコードレビューも並行して行われていることがわかります。 通常の分割手法を行った場合はレビューが完了するまで後続の開発を行わないため、コードレビューも並列で行われません。そこで、各プルリクエストのレビュー時間の合計を通常の分割手法の場合のレビュー時間と仮定します。 Stacking手法によるレビュー時間をPR1のレビュー依頼からPR6のApproveとして比較すると、Stacking手法によりレビュー時間を7%削減できたことになります。 実際には並列でコードレビューを行わないことで、各プルリクエストのコードレビュー時間が短くなる可能性もありますが、プルリクエストはGitHub上のコメントによる非同期なコミュニケーションが主であることから、相手からの返信を待つ時間が支配的となるため複数のプルリクエストを並列で行うメリットは大きいと考えられます。 4: コードレビューを専門性のある別々のチームに依頼できる Validation MSドメインにフォーカスした小さいプルリクエスト(PR4, PR5)はマーケティングシステムの詳細を知らないValidation MSチームがレビューしやすくなっています。結果としてValidation MSチームの複数名の開発者がレビューに参加してくれて、コードの質が向上しました。 具体的には、当初はマーケティングシステムに実装されていたValidation MSのSingle IDエンドポイントの変換メソッドとBatchエンドポイントの変換メソッドの詳細が異なっており、マーケティングシステムの挙動を変えないために、Single IDエンドポイントと同じ変換を行う新規Batchエンドポイントの変換メソッドの作成を考えていました。それがValidation MSチームとSlack上で議論していく中で、この実装の詳細の差分は、既存のBatchエンドポイントの変換メソッドの修正を行うことで安全に解消できました。 5: 小さいプルリクエストは開発者自身も思い出しやすい プルリクエストのサイズが小さくなることで、レビュアーがレビューしやすくなるだけではなく、開発者自身にもメリットがありました。マーケティングシステム開発の他に別の機能の開発や、メンバーのコードレビュー、ミーティングへ参加をしていると、開発した際の記憶が薄れていて、レビューコメントに対応するために再度思い出す作業が必要になります。プルリクエストが小さいことで思い出しやすく、コンテキストスイッチが多い中でもレビューコメントに対応しやすかったです。またメリット2で述べたレビュー時間が短くなったこともあり記憶が薄れずに対応できた割合も多かったです。 結論 本記事ではGitのブランチ戦略の1つであるStacking手法をチームで試した結果を整理しました。レビュー待ちの課題を解消することで、プルリクエストの分割を推進し各プルリクエストのサイズを13%〜40%と小さくすることができました。また並行して開発し、レビュー依頼をすることでレビュー時間を7%削減できました。このようにコードレビューにブロックされることなく開発ができるメリットを得ることができました。 機能開発をする中でコードベースへの理解が深まり、小さい改善点を見つけることがよくあります。そうした場合に、改善を後回しにせず、小さいプルリクエストとして分割してレビュー依頼できる点も開発者体験が上がったと感じました。 また想定外の恩恵として専門ドメインで閉じたプルリクエストを作り、専門チームにレビューをしてもらうことで、コードレビューでフォーカスする点が明確になり、最終的なコードの質が上がりました。この点はStacking手法を使わない場合でも継続して意識していきたいと思います。 明日の記事は reyさんです。引き続きお楽しみください。
この記事は、 Merpay Advent Calendar 2023 の9日目の記事です。 こんにちは。今年の春に新卒でメルペイに入社し、Credit Platform Team でバックエンドエンジニアをしている @champon です。Credit Platform Team では主に ML(いわゆるAI与信) を用いた与信枠の算出を行っていますが、その中でも自分はワークフローエンジンである Airflow を用いたデータパイプラインの開発・運用を行っています。 今回は、業務中に Airflow のバグを見つけてからその原因を調査し、実際にコントリビュートするまでの過程をお話したいと思います。 Airflow とは まず簡単に、Airflow について説明します。 Airflow とは、ワークフローエンジンの一種であり、Apache Software Foundation が管理する OSS です。 DAG と呼ばれる有向非巡回グラフの形式でワークフローを定義し、それぞれのノードは Task と呼ばれるワークフロー処理の構成要素となっています。 Task には、Airflow から提供されている様々な Operator を使用することができ、例えば BashOperator や PythonOperator などがあり、それぞれ Bash コマンドや Python プログラムを実行できます。 また、Amazon Web Service (AWS) や Google Cloud Platform (GCP) のサービス・プロバイダも公開されているため、クラウドサービス上のデータを容易に扱うことができます。 自分のチームでは、GCP 上の Cloud Composer で Airflow 環境を構築し、BigQuery や Dataflow と連携しながらデータパイプラインとしてメルペイの与信枠計算の一部を管理しています。 予期せぬエラーの発生 QA Engineer によるテスト実施中に、Dataflow を使っている Task で以下のエラーが発生しはじめました。 Exception: Google Cloud Dataflow job <xxx> is in an unexpected terminal state: JOB_STATE_DONE, expected terminal state: JOB_STATE_DONE 直訳すると、「予期していた終着状態は JOB_STATE_DONE でしたが、Google Cloud Dataflow job が予期せぬ終着状態 JOB_STATE_DONE となりました」でしょうか。 明らかに筋が通っていないこちらの1文を読んで、もしかしたら Airflow 側に何かバグがあるかもなと思い、Airflow のソースコードを探ることにしました。 エラーの原因調査 こういうときはまず、該当箇所の直近 commit を見ることにします。 スタックトレースもエラーメッセージと一緒に出力されていたため、それを頼りに該当ファイルにたどり着きました。 このファイルの最新 commit を見てみると、 PR #34217 が merge されていることがわかりました。 さらに深掘ってみると、どうやら apache-airflow-providers-google==10.9.0 のリリースに入った変更で、expected_terminal_state という引数を DataflowHook に加える対応のようです。 この expected_terminal_state というのは、 こちら で議論されており、Dataflow job が完了したとみなすステートをユーザーが設定できるというものです。 (Airflow には Dataflow job のステートがいくつか定義されており (※1)、どれを job 完了状態とみなすか、といったもの) 話を戻しますが、この PR #34217 の変更を見てみると、ちょうどエラー発生箇所に変更が加えられていました。 また、念のため Cloud Composer の package 一覧を確認したところ、該当環境の apache-airflow-providers-google のバージョンが 10.9.0 となっていたので、原因はこちらで間違いなさそうです。 gcloud composer environments list-packages <your environment> –project <your project> –location <your location> 原因はわかったので、対症療法としてバージョンを 10.8.0 に落とせばエラーをなくすことができますが、せっかくなので自分で直すことにしました。 (※1) https://github.com/apache/airflow/blob/providers-google/10.9.0/airflow/providers/google/cloud/hooks/dataflow.py#L130-L141 Issue, PR の作成 とりあえず Issue を出しました。 Issue テンプレートの下部に “Are you willing to submit PR?” という文とともにチェックボックスが添えてあったので、チェックをして PR 作成に取り掛かります。 修正箇所は前述の通り、expected_terminal_state の挙動によるものと思われます(正確には、DataflowJobsController の check_dataflow_job_state メソッド (※2))。 特に、expected_terminal_state = None (デフォルト値) のときに考慮漏れがありました。 expected_terminal_state がデフォルトのときに関係するコードを次に抜き出します(今回は Dataflow のバッチ処理なのでストリーミング処理に関係するコードは省きます)。 AWAITING_STATES = { JOB_STATE_RUNNING, JOB_STATE_PENDING, JOB_STATE_QUEUED, JOB_STATE_CANCELLING, JOB_STATE_DRAINING, JOB_STATE_STOPPED, } def _check_dataflow_job_state(self, job) -> bool: current_state = job["currentState"] if self._expected_terminal_state is None: self._expected_terminal_state = DataflowJobStatus.JOB_STATE_DONE if not self._wait_until_finished and current_state == self._expected_terminal_state: return True if current_state in DataflowJobStatus.AWAITING_STATES: return self._wait_until_finished is False raise Exception( f"Google Cloud Dataflow job {job['name']} is in an unexpected terminal state: {current_state}, " f"expected terminal state: {self._expected_terminal_state}" ) ここで、wait_until_finished という要素が新たに登場します。 このパラメータは expected_terminal_state が導入される以前から存在したもので、簡単に言うと “Dataflow job が終了するまで処理を待機するかどうか” のフラグです。 これを踏まえて上記のコードを解釈すると、例えば次の全てを満たす状態のときに Exception が返ってしまうことがわかります。 wait_until_finished = True current_state = DataflowJobStatus.JOB_STATE_DONE expected_terminal_state = DataflowJobStatus.JOB_STATE_DONE ここでようやく、今回のエラー発生時の状態にたどり着きました。 後は修正するだけです。 if not self._wait_until_finished and current_state == self._expected_terminal_state の分岐処理を以下のように変更します。 if current_state == self._expected_terminal_state: if self._expected_terminal_state == DataflowJobStatus.JOB_STATE_RUNNING: return not self._wait_until_finished return True wait_until_finished の条件が悪さをしていたので、expected_terminal_state が DataflowJobStatus.JOB_STATE_RUNNING のときの分岐を増やし、それ以外の場合は current_state == self._expected_terminal_state であれば True となるようにしました。 詳細は 修正 PR を御覧ください。 (※2) Helper method to check the state of one job in dataflow for this task if job failed raise exception: https://github.com/apache/airflow/blob/providers-google/10.9.0/airflow/providers/google/cloud/hooks/dataflow.py#L389-L433 余談: このような実装になった原因 このようなエラーが引き起こされた原因として、wait_until_finished と expected_terminal_state という似たようなパラメータが共存することが大いに関係あると考えられます。 どちらも Dataflow job の完了状態を考慮する必要があるため、完了判定条件がより複雑になってしまったことが考えられます。 また、wait_until_finished = True は、expected_terminal_state = DataflowJobStatus.JOB_STATE_DONE と実質同じ意味なのかなと考えており、将来的には wait_until_finished を廃止することでより簡潔な実装になるのかなと思いました(一応 PR 内のコメントで提案しておきました (※3))。 (※3) https://github.com/apache/airflow/pull/34785#discussion_r1348054361 まとめ 今回は、Airflow におけるバグ発見から PR を作成するまでの課程を、自分の思考を振り返りながら記事にしました。 その後、無事 apache-airflow-providers-google==10.12.0 にてリリースされたので、今後は同様のエラーが起こることはないはずです。 普段は OSS 等へコントリビュートはあまりしない(バグ見つけたら Issue 書くか、時間があったら PR 出すくらい)ですが、久々に結構楽しめたので、今後もちょくちょく Issue 見つつ手伝えそうであればコントリビュートしていこうかなと思いました。 明日の記事は @ryuyama さんです。引き続きお楽しみください。
 こんにちは!横浜国立大学理工学部情報工学EP3年の @shion1305 です。今年の10月から株式会社メルペイ Settlementチームにてバックエンジニアのインターンを始め、12月初めでちょうど2ヶ月となります。  この記事は、 Merpay Advent Calendar 2023 の8日目の記事です。  今回は、自分のインターンの振り返りも含めて以下について書きたいと思います。 インターン2ヶ月の振り返り 働く環境 メルカリグループのインターンの特徴 インターン2ヶ月の振り返り(自分の中での主なイベントまとめ) 入社オリエンテーション  インターン生は、同月入社の新入社員と一緒にオリエンテーションを受講します。メルカリでは働くにあたってカルチャーやバリューを共有することをとても大切にしていて、最初の1週間はメルカリとしてのカルチャーやバリューに対する考え方についての社内の学習教材に取り組んだり、他の新入社員とディスカッションをしたりしていました。 入社日翌日にはウェルカムランチがあり、そこで新入社員やメンターの方と交流を深めました。(ランチについては後述) 所属チームでのインターン  入社オリエンテーションが終わると本格的にチームのタスクに入っていくことになります。決済システムにはたくさんのドメイン知識が必要になるため、最初は決済システムのコンテクストの薄いタスクを行いながら、過去の資料を参照して決済システムならではの必要知識の理解や現在のレポジトリの状況の把握を行っていました。  11月に入り、ある程度慣れてからは、本格的に決済に直接関連するタスクを任されました。これまで以下のようなタスクに取り組みました。 Go言語のLinter golangci-lint の設定見直し 検証環境で発生しているトラブルの原因調査 Go言語のエラーハンドリングライブラリ pkg/errors の置き換え APIサーバーが稼働するPodの設定調整 PodDisruptionBudget / HorizontalPodAutoscaler / Resources (cpu limits) の設定値見直し Kustomizeのリファクタリング マイクロサービスの改修 改修範囲の特定と修正 テストケースの修正・改良 protoファイルの更新 リファクタリング Office Week  メルカリグループでは普段リモートで働いている人が多いのですが、メルペイ・メルコインではだいたい半期に1度Office Weekがあります。11月中旬にメルペイ・メルコインにてOffice Weekが実施され、基本社員全員が六本木オフィスに出社しました。  11月のOffice Weekは3日間で、初日からイベントやLT大会が盛りだくさんでした。自分は大学の都合上初日のみの参加でしたが、メルペイ全社が集まるキックオフイベントに参加したり、十数のLTの発表を聞いたりしました。LT会では、メルペイの他のチームではどのようなことをしているのかを知ることができたり、自分が普段あまり触れていない技術についての知見を深めることができました。普段オンラインのみでしか会っていない方やメンターランチで交流したインターン生と話したりと、対面ならではの体験がたくさんできました。 Office Weekの様子はこちらから!👇 Fintech Tech Talk at Office Week を開催したよ! | メルカリエンジニアリング インシデントを起こしてしまった  11月後半、インターンのタスクの一つとしてデータベースのマイグレーションの見直しに取り組んでいました。その作業中にコマンド1つを誤ってしまい、ステージング環境のデータベースを消去してしまったことがありました。本番環境ではなかったものの、メルペイにて関連するマイクロサービスが多くあり、社内で他のチームに影響が出てしまいました。  失敗してしまった時はとても不安と後悔でいっぱいで気が気でありませんでした。しかしさまざまな方に支えられたことによって、非常に前向きに乗り越えることができました。このインシデントは、対策の不備とオペレーションミスが重なった結果でしたが、失敗に対する自分やチームとしての向き合い方、そしてオペレーションに対するリスク管理など、エンジニアの一人として得た学びがたくさんありました。貴重な苦い経験として今後のエンジニアリング人生の教訓としていきたいです。 12月・Advent Calendar ← 現在地  Office WeekにてAdvent Calendarの存在を知り、インターン生としてAdvent Calendarに急遽参加させていただくことになりました。合計2つ枠を頂き、息を切らしながらも頑張って執筆しています ✏️ この記事は2本目で、1本目は以下です! 動作例からKubernetes PDBの挙動を理解する | メルカリエンジニアリング 働く環境  メルカリグループでは、 YOUR CHOICE というワークスタイルを採用していて、「バリュー発揮がもっとも高まるワークスタイルを、自ら選択して決めることができる」というポリシーのもと、完全フレックス制で働く環境を選んだり時間を調整できたりします。インターン生の中でも働き方はさまざまなようで、基本オンラインで働いている方もいます。  私はオフィス出社が好きなので、週1回六本木オフィスに出社しています。オフィスの居心地はなかなか快適だと思います。メルカリグループのオフィスは基本的にフリーアドレスなので、時々場所を変えたり必要に応じて個室を利用したりと、自由にスペースを利用させてもらっています。  自分は大のコーヒー好きなのですが、社内にカフェがあり本格的でさまざまなブレンドコーヒーを低価格で飲むことができるので、私のコーヒー欲求は簡単に満たすことができます。社内の自動販売機は無料で利用できるので基本飲み物には困らないはずです。 メルカリ本社オフィスがアップデート! Mercari Base Tokyoに潜入!新しい時代のオフィスの形とは? メルカリグループでのインターンの特徴 プロフェッショナル性が求められる  メルカリバリューの一つに「Be a Pro」というものがあり、インターン生も例外なくプロ意識を持って自ら考え、適切な判断を下すことが求められます。原則ある程度の知識やスキルがある状態で自分の知識を活かしてタスクに取り組むことが求められるため、かなり緊張感を持って取り組むことができます。  メルカリバリューには他に「Go Bold」「All for One」があり、社員と同様これらを意識してインターンに取り組むことが求められます。 多様なコミュニケーションの機会  メルカリグループでは社内のコミュニケーションの場を非常に大切にしていて、そのためのイベントや制度が多く存在します。基本的にインターン生は社員と同じように活動でき、社内のさまざまなイベントに参加したり制度を利用したりすることができます。社員のコミュニケーションを促進するための制度が多くあるため、インターン生にとっては非常に貴重な機会だと思います。  制度の一つに、食事代を会社が補助する制度があります。インターン生は以下の制度が利用できます。 メンターランチ 新入社員やインターン生がメンターと一緒に社内の色々なチームの人とランチ。 ウェルカムランチ 入社日直後に実施されるランチ会。 インターン生ランチ会 インターン生のみで毎月4名程度でランチ会が開催されます。メルカリグループのインターン生の人数はかなり多いので、インターン生同士で情報交換をする機会に恵まれています。 チームビルティング 自分の所属するチームでは毎月1回、所属するチームで食事会があり、他のチームの人を招くこともあります。  また、部活動というものがあります。部活動は趣味を通じてさまざまな人と良い関係性を築くことを目的としたもので、誰もが設立したり参加したりすることができます。自分はつい先日CTF(capture the flagというセキュリティコンテスト)のグループに参加していて、早速社員の方と12月中旬にCTFに参加することになり、とてもワクワクしています!  その他にも社内ではさまざまなイベントが存在します。 英語でのコミュニケーションに挑戦できる  メルカリグループのエンジニアリング組織の約半分は外国籍です。チームによって英語を使ったり日本語を使ったりさまざまです。自分のチームは日本人が多いですが、週替わりでEnglish Weekという英語を推奨する期間を設けています。  特に、英語でSlackで返信を打つ時や開発でPull Requestを出す時などは、どのように表現したら相手に伝わりやすいかを必死に考えるので英語を鍛える良い機会になると思います。他にも英語でディスカッションすることができたり、一部の会議では同時通訳を聞くことができたり、などなど、なかなか経験することのできない機会が盛りだくさんです。 大規模かつ運用年数のあるシステム開発ならではの経験  メルカリグループのインターンでは、フルスクラッチで何かを開発することは少ないかもしれません。私のチームでは、運用されてから数年が経過したマイクロサービスを扱い、過去の歴史的経緯による技術的負債に多く直面しました。割り振られたタスクでは、その負債の影響を正しく理解し、最適な解決策を見つけることが求められます。  私が初期に担当したタスクの一つでは、技術的負債が絡む部分があり、それに対して関連する箇所を全て洗い出し根本から修正する方針で進めました。その結果、変更箇所が大きくなりすぎてタスクの収拾がつかない状況になったことがありました。技術的負債が存在する場合でも、一気にすべて解消しようとすると、レビューが困難になったり、変更ミスが生じるリスクがあります。メンターからのアドバイスを受けたことで適切に選択を行い、解決策を提案することができました。  また、メルペイのマイクロサービスはかなり大規模なので、仕様を変更する時は、各マイクロサービスの担当チーム間で適切なコミュニケーションを取り連携していく必要があります。大きな組織の中で複数のチームをまたいでのコミュニケーションを実践できる機会があるのも魅力だと思います。 終わりに  改めてメルカリグループでのインターンは自分次第でたくさんの挑戦ができる、最高の機会だと思います。技術的なノウハウのみならず、コミュニケーションや仕事に対する考え方など、一人前のエンジニアとしての成長を促す多様な経験が得られます。  あと1ヶ月弱期間が残っていますが、今回のAdvent Calendarでの振り返りを元に残りの期間で、チームメンバーの一員としてプロ意識を持って積極的に貢献するとともに、最大限機会を活用してメルペイでのインターンを楽しみたいと思います。  今回のこの記事がメルカリグループのインターンを検討している方の参考になれば幸いです。  現在、インターンを通年募集していますので、興味を持たれた方はぜひ以下からぜひ申し込んでみてください! Students | 採用情報 明日の記事は champon さんです。引き続きお楽しみください。
この記事は、 Mercari Advent Calendar 2023 の7日目の記事です。 こんにちは!メルカリの Search Middleware チームで Software Engineer をしている @otter です。 ご存じの方も多いとは思いますが、メルカリのエンジニア組織ではグローバル化が進んでおり、チームにもよりますがコミュニケーションやドキュメントではほぼ英語が必須な環境になっています。 そのような環境のメルカリに英語がほとんど話せない私が入社してから4年が過ぎました。会社の環境も私自身も変わってきており、そこで得られたものや感じたものを紹介していきたいと思います。 どんな人にこの記事を読んでほしいか? 英語を使った環境で仕事をしてみたい人 仕事で英語を使っているがコミュニケーション方法の参考にしたい人 組織のグローバル化を検討している人 入社前のモチベーション 前職では某IT企業でゲームプラットフォームの開発をしていました。コミュニケーションは全て日本語で、技術関連の英語のドキュメントを読むことはよくあるのですが、ドキュメント作成もほとんどが日本語でした。 ただ、エンジニアとして成長するには英語は必要だし、英語を使う環境で働きたいなと考え始め、元同僚からのお誘いもあり転職を決めました。 今考えると、全然話せもしないのに転職しようとした自分は少し無鉄砲だったと思いますが、当時はグローバル化推進への転換時期だったので日本語面接で採用されました。 また、転職を考え始めたタイミングでオンライン英会話を始め、有給消化期間中にニュージーランドのクライストチャーチで3週間だけ語学学校に通いました。 入社直後どうやって切り抜けたか 直前の語学学校やオンライン英会話はあまり役に立ちませんでした。 まず、入社当日のオリエンテーションや全体向けの会議にはありがたいことに GOT (Global Operations Team、メルカリの翻訳および通訳を行うチーム) の同時通訳が入っており、日本語で説明を聞くことができました。また、配属先のマネージャーとメンターが日本人だったので個別に相談するときは日本語を使っていました。 ただ、入社当日のウェルカムランチでは多様な出身のメンバー同士の会話が、それぞれの訛りもあり、早すぎてついていけず本当に面食らいました。当たり前ですがオンライン英会話の先生のように話す人なんて現場にはいません。近年はインド人の同僚と一緒に仕事することが多いので、Indian English には慣れていますが、最初の頃は全く聞き取ることができませんでした。 では、どうすればいいのか?一朝一夕でリスニング力をあげることはできません。私はツールに頼りました。Google Meet には英語字幕を付ける機能があるので、会議中は字幕をひたすら読みます。最近は自動翻訳機能も追加されましたが、そちらはまだ精度が高くないのでおすすめできません。 またオンライン会議ではなく対面のオフライン会議の場合でも、とりあえず自分のPCで Google Meet を開いておけばマイクが周りの会話を拾ってくれるので字幕を参考にしながら会議に参加することができます。目の前に人がいるのに画面ばかり見るのは難しいので、おすすめ度は低いですが参考までに。 メルカリの言語学習サポート メルカリでは公用語を英語と決められている訳ではありません。そのため言語学習は強制されるものではなく業務上必要と判断されたメンバーが受けられるサポートという位置づけです。また、日本語を学びたいメンバーが受けられる日本語学習サポートも同様にあります。 「やさしい日本語」や「やさしい英語」といったカルチャーもメルカリならではで、全員の言語スキルを上げさせるのではなく言語ギャップをお互い埋めていこうという方針があります。 私が今まで英語学習に関して受けた恩恵は下記です。 オンライン英会話の費用全負担 MECT (Mercari English Communication Test) コミュニケーションスキルレベルを知るための独自のスピーキングテスト 独自の英語学習プログラム 専任の先生とメルカリでの仕事に合わせた教材でレッスン English Chat Lunch ネイティブスピーカーのチームリーダー1名と学習者3名で毎週ランチ エンジニアのための英語・日本語ボキャブラリーリスト 社内ミーティングの会話から抽出されたエンジニアがよく使う語彙のリスト 日本語学習者にも最適な学習ツール 各サポートは都度内容見直され更新されているので現在と異なるものもあり、私が受けたことがないものもあります。 (参考) 言語学習プログラム コミュニケーション力をどうやってあげていくか あえて英語力ではなくコミュニケーション力と書きました。私はUSで働いている訳でも外資系企業で働いている訳でもありません。本当にネイティブな英語話者は少なく、ほとんどのメンバーが英語を第二言語としている人たちばかりです。なのであまり難しい単語やフレーズを覚える必要はなく、実際に周りが使っている言葉を真似していく方が近道です。とくに仕事で使う内容は限られているので、各種学習サポートはあるのですが、実際に仕事で積極的に使って行く方がコミュニケーション力は上がると思います。 おすすめは少人数のミーティングに頻繁に参加することです。以前、インド人の新卒メンバーと毎日ミーティングの時間を作って、話しながら一緒に仕事をしていました。1対1だと「やさしい英語」で話してもらえるし、自分の発言するタイミングが増えるので、話す練習にもなります。 また大事なのは、説明が難しい内容のときは必ずドキュメントを作って挑むということです。 これは英語に限らずだと思いますが、たとえば、他チームに複雑なシステムの説明を1からするときは、予め詳細なドキュメントを準備してから説明します。そして上手く説明できなかったところは後から Slack で補足したり、こう話せばよかったという反省は次回への文章づくりに活かしたりします。 前述のようにコミュニケーションは口頭の会話だけではありません。Slack や PullRequest 上でも、周りから学ぶことが多々あります。入社してすぐ驚いたのは飛び交っている Acronyms (頭字語、イニシャルを並べた略語の一種) の多さです。初めて見るものばかりだったので、ググってはリスト化していました。その一部を紹介します。 【頻出 Acronyms in メルカリ】 OOO = out of office (Slack名やステータスで使う、例: @otter – Dec 7th OoO) PTAL = please take a look (このPullRequestを見て!というときに) BTW = by the way (話を切り替えたいときに) IMHO = In my humble opinion (私の率直な意見では) TIL = today I learned (それ初めて知った、というときに) TBH = to be honest (正直なところ) TBD = to be determined (仕様書や設計書の未定義の箇所に使う) BRB = be right back (会議の途中で一時的に抜けるときに) AFAIK = as far as I know (私の知る限りは) IIUC = if I understand correctly (私の理解が正しければ) IIRC = if I remember correctly (私の記憶が正しければ) SSIA = subject says it all (タイトルだけで説明が不要な小さなPullRequestのDescriptionに使う) これ以外にも略語ではないのですがよく使う言葉としては NIT/NITS (PullRequest上で些細な指摘をするときに使う) などがあり、思っていたよりたくさんの新しい用語を覚える必要がありました。 そして現在は この4年間で直属のマネージャーは日本人→スペイン人→フランス人→スウェーデン人と変遷し、日本語が飛び交っていたチームも9人中6人がグローバルメンバーになりチーム会議も100%英語となりました。未だに私の英語はお世辞でも上手とは言えませんが、コミュニケーションの工夫と周りの温かいサポートのおかげで今ではそのグローバルなチームのTL(Tech Lead)もしています。 また英語を使う機会が増えるとともに人脈も仕事の種類も増えてきました。言語の壁があると他のチームとコラボレーションにも支障が出るし、新規プロジェクトからの声もかかりづらくなります。私の観測した限りでは両言語とも流暢に話せてコミュニケーション力が高いエンジニアは各所から引く手あまたです。私も現在全社規模のプロジェクトに参加しており、今まで自分の領域である検索機能まわりを中心に仕事をしていましたが、違う領域のチームに参加したり、別事業のヘルプに呼ばれることもあり、充実した働き方ができています。 メルカリ全体としても英語だけをサポートするわけではなく、言語のギャップをなくそうという取り組みがさらに進んでいる実感があります。以前は広範囲にアナウンスされる内容が日本語だけだったり、英語だけだったりということがよくありましたが、今では両言語でアナウンスされることが徹底されており、片方の言語だけだったとしても瞬時にbotが自動翻訳してくれる仕組みがあります。 さらに私事ですが、昨年はイタリア人のエンジニアと結婚し長男を出産しました。なので家でも基本は「やさしい英語」です。業務では絶対に使わないだろうという単語を頻繁に使うことになるので、それはそれで面白いです。息子もそろそろ言葉を覚えていく時期なので一緒に学んでいこうと思いますが、きっとあっという間に追い抜かされるでしょう。今から楽しみです。 最後になりますが、この4年の間に私が感じた、これから英語を扱う環境に飛び込んでいこうとする方たちの英語学習に関して重要だと思った点をあげておきます。 入社前のオンライン英会話は業務の英語にはあまり役に立たない 聞き取れないときはツールに頼ろう (Google Meet の英語字幕機能) 難しい英単語やフレーズを覚える必要はない 実際に周りが使っている言葉を真似していく方が近道 言語のギャップをなくそうという取り組みが大事 それでは最後まで読んでいただきありがとうございました!何かひとつでも参考になれば幸いです。 明日の記事は @wills さんです。引き続きお楽しみください!
はじめに メルカリ Engineering Office マネージャーのhiroiです。 我々のチームでは「Establish a Resilient Engineering Organization」というミッションを元に、エンジニアリングにおける、組織横断課題の解決を目指しています。 組織横断というと、Platformチームや、インフラ周りのチームを想像する方も多いと思いますが、我々のチームでは、 プロダクト開発における技術的な課題を除く 、組織課題や横断的な取り組みを推進しています。 具体的には、各技術領域ごとの研修プログラムの構築、エンジニア向けのイベント企画運営、技術広報(このEngineering Websiteも我々の活動の一つです)、ナレッジマネジメント、エンジニア文化の言語化や醸成、技術戦略策定、果てはインド開発支部の立ち上げのプロマネなどをしています。 この記事ではそんな我々の主な活動の内容、目的の紹介をします。 開発や技術力の高い組織を目指すために、その裏でどんな技術外の仕事や工夫を、メルカリではしているのか、そんなちょっとニッチな領域における話を書いてみます。 こんな人におすすめ エンジニア組織の技術以外の課題に取り組んでいる方はもちろん、そういった取り組みに興味があるマネジメント職の方におすすめです。特に上記に記載したような仕事(研修、イベント企画、技術広報、ナレッジマネジメントなどなど)のワードが気になる方、是非ご一読ください。 規模が一定以上の組織固有で発生する課題もありますが、どんな組織にも共通している取り組みも含まれています。特に規模が近い会社の方におすすめですが、どのサイズの組織でも、「その課題わかる!その仕事あるよね!」とある程度共感いただける内容を目指します。 6つの重点領域 Engineering Officeの仕事は、大きく以下の6つの領域にカテゴライズされています Tech Branding Internal Communication Onboarding Career Development Knowledge Management Strategy メンバーはジェネラリストですが、それぞれの領域に対して専門性をもって取り組んでいます。各領域ごとに3~5年の中長期計画があり、その達成を目指して日々の仕事を進めるというやり方をとっています。今回は領域ごとのミッション、主な仕事の2点を説明していきます Tech Branding Mercari Gears – Youtube。 手前味噌で恐縮ですが、本当に良いコンテンツを発信しています ミッション 技術広報です。技術発信や、カンファレンスやOSSのスポンサーもこの領域です。主に以下の3つを目的としています。 ・採用のためのブランディング ・技術コミュニティへの貢献 ・エンジニアのキャリアアップ 1点目、一番わかりやすいゴールですが、採用のためのブランディングがあげられます。採用候補者となるエンジニアにメルカリが使っている技術や、エンジニア文化に興味・関心をもってもらい、「技術力が高いエンジニア組織だ」「こういった文化のところで働きたい」といった認知を獲得することを目的としています。 2点目は技術コミュニティへの貢献です。エンジニアという業界の発展のスピードの大元には、そのコミュニティの強さ、知識や成果物の共有文化があります。実際、メルカリのアウトプットは、過去のエンジニアの経験や知見やOSSといった、技術コミュニティが築いてきた資産の上に成り立っています。私たちの経験や知見も同様に、誰かのアウトプットに繋げることで、コミュニティの発展に貢献、恩返しが出来ます。そのため、コミュニティへの貢献を2つ目の重要な目的としています。 最後に、エンジニアのキャリアアップです。エンジニアは、技術発信をする中で、思考の整理が行われ、学びを深めることができます。また、発信したものはそのエンジニアの社外へのアウトプットとなり、社内外の自身のブランディングに繋がります。社内においても、外部へのアウトプットは明確に評価の対象物になりうるため、キャリアに繋がります。これを3つ目の目的としています。 以上3点を中心に、メルカリでは、技術発信によって会社、発信者、コミュニティの三方良しの状態を目指しています。 主な仕事 ・技術発信の媒体運営、管理(Engineering Website、Gears Youtubeチャンネル、Twitterを始めとするSNSアカウントなど) ・結果の見える化とPDCA(来訪者数、チャンネル登録者数、国別アクセス、etc…) ・Engineering Blogのレビューの仕組み化 ・技術発信に対する広告運用 ・OSSや技術コミュニティ、カンファレンスへのスポンサーシップ ・発信内容の企画、制作 技術発信はメルカリにおいて仕事として認められますが、もちろん強制するわけではないですし、何を書くかといったのも個々のエンジニアの裁量です。Engineering Officeは、エンジニアが発信しやすい環境、そしてエンジニアの発信の価値が最大化されるような環境作りを行っています。 また、スポンサーシップとして、メルカリがお世話になっている 技術カンファレンスへの協賛 はもちろん、 PHP FoundationやPython Foundaitionといった団体へのスポンサー などに関しても、我々の方で提案、実施を進めています。 ちなみに写真にある Mercari Gears – Youtube はYouTube Channelですが、最近登録者数が7万人を超えました。国内のテックカンパニーが運営している技術チャンネルの中では最大規模です。豪華なコンテンツが盛りだくさんなので、見たことがない方は是非。 Internal Communication 技術の祭典であるHack Fest。毎回デザイナーさんが素敵な扉絵を作ってくれています ミッション サイロ化の防止、チーム間のコラボレーションの増加、強固な文化形成による、全体最適をミッションとしています。組織を見渡した際、チーム間での協力がスムーズに行われ、ナレッジのシェア、同じ文化の形成が出来ている状態が理想です。 一定以上の規模の組織になると、サイズが大きくなればなるほど、個別最適が発生しやすくなります。カルチャーや考え方も、チーム間で少しづつズレが生まれやすくなります。チームの一員という誇りは重要ですが、隣のチームが同じ目標、ミッションのために働いている仲間だという意識も同じく重要です。 これに対する一番の解決策はコミュニケーションだと考えています。チーム間、もしくはレイヤー間で発生する課題は、見えているものや、抱えている背景が違うことに起因することが多く、多くの場合、丁寧なコミュニケーションによる相互理解を進めることで、解消可能です。 Engineering Officeでは、普段接点を持ちづらい人同士の対話、コミュニケーションや、リーダーからの発信が進んでいく仕掛け作りをしています。 主な仕事 ・Engineering All Hands(全エンジニアが参加するMeeting)の企画運営 ・グループ横断の技術会議の企画運営 ・EM向けオフサイトの企画運営 ・Hack Festの企画運営 ・Ask Me Anything(トップエンジニアとのOpen Discussion)の企画運営 さまざまな会議の企画運営に加え、全エンジニアが開発を止め、自身のアイデアを元に好きなものを作る、 技術の祭典、Hack Festの運営 。社内のDistinguished Engineerをはじめとする、トップ層のエンジニアと、カジュアルに技術についてDiscussionを行う場の提供などをしています。技術に関して横断的に話す場だけでなく、リーダー達の考え方、思いを直接聞ける、話せる場を作るというのが重要です。 Onboarding メルカリのOnboardingの主な区分け。詳しくは こちら ミッション 入社後の戦力化までの時間の最短化、共通化やクオリティの向上による学習コンテンツの価値向上と効率化、ガバナンスの強化に加え、入社時に最高の従業員体験を提供することを目的としています。 特定のドメインナレッジ等、チーム特有で学ばなければいけないことはもちろんありますが、開発環境の作り方、コーディングのお作法、リリースサイクル、QAの考え方、インシデントマネジメントなど、チームを超えて共通する内容も多く、横断チームによる管理運営が適しています。コンテンツの集約により、重複や再作成の防止に加え、クオリティの向上が見込めます。 また、エンジニアという比較的転職サイクルが早い職種においては、いかに早く戦力化するか、という重要性が他の職種と比べ高いと考えています。一般的にOnboardingは3ヶ月〜6ヶ月かかると言われています。この最長と最短の差分である3ヶ月の差について、もし社員が3年勤続する場合、Onboarding終了後の実働が33ヶ月と30ヶ月になり、誤差がなんと10%程もあります。勤続年数が短い傾向にあるエンジニアにとって、Onboardingの速度は大きなインパクトがあります。 また、ガバナンスの強化においてもOnboardingは重要です。特に中途採用を行う際は、過去の組織の働き方から新しい組織の働き方へと移行するためのアンラーニングをきちんと行わないと、複数のお作法が意図せずして組織に定着し、さまざまな弊害を生む原因となります。出社自由といった制度などもそうですが、メルカリは自由度が高い会社なので、多くを厳格に標準化するわけではないですが、一定の標準化は必要です。入社してすぐは、比較的フレッシュなマインドで新しいことを受け入れ、過去の組織のやり方から脱却しやすい時期です。標準化が必要なものに関しては、この時期にきちんと学習できるプログラムを提供できることを目指しています。 最後に、第一印象、つまり入社時の体験はとてもとても重要です。メルカリに入社した全てのエンジニアが、入って良かった、歓迎されている、誇りをもてる、そういった気持ちになれるようなプログラムを目指しています。 主な仕事 ・全エンジニア向けオンボーディングプログラム作成 ・各技術領域(Backend、iOS、Androidなど)ごとのオンボーディングプログラム作成 ・EMのオンボーディングプログラム作成 ・オンボーディングプログラムの社外発信 基本的には技術、職種ごとに必要なOnboardingの集約、プログラムの作成、提供を行っています。それぞれの技術ごとにコミッティーを形成し、様々なチームのエンジニアが協力してコンテンツの作成を担当しています。多くのコンテンツはメルカリでないエンジニアが見ても面白いものになっています。そのため、一部のConfidentialな情報をのぞいた上で、出来る限り社外にオープンにしていくというチャレンジを最近では推し進めています。コンテンツ作成に協力してくれているエンジニアにとっても、社外のオーディエンスが増えるのはプラスになるので、この取り組みは今後も強化していきます。 Career Development エンジニアの成長段階を Engineering Ladder によって言語化をすすめています ミッション エンジニアのキャリアの可視化や、キャリアアップのための環境整備を進めている領域です。 エンジニアは自分で積極的に学習する人が非常に多いため、学習を我々が推し進めるのではなく、その学習のサポートとなるような環境、制度を提供しています。また、キャリアアップも同じく、推し進めるというよりは、キャリアアップを目指す人たちをどのようにサポートできるか、という観点から、環境の整備を行っています。 主な仕事 ・ Engineering Ladder の作成・保守 ・ Continuous Feedback の仕組み化、推進 ・職種(EMなど)の定義、言語化 ・オンライン学習コンテンツの提供 ・社外カンファレンス参加の推進、ポリシー作成 グレードや職種の言語化に加え、外部のエンジニア向け学習サービスの管理、社外カンファレンス参加におけるポリシー作成などを行っています。特にマーケットプレイスのエンジニアは、海外国籍のエンジニアが半分を超えているため、海外カンファレンスの参加も多く、費用もそれなりに高額になりやすいため、各カンファレンスの参加人数の上限を設ける、カンファレンス参加後にナレッジをシェアしてもらう、といったポリシーを定めています。 社内のキャリアアップに関しては、一番重要なのは現在地を正しく知ることだと考えています。今の自分に何が足りないのか、次のグレードにはどんなスキル、行動が求められるのかを知ることで、どんな学習、チャレンジが必要なのかというアクションを考えられます。そのため、キャリアの言語化、可視化に加え、Continuous Feedbackのような、マネージャーから適切なフィードバックを得られやすいようにするための仕組み作りを目指しています。 Knowledge Management エンジニア用の社内辞書。多くのエンジニアがコントリビュートしてくれています ミッション 社内におけるナレッジの最大化をミッションとする領域です。Engineering Officeは多くのメンバーがジェネラリストですが、この領域に関しては、Technical Writerという職種のメンバーが専属で推し進めてくれています。 メルカリではオンライン中心で働くエンジニアが非常に多いため、以前のような「隣の人にちょっと聞く」というコミュニケーションから「社内のWikiで調べる」といった行動が増えており、ナレッジをドキュメント化し、蓄積する重要性が高まっています。 また、プロダクトも10年目ということもあり、一目ソースコードを見ただけではわからないような、いわゆる歴史的経緯などが多く存在します。ナレッジは言語化を進める事で、特定の人に依存する状態から、社内のナレッジへと変わります。社内のナレッジが必要な時に、必要な人のもとに届く状態を目指しています。 主な仕事 ・社内のエンジニア向けポータルの管理 ・ポータルの利用、コントリビューションの可視化と最大化 ・ナレッジの収集、発信 ・ポータルのポリシーの仕組み作り、運用 一番メインとなっている活動が、社内におけるエンジニア向けのポータルの管理です。そこに価値のあるナレッジを収集し、必要としている多くのエンジニアに届けられる状態を作っています。例えば社内のエンジニア向けの辞書であったり、Onboardingコンテンツ、キャリアアップのために有用な情報や、エンジニア採用のプロセスやノウハウなどが整理されています。 もちろん、Knowledge Managementの担当者だけが全てのコンテンツを作ったり、アップデートしたりするのは不可能なため、一定のポリシーやルールを作り、運用するというのも大きな活動の一つです。どれくらいのエンジニアが見て、どれくらいのエンジニアがコンテンツにコントリビューションをしてくれているのか、というのを重要な指標としており、エンジニアが自然に日々の業務の中で、ナレッジをシェア、ドキュメント化しようと思えるような文化、環境を作ろうとしています。 Strategy ミッション エンジニアリングにおける戦略の言語化をすすめ、外部に発信したり、他部署に理解してもらえる状態を目指しています。Engineering Officeにおいて一番新しい取り組みです。 ビジネスは数年単位の戦略が存在するように、エンジニアリングにおいても、年単位の投資が必要な活動が多く存在します。過去の例でいうと、MobileとWebのリファクタリングプロジェクトや、ビジネスの共通基盤ドメインの大幅アップデートである RFS などがそれにあたります。こういった開発は、売上にすぐに繋がるような、緊急性の高いものではありませんが、将来の開発速度や、メンテナンスコストなどを踏まえると、非常に重要です。 これらの開発が考える重要な投資をエンジニア以外の方が理解しやすいような形で言語化し、エンジニア戦略として発信を行っています。それにより、他部署やプロダクトマネージャーにその重要性を理解を得て、売上をあげるような新規開発と、中長期を見据えた機能を直接増やすわけではない開発の適切なバランスが取れている状態を目指しています。 主な仕事 ・技術課題における中長期計画作成のサポート・発信・運用 ・Engineering Principlesの作成のサポート、発信 ・Engineering OKRの作成のサポート・運用 もちろんこういった計画の中身自体はCTOをはじめとしたエンジニア部門のリーダーが中心となって考えますが、ボトムアップで必要な情報を集めたり、更新サイクルの作成、適切な発信を行っていくためのサポートをEngineering Officeでは行っています。 今回紹介した6つの領域はそれぞれ強く結びついています。例えばOnboardingで作成したコンテンツはTech Brandingを通して外部に発信されます。Strategyで決められた方向性やカルチャーは、Internal Communicationを通してEMやエンジニアに発信され、Onboardingを介して新しく入社するエンジニアに届けられます。また、新しい目指すべきカルチャーに沿って評価の定義が微調整され、Engineering Ladderによって、その見える化が進み、そのドキュメントはKnowledge Managementの元、管理、更新が徹底されます。メルカリにおけるEngineering Officeの強みは、これらの活動のシナジーを意図的に生み出せるところにあるかなと思っています。 課題と展望 以上がEngineering Officeがメルカリエンジニアリング組織横断で行っている仕事です。 どの活動もまだまだ道半ばで、やれること、やらなければいけないことが非常に多いです。特にオンラインとオフラインが入り混じるハイブリッド環境下でのコミュニケーションの促進、改善はいまだ試行錯誤しており、いまだに新しいチャレンジを繰り返しています。 また、Knowledge Managementの最適化は十分なスピードで行えておらず、コンテンツが過去のまま更新されずに利用されていたり、どこにドキュメントを書けばいいかわからないといった問い合わせがあったり、場合によってはフロー情報であるはずのSlackが、Wiki代わりに使われてしまって、誤った過去の情報を元に仕事が進められてしまったり、ということも発生しています。 プロダクトも大きくなり、フィンテック領域が黒字化し、会社としても少しづつステージや雰囲気が変わってきたなと内部からも感じることが増えています。今後も既存プロダクト、新規プロダクト開発での新しい技術的チャレンジは増えていきます。少しでも価値が早く提供できるように、それまでの道のりがエンジニアにとって良い体験になるように、今後も足元の課題解決を進めていければと思います。 長文になりましたが、読んでいただきありがとうございます。読者の方にとって、少しでも何かプラスになれば幸いです。メルカリ編と書きましたが、こういった話は中々表に出てこない領域でもあるので、他社の方で同じような取り組みをしている方がいれば是非書いてみてください!
この記事は、 Merpay Advent Calendar 2023 の6日目の記事です。 はじめに こんにちは、MerpayでBackend Engineerをしている @panorama と申します。 今年(2023年)の4月に新卒として入社しました。 今回は「メルペイに新卒入社して1年目にやったこと」という内容で、入社後から現在にかけてどのようなことをしてきたかご紹介したいと思います。 今後入社される方やメルペイ新卒エンジニアの1年目の動きに興味がある方の参考になればと思います。 (一部プロジェクトは社外秘で内容は伏せています🙏) それでは早速始めていきます。 4月~6月 研修期間 4月~5月の頭にかけてはメルカリグループの新卒研修である「DevDojo(※1)」を受けていました。 DevDojoでは特定の分野に限らず Backend、 Frontend、 セキュリティ、 アーキテクチャ、 Spanner 、・・・ などさまざまな技術について学びます。 また今年は新しい試みとしてマナー研修もありました。 「人生に1度きりの新卒研修なのでマナーについて学んでおこう」というものです。 名刺の渡し方や席の座り方(※2)、社内の人間の呼称など基本的なマナーを勉強しました。 今年のDevDojoは取材も入っていて、上記のマナー研修の様子もYouTubeに上がっているのでご興味があればぜひ見てみてください。 業務開始 DevDojoが終わってからは本格的に業務に入っていきました。 そのとき進んでいたプロジェクトとして「メルカード審査完了後に即座にカード番号を利用できるようにする」というものがあり、その機能の一部の実装を担当しました。 今まではカードを利用するためにカードの到着を待つ必要があったのですが、上記のプロジェクトによってオンラインでの決済であれば審査後すぐにご利用いただけるようになりました。 審査完了後すぐカード番号が利用可能に そのプロジェクトが終了してからは他の機能も実装しつつ、少し大きめの改善系のタスクなども実施していました。 これに関しては以前記事(※3)を書いたため、気になる方はそちらをご覧ください。 また上記の期間を通してドメイン知識のキャッチアップや運用の理解、QA環境の用意の仕方やリリース手順などBackendが関わる基本的な作業についても学んでいました。 ※1 技術トレーニングDevDojoで実際に使用されている学習コンテンツを公開しています。 こちら をご参照ください。 ※2 ちなみに余談ですが、筆者のpanoramaはこのマナー研修後にExec(役員)と新卒のランチ会に30分遅刻(😇)し、なぜか上座が空けられていたので座ったという体験をしています。そしてなぜか誰もそれを気にしていませんでした。(補足すると遅刻の理由は寝坊ではなく直前のMTGの終了時刻がランチの開始時刻であったことと、ヒルズを出た後迷子になったというダブルパンチによるものです。) ※3 Cloud Tasksで外部APIへの流量制御をするときに考えたこと 7月~9月 7月からは業務の幅を広げて、お問い合わせの調査なども積極的に拾うようになりました。 私のチームでは、お客さまからのお問い合わせは基本的にはCS(カスタマーサポート)チームが対応するのですが、サポートツール上からはわからない事象だった場合はBackendが調査を行う体制になっています。 また8月からはオンコールのシフトにも入るようになりました。 オンコールとは「サービスのパフォーマンスが悪化したり、停止が疑われたりする場合に備えて担当者が常時対応できるようにしておく仕組み」です。 メルカリグループではPagerDutyを使用してオンコールシフトを管理しており、PagerDutyに紐づけられた特定のDatadog Monitorが閾値を超えた場合、自動で担当者を呼び出す仕組みになっています。 5月~6月にかけて知識のキャッチアップや運用の理解を進めてきたため、(難なくとは言いませんが)お問い合わせやオンコールに対応できるようになりました。 (※またオンコールは万が一手に負えない場合、エスカレーションする仕組みがあります。) オンコールで使用しているツール (左: Datadog, 右: PagerDuty) (Datadog 画像 出典: https://www.datadoghq.com/ja/about/resources/) (PagerDuty 画像 出典: https://www.pagerduty.com/brand/) DatadogのロゴになっているワンちゃんはBitsという名前みたいです 合わせて8月1日から入ってこられたインターン生(※4)のメンターにもなりました。 メンターの主な役割はインターン生のサポートですが、メルカリグループでは新しくチームに入られた方に対してメンターランチ(※5)やチービルランチ(※6)を行う文化があるためそういったサポートも実施しました。 インターン生の方はみなさんとても優秀ですが、社内の知識に関しては初めてのことばかりなので、メンターとしてタスクを適切に分割してお渡ししたり、実装に必要な知識をお伝えしたり、場合によっては巻き取って進められるように自分もタスクを追ったりしていました。 8月中旬以降は新しいプロジェクトに参加しました。 そのプロジェクトは今までに経験したことのない別のチームと連携して行うもので、かつ延期が難しいハードスケジュールのものでした。 自分のチームから担当としてアサインいただいたのですが、開発終盤で別のチームとの依存関係を見落としている箇所があることが発覚し、ギリギリで実装を追加することで乗り切りました。 (他の開発チームと特にQAの方にご協力をいただいてなんとか無事故・不具合なしで期日内にリリースできました。) この経験以来、他チームとの調整がある場合にはなるべく早い段階で変更箇所を確認し、定期的にsyncしていく必要があることを意識するようになりました。 上記はプロジェクトの内容を伏せてしまっていますが、他にはFIDOの対応などもやっていました。 FIDO認証画面 ※4 参考: mercari careers / Students ※5 メンターランチ: メンターとメンティー(新入社員・インターン生)とのランチ。チームメンバーや他チームを紹介がてら行います。 ※6 チービルランチ: 目的はメンターランチと同じでrelationship buildingですが、関係性はメンターとメンティーに限りません。 10月~現在 10月の中頃でメンティーだった方のインターン期間が終了しました。 そして新しく動き始めたプロジェクトにBackendの担当としてアサインされました。 このプロジェクトではまず機能自体の調査とそれを実現するための調査が必要でした。 機能に関する資料と調査結果をチーム内で読み合わせ、ある程度固まったら関連するチームも巻き込んで共有会を行いました。 担当のBackendとしてこの調査や会議のリードを任せていただき、現在は設計に入っています。 ありがたきUnipos (社内投げ銭サービス(※7)) 今まではタスクがアサインされた時点でやることが決まっていることが多かったのですが、今回は「何をどこまでやるのか」「どうすれば実現可能か」という段階からPMと一緒に関わらせていただいているので非常に新鮮に感じています。 先述の通りまだ設計中で、その後にbreakdownして実装に入るので、引き続きプロジェクト達成に向けて努力していく所存です。 また上記のプロジェクト以外だとBe a Pro Days(※8)と呼ばれる取り組みで自動化のためのBotを作ったり、キャンペーン施策のBackendの実装をいくつかやったりしました。 ※7 参考: メルカリのピアボーナス制度「メルチップ」、メッセージ累計数が100万を突破しました〜!#メルカリな日々 ※8 参考: 「自分自身が発揮できる価値」に向き合う──1人ひとりがオーナーシップを持って課題解決を取り組むために導入した「CD Be a Pro Days」 まとめ 今回は私が新卒入社後にどのようなことをしていたか、(振り返りの意味も込めて)記事化してみました。 入社前には自分が1年目でインターン生のメンターになったり、一部のプロジェクトのリードを任せてもらえるとは思っていなかったため本当に「Go Bold」の考え方が実践される素晴らしい環境だと感じました。 また多少の修羅場(?)やさまざまなチームの方とのコミュニケーションの機会を通じて、技術一辺倒だった学生時代よりも色々なスキルを身につけた気がします。 内容としては個人ブログのような部分も多かったかもしれませんが、社内レビューを通っているので”公認”で社内の話についていろいろ言及できた気がします。 メルペイ(メルカリグループ)の新卒入社後について気になっている方がいて、具体例として参考になっていれば幸いです。 それでは、ありがとうございました。 明日の記事は @Malli さん, @ben.hsieh さんです。引き続きお楽しみください。
こんにちは。メルペイ Engineering Engagement チームの mikichin です。 この記事は、 Merpay Advent Calendar 2023 の5日目の記事です。 11月のOffice Weekで「Fintech Tech Talk at Office Week」を開催したので、その様子をお届けします。 Fintech Tech Talk at Office Week について Office Week とは? メルカリグループでは、「YOUR CHOICE」という制度があり、約90%以上のメンバーがリモートワークで働いています。 関係性が薄くならないようにメルカリグループのFintech領域では「Office Week」というイベントをだいたい半期に1度開催し、なるべく出社し集まることでチーム内・他部署・経営とのコミュニケーション機会の創出、関係強化を図っています。 メルカリ、多様な働き方を尊重した 「メルカリ・ニューノーマル・ワークスタイル “YOUR CHOICE”」の活用状況を公開 Fintech Tech Talk とは? エンジニアリング組織全体で得た知見を共有するLT大会です。 発表時間は5分、話すテーマは技術的な話はもちろん、趣味の話など何でもOKというゆるいルールです。 リモートワークが中心となった今、オフラインで全体に知見を共有する機会も少なくなりました。そこで、他チームのメンバーや取り組みを知り、交流のきっかけになればと考えて運営しています。 当日の様子について どんなLTがあったのか 内容は業務にとどまらず、興味のある領域も対象です。キーボードの話や直近チームで取り組んだプロジェクトについての話、メルカリグループの部活として行っている 技術書典 の話など、さまざまなテーマのLTがありました。 △メルペイVPoEのkeigowさんが「Introduction of Competitive Programming」の発表をしている様子 メルペイ Frontendエンジニアの @yutaro さんは、以前 社外イベント で発表した「内製UIコンポーネントのアクセシビリティテストを支えるOSS」を社内用にアレンジして発表をしました。社外イベントの資料は公開していますので、興味がある方はぜひこちらをご確認ください。 メルペイ Backendエンジニアの @Liu さんが発表した「LINE 公式アカウントPJ」については、下記記事をご確認ください。 Flow Control Challenges in Mercari’s LINE Integration 参加者の反応について イベントには、メルペイ新CEO @Takeshiさんをはじめエンジニアリング組織以外のメンバーも含め、100名以上が参加しました。 現在のメルカリグループは、約50カ国のメンバーで構成されています。本イベントに全員が参加できるよう、Global Operation Team(GOT)※ の同時通訳を入れ、登壇者の言語にあわせた言語で司会進行しました。 ※:社内の通訳・翻訳を担当する専門チーム GOTの取り組みはぜひ、メルカン記事「 言語を活用してメルカリのビジネスやD&Iをサポート!──Global Operations Teamが提供する通訳・翻訳業務以上の価値 」をご確認ください。 イベント中、Slackには「アクセシビリティ、大事だよねぇ」「全然知らない内容でおもしろい」といった内容についての反応や「日本語だけではなく、英語のLTもあってよかった」「おもしろかった」といったイベント全体への感想が投稿されていました。 Office Weekにあわせて出社した社員はもちろん、Fintech Tech Talkはオンラインでの参加者もたくさんいました(Google Meetで社内向けに配信していました)。 おわりに 社内向けLT大会は、参加者が発表をきいて何かを得ることも大事ですが、それよりもわいわいみんなで楽しむことができること、気軽に発表をするという経験をすること、が大事かなと思っています。 今回、イベント当日の朝に飛び込みで登壇が決まったLTがありました。プレゼン資料はなく、完成したばかりのシステムの画面を使ってアップデート箇所を紹介するLTだったのですが、このLTもとても盛り上がっていました。こういうふうに気軽に発表でき、みんなで盛り上がる場所を今後もつくっていきたいなと思います。 明日の記事は panoramaさんです。引き続きお楽しみください。
 こんにちは!横浜国立大学理工学部情報工学EP3年の @shion1305 です。今年の10月から株式会社メルペイ Settlementチームにてバックエンドエンジニアのインターンとして所属しています。 この記事は、 Merpay Advent Calendar 2023 の4日目の記事です。 Settlementチームでは、メルペイ加盟店で発生した売上金を加盟店に振り込む際に、指示を出したりデータの管理を行ったりするマイクロサービスの開発を行っています。Settlementのマイクロサービスについては こちらの記事 でも紹介されています。 私がJoinして早々担当したタスクの一つが、Settlementサービスに対するKubernetesのPod Distruption Budget(PDB)設定の見直しでした。Kubernetesについてはこれまで個人開発で少し調べたことがある程度でした。今回PDB見直しを行う中で仕様についてリサーチをしていたのですが、多くの記事がある中で実際の挙動について自分が思うような記事があまり見つかりませんでした。今回のAdvent Calendarを機に、自分なりにわかりやすくまとめてみることにしました。 本記事では、特に以下にフォーカスします。 PDBの挙動 パーセント指定を用いた場合のPDBの動き minAvailable maxUnavailable それぞれのポイント Pod Disruption Budgetの概要  PDB(Pod Disruption Budget)は、 Voluntary Disruptions(システムの計画的な中断) からアプリケーションの可用性を保護するKubernetesの機能です。 Voluntary Disruption の具体例としては以下が挙げられます。 kubectl drain でのNodeからのPod退避 Nodeスケールダウン時のPod退避 Node間のPodの移動 (NodeからPodを他のNodeに退避させる操作を、以降Drain操作と表記します。)  例えば、以下のように記述すると、 Voluntary Disruptions において、使用できないPodの割合を33%までとなるように指定できます。 apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: pdb-sample namespace: namespace-sample spec: maxUnavailable: 33% selector: matchLabels: app: pdb-tester  PDBの設定においては、 minAvailable または maxUnavailable のいずれか一方を指定することが可能です。 minAvailable では、指定したPod群の中で常に稼働していなければならない最小限のPodの数または割合を指定でき、 maxUnavailable は、一度に中断または利用不可となっても良いPodの最大数または割合を指定できます。 自動スケールによってPod数が変動する場合において固定値を設定するのみではPod数に応じたPDBの挙動を設定することができないため、パーセント指定が用いられることがあります。実際、メルカリグループのマイクロサービスで設定されているPDBの多くでは、パーセント指定が用いられています。  しかし、パーセント指定を行う場合、PDBがどのような挙動をとるのか、分かりにくくなってしまいがちです。 パーセント指定におけるPDBの挙動 公式ドキュメントでの記載 公式ドキュメントには以下のように、パーセント指定で中途半端な数になった時には数が繰り上げられることが明記されています。 When you specify the value as a percentage, it may not map to an exact number of Pods. (中略..) Kubernetes rounds up to the nearest integer, so in this case, 4 Pods must be available. When you specify the value maxUnavailable as a percentage, Kubernetes rounds up the number of Pods that may be disrupted. Thereby a disruption can exceed your defined maxUnavailable percentage. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget 対応するソースコードを見てみる  中途半端な数になった際の繰り上げの振る舞いについて、実際のソースコードを確認してみます。 minAvailable と maxUnavailable の読み取りに対応する部分は以下のようになっています。 /pkg/controller/disruption/disruption.go L797-L800 (2023/12/1時点) maxUnavailable, err = intstr.GetScaledValueFromIntOrPercent(pdb.Spec.MaxUnavailable, int(expectedCount), true) if err != nil { return } minAvailable, err = intstr.GetScaledValueFromIntOrPercent(pdb.Spec.MinAvailable, int(expectedCount), true) if err != nil { return } ここで用いられている GetScaledValueFromIntOrPercent の中身の実装はこのようになっていて、上記では パラメータとして roundUp: true が指定されているため、繰り上げ処理がされていることが確認できます。 func GetScaledValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool) (int, error) { (中略...) if isPercent { if roundUp { value = int(math.Ceil(float64(value) * (float64(total)) / 100)) } else { value = int(math.Floor(float64(value) * (float64(total)) / 100)) } } return value, nil } PDB設定時の動作例 前述で繰り上げ処理が行われることはわかりましたが、受け付けた値に対してPDBがどのような動作をするのかについて、いくつかケースを想定して検証しました。 今回想定した流れは以下の通りです。 Nodeが2つ存在している 片方にPodが入っていて、PDBが設定されている Podが存在しているNodeに対して kubectl drain が実行され、Podの退避処理が実行される ケース1: Pod数:2, maxUnavailable:50% maxUnavailableのPod数は1Podとして計算されます。その結果、図のように可用性を担保した状態で Drain操作ができることが確認できました。 ケース2: Pod数:1, maxUnavailable:50%  maxUnavailableのPod数は1となります。そのためDrain操作が可能となりますが、退避するPodの中断処理と新しいPodの起動処理は同時に実行されるため、Drain操作中に利用可能なPod数が0となる可能性があります。  このようにmaxUnavailableを用いる場合、最小pod数を考慮する必要が出てきます。(Pod数が1の時にあえてDrainできないようにする手段もあるようです。 公式ドキュメント ) ケース3: Pod数:2, maxUnavailable: 80%  maxUnavailableのPod数は2となります。そのため2Podに対して同時に退避処理が実行されます。そのため、drain操作中に利用可能なPod数が0となる可能性があり、可用性に問題が出る可能性があります。 ケース4: Pod数:1, minAvailable: 50%  minAvailableのPod数は1となります。PDBはdrain操作のためにPod数の調節を行うことはしないため、PDBの条件を満たすDrain操作ができず、Drain操作は止まったままの状態となります。  このように、minAvailableを用いる場合でも最小pod数を意識する必要が出てきます。 minAvailableとmaxUnavailableの整理  これまで具体的なケースにおけるPDBの影響を確認しました。  PDBではminAvailableとmaxUnavailableどちらかのみしか設定することができません。それぞれを採用することによるメリット、考慮すべき点について以下にまとめます。 minAvailable メリット 0より大きい数を指定しておけば、Drain操作時において必ず1Pod以上動作させて可用性を持たせることができる。 考慮が必要な点 (パーセント指定ではなくPod数で指定した場合) スケールアップして多くのPodがPDBの管理対象となっている場合、Drain操作で一度に多くのPodが利用できない状態となり、パフォーマンスに影響が出る可能性がある。 適切に値を設定しないとDrain操作ができなくなってしまう。(特に管理対象のPodが少数である場合は注意が必要) Drain操作ができなくなる条件 パーセント指定の場合、現存のPod数に対して計算を行い繰り上げ処理が行われた結果、minAvailableのPod数がPDBが対象とするPod数と同数になる時。 Pod数指定の場合、minAvailableのPod数がPDBが対象とするPod数より多くなってしまう場合。 maxUnavailable メリット Drain操作ができなくなる状態は基本発生しない。 考慮が必要な点 適切に数値を設定しないとDrain操作中に全てのPodが中断してしまう可能性がある。 Drain操作ができなくなる条件 maxUnavailableを0に設定する。 Pod数が1の状態のままでは可用性を持ってDrain操作をすることができないため、あえて maxUnavailable: 0 を設定して警告を出すために設定する方法もあるようです。 公式ドキュメント まとめ  PDBの設定に関しては、minAvailable と maxUnavailable のどちらが良いという一般的な答えは存在しません。システムによって要件は異なるのでPodの最小稼働数や中断許容範囲を理解し、それに基づいて適切な設定をすることが重要です。今回の記事が、皆さんのPDBに関する理解を深め、より効果的なKubernetesの運用に役立つ一助となれば幸いです。 明日の記事はmikichinさんです。引き続きお楽しみください!
はじめに こんにちは。メルペイVPoEの @keigow です。 この記事は、 Merpay Advent Calendar 2023 の2日目の記事です。 今年の3月まではソウゾウでHead of Engineeringとして働いていましたが、4月にメルペイに2年ぶりに戻ってきました。本日はメルペイのProduct組織の改善とProgram組織への移行の取り組みについてご紹介します。 以前のProject Matrix型組織 2022年9月までは、Microservicesの単位をベースとして構成されたFunctionチーム(Growth、Platform、与信領域など)から、3ヶ月ごとに決めているProject(新機能開発、他社連携など)に各メンバーをアサインしていくという形でProduct開発を推進していました。 会社のOKRとして合意した目標に沿って、Productチーム内でProjectの優先度を決めて左から順に並べ、Project毎にProject LeaderとTechnical Project Manager(Engineeringのカウンターパート)を置くことで、以下のような良い点があったと考えています。 事業としてフォーカスされている点が理解しやすい 優先順位が明確なためアサインの判断がしやすい 結果として、会社として重要なProject(チーム横断な動きが必要なものであっても)をスピード感を持って推進できる 一方で以下のような課題感もありました。 組織の成長と人員増加に伴い、優先順位の調整コストが高まってきた 3ヶ月単位でProjectの見直しがあり、アサインの変更も随時行っていたため、チームビルディングのコストが高い 今後の運用や改善までを想定した中長期の計画づくりが難しくなっていた これらの課題感を踏まえて、2022年10月より新しいProgram型組織への移行を開始しました。 Program型組織の導入 特定のドメインごとに組織を分けて、より小さな単位で意思決定をできるようにしたチームをProgramと呼んでいます。現在メルペイには6つのProgramがあり、その役割ごとに大きくProduct / Foundation / Enablingという3つの領域に分けています。 Product: 支払いや与信、還元の仕組みなどお客さま体験のコアとなる部分の提供を担う。 Foundation: 各Product領域のProgramに対して汎用的に利用可能なPlatform機能を提供する。決済の中心となるマイクロサービスや、KYC(本人確認)、ポイント付与の仕組みなど。 Enabling: ArchitectやSRE、Data Platformなど、横断的な技術課題の解決や生産性向上など開発全体を支援する。 各ProgramにはProduct HeadとEngineering Headを置いています。Product Headは施策の優先順位の決定や、戦略・ロードマップの策定とその推進に責任を持ち、Engineering Headは中長期を見据えた技術的な戦略や方針の策定と推進に責任を持っています。 基本的にはOKRなど会社方針をベースにProgram内で意思決定が出来るようにしていますが、3ヶ月ごとにProgram HeadメンバーとCPO/CTO/VPsを交えたStrategy Reviewを行うことで、Program組織の戦略と経営の戦略の方向性を揃えられるようにしています。 Engineering組織のアップデート ドメイン毎のProgram組織を作ることで、Program内のアサインに柔軟性が生まれ、運用や改善も踏まえた、中長期の戦略への投資がしやすい環境になりました。一方でEngineering組織のレポートラインは職種別となっており、Backend、Frontend、iOS、Androidなど各職種別にEngineering Manager(EM)、Manager of Managers(MoM、EMのManager)が居るという体制になっていました。その結果として一部のEMやMoMが各Programにフォーカスすることが難しいという課題が有りました。 この問題を解決するため、今年の10月からProgram組織に合わせたレポートラインに変更し、それぞれのEMやMoMが自身の担当するProgramにフォーカスできるような体制変更を行いました。 振り返りと今後 Program組織にトライし始めたのは1年ほど前ですが、Engineering組織のアップデートも含め、細かい改善を積み重ねることで、少しずつ動きやすい状況が作れてきたと思います。とはいえ、まだまだ課題も多いため、1つずつ課題と向き合って解決していきたいと思っています。 余談になりますが、今回のような組織体制はメルペイとしては初めてではなく、Project Matrixをベースとした体制に移る前には、(当然今と違う部分はありますが)Program組織に近い体制を取っていた時期もありました。 組織変更はコストが高いので、頻繁に変えすぎるのは良くないと思っていますが、一定のタイミングでその時の状況やニーズに合わせて、変化をしていくこと自体は必要だし、やっていきたいと思っています。どのような組織もPros/Consがあるものだと思うので、ある意味自然な姿だとも感じます。 おわりに 明日の記事はkeigoandさんの「Merging teams for a Growth Platform」です。引き続きお楽しみください。
この記事は、 Merpay Advent Calendar 2023 の1日目の記事です。 hello hello hallo how high? メルペイで5月からVPoE の @nu2 です。 はじめに 2023年6月、メルペイはエンジニアリング組織の新体制を発表しました。 https://mercan.mercari.com/articles/39414/ (新体制になったメルカリグループのFintechのエンジニアリング。新CTOとVPたちが語る、グループLTV最大化のためにFintech事業が果たすべき役割) 今年の Merpay Advent Calendar はエンジニアリング組織新体制の元、オープナーとしてメルペイのこの1年を淡々と振り返ってみたいと思います。 特に私は5月に入社しましたので新鮮な視点をお伝えできればよいなと考えています。 https://engineering.mercari.com/blog/entry/20230704-merpay-techasset-first-impression/ (New Member として見たMerpay Tech Asset First Impression) LLM 入社日当日にLLM を活用した「ぐげん会議」を開催するからVP としてチームのスポンサーになってくれと言われました。全く前知識とコンテキストがないまま、これまでの経験から障害報告書を障害の状況から規定の形式に自動生成して書記をするAI を開発するチームをスポンサードする事に決めました。 https://mercan.mercari.com/articles/39144/ (LLMを活用してなにがつくれるか?——「ぐげん会議」開催から見えてきた、AI活用の新たな可能性) 私がスポンサードしたチームは見事にCTO 賞を受賞しました。 また、MVPを受賞した返済相談チャットシミュレーターを開発したチームはその品質の高さとともに、会社の決算資料にも報告を開始したクレジットサービスの債権残高 / 回収率にとても大きなインパクトを残しそうなポテンシャルを感じるAI プロダクトでした。 メルカード 2022年12月から提供を開始したメルカードの発行枚数が200万枚を突破しました。 https://jp.merpay.com/news/2023/11/2million/ (「メルカード」、すべてのお客さまへの提供開始から1年足らず(約11か月)で発行枚数200万枚突破) 提供開始からわずか半年で機能をアップデート、その約3ヶ月後に更にアップデートをしています。 https://jp.merpay.com/news/2023/06/20230627seisan/ (メルペイ、清算機能のアップデートで清算後すぐに「あと払い利用枠」が回復する機能を追加) https://jp.merpay.com/news/2023/10/20231016seisan/ (メルペイ、清算機能のアップデートで清算後すぐにポイントが付与される機能を追加) このような体験向上をデザイン面、エンジニアリング面から支えた結果がグッドデザイン賞を受賞した事につながっているのではないかと思います。 エンジニアリングとしてこのように短期間でアップデートをかけられる決済機能をこれまで日本国内で見た事はありません。 なぜこのような事が可能なのか?という事はMerpay & Mercoin Tech Fest 2023 の こちらのセッション にて発表されています。 グッドデザイン賞 https://about.mercari.com/press/news/articles/20231005_gdesign/ (メルカリグループのサービス、「メルカード」と「ビットコイン取引サービス」が2023年度グッドデザイン賞をW受賞) Merpay & Mercoin Tech Fest 2023 そしてエンジニアリング組織の新体制後初のTech Fest を開催しました。 Fintech 領域の業務経験やドメイン知識が不十分な状態で入社しましたので 個人的にもこのTech Fest は自分のインプットを増やす上で非常に有用でした。 https://mercan.mercari.com/articles/39180/ (8月22日より3日間にわたって開催!Fintech CTOと2名の新VPoEに聞く、「Merpay & Mercoin Tech Fest 2023」の見どころと意気込み) https://engineering.mercari.com/blog/entry/20231023-mmtf2023-day1-2/ (【書き起こし】How to Unleash Fintech – Shunya Kimura / Keigo Watanabe / Noriaki Utsunomiya 【Merpay & Mercoin Tech Fest 2023】) 現在配信したセッションの動画を全てテキストに書き起こしてくれているので予習、復習に最適です。 https://engineering.mercari.com/blog/entry/20231023-mmtf2023-list/ (Merpay & Mercoin Tech Fest 2023 セッション書き起こしまとめ) 求人プラットフォーム「メルカリ ハロ」 そしてTech Fest のトークセッションで「まだ言えない事がある」とCTO が言及していたのがこのスポットワーク事業に参入する話です。 https://about.mercari.com/press/news/articles/20231113_mercarihallo/ (メルカリ、2024年初春にスポットワーク事業に参入、本日より求人募集パートナーの先行受付を開始) “メルペイを通じて、給与デジタル払いを実現し、「メルカリ ハロ」をご利用いただいた際、「メルペイ」で給与を受け取れる体験を提供することを目指します。” プレスリリースから引用した文章のとおり、この体験の提供を実現するため現在急ピッチかつ慎重にプロジェクトを進行しています。 貸金業務取扱主任者制度 貸金業務取扱主任者制度 とは貸金業法で定められている国家試験です。 我々は貸金業を営んでいますので、所属する社員は誰でも会社の経費で受験する事ができます。ドメイン知識を習得する絶好の機会なので受験してきました。 毎年試験にチャレンジするエンジニアはかなりおり、試験前後は試験対策用に立てられたSlack チャンネルがとても盛り上がってました。 なぜこのような法律ができて、貸金業を事業とする事業者は資格の保有を義務付けられるのか?というこれまでの歴史的背景から学ぶ事も多くあり私は既に来年の試験に向けて毎日少しずつ学習を繰り返そうと考えています。 経済安全保障推進法 株式会社メルペイは経済安全保障推進法の特定社会基盤事業者として指定されました。 給与デジタル払いを実現するためにも必要なことであります。 https://www.fsa.go.jp/news/r5/economicsecurity/231117infrastructure.html (金融分野における経済安全保障対策) “経済安全保障推進法第50条第1項及び第2項の規定に基づき、特定社会基盤事業者を令和5年11月16日に指定し、同年11月17日に公示しましたので、別添をご確認ください。” https://www.fsa.go.jp/news/r5/economicsecurity/tokuteishakaikiban.pdf (特定社会基盤事業者として指定した者) 私が入社後ちょうど半年を経過したタイミングで国から社会インフラの一部として指定され、入社後丸一年経過する日までに法令に準拠する体制を構築しなければなりません。 私個人の経歴としてもインターネットポータル、検索、通信とICT の社会インフラ企業で経験を積んできましたので運命めいたものを感じてしまいました。 「守り」あってこその「攻め」を来年は実践していく所存です。 おわりに 2023年のメルペイは前年にリリースをした大きな機能を磨き上げる年になったと個人的に感じました。またその大きな機能に対してさまざまな反響をいただきました。 今後もお客さまの安心・安全を維持しながら新たな価値をお届けすることを、エンジニアリングで達成していきたいと思います。 明日の記事は VPoE のkeigowさんです。引き続きお楽しみください。 おまけ 今年無事。 所属する会社が変わってもこのフレーズをAdvent Calendar に投稿する事は私の恒例行事なので、 今年もILL-BOSSTINO のこの言葉を捧げます。 特に我々の業界は月跨ぎ、年跨ぎのタイミングでインシデントが発生しやすいです。 皆さま良いお年をお迎えください。 (THA BLUE HERB “今年無事” @ 東京 contact – 2019.12.29)
こんにちは。メルペイ Engineering Engagement チームの mikichin です。 早いもので来週から12月ということで、Advent Calendarの季節がやってきます!今年も、メルカリとメルペイ2社で Advent Calendar を実施します! ▶ Mercari Advent Calendar 2023 はこちら Merpay Advent Calendar とは? Advent Calendar の習慣にもとづいて、12月1日から25日までの期間毎日ブログ記事を投稿する、というブログ公開型イベントです。 メルペイ・メルコインのエンジニアがプロダクトや会社で利用している技術、興味のある技術分野やちょっとしたテクニックなど知見をアウトプットしていきます。このAdvent Calendarを通じてクリスマスまでの毎日を楽しく過ごしていただければと思っています。 2022年のMercari / Merpay Advent Calendar はこちら Mercari Advent Calendar 2022 Merpay Advent Calendar 2022 公開予定表 (こちらは、後日、各記事へのリンク集になります) Date Theme / Title Author 12/1 メルペイ VPoE による2023年の振り返り @nu2 12/2 メルペイのProgram型組織への移行 @keigow 12/3 Merging teams for a Growth Platform @keigoand 12/4 動作例からKubernetes PDBの挙動を理解する @Shion (Intern) 12/5 Fintech Tech Talk at Office Week を開催したよ! @mikichin 12/6 メルペイに新卒入社して1年目にやったこと @panorama 12/7 Enhancing Collaboration and Reliability: The Journey of Version History in our Page Editor Tool @Malli , ben.hsieh 12/8 メルペイでのインターンを2ヶ月経験してみて @Shion (Intern) 12/9 新卒エンジニアが Airflow のバグを発見してからコントリビュートするまで @champon 12/10 加盟店精算のインボイス対応 @ryuyama 12/11 Cypress + Gmail APIでメール+SMSの2FA認証をテスト自動化する(気合&パワー) @fukutomi 12/12 Flow Control Challenges in Mercari’s LINE Integration @Liu 12/13 多国籍メンバーで構成されたメルペイ決済基盤チームが言語の壁を突破するために取り組んだこと @abcdefuji 12/14 TnS Platform Team, past, present, and future @ntk 12/15 Merpay Frontend のこれまでとこれから: 2023年版 @tokuda109 12/16 品質要件が厳しいLLMアプリケーションのトライアル評価を通じて得た知見 @gucci 12/17 2023 GopherCon Review @tenlingp 12/18 (JA) Merpay Enabling Client チームが目指すこと (EN) What the Merpay Enabling Client Team aims for @masamichi 12/19 モダリティを考慮したiOSアプリのナビゲーションの再設計 @kenmaz 12/20 決済基盤の Observability を向上するための Datadog Dashboard の進化 @komatsu 12/21 AWS Transfer Family で SFTPサーバーを作ってみたら便利だった話 @myoshida 12/22 お手軽な検索API構築 その2 ~マルチコア・ベクトル・分散検索 @orfeon 12/23 メルコインにおけるGitHub Actions活用術 @iwata 12/24 Offsitesのワークショップでの4つの工夫 @pooh 12/25 メルカリEngineering Roadmapの作成とその必要性 @kimuras Merpay Advent Calendar 2023 の1日目は、 VPoE の @nu2 が執筆予定です。 ひとつでも気になる記事がある方は、この記事をブックマークしておくか、 エンジニア向け公式X(旧Twitter) をフォロー&チェックしてくださいね!
こんにちは。メルカリ Engineering Officeの yasu_shiwaku です。 またまたこの季節がやってきましたね!来週から12月ということで、Advent Calendarがはじまります。今年もメルカリとメルペイ・メルコインで2本のAdvent Calendarを実施します! ▶ Merpay Advent Calendar 2023 はこちら Mercari Advent Calendar とは? Advent Calendar の習慣にもとづいて、12月1日から25日までの期間毎日ブログ記事を投稿する、というブログ公開型イベントです。 メルカリグループのエンジニアがプロダクトや会社で利用している技術、興味のある技術分野やちょっとしたテクニックなど知見をアウトプットしていきます。このAdvent Calendarを通じてクリスマスまでの毎日を楽しく過ごしていただければと思っています。 2022年のMercari / Merpay / メルカリ Shops Advent Calendar Mercari Advent Calendar 2022 Merpay Advent Calendar 2022 メルカリShops [フライング]アドベントカレンダー2022 公開予定表 (こちらは、後日、各記事へのリンク集になります) Date Theme / Title Author 12/1 The Bitter Lesson about Engineers in a ChatGPT World @darren 12/2 How We Saved 75% of our Server Costs @pratik 12/3 How we reduced response latency by over 80% @rclarey 12/4 Performance monitoring in Mercari mobile apps @fp 12/5 The Spirit of Giving: A Year-End Roundup of Our Open Source Contributions @adbutterfield 12/6 強いエンジニア組織に必要な、6つの技術以外のこと – メルカリ編 — @thiroi 12/7 英語が苦手なエンジニアがメルカリに入ってどうなったか @otter 12/8 t9n, i18n, l10n, g11n ?! @wills 12/9 Gitブランチ戦略 Stacking手法のケーススタディ @osari.k 12/10 In search of a knowledge management silver bullet @rey 12/11 チームワークと効率向上のカギ!メルカリが成功する大人数iOS開発のための手法とは? @sae 12/12 The art of streamlining mobile app releases @fp 12/13 Leading a team of lead engineers @fp 12/14 Current Microservices Status, Challenges, and the Golden Path @ayman 12/15 BigQuery Unleashed: A Guide to Performance, Data Management and Cost Optimization @sathiya 12/16 Closing the visual testing gap on Android with screenshot tests @lukas 12/17 The new Mercari Master API @cafxx 12/18 ① The Frontend Infrastructure Monorepo @jon 12/18 ② Onboarding施策を成功させるポイント @aisaka 12/19 Leveraging LLMs in Production: Looking Back, Going Forward @andre 12/20 GCSのリソース最適化の取り組みで得た知見 @ayaneko 12/21 iOSDC2023で発表した「メルカリ10年間のiOS開発の歩み」のトークスクリプトを公開 @motokiee 12/22① Making of "Your Mercari History" @manoj 12/22② 言語モデルを用いたQuery Categorization ( EN ) @pakio 12/23① メルカリの中長期技術投資 プロジェクトRFS: 約2年の振り返り @mtsuka 12/23② Fine-Tuned CLIP: Better Listing Experience and 80% More Budget-Friendly @andy971022 12/24 Renovate Web E2E tests with Playwright Runner @jye 12/25 メルカリEngineering Roadmapの作成とその必要性 @kimuras Mercari Advent Calendar 2023 の1日目は、 Data Engineeringチームのdarren が執筆予定です。 ひとつでも気になる記事がある方は、この記事をブックマークしておくか、 エンジニア向け公式Twitter をフォロー&チェックしてくださいね!
はじめに こんにちは、mercari.go スタッフの hiroebe です。 11月1日にメルカリ主催の Go 勉強会 mercari.go #24 を YouTube でのオンライン配信にて開催しました。 今回は GopherCon 2023 に焦点を当てた特別回として、サンディエゴで開催された GopherCon 2023 に実際に現地参加したメルカリエンジニアが、セッション内容を要約して発表しました。この記事では、当日の各発表を簡単に紹介します。動画もアップロードされていますので、こちらもぜひご覧ください。 GopherCon 2023 Recap 1つめのセッションは nsega さんによる「GopherCon 2023 Recap」です。 発表資料: GopherCon 2023 Recap at mercari.go#24 このセッションでは、はじめに GopherCon の概要と今年の GopherCon 2023 の様子について紹介し、後半のパートでは GopherCon 2023 から「The Future of JSON」というセッションについて振り返りを行いました。 Go の encoding/json パッケージは、長年使われてきた中で機能の不足やインターフェースの欠陥、パフォーマンスの制約といった問題を抱えていることがわかっていて、これを解決するために新たなメジャーバージョンである encoding/json/v2 パッケージが提案されています。セッションでは、これまでに挙げられた問題点が encoding/json/v2 パッケージによってどのように解決されるかについて詳細に説明されていました。 json と jsontext の2つのパッケージを用意する話など、個人的にもとても興味深かったです。 またセッションの最後には、このような大きな変更を伴う開発をどのように進めていくか、という点についても触れられていました。オープンに議論をしながら合意形成をしたり、パフォーマンスに関してはベンチマークを取りながら進めるといった手法は、nsega さん自身も今後開発を行っていく上で参考にしたいと仰っていました。 Concurrent Data Structures and CPU Caching with Go 2つめのセッションは derrick さんによる「Concurrent Data Structures and CPU Caching with Go」です。 発表資料: Concurrent Data Structures and CPU Cache with Go セッションの前半は、GopherCon 2023 の中から「Building A Highly Concurrent Cache in Go」というセッションの振り返りを行いました。このセッションでは Reddit でのキャッシュの活用事例について話されていて、Redis でのキャッシュとは別にローカルなキャッシュを導入することでコスト削減に成功した事例や、キャッシュのための独自のデータ構造を作成した事例などが紹介されていました。データ構造はシンプルなものから始めること、それを変更する際には都度プロファイルやベンチマークをとることといったノウハウが詰まった発表でした。 セッションの後半では、前半のセッションで言及のあった Cache Line について掘り下げて解説を行いました。サードパーティの xsync.Map は標準パッケージの sync.Map と比べても高いパフォーマンスを見せていて、その理由は Cache Line を考慮したデータ構造にあるそうです。Cache Line を理解するための前提知識として CPU のキャッシュについてもわかりやすく説明されていて、個人的にもとても勉強になりました。 Recap: Automatically Instrument Your Go Source Code with Orchestrion 3つめのセッションは komatsu さんによる「Recap: Automatically Instrument Your Go Source Code with Orchestrion」です。 発表資料: Recap: Automatically Instrument Your Go Source Code with Orchestrion このセッションでは Datadog 社が開発している orchestrion という CLI ツールについて紹介されました。orchestrion は Datadog で APM を計測するための Go のコードを自動計装 (code instrumentation) するためのツールです。Go は Java でいうアノテーションや Python でいうデコレータのような構文を持ちませんが、一方で文法がシンプルで AST のパースが簡単という特徴があり、それを踏まえたアプローチになっているそうです。また AST の解析には標準パッケージの go/ast ではなく dave/dst を使っているそうで、その理由についても触れられていました。シンプルなツールであるため導入が簡単である一方、大規模なリポジトリに導入するにはまだいくつかの課題があると komatsu さんは考えているそうで、今後のさらなる開発に期待したいです。 GopherCon 2023 Overview 4つめのセッションは tenling さんによる「GopherCon 2023 Overview」です。 セッションの前半では、GopherCon 2023 で行われた CTF について紹介しました。GopherCon で CTF が行われたのは今年が初めてで、セキュリティやコードに関してだけでなく、以前の GopherCon で発表されたテーマに関する出題もあったそうです。このセッションでは、CTF で出題された中から tenling さんがお気に入りの問題を2つ紹介しています。CTF は来年も実施を予定しているそうなので、今回の発表で興味を持った方はぜひチェックしておきましょう。 セッションの後半では、GopherCon 2023 から「From Zero to Hero: Launch Your Own Game in 45 Minutes」というセッションについて紹介しました。 feed-the-gopher というゲームを開発した事例の紹介で、 Momento というサービスを利用することで素早い開発を実現しているとのことでした。また、ゲーム開発では Unity などを利用するのが一般的になっていますが、Go でゲーム開発をする人がもっと増えてほしいという思いもこのセッションには込められているそうです。 Navigating the Seas of Data: A Migration Journey 5つめのセッションは mann さんによる「Navigating the Seas of Data: A Migration Journey」です。 発表資料: GopherCon 2023 Bitly _ Migrating 80 billion records from MySQL to Bigtable このセッションでは、Bitly がセルフマネージドな MySQL から Google Cloud の Bigtable へマイグレーションを行った事例が紹介されました。Key-Value 形式の膨大なデータを持つ Bitly 社では、従来の MySQL を利用した仕組みにおいてスケーラビリティやバックアップに関する課題を抱えていたそうです。それらの課題を解決するために Bigtable へのマイグレーションが実施され、結果として高いスケーラビリティや強固なバックアップが実現されました。セッションではマイグレーションの手順について順を追って説明されていて、中でも古いレコードのバックフィルなどを行うマイグレーションスクリプトが Go で記述されているそうです。マイグレーションは手順だけ見るとシンプルですが、これを膨大なデータを抱えるプロダクションサービスで実際にやりきったという事例はとても参考になると思います。 GOOOPs – Talking about Go and OOPs 6つめのセッションは amit-kumar さんによる「GOOOPs – Talking about Go and OOPs」です。 このセッションでは Go と OOP (オブジェクト指向プログラミング) の関係について説明しました。開発者の多くは Go に触れる以前に C++ や Java といった他のオブジェクト指向のプログラミング言語を扱った経験があるかもしれませんが、それらの言語におけるオブジェクト指向の考え方をそのまま Go に適用するべきではありません。そのような誤った方法で Go に OOP が適用された状態をこのセッションでは GOOOP (= GO + OOP) と呼び、GOOOP を疑うべき兆候としてどのようなものがあるか、具体例とともに紹介されています。またセッションの後半では、OOP とセットで語られることの多い SOLID 原則についても紹介しました。SOLID の各原則が Go ではどのように実現されるかについて、1つずつ順番に説明されています。従来の OOP の考え方をそのまま適用するのではなく、その背景にある原則を正しく理解し Go らしい書き方で実現することが重要であると結論づけていて、個人的にもとても勉強になるセッションでした。 おわりに 今回は GopherCon 2023 の活動報告会として、実際に現地参加したエンジニアからセッションの振り返りの発表をお送りしました。GopherCon 2023 に参加できなかった方も、イベントの雰囲気を感じていただけたのではないでしょうか? ライブで視聴いただいた方も録画を観ていただけた方も本当にありがとうございました! 次回の開催もお楽しみに! イベント開催案内を受け取りたい方は、connpassグループのメンバーになってくださいね! メルカリconnpassグループページ
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるエンジニアリングを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 今回、より多くの方に知ってもらい役立ててもらうため、Merpay & Mercoin Tech Fest 2023の全セッションを書き起こした記事を用意しました。セッションがたくさんあるので、その記事リンクまとめを作成したのが本記事です。お役に立てば幸いです。 ▼Merpay & Mercoin Tech Fest 2023 書き起こし一覧 ※各記事にYoutubeのセッション動画が埋め込まれています。 .author_icon{width:50px; height:auto; margin:1px; border-radius:20px} .day1{ border: 2px solid #ff0211 !important} .day2{ border: 2px solid #4dc9ff !important} .day3{ border: 2px solid #00c1aa !important} Author Session Title Keynote Shunya Kimura How to Unleash Fintech Shunya Kimura , Keigo Watanabe , Noriaki Utsunomiya 1週間リリースを支えるAndroid自動テスト運用のその後 Kenta Takahashi , Shintaro Miyabe Merpay iOSのGroundUp Appへの移行 kenmaz Merpay iOSにおけるSwift Concurrency対応の挫折と今後 Takeshi Sato SwiftUIでビットコインの価格チャートを改善・再実装した話 andooown フロントエンドチームのスキルテスト評価システム改善の取り組み tokuda109 WYSIWYGウェブページビルダーを支える技術的マジックの裏側 Hal Amano , Arvin Huang , Ben Hsieh , Jas Chen メルカリのカスタマージャーニーにおける不正防止の取り組み codechaitu 日本におけるお客さま本人確認と今後の技術的課題 Tim Tosi , Manpreet Kaur , Christophe Labonne メルカリへのFIDO導入の経緯とこれからの展望、課題から得た学び koi , kokukuma , daichiro , hidey メルペイのあと払いとスマートマネーを支える返済基盤マイクロサービスの進化 Peichong Cui 拡張性を備えたソフトウェア設計 Rupesh Agrawal 発行枚数100万枚を支えたメルカードGrowth施策の裏側 Kazuya Kawashima , Soichiro Kashima , Mikael メルカードの常時ポイント還元開発の裏側 keitaj メルペイ加盟店売上精算の仕組み Takumi Shibazaki GoによるSQLクエリテストの取り組み Yuki Mukasa 発生可能な取引の属性データを用いた素早い不正検知 Liu , Li メルペイMLにおける機械学習の品質保証とリスク管理 shuuk , Haruki Kaneko , Yuki Saito Merpay & MercoinにおけるLLM活用の取り組み Yuki Ishikawa , Daisuke Torigoe , Noriaki Utsunomiya , hmj BigQueryのデータ監視社内サービスを作った話 Hirobumi Takahashi 社内用GitHub Actionsのセキュリティガイドラインを作成した話 Toshiki Kawamura BigQueryのコンピューティングリソース管理の取り組み Go Kojima fake clock microservice -時刻をハックしてテストする方法- vvakame , Hiraku Nakano , Hiroyuki Tanaka メルコインのインフラ設計・構築と、信頼性のあるサービスをリリースするためのSREの取り組み Masaki Iino , Takaaki Yuhara メルコインにおけるシステム間のデータ分離を実現するための通信アーキテクチャ Kohei Noda Building a Global environment at Merpay: India & Japan Robert Jerovsek , Keigo Andrade , Sumil Panicker なめらかなFintech QAを実現するためにテストケースフォーマットを標準化した話 Yuki Sakamoto , Masatoshi Sato メルコイン決済基盤の実践話 Junwei Liang メルコイン決済マイクロサービスのトランザクション管理を支える技術 Shota Suzuki Merpay Engineering Career Talk Keigo Watanabe , Osamu Tonomori , Katsuhiro Ogawa gRPC Federation を利用した巨大なBFFサービスに対するリアーキテクチャの試み goccy Enabling ProgramのEngineering Headをちょっとやってみている Masahiro Sano Merpay & Mercoin Tech Fest 2023 プレイリスト Merpay & Mercoin Tech Fest 2023 の各セッションごとの動画と、各DayごとのLiveアーカイブ動画をまとめたプレイリストです。気になる動画や、一気に視聴する場合などにお役立てください。 再生リスト: Merpay & Mercoin Tech Fest 2023 – YouTube