技術的チャレンジへつながるピックパックのモジュール化 | お届けチーム取組紹介

はじめに

10X ソフトウェアエンジニアの鈴木です。 これからしばらく「お届けチーム取組紹介」と題して「イベント駆動アーキテクチャ」につながることを複数の記事に渡ってお伝えしていきます。 product.10x.co.jp

お届けチームでは、 「ピックパック」というお客様から承った内容を元に、商品を売り場や在庫置き場からとってきて(ピック)、箱詰め(パック)する業務領域(以下ピックパック)のシステムを疎結合化することで、技術的な課題を解決することを目指してきました。

社内では「モジュール化」という言葉を使用して取り組んできましたが、これは「ピックパック領域のコードをお客様へ対面するためのコードと疎結合にする取り組み」でした。本記事では、この取り組みの概要を紹介します。技術的な詳細については、後続の記事で解説します。

注文内容をピックしてパックして、配達へ受け渡す

チャレンジ前の構造

取り組み前のシステムでは、Orderクラス(as 1 Firestoreドキュメント)に、注文に関するあらゆる領域のロジックとデータ永続化処理が集中していました。具体的には、お客様の注文内容、ポイント処理、クーポン処理などのお客様との契約に関する情報から、ピックパック業務の状態、配達の状態など、注文処理全体に関わる情報が含まれていました。

このような設計は、単一のプロダクトで注文受付から配達完了までを管理できるという利点がある一方で、システムが密結合になり、機能の拡張や修正が困難になるという課題がありました。

たくさんの領域の関心ごとがOrderにいる図

主な課題は以下の3点です。

  • コード変更の複雑さ: 複数のチームがOrderクラスを共有していたため、コードを変更する際に他のチームとの調整が必要となり、開発のボトルネックとなっていました。
  • データ操作のロック競合: Orderドキュメントが複数の商品情報を含んでいたため、別々の商品に対する同時操作が頻繁に競合し、データ整合性の問題が発生していました。とくにピッキングの業務中では個別商品ごとに作業は並走するので問題が顕著に現れていました。
  • カスケード障害のリスク: ピックパック領域の障害が、お客様の注文明細表示など、直接関係のない機能にまで影響を及ぼすカスケード障害が発生しやすい状況でした。 例えば、ピックパック処理に問題が発生した場合、お客様が注文内容を確認できなくなるという問題が発生していました。お客様は、注文した商品が届くかどうかを知りたいだけなのに、スタッフの業務プロセスが原因で注文内容すら確認できなくなるという事態は避けるべきです。

とくにお届けチームのプロダクト改善はピックパックに関わることが現在多く、コードや構造改善の恩恵が得やすいということで改善の実施に踏み出しました。

構造の改善

これらの課題を解決するために、以下の取り組みを実施しました。

  • データモデルの分離: お客様対応に必要なデータとピックパック業務に必要なデータを、別々のFirestoreドキュメントに分割しました。これにより、各領域のデータを独立して管理できるようになりました。
  • コードの分離: データ操作を行うクラスも、お客様対応とピックパック業務で分離しました。これにより、各領域のコードの独立性が高まり、変更の影響範囲を局所化できるようになりました。

これらの取り組みに伴い、以下の2つのデータ連携が必要になりました。

  • お客様からの注文内容に基づいて、ピックパック担当者に指示を出す。
  • ピックパックの進捗状況をOrderドキュメントに反映する。

これらのデータ連携を、業務上の意味を持つ「イベント」としてモデル化し、イベント駆動型の非同期処理コンポーネントを導入することで実現しました。 また、ピックパックの進捗状況をリアルタイムに集計するために、イベントをトリガーとして集計処理を実行する仕組みも導入しました。

領域が非同期処理によって連携する(非常にシンプルにした図)

非同期処理のトリガーになるイベントを元に集計が起きている

これらの改善により、Orderとピックパックの間の影響関係がインターフェースを通じて明確になり、「実はXXXにも影響があった」という予期せぬ影響を減らすことができました。

ロック競合についてはピックの操作はPickingというある1注文の1商品ごとにあるデータへの操作になったので、最終的にOrderドキュメントへのデータ連携処理が残るものの、バックグラウンドで非同期に処理されるためスタッフの業務への影響はほとんどなくなりました。

カスケード障害のリスクも、データとコードの分離、および非同期処理の導入によって大幅に低減しました。ピックパック処理にバグがあった場合でも、ピックパック業務が開始されるまでの間に修正できれば、お客様やスタッフに影響が出るのを防ぐことができるようになりました。これは、改善前はピックパック処理のバグが注文受付自体を妨げる可能性があったことと比較すると、大きな改善です。


本記事では、ピックパック領域の疎結合化に関する取り組みの概要と、その効果について説明しました。技術的な詳細については、後続の記事で詳しく解説する予定です。

読者になるボタンを押すと後続の記事が公開されたときに通知を受けとれるのでおすすめです。

アプリを起動せずにアプリを開発して品質と生産性を上げる

先日、Flutter Tokyo #6 で同タイトルの発表をさせてもらいました。10分ほどの発表でしたが、割と良い反応をいただけたので、少し内容を補足してブログとしても公開します。

発表時のスライドは以下です。


前提

一般的に、モバイルアプリは自動テストしづらい箇所が多いと言われます。たしかに、画面から素朴に実装していくと、自動テストでは確認が難しくなりやすいです。そうなってしまうと、アプリを起動して手動で動作確認するしかなくなってしまいます。

一方で、設計やツールを適切に使えば、モバイルアプリであっても広範囲が自動テストで検証可能になります。手動での動作確認を完全になくすことはできませんが、手動テストへの依存度は下げられます。

手動テストへの依存度が下がると、検証時間の短縮、手戻りの抑制など、さまざまなメリットが得られます。また、手動テストにも良い影響を与え、手動テストでなければ確認できないことに集中できるようになります。

なぜテストしづらくなるのか

テストしづらさは、以下の2つに分解できます。

  • テストする条件の再現が難しい。
  • 結果の検証が難しい。

原因は色々と考えられますが、最もよくある原因はテスト対象の役割が大きすぎることだと思います。モバイルアプリではデータとUIの両方を制御する必要がありますが、両者の役割が混在すると状況はより厄介になります。また、役割が大きくなると記述するテストケースも網羅しづらくなり、抜け漏れが出てテストの価値が下がりやすくなります。

役割を混ぜないこと(特にデータの制御とUIの制御)、役割を大きくしないことを守れば、あとは場所ごとに適切な手段を使えば十分テスト可能となります。

例を使って解説

例としてGitHub APIでリポジトリ検索をして、結果を表示する画面を考えます。

この画面はそれほど複雑ではありませんが、それでも一気にすべてをテストするのは得策ではありません。役割の種類を混ぜないこと、役割を大きくしすぎないことを守りながらクラスの境界を設計し、それぞれをテストしていきます。

データとUIの関係を疎にする

数ある責務分割の中でもトップクラスで効果的なのは、データとUIの関係を疎にすることです。これを守ると、先に挙げた「テストしづらさ」の要因の1つである「テストする条件の再現が難しい」は解消しやすくなります。

依存関係の向きは常にUI → データなので、データとUIの関係を疎にするには、データ側のロジックの詳細がUI側に漏れないように設計します。今回の例ではデータ側はGitHubと通信を行い、レスポンスのステータスコードを確認し、JSONをパースし、データが想定通りか検証する、といった処理が必要ですが、この一連の内部処理の制御にはUIは関わらないようにします。

具体的な実装としては、データ側は以下のようなインターフェースを提供します。

UI側の視点で見れば、データ側に入力を渡せば結果が得られる状態になっています。一連の内部処理について立ち入ることはできず、結果だけを受け取るようになっています。

出力を適切にレイアウトに反映するには、内部処理の中で何が起きたか知る必要がある場合もあります。そういった場合に備えて、データ側では実行結果に適切な情報を含めるようにします。上記の例では、検索の失敗時にGitHubExceptionをスローすることになっていますが、この例外に適切な情報が含まれていれば、UI側は利用者と適切にコミュニケーションができます。

データとUIの関係が疎になると、UIの役割は「データに入力を渡して、出力をレイアウトに反映するだけ」というシンプルなものになります。これはコード上にもあらわれ、実際にwidgetの実装は以下のようになります。

なお、ここではRiverpodを使っており、前掲のデータ側のインターフェースを呼び出すproviderを以下のように定義しています。

ここでもう1つ重要なのは、UIが依存するデータ側の実装が差し替え可能になっているということです。Riverpodにはproviderを差し替えるoverrideという機能があり、データ側の出力を任意のものに変えられます。これによって、先に挙げた「テストしづらさ」の要因の1つである「テストする条件の再現が難しい」は解消されるという訳です。

役割がシンプルになったUIをテストする

UIの役割は「データに入力を渡して、出力をレイアウトに反映するだけ」というシンプルなものになりました。テストでもこの役割を検証します。

「テストしづらさ」の要因として「テストする条件の再現が難しい」「結果の検証が難しい」の2つを挙げていましたが、これまで説明していなかった「結果の検証が難しい」は、UIのテストにおいてはgolden testを使って解消します。

実際のテストケースに入る前に、テストする条件が再現されるwidgetを返す関数を準備します。テストする条件のデータの出力を渡して、providerをorverrideしてwidgetを返します。

ここまで来れば、あとは条件ごとにテストケースを書くだけです。以下のテストコードは、データ側がリポジトリのリストを正常に返した時に、その結果がUIに正しく反映されるか検証しています。

左側の画像はテストに使用するgolden fileです。右側のテストコードを書いて、flutter test--update-goldensオプションをつけて実行すれば生成されます。実装中はgolden fileが想定通りになるまで修正と再生成を繰り返します。一度完了したら、以降はテストのリファレンスとして使用します。

通信が失敗した場合のテストケースも同様に書けます。今度はresultFuture.error(GitHubException.connectionFailed()を渡して、通信が失敗した場合を再現しています。

このように「テストしづらさ」の「テストする条件の再現が難しい」と「結果の検証が難しい」をそれぞれ解決すれば、UIのテストも簡単に書くことができます。このような形で開発を進めていけば、アプリを起動して動作確認する必要性は自然と下がっていきます。

品質と生産性

視点を品質と生産性に移すと、以下のことが言えます。

  • 手動テストでは再現が難しい条件も含めて、あらゆる条件を簡単に再現できる。
  • 自動テストがリファクタリング耐性を持っているので、変更がしやすくなる。
  • 高速に反復実行できるため、開発中の修正サイクルを速く回せる。
  • 頻繁な全件実行が現実的なので、マイナーケースのデグレも早く発見できる。

あらゆる条件を簡単に再現できる

手動テストでは再現が難しい条件も、今回の形なら簡単に再現できます。

例えば、GitHubで障害が発生して500エラーを返した時にUIがどうなるかは、手動では再現が難しいです。しかし、今回の形であれば_createWidget()resultGitHubException.unsuccessfulResponse(statusCode: 500)を渡せばそれが再現できます。

あらゆる条件の再現が簡単になり、自動テストが実装されるということは、実行コストが大幅に圧縮され、その条件の検証が行われる機会が増えるということになります。それが、最終的には品質の底上げに繋がります。

リファクタリング耐性があるので変更がしやすい

UIのgolden testは、描画結果のスクリーンショットを使って検証しているため、widgetの内部実装には依存していません。そのため、widgetの内部実装を大幅に変えたとしても、テストコードを変える必要はなく、リファクタリング耐性があると言えます。

検証内容を変えない限りはテストコードを固定できるため、その分内部実装は柔軟に変更しやすくなり、結果として変更を早く終えられるようになります。

高速な反復実行による開発中の修正サイクルの高速化

今回のテストはFlutterのwidget testであり、これは非常に高速です。実装の仕方にもよりますが、今回のような形であれば10件くらいのテストケースも実行は1秒ほどで終わります。

また、Flutterにはhot reloadがありますが、これと比べてもメリットがあります。今回の形では、再現が難しい条件や、テキスト入力などのUIの操作が必要な条件などであっても、確認と修正のサイクルの速度はあまり影響を受けません。

頻繁な全件実行による品質の底上げ

テストの実行速度が速いため、手元でもCI上でも全件の実行が現実的になります。これにより、アプリの大通りでないケースについても、常に検証を行うことができます。

最終的に手動テストが不可欠であることに変わりはありません。なぜなら、今回の形のテストは結合した状態でテストしている訳ではないため、結合に起因した不具合や、使い勝手という観点の検証ができないためです。しかし、それでも自動テストは手動テストの負担を下げたり、稀にしかテストされないマイナーケースも含めた全体の品質の底上げに役立ちます。

例えば、レイアウト崩れを早期発見するgolden testがあれば、レイアウト崩れによる手戻りの頻度は大幅に抑えられ、開発担当者とテスト担当者が手戻り対応に割く時間を抑えることができます。

UI以外のテスト

今回はUIのテストを中心に説明しましたが、アプリを起動せずに開発を進めるにはデータ側のテストも同様に重要です。また、UIに関しても画面遷移のテストや、分析ログのテストなど、まだまだテストすべきものがあります。

これらについては、また別の機会に解説したいと思います。

まとめ

  • モバイルアプリ開発は手動テストに依存した部分が増えやすいと言われる。
  • しかし、役割をちゃんと分解すれば、ほとんどのことが自動テストできる。
  • それなりに頑張る必要はあるが、やる価値はある。

メンバー募集

10Xではソフトウェアエンジニアを募集しています(特にバックエンド)。

今回はモバイルアプリのテストの話を書きましたが、役割の分解のところはバックエンドでのテストにも通ずるものです。こういった考え方で開発をより上手くやっていきたいという方に是非来ていただきたいです。

興味があれば、ぜひ会社紹介をご覧ください!

open.talentio.com

お届けチームがイベント駆動アーキテクチャを採用した理由

ネットスーパーで注文された商品が効率よく確実にお客さまのもとに届くためには、店舗でのピッキングやパッキング、配送といった業務が必要となります。この業務を支えるStailer上のアプリケーション開発を担っているのが、お届けチームです。

10x.co.jp

お届けチームは昨年「イベント駆動アーキテクチャ」を導入する取り組みを行いました。イベント駆動アーキテクチャをどんな狙いで導入し、どんな成果が得られたのか。お届けチームの開発メンバーである鈴木さんに聞いてみました。

イベント駆動アーキテクチャ: イベント駆動アーキテクチャは、システム内で発生するイベントをトリガーにして処理を実行する設計パターン。コンポーネント同士が直接やり取りをせず、イベントを介して情報を共有するため、疎結合になり、スケーラビリティと柔軟性が高くなる。イベントはイベントバスやメッセージキューを通じて通知され、受け取ったコンポーネントが必要に応じて処理を行う。

密結合なシステムの課題

── まず最初に、どんな課題を解決するためにイベント駆動アーキテクチャを導入しようとしたのか、というところを聞いてみていいですか?

鈴木: はい。 元々あった課題として、Stailerはいろんな領域のデータだったり、コードだったりと、いろんなものが密結合になってたんですね。 密結合になってるがゆえに、ソースコードを触るときに、あっちにお伺いを立てて、こっちにお伺いを立てて、みたいな一つ触るのにも気にすることが多いという状況でした。そうした、開発の面での認知負荷が高いというところが1つ。

それに、障害リスクの観点がもう1つ課題としてありました。ネットスーパーをやってると、エンドユーザーが利用するECサイトと、店舗のスタッフの方が利用するシステム、2つのシステムを管理する必要があります。店舗向けのシステムで障害起きてしまうと、ECサイトまで注文できなくなるようなシステムが本当にいいシステムなのか?というと、そうではないと思うんですね。

実際、密結合がゆえにスタッフ向けのシステムの面がちょっと壊れたりすると、エンドユーザー向けのECサイトでも注文が受け付けられないといったような障害に繋がる、カスケード障害のリスクが当時はいろんなところに点在していました。そういうのを解決したくてイベント駆動を採用しようとしてた。 ってとこですかね。

Eventarcの活用

── そうしたモチベーションでイベント駆動を導入し始めたと思うんですが、導入するにあたってどんな部分が大変でしたか?

鈴木: そうですね。やはり、スタート地点でコードやデータがすごい密結合になっていたので、これをどうやって分解しようかな、というところですかね。イベントをどうモデリングするかっていうのは、頭を抱えましたし、モデルって、常に省みるものなので、今でもこれは正しいのかなぁ、どうなんだろうなぁっていうのは、悩み続けているし、大変だったところですかね。

一方でより技術的な面でいうと実はそんなに大変ではなかった、 とは思っていて。弊社ではFirestoreを中心的なアプリケーションのデータベースとして使ってるんですけど、それがEventarcっていうイベント駆動のためのサービスとうまく繋げることができたので、イベント駆動をシステム的に実現するっていうのは、思ったより大変ではなかったとこでした。

Stailerでは主にDB(Firestore)上の特定のデータの書き込みや更新をトリガーとし、Cloud Runを経由して期待されるコンポーネントの処理が実行される。

Eventarc: Google Cloudの内外のイベントを統合して処理できるサービス。Cloud StorageやCloud Pub/Sub、Firebaseなどからのイベントをトリガーにして、Cloud RunやCloud Functionsで処理を実行することができる。

意思を持って言葉を定義すること

── モデリングをちゃんとやろうとしたとき、使ってる言葉がブレてるとか、そもそも言葉の定義が決まってないみたいで苦労することがあるんじゃないかと思うんすけど、その辺で何か工夫されたこととかってありますか。

鈴木: まず、自分たちで決めないと、その言葉がないってことからスタートだなって思ってまして。

例えば会計とかクレジットカードみたいなドメインだと、その業界の中でいろんな言葉があったりするんですけど、僕らの作ってるピックパックってそもそも紙ベースで仕事がされてた頃からシステム化しましたっていう経緯がありまして。

紙のときにはそもそもやってなかった業務が増えてる。 増えた業務ってまだ名前がなかったり、ふわふわしてたり、名前があるけど、実は何かお届けの領域にとっては正しくない名前をしてるとか。

そういうのが多かったんで、自分たちでこれはこういう言葉を使うんだっていう強い意志を持ってことを決めるっていうことがすごい大事でした。そこで、そのユビキタス言語辞書を作ってみるっていうのはすごいやってよかったというか、これがなかったら厳しかったなっていうとこですよね。

お届けチームのユビキタス言語辞書の一部

── モデリングを見直したときって、既存のデータ構造を変えるみたいな必要があると思うんですけど、実際動くものがある状態でデータ構造とかモデルを変える大変さってありましたか?

鈴木: そうですね。 もちろんデータマイグレーションとかは大変なんですけど、幸いにもお届けチームが受け持つ領域って、一つのデータの生存期間というか、使われる期間が非常に短いんですね。

お客さまが注文を入れてから、手元に行くまでの間で扱われるデータなので、長くても2週間ぐらいで役目を終えるし、後からその生のデータを省みるってことはあんまりないんですよね。

データの生存期間が短いんで、並走期間はその2週間分を見てダブルライトして短い期間の移行期間を経て対応できたので、実はそんな大変じゃなかったんですよね。

イベント駆動アーキテクチャの恩恵

── お届けチームが持ってるコンポーネントと他のチームのコンポーネントが密結合だと、境界上から見えづらくてモデリングしづらいみたいなところとかもあったりするんじゃないかなと思うんすけど、その辺で苦労されたこととか、工夫されたことってありますか。

鈴木: そうですね。 ピックパックの話で言うと、幸い他のチームが運んできたものを最後扱うところなので、比較的自分たちの都合で決めるというか、あんまりお伺いを立てずに進められたかなとは思ってますね。

なので他チームとのインタラクションという観点だと、ここまではあんまり苦労はなかったです。ただ、チームの中で発見したり、作った言葉を他チームに浸透していく大変さを、これから味わっていくんだろうな、というのは予感しています。

── イベント駆動アーキテクチャを導入してみて、実際にどんな恩恵が得られましたか?

鈴木: 保守性の話にも繋がると思うんですけど、イベント駆動で開発をするとイベントを大事にするからモデリングをしっかりする、といったようにモデリングする動機付けになったという部分があります。

また、イベントを保存して扱うというやり方になったので、トラブルシューティングのときに信用できる事実が溜まってくってのはすごい良かったことですね。

以前からも業務の生産性を計測するために、いわゆるGoogleアナリティクスにログを送るみたいなことをしてました。 広い意味だとそれもログではあるんですけど、どうしてもデータが使いにくかったり、実際にシステムに反映されてる状態と、Googleアナリティクスにあるログは乖離し得るものなので、何かデータの不整合があるんですけどみたいなことがあったりしました。

イベント駆動を始めてイベントを保存するようになってから、それを基準に業務の生産性を図ることができるようになりました。システムの都合で変な不整合が起きないっていうのは、明確に前進したかなっていうところですね。

理想のモデリングを志すことに価値がある

── 正しく業務の内容を記録するされるっていう副産物も得ることができたってことですね。ありがとうございます。 最後に何か今、この話を聞いて、イベント駆動を自分をやってみたいなってなった人へのアドバイスとかってありますか。

鈴木: いろいろあるけど、やっぱりイベントを通してモデリングする業務に着目することですね。この業務の中ではどういうことが起きるんだろうっていうのに着目して作っていくことが何よりも大事かなって思ってます。

あとはイベント駆動なので非同期処理が入ってくると、非同期であるが故に技術的に難しいことがたくさん出てくる。 そこは失敗しながら、学んでいくしかないのかなと思ってます。

それから、もし仮にですけど試してみたが、やはりイベント駆動はやめておこう、という結果になっても、イベント駆動を志してモデリングした経験は残ると思うんですよね。イベント駆動アーキテクチャを最終的に採用しなくても、今後の自分のモデリングの糧にはなるはずなので、ぜひやってみるといいんじゃないかなと思います。

モデリングを大事にしてやってみると良い、というのは明確にアドバイスの一つかな、と思います。

── なるほど。イベント駆動が導入されたこと自体より、業務があるべき姿にモデリングされていることこそが一番良い成果、というような。

鈴木: そうですね。志すといいますか…あるべき姿、完璧になるってことはやっぱ難しいし、出来ないかもしれないんですが、でもそれを目指す。 目指して、頭の中に理想がある状態を作る。足元の現状を考える際にそうした理想とのギャップを考えることができると良くて、それをさらにシステムに反映できるとより良いな、と思ってます。

おわりに

10Xではより良い設計、より良いモデリングによってプロダクトや事業を成長させたい、というソフトウェアエンジニアを募集しています。 この記事を読んで、自分も理想のモデリングを志したいと、と感じた方はぜひ下記をご覧ください。 open.talentio.com

Devin AIの商品データパイプラインへの適用

はじめに

10X ソフトウェアエンジニアの野々村です。元々アプリケーション開発者としてサーバーサイドを中心に仕事をしてきましたが、最近は協業する小売事業者様から受領したデータをネットスーパーに掲載できる状態へ加工する商品データパイプラインの開発に主に携わっています。

10x.co.jp

10XでもDevin AIを利用し始めて1ヶ月程度が経ったので、適用事例と展望について紹介します。

前提

Devin AI とは

Cognition AI社によって提供されるAIエージェントSaaSです。2024年12月に一般利用が開始され、各所で導入事例が紹介されています。

devin.ai

Devin AIの特性として、以下のようなタスクが得意とされています。

  • 実装の検証が容易である
  • 参考実装にアクセス可能である

Devin AIと適用領域の特性のマッチング

10Xでは私が開発に携わる商品データパイプライン領域においてDevin AIの特性がマッチするのではという仮説があり、導入検証を行いました。

弊社の商品データパイプラインは大きく、「小売事業者様から受領したデータを計算処理に渡すための共通フォーマットにクレンジング・結合・絞り込み・整形を行う箇所」と「検証されたデータセットを元に共通の計算処理を行う箇所」の2層で構成されています。

前者の小売事業者様に近いレイヤーは、小売事業者様ごとに個別のパイプラインが実装されています。一方で完全なワンオフではなく、開発者の認知負荷を削減するため、一定のルールに基づいた共通構造が実装されています。

商品データパイプラインのイメージ図

そのため、「ある小売事業者様向けのパイプラインで実装した内容を他のパイプラインに水平展開する」ようなタスクが頻繁に発生します。このようなタスクは以下のような点でDevin AIに依頼しやすいタスク群でした。

  • 事前定義されたスキーマによって型制約を与えつつ実装が進められ、自動化された単体テストや結合テストで回帰試験が可能である → 作業中および作業完了後の検証容易性を担保できる
  • あるパイプラインへの実装を参考実装として渡してDevin AIに指示を出せる → 参考実装のアクセス容易性を担保できる

効果測定

導入による影響と費用対効果

商品データチームではスクラムを採用して1週間毎にSprintを回しています。4週間の消化StoryPointの比率からDevin AIを利用して対応したStoryPointを観測すると、概ね20-30%程度の消化StoryPointへの貢献が見て取れました。

商品データチームはEMを含め4人で運営しているため、20-30%は単純計算でエンジニアを1人追加した程度のインパクトと言えます。

一方で費用についてですが、Devin AIの料金はACUと呼ばれる計算量の単位で決まります。

devin.ai

記述時点(2025/3/17)では$500/250ACUsが月間の基本料金であり、以降は$2/ACUの従量課金です。

検証期間中利用したACUは400ACUs程度でした。金額換算では$800程度になります。¥150/$で換算すると¥120,000程度となります。

開発ツールへの出費としては安くありませんが、開発生産性へ与える影響との比較で言えば破格と評価しています。

導入時の工夫

使い始めるためのドキュメントを整備する

AIエージェントを利用した開発は開発者の受け入れコストが小さくありません。自分の手元で完結するコーディングとは異なるマインドセット、ワークフローを要求しますし、そもそも仕組みの理解やサービスの仕様について理解しておく必要もあります。

まずは使ってもらわなければ妥当な検証が行えないため、社内でのプラクティスをまとめた手引を作成し、少しでも初回利用のハードルを下げてもらえるようにしました。

実際に作成した手引の目次(一部)

最小権限を付与する

Devinは高い自由度を持ちます。ミニマムでも対象GitHub Repositoryへのwrite権限を持つため破壊的な変更を実行できますし、例えばインターネットアクセス環境とブラウザを持つため、認証情報を持てば多くの環境にログインして作業することができます。しかしセキュリティ的に、あるいは本番オペレーターとして信頼できる水準では必ずしもないという事例も共有されています。

note.com

note.com

一方でDevinへのタスク委譲を考えると一定の権限付与は避けられません。例えば商品データパイプラインにおいては、BigQueryへのwriteができないと修正後のパイプラインにおいてスキーマの一貫性が保たれているかの検証ができません。

このようなケースにおいて、Google CloudのProjectレベルの権限を付与するのではなく、データセット単位の権限付与を行うことで意図せぬ開発環境への影響が起こらないようにしました。具体的にはDevinが作成するデータセットは所定のprefixを設定する運用とし、Google CloudのIAM Conditionsを用いて特定データセットへのみwrite権限を持つように定義しました。

cloud.google.com

10XではIAMをTerraform管理しているため google_project_iam_member resourceを用いて以下のように実現しています。

registry.terraform.io

resource "google_project_iam_member" "${resourceName}" {
  project = "${projectId}"
  role    = "roles/bigquery.jobUser" # クエリ発行のために最低限jobUserが必要
  member  = "serviceAccount:{devin's ServiceAccount}"
}

resource "google_project_iam_member" "${resourceName}" {
  project = ${projectId}
  role    = "roles/bigquery.dataEditor"
  member  = "serviceAccount:${devin's serviceAccount}
  condition {
    title       = "only_owned_dataset"
    description = "商品データパイプライン用のDevinは自分用のdatasetのみ編集可能"
    expression  = "resource.name.startsWith(\"projects/${projectId}/datasets/dbt_devin_sandbox_\")"
  }
}

またDevin AIはSlack Appを用いたSlack Integration機能を持ちますが、このAppは参加したチャンネルの全メッセージの読み取り権限を持つため、所定のDevin連携用チャンネル以外では参加させない運用とし、予期せぬ情報漏えいを防ぐようにしました。

DevinによるPull Requestのレビュールールをチームで決定する

Devinが作成したPull RequestはGitHub上ではbot userが作成したものとなります。商品データチームの所管Repositoryでは、CodeOwnerによる1 approvalでマージ可能な運用としていたため、Devinが作成したPull Requestを依頼者がapproveすることで実質的なセルフレビューでのマージが可能になってしまいます。

これに対し我々のチームでは以下のような運用を決めて運用しています。

  • 原則、依頼者 + 1名のapprovalでマージ可能とする
  • 本番影響のないドキュメンテーション、テストコードの修正に限り依頼者のレビューでマージして良い

ドキュメンテーションの補填や欠けているテストの充足などもDevin AIに期待する役割に含まれるため、それらの速度を落とさず、一方で安全に本番運用を進めるために上記のようなルール設定としました。

Knowledgeは定期的にリポジトリにdumpさせる

Devin AIでは作業に必要な知識・コンテキストを Knowledge という形で登録することができます。

docs.devin.ai

作業毎にDevin AI側から更新を提案してくれるなど非常に便利な機能です。一方でチームのスタンスとして、今後Devin以外のAIエージェントやツールへの転換も十分あり得ると考えています。そのため、Devinに対し定期的に Knowledge をまとめたものをドキュメントにまとめてRepositoryに追記させ、重複するようになったKnowledgeは削除するような運用を取っています。

これにより、ロックインを避ける形でAI ReadableなRepositoryへの磨き込みを進めています。

今後の課題

適用範囲の拡大

今回の検証期間では商品データチームが主要なユーザであり、適用範囲はdbt, GitHub Actions等限定的でした。現在、terraformにて管理されるinfrastructure resourceやDartで実装されたアプリケーションコードへの適用を進めています。

開発チームのパフォーマンスへ与える影響については引き続き測定が必要ですが、特にDartのような静的型付けをもつ言語においては、SQLを主体とするdbtより直接に、高い表現力で値への要求を表現できるため、精度の向上が期待できるのではと考えています。

一方で技術的な課題として認証情報の使い分けがあります。DevinにSecret管理の機能はあるもののグローバルに利用可能なため、チームごとに最小権限で運用しようとすると一工夫が必要です。

docs.devin.ai

現状はSnapshotとして認証情報を保持した状態を保存し、作業指示する際に指定するような運用を想定していますが、改善の余地があります。

レビュー運用の仕組み化

上述の通り、現状のマージルールは運用によってカバーにしていますが、GitHub Actionsによる仕組み化を進めています。具体的には、Commit author および co-author*1 によるapproveしかない場合はfailするようなGitHub Actionsを実装し、GitHubのRuleSetにおいてrequiredとすることで、安全に運用できる状態を作ろうとしています。

導入しての所感

チームの生産性に与える影響はスケールアウト的

Devinを利用しての作業は概ね作業依頼と成果物のレビューというサイクルで成り立ちます。

Devinを使い倒すのであれば、例えばDevinに対して3件の作業を並列に依頼し、これを順次レビューしていくという方法も可能でしょう。一方でDevinに渡せるのは比較的ゴールの明らかな、複雑度の小さいタスクがメインとなるため、このようなタスクばかりを大量に消化するという場面も限定的です。

実際はDevinに定型的なタスクを依頼している裏で人間が複雑度の高いタスクを請け負う(あるいはDevinに渡すための最初の参考実装を作る)という働き方が最もうまく回るように感じました。

この場合、複雑なタスクと並行に簡単なタスクを進められるため、開発者の能力を高めるというよりは、既存の開発者と並列に作業を進めてくれるメンバーが追加されたような捉え方のほうが近いと考えます。

従って、今より複雑な課題が解けるというよりは、今までは後回しになりがちだった事にも適切に取り組めるようになるという工数制約の解消を期待する場合に、うまくフィットしそうです。

投機的な依頼という付き合い方

今のところDevinが作成する成果物は、常に100点を取ってくれるわけではありません。細かいところで意図と違う事をしてしまったり(ベタ移植して欲しいところを手直ししてしまったり、必要なコメントを消してしまったり…)、そもそも作業方針が期待と異なることも間々あります。

Knowledgeという形式で必要な知識を伝授したり、RepositoryにAIエージェント向けのヒントを拡充することである程度は精度を高められますが、それでも本番環境にリリース可能な成果物を常に生み出せるようになるまでにはしばらく時間がかかりそうです。

それまでの付き合い方として、投機的な依頼という付き合い方をチーム内には推奨しています。

依頼を投げてみて、人が作業すると4hかかるはずだった作業がうまくすると5-10minで完結する。もし細かいところが期待と異なっても、それを手直しすれば30minで対応できることがあります。

AIエージェントに確信を持って依頼できるタスクと、複雑度が高すぎて振りづらいタスクの中間に、できるかも知れないが完璧にはやれないかもしれないタスクが無数に存在します。これらを投機的に依頼してしまうことで、期待値としてのパフォーマンスは大きく伸ばしうると感じました。

We are hiring!

この記事では10Xの商品データチームにおけるDevin AIの導入について事例を紹介しました。

開発ツールとして考えると必要な費用が小さいツールではありませんが、開発生産性への影響は非常に大きいと捉えています。

生成AIの発展に伴いエンジニアリングの手法は大きな変革期を迎えつつありますが、この波を乗りこなしてともに10Xを作るメンバーを募集しています。

興味がおありのところがあれば、お気軽にカジュアル面談からお声がけください。

open.talentio.com

*1:デフォルトの設定ではDevinの積むcommitには依頼者がco-authorとして設定されます

アーキテクチャの変更をどうやって完遂するか

既存のアーキテクチャの問題が見えると、アーキテクチャを変更して解決すると思います。

それ自体は素晴らしいことなのですが、変更が全体に浸透し切らず古いアーキテクチャと新しいアーキテクチャが混在したままになってしまうと、状況はさらに悪化します。そのため、アーキテクチャを変更する時には、「どうやって完遂するか」もセットで考えるべきでしょう。

10Xの現状は?

混在しています。

自然と移行を完遂できる日は来なかったので、完遂する努力をしています。

完遂するための取り組み

アーキテクチャの限界を漸進的に押し上げる取り組み で紹介した通り、10Xでは 以下の4ステップのサイクルを回してアーキテクチャを改善しようとしています。

  • 欲しい特性を狙ってアーキテクチャ決定を積み重ねる
  • ADRでアーキテクチャ決定の意図を明確にする
  • linterでADRに辿り着けるようにする
  • ADRへの違反状況を可視化して漸進的に適応度を上げる

完遂に向かう話は4番目で触れているのですが、実際に移行を完遂するには非適合箇所がわかるだけではなく、適合状況の俯瞰的な現在地がわかる必要があると感じました。

そこで、以下のようなイメージの可視化を行いました。

横軸は日付で、縦軸は非適合の数です。アーキテクチャ決定ごとに色分けしています。

可視化にあたっては、以下の2点を把握できることを重視しました。

  • アーキテクチャ決定とコードの乖離は過去と比べて増えているのか。
  • コードとの乖離が多いアーキテクチャ決定はどれか。

アーキテクチャ決定とコードの乖離は過去と比べて増えているかどうかが把握できると、乖離を解消する動きに割く力が今くらいで十分なのか、それとも不足しているのか、理解できます。また、乖離の増減に加えて総量も把握できると、今が新しいアーキテクチャ決定を加えても良い時なのかどうかも判断できます。

コードとの乖離が多いアーキテクチャ決定を把握できると、何の乖離の解消に力を割けば状況が良くなるのか理解できます。乖離が生じている理由は様々で、単に移行の腕力不足の場合もあれば、アーキテクチャ決定の内容自体に移行を鈍らせる要因がある場合もあります。いずれにせよ、何を見るべきかのヒントにはなります。

可視化の仕組み

10Xではアーキテクチャ決定はADR化し、ADRへの非適合箇所はlintで検出できるようにしています。新しいADRの導入時には非適合箇所がたくさん出るので、当該箇所ではlintを無効にするのですが、この無効にするコード(Dartの場合は // ignore: <rule>)を可視化の材料にしています。

以下のようなスクリプトで日ごとの非適合箇所を抽出し、データを作成しています。

date=<YYYY-MM-DD>
sha=$(git log main --merges --until="${date}$ +0900" -1 --pretty=format:"%H")
git grep -rE "// (ignore|ignore_for_file): .+" "${sha}"

デイリーのデータ作成はGitHub Actionsで行い、BigQueryにロードし、Looker Studioでグラフ化しています。

やってみた手応え

実際にアーキテクチャ決定への適合状況を時系列で可視化してみて、今までよりも良い判断ができそうだと感じました。今自分が主に開発しているリポジトリでは「今はアーキテクチャ変更よりも既存のコードを適合させることに注力する」と判断していますが、今回の可視化は判断の拠り所となる事実であり、この判断を変える条件を考える材料にもなりました。

今後もより良い判断をするための仕組みづくりをしていきたいと思います。

メンバー募集

10Xでは技術的判断をより良くしていきたいソフトウェアエンジニアを募集しています。

興味を持っていただけた方は、ぜひ会社紹介をご覧ください!

open.talentio.com

しなやかなデータ連携に向けたdatacontract-cliへの貢献について紹介します

データ基盤チームに所属しているデータエンジニアの吉田(id:syou6162)です。10X社内のデータマネジメントの仕事をしています。

最近、チーム内外でData Contractを取り扱う機会が増えています。本エントリでは、Data Contractの実践にあたり利用しているdatacontract-cliというOSSをなぜ選定したのか、業務で利用するにあたり不足していた機能にpull requestを送って貢献した話を紹介します。

Data Contractの必要性: しなやかなデータ連携を実現したい

10Xのこれまでのデータ基盤は

  • プロダクトから出力されるデータをBigQuery上に取り込んだ上で
  • ディメンショナルモデリングなど分析に使いやすいデータに加工し
  • その上でTableauなどのBIツールで分析結果をダッシュボードで可視化する

というよくある形式でした(この役割はもちろん現在も担っています)。しかし、プロダクトの高度化や事業の進展に伴ない、以下のようなユースケースも登場してきました。

  • BigQueryで集計したデータをプロダクト側の管理画面に表示したい
    • 単純に集計すればよい、というわけではなく、DWHやBIツールなどで整備されているロジックと共通化された集計結果を出したい
    • プロダクト側の開発チームとしては、集計された結果のロジックの詳細には踏み込まず、表示や可視化の部分に集中したい
  • データプロダクト間でデータのやり取りが発生するため、その仕様をプログラムが扱いやすい形でやり取りしたい
    • 手動で仕様をやり取りする形式(例: スプレッドシートやnotionで仕様の管理)はやめたい。実装と乖離してしまうことが経験的にも分かっている
    • データがある状態にたまたまなっているのか、生成側の制約として担保されているのかをスキーマの制約として記述したい
    • コードから仕様の自動生成や仕様からコードの自動生成(例: dbtのsourceの自動生成、Protocol Bufferの自動生成)を行なえるようにして、チーム間のコミュニケーションを疎にできるようにしたい

データを中心としたこういった複数チーム間でのデータの仕様(スキーマやその制約)を担保しつつ、機械からread / writeが可能で、開発者同士のコミュニケーションはなるべく疎にするようなデータ連携を本エントリでは「しなやか」と定義します。

Data Contractの導入に向けたより詳しい背景については、以下の発表資料にまとめていますので、そちらを参照してください。

datacontract-cliを通じて、しなやかなデータ連携を実現したい

Data Contractの仕様を考える際、10X独自の仕様を自分たちで考えることもできますが、継続的なメンテナンスを考えると、世の中の標準に合わせるのがよいと考えました。Data Contractの仕様としてはData Contract SpecificationOpen Data Contract Standard (ODCS)がありますが、10Xでは前者のData Contract Specificationを選択しました。理由としては

  • 取り扱える情報にそれほど大きな差異がない
  • 仕様だけでなく、周辺ツールであるdatacontract-cliが強力であると感じた
  • datacontract-cliを通じて、 Data Contract SpecificationからOSDCへの変換が比較的容易であり、後から乗り換えることが可能

が挙げられます。datacontract-cliは様々な機能を持っているため、詳しくは本家の情報を参照して欲しいですが、10Xで特に魅力に感じた点は

  • 様々な種類のデータ仕様書からのdatacontract-speficiationへの変換
  • datacontract-speficiationから様々な種類のデータ仕様書への変換

が挙げられます。こうした変換は一個一個は大したものではないため、自作する選択肢もありえます。直近でありえる変換{元, 先}としては

  • dbtのsourceやmodel
  • protobufやjsonschema
  • great-expectationsなどのvalidatorコード

などがあり、これら全てを自分たちで実装 / 継続的にメンテナンスするのは骨が折れます。datacontract-cliを利用することで、事業ドメインに深く関わる時間をより確保できる可能性が高いと考え、datacontract-cliを採用することにしました。

datacontract-cliに取り込まれた修正

これまで説明したように魅力的な機能を持つdatacontract-cliですが、10Xの業務利用を考えると不足している点も多かったです。ここでは、業務で利用可能にするためにdatacontract-cliにpull requestを送って取り込まれた修正について紹介します。

Data Contractとdbtの相互変換の際の型修正

最近Snowflakeの利用が増えているというのはOSSの世界でも感じることが多いですが、これはdatacontract-cliにおいても同じでした。data contract側で持っている型とdbt側で持つ型を変換する際、Snowflakeしか考慮されておらず、そもそもBigQueryが対象のdbtモデルではdatacontract-cliが動かない、という状況でした。そこで、BigQueryをはじめ、他のDWHにおいても動かしやすい形にリファクタリングし、Snowflake以外が対象でも動くように修正をしました。

スキーマの制約が反映されるように修正

Data Contractとdbtで仕様を変換する際、当初はスキーマの制約に関する情報の大半が抜け落ちてしまう状況でした。具体的には当初は

  • テーブル名、テーブルのdescription
  • カラム名、カラムのdescription、カラムの型

といった本当に必要最小限の情報しか変換後は残っていませんでした。チームをまたいでデータを取り扱う場合、以下のようなよりリッチなスキーマに関する情報が必要なことが多いです。

  • テーブルの主キーはどれか
  • 該当カラムは値が入っていることが必須かどうか(dbtのnot_null)
  • 該当カラムの値は一意であるか(dbtのunique)
  • 該当カラムはどのカラムの外部キーになっているか(dbtのrelationships)

10Xでもこういった情報はこういった情報はまさに必要としたため、datacontract-cliに対応するpull requestを少しずつ送り、その結果全て取り込まれました。

その他の細かい修正

これまで紹介した修正以外にも、datacontract-cliの使用感に関わる細かい修正も多数pull requestを送り、取り込んでもらいました。

Pull Requestが取り込まれたことでできるようになったこと

これまでに紹介した修正により、datacontract-cliを使って以下のData Contractの運用ができるようになりました。

  • データ基盤チームが管理するBigQuery上のデータの仕様をData Contractのyamlとして渡す
    • dartやprotobufの自動生成などに利用を想定
  • データメッシュ的な文脈でデータアプリケーションBが必要とするデータアプリケーションAの仕様をData Contractを通じてやり取りする
    • データアプリケーションAとBはそれぞれdbtで動いており、dbtのmodel定義 => Data Contract => dbtのsourceという形でdatacontract-cliを使って変換

Data Contractとの相互変換はGitHub Actions上で行ない、成果物であるyamlファイルはGitHub Releasesとして保存するようにしています。また、主キーや外部キーといったスキーマ上の制約も相互変換内で欠落することなく保持できるようになったため、しなやなかデータ連携に向けてのスタートを切ることができたかなと思っています。

今後の予定

現状の10Xの業務で必要なレベルのものは上記でひとまず揃ったのですが、まだまだ整備したい点がdatacontract-cliにはあると感じているので、いくつか紹介します。

インストール時に必要な依存ライブラリの整備

datacontract-cliはData Contractと多様な形式への相互変換ができることが魅力の一つですが、多様な形式をサポートするため、インストールに必要なライブラリが非常に多くなっています。ユーザーサイドが使う予定のない形式のための依存ライブラリもインストールされてしまうため、pip installなどの複雑性が上がってしまっています。実際、dbtやdbt-osmosisなど他のエコシステムと同居させる際に、依存ライブラリのバージョンの噛み合いが悪く、dbtが最新バージョンになかなか上げられない、といった弊害も出てきています。

そこで、ユースケース毎にoptional-dependencyとして切り出す作業を少しずつ進めています。

追加的なスキーマの制約に関する仕様のやり取りをできるようにする

本エントリでData Contractと相互変換をする際にリッチなスキーマ情報が落ちないようにする、という話を書きましたが、Data Contractの仕様ではよりリッチな情報を保持できます。例えば

  • あるカラムが取り得るenumの値の種類を記述
    • これらの値のどれかしか入らない
    • dbtのaccepted_values
  • あるカラムが取り得る値の範囲を記述
    • dbtのdbt_utils.accepted_range

といったものがあります。そういったものも相互変換の際に抜け落ちないようにする対応をいつかやりたいなと思っています。

まとめ

本エントリでは

  • 10XでData Contractが必要になった背景 / 課題
  • しなやかなデータ連携を実現するため、datacontract-cliを選定した理由
  • 業務で活用できるレベルまでdatacontract-cliにpull requestを送って貢献した話

を書きました。datacontract-cliは2024年のAdvent Calendarでも紹介している記事が複数上がっており、盛り上がりを見せています。

本エントリで紹介した内容やより踏み込んだ話題を上記のエントリの著者の方々とパネルディスカッションで議論する場を来月(?)主催しますので、ご興味ある方は是非ご参加ください!

参考:

セキュリティチームの日々の取り組みの紹介 (10X アドベントカレンダー 2024)

10xall.notion.site

10Xセキュリティチームの沢田(@swdyh)です。10Xアドベントカレンダー2024 の26日目の記事です。昨日は@yutatatatata さんの「商品データの裏側を覗く:意外に知らない商品IDの世界」という記事でした。自分も商品データに関する開発をしていた時期がけっこうあったので、奥が深くて面白いなと思って読みました。

先日、情報処理安全確保支援士の試験を受けたのですが、今日が結果の発表日でした。結果は不合格でした。JavaScriptのコードができてたり、画面を描く問題あったりして面白く解いてたはずだったんですが、午後の点数が57点で、あと1歩でした。またがんばります。

今日の記事では、セキュリティチームの日々の取り組みについて紹介したいと思います。

プロダクトの設計と実装レビュー

社内で書かれたDesign Docに一通りチームで目を通すようにしていて、気になるものあればレビューをするようにしています。また開発チームから、ここ気になるのでみてほしい言われることもあります。また実装されたときのコードレビューもやれる範囲でやっています。レビュー対象は、外部連携だったり、認証に関わるものが多かったりします。最近の事例だとOpenID Connect連携があります。

10x.co.jp

安全なサービスを提供するというのが第一の目的ではありますが、自分も元は開発をしていて、そういう大事な部分をつくるときには、これで大丈夫なはずだけど、、、みたいな不安を持っていたので、そういう開発者の不安を減らすこともできればと思っています。

プロダクトに関わる脆弱性アラートのトリアージ

GitHubの全リポジトリでDependabotのチェックを有効化し、新しくてできたアラートにに対処しています。さっと更新できそうなものは更新しつつ、そうでなくて影響がありそうなものは、issueを作って調査しています。

それとは別で、全範囲に適用できていないものの、Renovateを運用していて脆弱性のあるなしにかかわらず日々依存パッケージ更新できるようにしていて、こっちの更新でアラートが解消する場合もあります。

それから各リポジトリの更新できていないパッケージ情報集めるスクリプトを書いて、可視化するツールをお試しで作っていて、全体でどれくらい溜まっているとか、どのあたりのパッケージが手当されていないのかなどが分かるようにしています。

未更新パッケージの可視化

クレデンシャルレビュー

サービス連携などの使われるクレデンシャルを発行して使うケースで、それらの情報を記録し、管理方法や権限の強さや範囲をレビューするようにしています。過去、Secret Managerや1Passwordなどに用途不明のsecretがある状態になってしまっていたために、それはら棚卸ししつつ新規に発行するものにつては記録をしようということで始めました。クレデンシャルでできることは、その目的に対して最小限のものになっていてほしいところですが、そもそも細かく権限を指定できるサービスも多くなかったりして、大きめの権限を要求するサービス連携が多いのが悩み種だったりします。あとWorkload Identity Federationが普及してほしいなと日々感じています。Workload Identity Federationであっても適切に設定されているかのレビューは必要ですが、クレデンシャルそのものがないというのは安心ですね。

外部セキュリティアドバイザーとの相談会

セキュリティに関わる施策の相談や、設計レビュー、そのほか悩み事を相談をさせてもらっています。もともとチームメンバーがセキュリティ専門でないことを補うために始めた取り組みですが、悩みはつきないし、自分たちでは気づきにくい視点を得られるため大変助かっています。開発チームから開発担当者を呼んでいっしょにレビュー会をすることもあります。

アクセス制御不備チェック会

定期的に脆弱性診断を実施していますが、よく見つかるのが、本来アクセスできてはいけないデータにアクセスできてしまうケースで、パラメータのチェックが足りていなかったり、認可のチェックが足りていなかったりするものです。これに類似したケースは見つかってないだけで、他にもあるだろうということで、エンドポイントを1から眺めて同じようなパターンがないかを確認するという作業をはじめました。なかなか地味で果てのない作業なので、それぞれの担当場所のコードを読みながら、これどういうことなんだろうとか、ここちょっと危ないかも、みたいなことを話しながらやっています。実際に危なそうな箇所をみつけることもあり、成果もあるんですが、これをずっと続けるのはコストが高いので、ある程度読み進めた中で、いくつかパターンをまとめ、そういうこと自体がおきにくくする仕組みを作れないかみたいなことを考えたいと思っています。

セキュリティ輪読会

セキュリティに関する本やWebの記事を読みながら話合う会をしています。事前準備なしで参加者のた誰かが本文を読み上げ、気になるところがあれば都度話をしながら進めています。これもセキュリティの専門性を補うためにはじめた取り組みですが、ときどき仕事のなかでも「あの本のあれに書いてあった」ということもあったりしています。今年読んだものとしては以下になります。

これらの日々の取り組み以外にも、いろいろな施策をしていて、一部紹介の記事があるので興味のあるかたはこちらも見てみてください。

product.10x.co.jp

これからの話

今まではプロダクトセキュリティをメインに担当していましたが、それに加えて、コーポレートセキュリティ/コーポレートIT領域もやっていくことになりました。いくつかの経緯があってこうなったのですが、それぞれの領域は重なっている部分も多く、ソーシャルエンジニアリングやマルウェアなどの攻撃が高度化してるなかで、プロダクトという枠を超えていくことでやれることも多くあると思っています。

こんなセキュリティチームで、コーポレートIT/コーポレートセキュリティ領域メインに一緒にやってもらえる方を募集しはじめました。応募とまではいかなくても、少しでも興味があるかたは声をかけてもらえると嬉しいです。

コーポレートIT / 株式会社10X

[共通]カジュアル面談 / 株式会社10X

明日のアドベントカレンダーは、代表の矢本さんの記事です。おたのしみに。