自己紹介
こんにちは、@KiKiと申します。今年9月に1ヶ月間、メルカリのインターンに参加させていただきました。
大学では情報系を専攻していて、大学の授業ではハードウェアからアプリケーションに至るまで幅広い分野について学んでいます。
今回のメルカリのインターンは自分にとって初めて参加するインターンでしたが、多くのことを学びながら大きく成長することができたと感じています。本記事では実際にインターンで取り組んだ内容と学んだことをご紹介できればと思います。どうぞよろしくお願いいたします。
参加したインターンについて
私が今回参加したのは「Build@Mercari」というプログラムの一部であるインターンシップです。
なお、Build@Mercariのプログラム自体の詳しい内容については、他の記事でとても詳しく紹介されていますので、そちらをご覧ください。
https://careers.mercari.com/mercan/articles/40098/
どうしてBuildインターンに申し込んだのか
一般的なインターンに応募する際、技術要件や事前知識の高さにハードルを感じる方も多いのではないでしょうか。特に、情報系を専攻していない方はもちろん、専攻している方でも、インターンの応募時に求められる技術要件や知識に不安を感じることはあるかもしれません。
大学では、アルゴリズムやハードウェア、OSの基本原理など基礎的な内容が中心で、Webアプリケーション開発などの実践的なスキルを学ぶ機会は限られることもあります。
私自身、フロントエンドやバックエンドといったWeb関連技術は全くの未経験で、「どこから始めればいいのかわからない」と感じていました。そんな中、STEM分野・IT分野におけるマイノリティである女性や、LGBT+コミュニティの方を対象にトレーニングとインターンシップの機会を提供する「Build@Mercari」というオンラインプログラムを知りました。
このプログラムは「Web関連技術の知識は全くないけれど、この業界に興味がある!」という気持ちひとつで応募できる懐の深さが魅力でした。「これなら私にも挑戦できるかもしれない」と思い、思い切って応募することにしました。
配属されたチームについて
私が配属されたのは「Contact Center」という、メルカリでのお問い合わせ対応をサポートする社内システムを開発しているチームです。
現在、メルカリのお問い合わせ対応は、お客さまがフォームからお問い合わせし、お客さまからいただいたお問い合わせ内容などの情報を元にCS(カスタマーサービス)オペレーターが対応する、という流れになっています。ただし、このCSオペレーションではお問い合わせの解決までに時間がかかりすぎる、という課題がありました。
このチームではそういったCSオペレーションを抜本的に再構築するプロジェクトを進めていました。具体的には、お客さまのお問い合わせにリアルタイムでBotが対応し、Botで解決が難しい場合は、有人チャットを通じてCSオペレーターが対応にあたる、という方式への移行を目指しています。インターン期間中は、この新しいチャット体験への移行を進めているフェーズだったので、メルカリの未来のCS体験を支える重要な仕組みに関われるのは、とても魅力的なポイントでした。
実際に取り組んだ内容
プロダクトに関わる業務は大きく分けて、バックエンドとフロントエンドに分かれます。
バックエンドはサーバー側やデータベースの処理を担い、フロントエンドはユーザーに直接触れる画面や操作部分を担当します。今回私は、バックエンドとフロントエンドのタスクを1つずつ担当させていただきました。
バックエンド開発
使用した言語・ツール
言語: Go, SQL
ツール: GCP, Spanner, Kubernetes, BigQuery, Spinnaker, yo
背景
お問い合わせ対応システムの開発を進める中で、会話履歴や関連データに紐づく識別情報をスムーズに取得することが、調査や分析作業を円滑に進める上での課題となっていました。
このチャットのシステムは、GCPのサービスを使った実装になっています。個々のチャットを特定するためのIDは連携・保存していましたが、ConversationIDと呼ばれる、Botが会話したIDはそれとは異なるIDとなっており、これはシステム上では保存していませんでした。
そのため、これまでの運用では、対象となる会話データから、ConversationIDを取得するまでに、複数の手順を踏む必要がありました。例えば、会話の記録から情報を一つひとつ検索したうえで、目的のデータを特定するといったプロセスが発生します。このような手間は、迅速な問題解決が求められる場面では特に大きな障壁となっていました。
実装したこと
こうした課題を解決するため、ConversationIDを自動的に収集・格納する仕組みを検討しました。具体的には、会話終了時に必要なデータを自動的に取得し、これまでテーブルに保存していなかったConversationIDも、会話終了時にテーブルへそのまま保存するように変更しました。この仕組みを活用することで、調査プロセスを大幅に簡略化し、より効率的な対応を目指しました。
結果
その結果、インターンの期間を通して、メンターさんをはじめとしたチームの方の助力もいただき、この仕組みを実際のシステムに反映させることができました。現場では「調査の高速化に役立っている」といった声もいただいており、自分が関わった仕組みが実際に使われていると実感でき、とても嬉しく感じています。この経験を通じて、開発したものが誰かの作業を少しでも助けられることのやりがいを改めて感じました。
フロントエンド開発
使用した言語・ツール
言語: TypeScript, GraphQL
ツール: Ant Design
背景
お問い合わせに関する情報にお客さまのメールアドレスが登録されていない場合、そのお問い合わせにはダミーのメールアドレスが登録されます。ただしそのような場合でも、CSオペレーターが操作する画面上には、「お客様のメールアドレス宛にメッセージを送信するボタン」が表示されていました。
しかし、有効なメールアドレスではないため、このボタンを押してもメールの送信は実行されません。それにもかかわらず、CSオペレーターの画面上にはその旨が表示されないため、メール送信が完了したという誤認識を招く可能性があるUIとなっていました。
実装したこと
この問題を解決するため、ダミーのメールアドレスが設定されている場合に送信ボタンが押されたら、エラーメッセージをモーダルで表示する処理を追加しました。
この実装を行うために、送信先メールアドレスの情報を取得できるように、データ取得クエリの一部を変更しました。この変更により、画面初期読み込み時に必要な情報が整う仕様に改めました。
結果
画面上にエラーメッセージが正しく表示されることを確認できました。これにより、CSオペレーターが誤認識をするリスクが減少し、日々の業務をより正確に進めることに役立つ改善が実現しました。
チーム開発ならではの学び
プライベートの個人開発では、自分の思いつくままに自由に実装することが多いかと思います。しかし、個人では達成が難しい大きな目標も、チームであれば実現できることがあります。一人では膨大な時間と労力がかかる作業も、チームで取り組むことで、それぞれの得意分野を活かし、知識やスキルを共有しながら効率よく進めることができます。
さらに、チーム開発では単なる作業の分担にとどまらず、互いにフィードバックを与え合うことでプロダクトの可能性を広げていきます。
今回のインターンは、私にとって初めて「お仕事でのチーム開発」や「大規模な開発」に触れる機会となりました。私がここで得た学びを、次にご紹介します。
プロダクトへの携わり方は業種によってさまざま
今回、Contact Centerチームに配属させていただき、チームの方々にサポートしていただいたり、働く様子を間近で見る中で、チームメンバーそれぞれの役割や業務内容について理解を深めることができました。
私が今回のインターンにおいては、以下のようなポジションの方と関わりがありました。
Product Manager
プロダクトを使うお客さま(私達の場合Customer Serviceのメンバー)からのニーズを取りまとめて、最適な形で実装できるように仕様を決定する役割です。今回のインターンでは、フロントエンドの実装を行う際、エラーメッセージの内容やデザインについて相談させていただきました。
Engineering Manager
エンジニアの意見をチームやプロジェクトに反映させるため、多くの会議に出席し関係者と調整を行ったり、他のエンジニアが意思決定に迷った際に相談に乗るのが主な役割です。また、チームのエンジニア一人ひとりと毎週1on1を行い、困りごとや課題に耳を傾けるなど、コードを書くこと以外にもチームメンバーとのコミュニケーションを重視している印象を受けました。
私もインターン期間中に何度か1on1を設定していただき、直接お話をする機会がありました。
Frontend Engineer
フロントエンドエンジニアはユーザーが直接目に見える部分を実装するエンジニアです。チームでの会議の際に、実装が出来上がった部分を紹介する時間があるのですが、フロントエンドのデモンストレーションは華があって見応えがあるので、いつも私も楽しみにしていました。
Backend Engineer
フロントエンドエンジニアとは逆に、表からは見えない部分を担当するエンジニアです。プロダクトの機能のに関わる裏側の処理を行うことができるという点が魅力です。適切なデータ構造やAPIの決定、システムのパフォーマンスに関わる仕事もできるのが個人的に面白いと考えています。縁の下の力持ちという印象です。
開発の流れ
チーム開発では、メンバーと協力して働くからこそ、個人開発にはないステップが必要になります。
ここでは、そのリリースまでの流れを簡単にご紹介します。
Planning (何をするか決める)
解決すべき課題と作るものを明確にする段階です。Product Managerの方を中心に議論し、作業の方向性を定めます。
Spec作成 / チケット起票
Planningで決まった内容をもとに、仕様を具体化し、タスク管理ツールに登録します。この時点でレビューを一度受けることもあります。
Technical Spec / 詳細設計
技術的な詳細設計を行い、データの流れやAPI選定など、具体的な実装内容を詰めていきます。今回のインターンでは、チームの方がすでにチケット起票までを終えてくださっていたため、詳細設計の作成から作業を引き継ぎました。
開発
設計に基づいてコードを実装します。
Pull Request(PR)作成
GitHub上でコードを共有し、実装の意図やテスト内容を説明します。扱ったリポジトリでは同時に、PR作成時には自動的にCIツールが実行され、コードに対してlintや単体テスト(unit tests)が走る仕組みになっていました。
レビュー
チームメンバーがコードの品質や設計の意図を確認します。レビューの結果次第では4の開発に戻ってコードを書き直し、再度レビューを受け、承認が得られるまで繰り返すことになります…。
リリース準備
環境設定や実行権限の取得を行い、開発用の環境でテストを経たうえで本番リリースに備えます。
リリース
完成したコードを本番環境にリリースし、ユーザーが利用できる状態にします。
大規模開発に向けた設計思想「Clean Architecture」について
今回、バックエンド開発で触ることになったリポジトリは、「Clean Architecture」に基づいて設計されていました。
コードの設計思想とは、特に大規模な開発において重要となる概念です。これは、「コードをどのように整理し、配置するか」を決める際に参考にするポリシーのことで、チーム全体での効率的な作業を支えます。たとえば、「このコードはここに置かれているに違いない」とチーム全員が共通認識を持てることで、開発効率が大きく向上します。
Clean Architectureでは、プログラムの役割や責任に応じてコードがレイヤーに分かれています。それぞれのレイヤーは、独立して役割を果たせるように設計されており、異なるレイヤー間の依存関係を最小限に抑えることが特徴です。この設計により、変更や拡張がしやすくなるという利点があります。
大規模開発に触れたことがなかった私にとって、コードの設計思想という概念に触れること自体、非常に大きな学びとなりました。
生成AIを用いた開発について
メルカリでは積極的に業務に生成AIを導入しています。
今回のインターンを通じて、ソフトウェア開発の現場では「言語の文法を覚えてスラスラと書くだけがスキルではないんだ」と実感しました。生成AIの進化によって、コードを書く作業がかなり効率化されており、大規模なプロジェクトのコードを理解する際にも非常に有用だということを学びました。
一方で、それ以上に重要だと感じたのは、大規模な開発に適した設計思想や、将来的に仕様変更がしやすい設計、自分以外の人にも分かりやすいコードを書くことの大切さです。また、モジュール化やメンテナンス性を意識した開発の考え方が、現場では重視されていることを強く感じました。
これらの経験から、「知らない言語を使うプロジェクトだから…」と機会を逃すのは、少しもったいないと気付かされました。言語自体の知識は必要に応じて身につけていけばよく、現場で学べる設計や開発の考え方こそが、より長く自分の糧になり、生成AIに取って代わられることのない人材へと成長することにつながるのではないかと思います。
終わりに
この記事では、私が初めてのインターンを通して学んださまざまなことについて、紹介させていただきました。
1ヶ月という期間はとても短く感じましたが、フルタイムで社員の方々に混ざって働き、たくさんお話をさせていただく中で、この記事には書ききれないほどの大きな学びを得ました。なにより、本当に楽しかったです。メンターをしてくださったPeranikovさんをはじめ、Contact Centerチームの皆様方、ありがとうございました。