「React Native Meetup #16」を開催しました

こんにちは、カンムのエンジニアリングマネージャーの佐藤です。カンムでは5月30日(木)に、React Native Japanコミュニティと協賛してReact Native Meetup #16を開催しました。本記事では、その様子をレポートしました。

当日の様子

イベントは、弊社オフィスの会議室で行われました。当日は30人ほど集まり、とても活気のある勉強会となりました。発表の後には懇親会も設けられ、皆様の意見交換や情報共有が盛んに行われました。

発表内容の紹介

今回は、弊社の社員含め5名のスピーカーからLTが発表されました。

1. 「React Navigation v7で導入されるStatic APIについて」

弊社からは私が、React Navigation 7で新たに導入されるStatic APIについて発表させていただきました。 背景や変更点、それによって何が嬉しいのか?弊社はどのような課題を解決できたのか?などをお話しさせていただきました。 詳しくは資料をご覧ください。

2. @yukukotani様「Capacitor製のWebViewアプリからReact Native製のハイブリッドアプリへ」

Ubie 社の@yukukotani様は、Capacitor 製のWebViewアプリをReact Nativeに移行する際のお話をテーマに発表されました。 React Nativeへ移行されたモチベーションとして、Capacitorに比べエコシステムの維持が強固であること、Next.js & TypeScriptで作られたアプリケーションとの親和性などを挙げられていました。 資料と合わせてご覧ください。

3. @mok_oshi様「React Nativeでスケジュール帳を作っている話」

@mok_oshi様の発表は、React Nativeを用いた美容サロンの予約システムKarutekunを作成する過程での経験を発表されていました。カレンダービューというとても複雑なUIを、FlatListScrollViewを巧みに組み合わせて表現されているのがとても印象的でした。 資料はこちらからご覧ください。

4. @kazutoyo様「React Native Skiaを使ってみよう!」

@kazutoyo様の発表は、ShopifyチームがメンテしているReact Native Skiaについてでした。Skiaは過去にFlutterが採用していた2Dグラフィックライブラリで、React Nativeでもリッチな体験を提供できます。 実際に動く多数のサンプルが掲載されている資料もぜひご覧ください。

5. shibafu-san様「WebViewを使って既存のウェブアプリをReact Nativeアプリに組み込む話」

shibafu-san様は、既存のウェブアプリとして展開しているL COLLECTIONなどのサービスをWebViewを用いてReact Nativeアプリに統合する方法について発表しました。

最後に

弊社では初となるエンジニア勉強会の開催でしたが、無事にイベントを進行できました。これもイベントへ参加してくださったゲストの皆様、スピーカーの皆様、そして準備にご協力いただいたReact Nativeコミュニティ及び当日スタッフの皆様のおかげです。心よりお礼申し上げます。

カンムではフロントエンドエンジニアを募集しています!

カンムでは現在、フロントエンドエンジニアを募集しています。私たちと一緒に「お金の新しい選択肢をつくる」ミッションを達成するを仲間を求めています。興味のある方は、ぜひご連絡ください!

team.kanmu.co.jp

【Go Conference 2024】プロポーザルに通ったカンムのエンジニアが準備したこと、通った後にやったことʕ◔ϖ◔ʔ

ソフトウェアエンジニアの@sho-hataです。 2024年6月8日(土)開催のGo Conference 2024に、ソフトウェアエンジニアの私と@bisho-joの2人が登壇します。また、カンムはブロンズスポンサーとして協賛します。

gocon.jp

カンムが提供している バンドルカードPool のバックエンドは主に Go で開発しており、スポンサーとして継続的に協賛させていただいております。

tech.kanmu.co.jp

tech.kanmu.co.jp

このイベントを通して Go コミュニティの発展に寄与できればと思っています。

セッションに登壇します ʕ◔ϖ◔ʔ

バンドルカード ソフトウェアエンジニアのbisho-jo氏は、

"Guide to Profile-Guided Optimization: inlining, devirtualining, and profiling"

というタイトルで、Goの公式コンパイラの最適化についてのshort(20 min)セッションを行います。

Go1.20で追加されたPGO(Profile-Guided Optimization)が、関数のインライン展開と脱仮想化という2つの最適化手法にどのように影響を及ぼすか解説してくれるそうです。私はひと足先に練習でセッションを聴きましたが、とても興味を惹かれる面白い内容でした。 何よりbisho-jo氏が楽しそうに発表しており、技術を愛するGeek色が感じることができてとても良かったです。

Poolのソフトウェアエンジニアの私は、

"GoのLanguage Server Protocol実装、「gopls」の自動補完の仕組みを学ぶ"

というタイトルで、Goのコーディング支援機能を提供するgoplsの自動補完機能についてのshort(20 min)セッションを行います。

VSCodeのGo拡張機能のデフォルトバックエンドにもなっているgoplsの補完機能は、スマートかつ適切に補完候補を提供してくれます。今回はその裏側で動く泥臭く堅実な処理を、参加者の皆さんと共にのぞき見ようと思います。

プロポーザルに通るためにやったこと、通った後にやったことʕ◔ϖ◔ʔ

直近のGo Conferenceでは、個人応募のセッションに加えてGoルドスポンサーのセッションという形で、継続的に登壇させていただいておりました。ですが近年のGoコミュニティの盛り上がりもあり、今年はGoルド以上のスポンサーの抽選が熾烈な争いに。惜しくも今年はGoルド以上のスポンサーの抽選に外れてしまいました(いや、カンムの近年の運の良さが異常だったとも言える... ʕ◔ϖ◔ʔ)。

今まで奇跡的にGoルド以上のスポンサーに通っていたので、震撼する面々
今まで奇跡的にGoルド以上のスポンサーに通っていたので、震撼する面々2

セッションで登壇するために、プロポーザル採択という狭き門をくぐる戦いが始まりました。 ここからは、Go Conferenceにプロポーザルを通したい方に少しでも良い知見が得られるよう、自分を含めカンムメンバーがやってきたことを書きます。

プロポーザル締切に間に合うように発破をかけあう

まず、セッション登壇に意欲のあるメンバーが集まるSlackチャンネルを作り、期限を設定して発破をかけあう体制が作られました。

個人的な経験で何度も痛感していますが、プロポーザル資料を作ったり発表資料を作ったりする作業はどーーーーーしてもギリギリになりがちです。そして毎回、締切前に急いで考えて、推敲する時間がなくそのまま投稿..ということになりがち。 誰かがちょっとづつでもプロポーザルを書くのを進めているのを見ると頑張ろうとなります。これはやって良かったことでした。

プロポーザルの相互レビューをする

締め切りが近づいてきたら、たとえ推敲できてなくてもとりあえず下書きを放流し始めました。

放流すると、カンムメンバーは的確なコメントをくれるので、どんどんシェイプアップされて良い内容に。自分一人で煮詰まって考えるより、他の人と考えたほうが産みの苦しみはかなり減りました。 プロポーザル内容は、Go Conferenceの審査基準をベースに、聴く人が興味を持ってくれるか・新規性・独自性はあるかなどの観点をかなり重視していました。 過去のGo Conferenceのプロポーザルを読んだり、ネタ探しの例を読んだり。

そして、自分なりに納得したところで、プロポーザルを提出。あとは祈るのみです。

発表練習

プロポーザルの結果が発表され、カンムからは2人登壇できることに。 これは正確な情報ではなく噂で耳にしたのですが、プロポーザル応募は100を超えたとか。狭き門でのこの結果ということで、とても嬉しい結果でした。

発表が決まったということで、登壇に向け資料作りを開始。ここでも、登壇前に発表練習をする時間を設定して締め切りを作ることで、登壇の3日前には最低限のクオリティを担保した発表ができるようにしました。

発表練習はカンムのエンジニアに集まってもらい、聴講してもらいました。ここでもメンバーは的確なフィードバックをくれるので、シェイプアップされてより良い内容に。 ちなみに2人そろって3分オーバーでした。まあ当日にはなんとかなるだろう...

おわりに

ここまで、Go Conferenceのプロポーザルに通るために&通ってからカンムメンバーでやってきたことを書きました。 久しぶりのオフライン開催ということで、オフラインならでの熱気、盛り上がり、そして今回のテーマである「一期一会」を体験できることをメンバー一同楽しみにしています。

当日、Abema Towersでお会いしましょう!

イベント当日は会場にスピーカーの2人がいます!会場スポンサーのサイバーエージェントさん、ありがとうございます🙌

  • カンムやバンドルカード・Pool について聞いてみたい!
  • 登壇していたエンジニアと話してみたい!
  • Go についてわいわい話したい!

team.kanmu.co.jp

などなど大歓迎です!当日、登壇者の2人はスピーカーTシャツを着て会場を練り歩いている予定なので、お気軽に話しかけてください!本当に!(大声)

Poolのソフトウェアエンジニアを募集しています

ソフトウェアエンジニアのhataです。

Poolはソフトウェアエンジニアの募集を公開しました。

ソフトウェアエンジニア(フロントエンド)- Pool / 株式会社カンム

今回の記事では、Poolというサービスを開発する面白さや、直近抱えている課題について紹介します。

Poolについて

pool-card.jp

Poolは投資と決済が一体となった、国内でもあまり類を見ないサービスで、値動きを気にせず資産運用ができる特徴と、投資した金額をVisaカードの利用可能額として使える特徴を持っています。これによりカードを使いつつ資産形成していけるという、他にはない投資体験ができることを目指しています。

2022年6月にPoolをリリース後、3ヶ月で累計投資金額が1億円を突破。その後も、サービス開始以降、正常運用率100%(※11)で着実に運用実績を積み重ね、継続的にユーザーの方に使っていただいております。

Pool は投資というより「置いてある」に近い感じ | ユーザーインタビュー vol.1 | Pool [プール]

Poolが目指している世界

カンムは「お金の新しい選択肢をつくる」というミッションを掲げています。一般的な投資サービスでは、投資資金と日々のお買い物は別々に管理されており、投資資金を急な出費に使うにはハードルがあります。Poolでは、「投資をしながら日常の買い物もできる」という、今までなかった投資・決済体験を「お金の新しい選択肢」として提供することを目指しています。

これまでは銀行が預金・融資によって支えていた間接金融が資金の流れの中心でした。現在は自社のバンドルカード事業が主な投資先ですが、投資先事業の拡充を予定しています。Poolを通じて、資金を増やしたい人に対しては新たな投資体験を、お金を必要とする会社等に対しては新たな資金調達の手段を作り、新しい資金の流れを広げてまいります。

Poolの開発の面白さ

決済と投資を組み合わせたユニークなサービスの開発に、「このサービスがどうあるべきか」の議論から携わっていただくことができます。 金融サービスはユーザーにとって難しい、複雑、といったイメージを持たれることが多く、その専門用語や複雑な手続きがしばしばハードルとなっています。しかし、そんなハードルを越えるために法律や規制といった要素を考慮しつつ、ユーザーにとってわかりやすい体験にするにはどうしたら良いのかをイチから考えることは非常にやりがいがあります。

また、そのハードルの越え方も非常にユニークです。Poolは投資した金額をVisaカードの利用可能額として使えるという特徴を持っていますが、これは既存の法的なスキームを組み合わせて実現しています。既存の法的なスキームを整理・組み合わせて、新しい体験を提供していくのは、カンムの特徴のひとつです。

そのため、開発者としてアプリのユーザー体験について議論をする際も、「文言・表現を変える」「導線を変える」以外に、「この法律をこう整理して、このようにしていけば課題をクリアしつつ、新しいことができるのではないか」という選択肢が常にあるのが面白いです。"法律"や"制度"など他の領域であれば足踏みしてしまうところに対しても、より良い改善を仕掛けることができるというのは、エンジニアにはハックマインドにも通じるところがありなかなか面白いのではないかと思っています。

「投資をしながら、買い物もできる」 さながらユーザーにとっての小さな銀行のような、既存のサービスとは全く違う新しい体験を自分たちでデザインし、他に参考となる先例がない中でウンウン言いながら作り上げていくことができるのは、他にはない醍醐味だと思います。

ソフトウェアエンジニアを必要としています

カンムは2023年に三菱UFJ銀行の子会社となり、Pool事業も今後さらなる事業拡大を目指していきます。事業拡大に伴い、開発速度を上げて改善サイクルを素早く回すことが必要です。今後もっと成長するプロダクトを支えるために、エンジニアリソースをより拡充し、投資していきたいフェーズにあります。

しかし現状4名のソフトウェアエンジニアがフロントエンドからバックエンド、インフラ、PCI DSS(クレジットカード業界の情報セキュリティ基準)をはじめとしたガバナンス対応まで幅広く対応しており、目指したいサービスの改善・成長速度に届いていないのが現状です。

技術スタックについて

Poolで使用している技術スタックについては、下記を参考にしてください。 ネイティブアプリのフロントエンドはTypeScript・React Nativeで開発しており、APIサーバー、決済システムといったバックエンドはGoで開発しています。

ソフトウェアエンジニア(フロントエンド)- Pool / 株式会社カンム

さいごに

Poolは決済と投資という2つの領域に跨ったサービスです。現状調べた限り同じようなサービスは国内にはなく、ユーザーにとっては新しい体験となります。 「なにこれすごい、初めてみた」という体験を追求しつつ、金融サービスという性質から、ユーザーが安心してサービスを利用できるようなUI/UXを両立していかなければなりません。 金融サービスの特性を理解しつつも、いちユーザーとしてフレッシュな視点でサービスを見つめ、固定観念にとらわれない新しい体験を一緒に議論し、作り上げていただけるエンジニアを求めています。

金融未経験の方や、直近の課題に関してすべて精通していなくても問題ございません。少しでも興味が湧いた方は、採用ページよりご連絡をお待ちしております。また、「話を聞いてみたい」といったカジュアル面談もお待ちしています。

Poolチーム エンジニア以外の職種インタビュー記事

note.com

note.com


  1. 2024年4月までに運用が終了した全21ファンドのうち、運用終了時点のお客様の出資持分を全額返還及び予定分配金額をお支払いできる状態になった割合です

カンムの機械学習インフラの今 2023 年版

こんにちは。ソフトウェアエンジニアの新田です。こちらは カンム Advent Calendar 2023、8日目の記事です。 昨日はデザイナー torimizuno さんによる バンドルカードの Google Pay デザイン でした。今年のバンドルカードの目玉リリースの1つであるスマホタッチ決済(Google Pay)のデザインについて説明されていて、凄く面白いです。

今回は、カンムの機械学習のインフラ周りについて話します。実はカンムのテックブログでは2年半前に同じテーマの記事があります。この内容からいくつかアップデートがあるので、今回はその差分を重点的に拾っていこうと思います。

tech.kanmu.co.jp

また、自分は入社してそろそろ一周年で、前回の記事は入社前に読んでいました。今回の記事では、入社前ではわからなかったところもあえて注目して取り上げてみたいなと思います。

Big Picture

機械学習インフラ全体図

Data Preparation

BigQuery データウェアハウスの刷新

クラウドの構成は以前同様、プロダクトは AWS をメインに使いつつ、データ基盤は Google Cloud の BigQuery に集約する構成は一緒です。しかし BigQuery 基盤自体は以前と違うものになっています。

これまでのカンムのデータ分析環境では、本番環境の DB からレプリケーションしている分析用のリードレプリカを利用していました。一方で、データベースは複数存在しているため、リードレプリカを利用した環境では複数データベースをまたいだデータ分析が難しいという課題がありました。

そこで複数のデータソースを一つの BigQuery によるデータウェアハウスに集約することを念頭において基盤を再構築しました。これによって複数のデータソースを横断した分析ができ、事業KPI をより精緻なかたちで算出できるようになるなど、データによる意思決定の精度が上がっています。

例に漏れず機械学習の学習データセットも、この新しい BigQuery 基盤を使うように変更しています。

Data Preparation

以前の構成では Embulk を利用していた BigQuery へのデータの取り込み周りも、新しい基盤では異なります。

カンムではプロダクトのデータベースは AWS Aurora を使っています。そこでエクスポート機能を使って S3 にデータをエクスポートします。

docs.aws.amazon.com

そのあと S3 から Google Cloud の Cloud Storage への転送を Storage Transfer Service で行います。

Cloud Storage に到着したデータを BigQuery の外部テーブルとして扱い、 BigQuery のテーブル・ビューとして整形するパイプラインを整備しています。

いわゆる Transform と呼ばれるこの一連のパイプラインは dbt を ECS Task として実行するような Step Functions で構成しています。 AWS から Google Cloud のリソースの認証には OIDC 方式を採用して鍵ファイルの管理を不要にしています。

このデータ取り込みにおいて、以前の構成の Embulk ではワークロードのリソース調達が必要になっていましたが、新しい構成では完全なマネージドなためその辺りの考慮が不要になったのは嬉しいポイントです。

以前同様、データ取り込みは差分更新ではなく全件洗い替えを日次実行しています。この辺はデータサイズ増加に伴うコスト面などの問題などがでてくると思うのでその際には改善を検討していきたいと思っています。

Training, Serving & Inference

推論モデルの増加

推論モデルは去年までは1つだったんですが、今では3つに増えました。

これまで学習データ不足などから機械学習でアプローチできていなかった課題に対しても、機械学習の推論モデルを徐々に導入できています。

いまのところ全てのモデルにおいて、同じアルゴリズムをベースに学習しています。

1つのリポジトリにて、ライブラリやウェブフレームワーク・ Web サーバ構成などは共通しており、デプロイパッケージは1つのコンテナイメージとして管理しています。

コンテナ実行時に環境変数を渡すことで実行する学習コードや推論コードが切り替わるようにしています。これによりモデルの数が増えてもロジック以外のセットアップが少なく完結できます。

これは利用するアルゴリズムを限定するつもりではなく、いまは1つのアルゴリズムで間に合っているためであり、新たなアルゴリズムが必要になったらその時々に拡張していければいいなという考えです。

推論モデルのデリバリー改善

以前と変わらず、モデルの学習から検証用のエンドポイントへの適用までを Step Functions によって自動化しています。

そのあとのモデルの性能やエンドポイントの動作に問題がないか確認をしたのちに、本番用のエンドポイントに適用する流れも同じです。ただ、この辺の作業が以前までは手動で行われていたのですが、運用するモデルが増加するにあたってこの手作業はトイルになってしまうので自動化しました。

自動化のために2つの GitHub Actions のワークフローを用意しています。

モデル更新のワークフロー

1つ目のワークフロー(図右) はモデルの性能結果を示す Pull Request を作成します。それをチームメンバー達でレビューしマージします。 マージを契機に、 2つ目のワークフロー(図左) が本番エンドポイントに EndpointConfig を適用します。これにより新しいモデルが本番にデプロイされます。

endmame によるデプロイ

2つ目のワークフローはデプロイに endmame という内製の CLI ツールを使って endmame deploy コマンドでデプロイを実行します。 ( えんどまめ と読みます。カンムでお世話になっている ecspressolambroll をリスペクトしています。)

この endmame のコマンド endmame deploy は、設定ファイルを読み込み、新しい EndpointConfig を適用するかたちで、対象の SageMaker Endpoint に更新します。 (sagemaker:UpdateEndpoint をコールし、デプロイが完了するまで sagemaker:DescribeEndpoint で状態をポーリングします。)

処理の流れ

1つ目のワークフローの実行

まず1つ目のワークフロー (図右) はあらかじめ用意した Jupyter Notebook のファイルを papermill を使ってバッチ実行し Pull Request の作成までを行います。

Jupyter Notebook はセルを順番に実行すると以下の処理が実行されるようになっています。 papermill をとおしてそれらの処理を GitHub Actions 上で実行します。

  1. 検証用エンドポイントからモデルの情報を取得し、それから学習結果のログやメトリクスを取得する
  2. 学習結果のログ、メトリクスの内容をセルに出力する
  3. 検証用エンドポイントにテストデータを用いて実際にリクエストしレスポンス内容をセルに出力する
  4. 本番エンドポイントの設定に対応している endmame の設定ファイルを編集する

このワークフローは上流の Step Functions の処理の完了時間からバッファを持たせて GitHub Actions の on.schedule によって自動で実行されるようにしています。また、開発者が任意のタイミングで実行できるように on.workflow_dispatch による手動実行も可能にしています。

このワークフローは以下の処理を行います。

  1. 上述の Jupyter Notebook を papermill によってコピー & 実行
  2. リポジトリをチェックアウトし新規ブランチを作成
  3. 新規に作成されたコピー先の Notebook ファイル と 変更された endmame 設定ファイル をコミット
  4. Pull Request を作成

つまりこの Pull Request のコミット内容は、検証エンドポイントにデプロイされた新しいモデルの性能評価結果および API サーバの動作検証結果がレポートされた Notebook ファイルの追加コミットと、本番エンドポイントに適用する予定の設定ファイルの変更コミットになります。

作成された Pull Request のレビュー・マージ

モデル開発チームはその自動作成された Pull Request の内容 ( Notebook の内容と設定ファイルの変更内容) を確認し、問題なければ承認しマージします。

2つ目のワークフローの実行

マージを契機に2つ目のワークフロー(図左)が動作します。

endmame deploy コマンドを実行して、 Pull Request で変更された設定ファイルを読み込んで実際に本番エンドポイントを更新します。

このワークフローの実行が完了したらデプロイの成否が Slack に通知されるようにしています。

ちなみにですが、1つ目のワークフロー上で、デフォルトの GITHUB_TOKEN によるユーザとして Pull Request を作成してしまうと、その Pull Request 上で GitHub Actions の CI が回らないので注意が必要です。

cf. https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow

解決策として GitHub App のインストールとして認証を行い git push や Pull Request 作成の操作等を行うようにしています。

自動化の意図

デリバリープロセスの自動化の意図は「モデルが増えてきた作業時間の増加を短縮したいから」「モデル自体を入れ替えないタイプの変更 (ライブラリのアップデート) なども素早く安全にやりたいから」「強力な権限による手動操作の排除」etc… などがありますが、それに加えて、データセットシフトなどの問題に対する推論モデルのロバスト性を高めるために、性能評価プロセスをより高度なものにしていきたいと考えているためです。

そこで、あらかじめプロセスを自動化しておくと今後のプロセス改善はラクになります。今回構築したフローでは、テンプレートの Notebook ファイルを編集するだけで、それ以降の実行に反映されます。作業手順書のメンテナンスの必要がなくなりますし、手順を誤ると起きてしまうヒューマンエラーを防いでくれます。

評価プロセスの改善は今後力を入れていきたい領域の一つであるため、アップデートがあればまた記事にできたらいいなと思っています。

推論処理の課題

全てのモデルの推論処理は、「モデルをメモリにロードしておき、リクエストを受け付けると推論処理の結果を返すサーバを稼働するアーキテクチャ」 (リアルタイム/オンライン推論サーバ)になっています。

つまりオンライン処理時点で入力特徴量の取得が必要になります。 現状では、呼び出し側のサービスがデータベースからデータを取得・計算して入力特徴量を組み立てて、推論エンドポイントにリクエストを投げています。

推論処理の流れ

図をみて勘の良い方はお気づきかもしれませんが、学習時と推論時に異なるデータソースを用いているため計算の再現性に気を付ける必要があります。モデルの数や特徴量の増減のたびにこの辺りに慎重な実装を要していることや、学習に利用するデータソースの種類を増やした場合に推論時はそれをどのように取得するか… などの考慮事項があり、色々と課題が表出しているため来期は取り組んでいきたい領域の一つです。

Development

ローカルマシンによる開発環境もありますが、重い計算をしたい場合もっと大きなインスタンスが欲しくなるという要望を受け、クラウド上で開発できる環境を整備しています。

SageMaker Studio を使った JupyterLab ベースの実験環境です。いくつか工夫して使っていて、アイドルインスタンスを自動停止する仕組み、 OIDC 連携の仕組み、デバイスフローで GitHub App のユーザアクセストークンを発行してプライベートのリポジトリを操作する仕組み… などです。

実は今回の記事は本当はその辺りの話を書きたかったんですが、この記事の一週間前に SageMaker Studio に大幅なアップデート がアナウンスされて、これまでのものが SageMaker Studio Classic と名称が変更されました。あんまり Classic の話を書いてもな… と思って、今回の記事の内容を方針転換した経緯があります 😇

基本的に JupyterLab ベースの開発ですが、何時間単位となるような長時間の計算は JupyterLab は不向きな場合が多いためその辺りをシームレスにジョブ化できるような開発体験構築も検討していきたいと思っています。

最後に

機械学習のインフラ周りについて、前回の記事からのアップデートを重点的に説明しました。

お察しの方もいらっしゃると思いますが、そこまでモダンな MLOps ! といった構成ではなく、必要なときに必要な自動化や改善をしてきて今のインフラになっています。途中途中で話しているように、まだまだやりたいけどやれてないことや課題などがあります。

入社してみて気づいたのですがカンムは情報の透明性が高いです。事業状況は事業計画が毎月アップデートされていたり、今後の事業方針について役員・ディレクター陣からの説明も随時行われます。

これまでに書いたようにまだまだ課題が山積みなので、事業状況にアクセスできる環境は、計画から先んじて必要な仕組みは何かを考えて次の打ち手を検討するときに非常にありがたいです。

この辺りの課題に向き合って楽しく議論しながら一緒に働いてくれるお仲間を募集しています。

team.kanmu.co.jp

バンドルカードの Google Pay デザイン

デザイナーのtorimizunoです。 こちらはカンム Advent Calendar 2023、7日目の記事です。 先日の記事はhikkyさんによるSecure W2で証明書を発行してEntra ID CBAを設定する でした。

はじめに

バンドルカードは2023年10月に Google Pay に対応しました。 お買い物という日々利用されるシーンのなか、非接触でバンドルカードが使えるようになったことに気づいて迷わず使い始められるよう、デザイナーとして意識したことをご紹介いたします。

とにかく、気づきやすく

Google Pay に追加ボタンのレギュレーション上、カードが表示されている画面でのみ表示が可能となります。

当初はひとつ奥の階層となる「カード情報」に設置することも検討していました。しかし、お買い物先のサイトで既にカード情報を登録した方は、頻繁にカード情報を見ない可能性もあります。そのため、明細を見に行ったり、アプリを起動したときに誰でも気づけるよう、最終的にはホーム画面にボタンを設置しました。

明確に伝える

今までバンドルカードを実店舗で使いたい場合、リアルカードを発行する必要がありました。

Google Pay では、Visa のタッチ決済を利用してスマホひとつでコンビニやスーパーなどで買い物ができるようになるため、そのことが伝わるようにライティングを意識しました。

具体的には、「タッチ決済」だとカードのタッチ決済と含めて勘違いされる可能性もあるため、「スマホタッチ決済」という機能名でお伝えしています。

そのタイミングで知りたいことに絞って伝える

Google Pay の設定前と後で、知りたい情報と取るアクションは変わります。 そのため、設定前では「何がどう便利になるのか」具体的にイメージできる情報に絞って伝えています。

設定後に起こすアクションはお店での支払いです。実際どこで、どう使うのかが知りたい情報となります。このマークがあるお店で使えることや、フィールドテストで自分たちが使い方に迷った、有人レジと無人レジでの使用方法をお伝えしています。

同じニーズに答える

Google Pay は「実店舗での支払いが可能になる」機能です。そのため、同じく実店舗での支払いが可能となる「リアルカード」を発行しようとしている方にも、便利となるものです。

アルカードをいざ発行しようとしている方や、リアルカードを申請したけれど住所の不備等で却下されてしまった方にも、「早く実店舗で使いたい」と同じニーズがある可能性があります。

そういった方たちがカードの発行途中で、「これならすぐに実店舗で支払いができるようになる」新しい機能に気づけるような導線をご案内しています。

リリース後もつまづきを減らす

リリース後の経過観測で、 Google Pay の設定を終えても Google ウォレット からカードが削除されてしまう、という問い合わせがありました。

調査したところ、 「 Android の画面ロックを解除した状態で設定を完了すると、セキュリティ上の問題で Google ウォレット からカードが削除される」という Google のセキュリティ機能があり、それに気づかず設定まで終えてしまう課題が発生していました。

数値的にも、設定を試みた方の15〜20%ほど、数としても数百件/1日この現象が発生していることがわかりました。(他の理由でのカード削除も含まれるため、すべてには該当しない)

そこで対応策として、画面ロック未設定の方に対して、設定に進もうとボタンを押したタイミングで、画面ロックの設定が必要なことをお伝えする打ち手を実施しました。

施策のリリース後、数値として10%以下まで数としても100件以下/1日に減少したことが確認できました。

おわりに

以上で一部抜粋にはなりますが、 Google Pay 対応の担当デザイナーとして意識した点のご紹介になります。

Google Pay のプレスリリース用の写真をチームメンバーで撮影したり、思い出深いプロジェクトとなりました。

また、今回文言まわりでレギュレーションがかなり厳格にあったため、AIを使って下記のようなプロンプトを書いてチェックを試したりしていました。

以下の文章をルールに沿って修正してください。

【ルール】
・ Google Pay の Google と Pay の間に必ず半角スペースをいれる
・文頭に Google Pay の単語がある場合、 Pay の後ろに半角スペースをいれる
・文中に Google Pay の単語がある場合、単語の前後に半角スペースをいれる
・文頭に Google ウォレット の単語がある場合、 Pay の後ろに半角スペースをいれる
・文中に Google ウォレット の単語がある場合、単語の前後に半角スペースをいれる
・文頭に Android の単語がある場合、後ろに半角スペースをいれる
・文中に Android の単語がある場合、単語の前後に半角スペースをいれる

【文章】
ここに推敲したい文章を入れる

AIについては他にPhotoshopで撮影した写真の不足部分を補うときに利用していますが、他にも試していきたいところです。

ここまで読んでくださりありがとうございました。

【デスクツアー】カンムメンバーの在宅環境

これは誰のデスクかな...?
こんにちは。Pool開発チームのhataです。

自分は人のデスク環境を観るのが好きです。人のデスク環境は三者三様で、その人らしさや個性が滲み出ており観ていて楽しいんですね。なので、ガジェット系Youtuberがたまに投稿しているデスク環境紹介動画を漁ったりするのが趣味になっています。

カンムでは、オフィス徒歩圏内に住むメンバー以外は全員フルリモートで働いています。自分もその一人で、オフィスは恵比寿にあるのですが、入社して以降ずっと富山県からのリモートワークです。

カンムのかなり自由な働き方を支える、リモートワークやフレックスなどの制度についてはこちらの記事をどうぞ。

note.com

物理出社が基本の会社では、メンバーのデスク環境は出社したときに観ることができると思います。ですが、フルリモートだと他の人のデスク環境は基本的には観れません。これが人のデスク環境を観ることが好きな自分にとっては悲しいんですね。

そこで「みんなのデスクみたい!」と言ってみたところ、多くの方が参加してくれました。

というわけで、個性あふれるデスクツアーのはじまりです。

バンドルカード バックエンドエンジニア:@bisho-jo氏

本人コメント

ErgoDoxEZ良

編集者コメント

トップバッターは関数プログラミングに強いbisho-jo氏。 縦に並んだ大きな外部ディスプレイが2枚、そして分割キーボードのErgo Dox EZが目を引くデスク。 大きなディスプレイが横に並んでいると視線の移動や首の負担が多くなりがちですが、bisho-jo氏はこれを縦にすることでカバー。なるほど、縦という選択肢があるのか...

セキュリティエンジニア:@miyaguchi氏

本人コメント

27インチの液晶2枚とErgoDox EZを使っています!KVMスイッチで仕事環境と個人の環境をパッと切り替えられるのが推しポイントです。

編集者コメント

こちらもErgoDox EZ勢。広い曲面デスクには取り回しのしやすそうなデスクアームタイプのマイクが装備されています。 推しポイントであるKVMスイッチ。こういう切り替えは毎回面倒ではありつつも、ツールを買う腰が上がらず、ついケーブルの抜き差しを頑張る運用になりがちです。

こぼれ話として、miyaguchi氏はこのErgo Doxのキーマップをカスタムしすぎて二度と普通のキーボードが使えない体になったそう。

Pool 開発エンジニア:@caffeine氏

本人コメント

私物のMacAirになったときにディスプレイを減らしました。27inchくらいのディスプレイを探してます。足元にはルーターなどをまとめてます。奥に転がってるのはラズパイとそのケーブル。

編集者コメント

MacBookクラムシェルモードで運用し、ディスプレイ一枚ですっきりしたデスク。扱いやすそうなモニターアームで支えられたDell製のディスプレイは、ベゼルが狭いので仕様以上に広く見えますね。良い。 Happy Hacking Keyboardの両脇に装備されたMagic Trackpadとトラックボールマウスにもそれぞれ使用用途が分けられていそうでこだわりが見えます。

データアナリスト:@gai氏

本人コメント

部屋全体もそうなのですが、デスク周りは物少なめです。 基本フルリモートであまり動かない生活になっているので、少しでも健康になれるように昇降デスクと分割キーボードを使ってみてます。

編集者コメント

両脇にモニターを構えたスタイル。気分転換ができる昇降デスクにはキーボードスライダーが取り付けてあり、デスク上はすっきりしていて本人の几帳面さが表れています。 シンプルにまとまりつつも、分割キーボードはカラフルで遊び心があっていいですね。デスク道具はどうも色味に欠けるものが多いのでこういったところに個性が光ります。

SRE:@sugawara氏

本人コメント

ディスプレイはLGの34インチ曲面ディスプレイ、キーボードはTEX Shinobiを使ってます。 細長いサイドテーブルをデスクとくっつけてL字にしています。

編集者コメント

大型の局面ディスプレイが目を引くデスク。そしてなんとマウスやトラックパッドが見当たりません。秘密はキーボードにあり。 この「TEX Shinobi」はトラックポイントが搭載されており、手をホームポジションから動かすことなくPC操作を完結できるとのこと。 ThinkPadは知っていましたが、外付けでトラックポイントが搭載されているキーボードがあるのは知らなかったなぁ。

バンドルカード バックエンドエンジニア:@sano氏

本人コメント

リビングで仕事しています。家族もリモートワーク中心でリビングで仕事しているため、会議のときは別部屋に移動することもあります。 道具は MacBook Pro のみです。こだわりは、家を職場のような雰囲気にしたくない、でしょうか...。でかいディスプレイや無駄な電子機器はあまり置きたくないというのと、書斎のような部屋も作りたくないと思っています。

編集者コメント

ISO8583を人力パースできると噂のsano氏。 こ、構図がおしゃれすぎる...!もちろん、拾い画ではなく、本人のご自宅です。 プライベートに仕事感を持ち込みたくない、という思想からリビングにMacBook一枚で仕事をこなすという無骨なスタイル。カッコいい。

Pool開発テックリード:@nakaji-dayo氏

本人コメント

油断すると足が痺れます

編集者コメント

こちらもシンプルなMacBook一枚スタイル。畳、襖といった伝統的な雰囲気が目を惹きます。こだわりのお座敷にローテーブルで、普段は正座で業務をしているとのこと。趣があるなぁ... 最近は正座椅子を導入されたとのことで、足の痺れにパッチを当てたそうです。

セキュリティエンジニア:@liva氏

本人コメント

FILCO Majestouch 2SS EditionにFILCOの無刻印キートップを付けてることが一番のこだわり。諸々を扱いやすい配置にして配線していたり、ちょいちょい趣味のものを置いていたりというデスク環境。浮かせてる曲面ディスプレイで動画流しながら作業してる。

編集者コメント

プラモデル、ミニチュアやメカニカルキーボードなどが置かれており、趣味性に溢れるデスク。ディスプレイは合わせて3枚で、かなり作業範囲が広く取れそうです。壁を背にして、L字型にすることで手の届く範囲に全てがあり、ちょっとした自分のお城みたいに感じられそうです。個人的にこういった配置はかなり好き。

データアナリスト:@teshima氏

本人コメント

FLEXISPOTの昇降デスクを使ってます。MTGの時は立ったほうが頭が冴える気がしており、使い分けしてます。私用デスクトップPC(業務時は主にBGMプレーヤーになっている)を天板にぶら下げており、スペース確保と昇降時にケーブルを気にしなくて良くて楽です。CO2モニターで二酸化炭素濃度を観測しており、換気の目安にしてます。デスク真横に懸垂バーを設置して、気分転換時に懸垂してます。

編集者コメント

昇降デスク・CO2モニター・懸垂バーと健康に配慮したスタイルとなっているデスク環境。デスク作業は集中力が切れると気分転換が難しいですが、すぐに立ち上がったり、ぶら下がったりして気分をリフレッシュできるのはいいですね。曲面になっている天板も注目ポイント。これにより、モニタやキーボード、マウスの位置調整が自然な形でできそうです。

機械学習エンジニア:@fkubota氏

本人コメント

とにかく机の上にはなにも置きたくない派です。 昔はデュアルでしたが今はウルトラワイドのシングルディスプレイです。 シングルにするとアプリの切り替え時の目線とマウスポインタの移動が少なく高速でできるのでこういう形に落ち着きました。 MacBookは机の横に添えるように置いているので圧迫感がなくてとてもいいです。 キーボードは、40%、スプリット、トラックボール付きのkeyball44を使っています。 Vimが好きでホームポジションから離れたくないのでこのキーボードは理想に近いくとても重宝しています。 ちなみに昇降デスクです。

編集者コメント

ぱっと見でわかる、並々ならぬデスク環境へのこだわり。シンプルなデスクに見えますが一つ一つにfkubota氏の哲学が見え隠れています。Vimmerであるfkubota氏は、キーの数が普通よりも40%少なくて、分割されており、トラックボールもついているかなり攻めたキーボードを愛用。ほとんどの操作がホームポジションから動かさずに完結できるので、かなり作業効率が良さそうです。

人事企画:@katsumata氏

本人コメント

業務PC、Switch、PS4、プライベートPCをノータイムで切り替えられるのがこだわったポイントで、お昼休憩に入った瞬間にスプラトゥーンを起動できます。(しています)

打ち合わせのときにイヤホンをつけるのが耳に負担がかかってストレスだったので、一昨年くらいからマイクスピーカーにしたんですがこれは正解でした。

編集者コメント

全体的に白のアイテムで構成された統一感のあるデスク。社内でも無類のゲーム好きであるkatsumata氏のデスクには、もちろんゲームのコントローラーがセット。 配信もされており、オーディオセレクターのメカメカしさがカッコいいですね。また、マウスにはlogicoolの多機能マウス、MX Masterをチョイス。マウスパッドも広めにスペースが取られており、ストレスなく作業ができそうです。

Pool開発エンジニア @hata

本人コメント

今回の記事の編集者である自分の仕事部屋です。ぜひ見てもらいたかったので... 普段は猫を抱っこして仕事をしています。昇降デスクとHHKBを分割キーボードのごとく2枚使用するという暴挙により、肩こりなどの体の不調はかなり減りました。また、本に囲まれた生活にアイデンティティーがあるので、仕事部屋は本で溢れています。


というわけで、カンム初のデスクツアーでした。人それぞれかなり個性があって、楽しんでもらえたと思います。 北は北海道から南は沖縄まで、カンムメンバーのほとんどは場所にとらわれず皆思い思いの環境で仕事をしています。気になった方はぜひぜひ↓。

kanmu.co.jp

ドキュメントを書く時に考えていること

ソフトウェアエンジニアの summerwind です。最近は LLM が自分のふりをして代わりに仕事をしてくれるような仕組み作りを趣味にしています。

先日社内で「ドキュメントをうまく書く方法はありますか?」という質問をもらったのですが、普段ドキュメントを書く時に意識をしている要素のようなものはあるものの、それをちゃんと言語化したことがなかったため、抽象的にしか答えることができませんでした。改めて言語化をしてみるのは面白そうだなと感じたので、今回はドキュメントを書く時に考えていることをいくつか書き出してみたいと思います。

想定する読者を決める

ドキュメントを書く時にまず最初にやるのは「そのドキュメントの想定する読者は誰か」についてを考えることです。よくある想定読者には次のような方々がいます。

  • 同じチームで働くエンジニアのメンバー
  • 同じプロジェクトで働くメンバー
  • 全メンバー

想定する読者が決まると、ドキュメントに書くべき情報は何か、どのような粒度で情報をまとめるべきなのかの検討がしやすくなります。例えば、様々な職種がいるプロジェクトメンバーに向けたドキュメントでは、いきなり技術用語や詳細な仕様の話を出しても理解が難しくなると思うので、アプリの動きや全体的な構成の話から深掘りしていくような流れを作るのがよさそうだ、といった判断ができるようになります。

全体的な構造を決める

想定読者が決まったら、その読者の理解度合いに応じてドキュメントの構造を決めていきます。例えばプロダクトに新しく追加する機能の説明用ドキュメントを書く場合は、背景や前提となる情報の説明から入り、機能の目的や説明、詳細と深掘りしていくような構成を作ります。

きれいな構造を一度にまとめるのは難しいため、まず最初に次のような見出しのリストを作り、ドキュメントに記載が必要と思われる情報をひととおり洗い出します。その後、見出しの順番を入れ替えたりセクションを分割したりというのを繰り返して、ドキュメントを読み進めるごとに詳しい内容が分かるような構成を組み立てていきます。

- 背景
- 前提となる情報
- 目的
- 要件
- 機能詳細
  - フローAについて
  - フローBについて

情報を文章にまとめる

全体的な構造がある程度決まったら、構造の見出しに従って情報を可能な限り簡潔な文章にまとめていきます。文章を書くにあたっては、最初に箇条書きリストで記載するべき情報をまとめ、その後、適切に段落を区切った文章を構成するようにしています。

以下は以前のブログ記事の中で 3D セキュアの説明をするための文章を考えた際の箇条書きリストのサンプルです。

# 3D セキュアとは

- 決済時にカードの所有者であることを事前に認証する仕組み
- 不正利用の防止に役立つ
- 3D というのは三次元のことではなく3つのドメインを指す
  - アクワイアラ、決済ネットワーク、イシュアの3者
- ...

この箇条書きリストをもとにして、次のような文章を書きます。

3D セキュアは、オンラインなど非対面でクレジットカードを使用して決済をする際に、カードの所有者であることを事前に認証する仕組みです。3D セキュアを使用することで、カード情報の盗用によるオンライン上での不正利用を防止できます。ショッピングサイトなどでカード決済をする際に突然パスワードの入力を求められた、といった経験がある方も多いかもしれません。あれが 3D セキュアによる認証です。 ...

自分だけが読むようなドキュメントは、脳内の理解した構造に基づく箇条書きリストでドキュメントを書くことがありますが、他の人に読んでもらうことを想定しているドキュメントは読みやすさを重視した簡潔な文章にまとめるようにしています。これは読み手が必ずしも自分と同じ脳内の理解構造を持つとは限らないと考えているためです。

適切なフォーマットで表現する

文章がまとまってきたら、読者にとって読みやすくなるように適切なフォーマットを使って情報の表現を調整します。

カンムの社内では広く Markdown が使われているため、例えば次のようなフォーマットを使用します。なお、どのような表現フォーマットを使うかについては、書き手の好みによるところが大きいかもしれません。


重要な説明や意識しておきたい単語は必要に応じて太字や斜体を使用して表現します。

3DS 最新仕様は **EMV 3-D Secure** です。
3-D というのは三次元のことではなく3つの *Domain* を指しています。

順序のない項目については順序なしリストを使用します。

- プランA: ...
- プランB: ...
- プランC: ...

手順や流れなどは順序付きリストにまとめます。

1. 最初に A を実行します
2. 次に B を実行します
3. ...

他のドキュメントや Web ページの内容、メッセージなどは引用形式を使用します。

> We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard.

前提となる知識や情報を整理する

新たにドキュメントを書く場合は、最初の方にそのドキュメントを理解するのに必要となる前提知識や情報を可能な限りまとめるようにしています。前提となる知識や情報が多くなるような場合は、前提を説明するための個別のドキュメントを用意することもあります。

例えば、バンドルカードの 3DS の実装に関する詳細設計ドキュメントを書く場合を想像してみます。この実装の説明には以下のような前提知識が必要となるため、ドキュメントの最初の方にこれらの説明や考え方について書いておくようにします。

  • 3DS とは何か
  • 3DS の実装に必要となるシステムは何か

制約条件を整理する

前提となる情報と同様に、設計や手順などのドキュメントを書く際は制約条件も整理して書くようにしています。ここで言う制約条件とは「ドキュメントの書き手の都合では変更できないような事項」のことを指します。制約条件には具体的には以下のようなものがあります。

  • パートナー企業が管理するシステムの仕様
  • パートナー企業と合意したスケジュール
  • 法規制やコンプライアンスなどに基づく変えることが困難な要件
  • 社内で確定したスケジュール

これらの制約条件を可能な限り整理しておくと、ドキュメントに書かれた情報の背景を理解する助けとなり、またドキュメントを土台にした設計レビューなどの議論もしやすくなると考えています。

基本的な方針を示す

前提や制約条件、要件などを記載して議論に使用するようなドキュメント (Design Docなど) を書く場合には制約条件や要件をよく考慮した上で基本的な方針を示す内容を書くようにしています。

  • 2023/12 までに機能 X をリリースする
  • 法規制に基づいて機能 Y の追加は必須とする
  • システム構成の制約によりコンポーネント A に機能 X を実装する

このような基本方針は、ドキュメントの内容をもとにレビューや議論をする際の大枠の合意に役立ちます。もし大枠の合意なしに詳細部分に関する議論に入ってしまうと、大枠部分に方針転換が発生した時に大きな手戻りが発生し、議論が最初からやりなおしになる可能性もあるので、これを避ける意図もあります。

運用時の動きを想定した内容を含める

プロダクトに関するドキュメントを書く際は、できるだけ運用時の動きを想定して、それに関する情報を含めるようにしています。

例えば新しい機能の設計をするためのドキュメントには、不具合発生時の調査を想定してログの出力に関する情報を追加したり、障害発生時に起きる可能性がある問題などについて言及するようにします。何かの操作手順に関するドキュメントを書くような場合には、エラーが起きるケースや入力値のバリデーションなどについて可能な限り言及するようにします。

どこまで運用時の動きを想定できるかは書き手の経験的な部分に依存するかもしれません。最初に全てを書こうとはせず、思いついたタイミングなどに必要に応じてドキュメントを繰り返し加筆するようにしています。

情報の説明と論点や確認事項は明示的に分けて書く

ドキュメントでは情報に関する説明と個人の意向や確認事項を混ぜて書かないように心がけています。これは単純に、ある情報に関する説明の文章の途中に個人の意向や確認事項を混ぜ込んでしまうと、どこまでが事実でどこまでが書き手の意向なのかが分かりにくくなってしまうためです。

ドキュメントを土台に何かを議論したり説明したりする場合は、論点や確認事項を個別のセクションに独立した形あるいは 要確認 といったラベルを付与した単独の段落として記述するようにしています。

一次ソースへの参照を書く

パートナー企業が管理するシステムとの接続のための設計ドキュメントや特定のツールを使った運用手順に関するドキュメントには、システムの仕様書や運用の中で扱うツールのマニュアルといった一次ソースへのリンクを記載するようにしています。これは読者がドキュメントには記載がないより詳しい情報を知りたいと思った時に、関連情報へのアクセス手段を提供することを意図しています。

継続的に更新する

ソースコードの管理と同じでドキュメントも継続的に更新しないと様々な問題が生じていきます。新しい情報や前提が生まれた場合は必要に応じて内容を更新するようにします。ドキュメントの継続的な更新が難しい場合は、すでに内容が古くなったことを明記するなどして読み手が混乱しないように配慮しておくのがよいかもしれません。これに関しては LLM のような新しい技術を活用して、継続的にドキュメントを自動更新していくような仕組みを作れれば、と最近は考えています。

おわりに

いくつかの項目に分けて言語化を試みたのですが、いかがでしたでしょうか。ここに書いた全ての項目を意識しながらドキュメントを書くことは自分にとっても難しいのですが、今後もよりよいドキュメントの書き方を常に模索していきたいと思います。

最後に、ChatGPT にドキュメントに関する俳句 (?) を考えてもらいましたので、それを紹介してこの記事を締めくくりたいと思います。

情報の海 一つ一つの波 大事にせよ

カンムではプロダクト改善に加わってくれるソフトウェアエンジニアを募集中です。カジュアル面談も大歓迎ですので、ぜひお声がけください。

kanmu.co.jp