LayerX エンジニアブログ

LayerX の エンジニアブログです。

複数プロダクトに散らばったデータ統合に苦労した話

この記事は、6月から始まっている #LXベッテク月間 38日目の記事です。 前回の記事は、かじさん(@kajicrypto)の「CSの生産性を定義する - CS1人あたりARRシミュレーション - 」でした。

こんにちは、LayerX バクラク事業部 OCRチームの秋野(@akino_1027)と申します!先日、SaaS Tech#4にて「マルチプロダクト×非構造化データ×機械学習を支えるデータ信頼性」というテーマで登壇させていただきました。

speakerdeck.com

登壇ではユーザーの課題からAI-OCR周りのデータ管理まで網羅的にお話しさせていただきました。この記事では時間の都合で割愛させていただいた「複数プロダクトの書類データ統合」についてフォーカスを当てて話していきます。(スライドだと下記↓)

背景

バクラクOCRでは請求書などの書類データをインプットとして、支払金額等の項目を読み取って出力しています。読み取り精度を向上させるために書類データ(インプット)と読み取りデータ(アウトプット)をペアで管理する必要がありました。

書類データは、そのままで概ね問題ないのですが、項目ごとの読み取りデータは工夫が必要でした。 一見、ユーザー入力値がそのまま使えるように思えるかもしれません。しかし「書類に記載されている値」を正確に紐付けたいので、独自に用意する必要がありました。そこで、OCRデータ基盤を開発しました。

下記のスライドがOCRデータ基盤を簡略化したものです。下記の図の「正解データ」が書類に記載されている読み取りデータを表しています。

上記の図でもわかるように、各プロダクトから書類データに何らかの形でアクセスする必要がありました。

ここから本題

そんな背景があり、各プロダクトから書類データをImportする機構の設計と実装を任されました。最初は他のタスクと同じ方法で進めていったのですが、かなり苦労しました。理由としては、問題自体も複雑で選択肢も多くある中で単独でガッと進めてしまったことかなと思います。

当然、設計がある程度進んだ段階でチームメンバーに共有するなどの工夫はしていたのですが、今回の場合は問題が複雑なため、頻繁にメンバーに相談するべきでした。そのコミュニケーションが不足していたために、「設計をする」→「実際に手を動かす」→「めちゃめちゃ辛いことに気がつく」というサイクルを繰り返してしまいました。

もちろん、ある程度は仕方ない部分もあると思いますが手戻りがかなり発生してしまったので、もう少し進め方を工夫するべきだったと反省しています。

以降では、試行錯誤した流れを実装候補と共に見ていきたいと思います。実装候補は主に下記の3つでした。

  • 各プロダクトのPrivate APIを利用する
  • AWS Database Migration Serviceを使ってデータを同期させる
  • バッチを使って定期的にOCRデータ基盤のDBにImportする →最終的に採用した案

それぞれ見ていきたいと思います。

案1:各プロダクトのPrivate APIを利用する

すでに実行環境が存在するため、インフラのリソースを新たに作成する必要がなかったり、ロジックを使い回すことができるなどのメリットがありました。しかし下記のような懸念点があり、断念しました。

  • プロダクトで使っているものなので、内部的に使用したくない(間違ってもOCRデータ基盤の都合でユーザー側に影響を与えてはいけない)
  • すでに存在するAPIのロジックを使用すると依存性が高まり、バグが起きやすくなってしまう
  • プロダクトごとにロジックを書く必要があり、実装・メンテナンス工数が高くなる

特にプロダクトごとにロジックを書かなければいけないので、管理コストが高くなってしまうのが辛いので別の方法を考えました。

案2:AWS Database Migration Serviceを使ってデータを同期させる

aws.amazon.com

AWSのDMSを使うことで、他のデータベースの一部を継続的に同期させることができます。実際に触ってみたのですが、複雑な設定等もなかったのでシュッと導入できそうでした。

しかし今回の場合、OCRデータ基盤はWebAPPなのでローカルで開発を進める必要がありました。AWS DMSはクラウド上のDBを同期させるサービスなので、ローカルのDBを同期させることができないという理由から断念しました。

案3:バッチを使って定期的にOCRデータ基盤のDBにImportする

バッチ上で各プロダクトのDBにアクセスして整形してOCRデータ基盤のDBにInsertしていく形です。こうすることでロジックの管理も容易にできますし、バッチのロジックに各プロダクトの複雑性を吸収させることで、OCRデータ基盤のDBをプロダクトの影響を受けることなく、定義することが可能になります。

もちろん既存のコードを使いまわすことができないなどのデメリットはありますがメリットの方が大きいと感じて、この案を採用しました。

試行錯誤と、その学び

このプロジェクトを通じて技術的な学びもよりも「複雑性が高い問題に対するアプローチ方法」を学べたことの方が大きいと感じました。問題が単純な場合は、複数人で分担することによってマネジメントコストが高まってしまうことを避けるために1人(or 少人数)でガッと進めたほうが効率的かもしれません。しかし今回のような複雑性が高く、選択肢も複数存在する問題の場合はチームで頻繁にフィードバックをもらう方が効率的だと感じました。例えば

  • 選択肢などの「叩き」だけを作ってチームで話してみる
  • 設計の全体像が決まったタイミングでチーム内で共通してフィードバックをもらう
  • 定期的に「気になり」を聞いてみる(もちろん、時間が取られない工夫をした上で)

このような工夫を凝らすことで、ある程度実装が進んだ後に手戻りが発生するようなことは避けられると思います。

バクラクシリーズの体験の良さの源泉のひとつに、「なめらかなプロダクト間連携」が挙げられると思います。それらを実現するために、その裏には複雑性が高い問題がまだまだ数多く転がっていると感じています。次の機会には、今回の学びを活かして、ユーザに価値を爆速で届けられるようにしていきたいと思います。

最後に

現在採用を進めており、LayerXに興味がある方はカジュアルにご応募いただけますと幸いです!

open.talentio.com

筆者のMeetyも公開しています。ざっくばらんにお話しましょう!

meety.net