visible true

技術的なメモを書く

患者さんと病院をつないでいくシステムの今とこれから

本エントリはUbie Advent Calendar 2020の22日目です。 21日目はtoCプロダクトAI受診相談ユビーのプロダクトオーナーである@shikicheeエンジニアの僕が強みを活かして施策推進したら、異次元の角度で数字が伸びちゃった話でした。

自分は現在toBプロダクトである、医療機関向けのAI問診ユビーのソフトウェアエンジニアをしています。普段はRails/Ruby、Spring Boot/Kotlin、React/TypeScriptを使ってバックエンドからフロントエンドまでプロダクトに関連することについて全般的に開発をしています。

またこのほかに最近は全社的な技術戦略に関するロールを持っており、サービス全体のカタチをどのようにしていくかについて考えたり手を動かしたりしています。

本エントリでは、Ubieの現在のシステムの状況と、起こり始めている現象などを紹介しつつ、今後どのようなことを行っていくかについてまとめます。

Ubieの今とサービス群

Ubieは今年で創業から4年目を迎えました。現在のサービス群の基となるコードは、共同創業者の一人である久保(@quvo_ubie)が大学院時代の研究で作り始めました*1。コードベースとしてはこの研究時代の2年間を足した6年物ということになります。

現在のUbieのソフトウェアエンジニアやサービス、プロダクトの数は次の通りです。

  • ソフトウェアエンジニアの数: 24人
  • サービスの数(デプロイの単位):15個
  • プロダクトの数:4個

独立して動作するサービス群の関連は次のようになっています。

f:id:sys1yagi:20201222101719p:plain
サービスの関連図

この図にプロダクトの境界を引くと...

f:id:sys1yagi:20201222101752p:plain
プロダクトの境界線

結構こんがらがっているように見えますね。実際に結構こんがらがっています。

現在に至る変遷

Ubieでは創業から現在に至るまで、不確実性を下げるための検証にフォーカスしてきました。それぞれの局面毎に、リソースや時間の制約を鑑みて最善手と考えられるものを重ねているものの*2、やはりどうしても複雑化していっています。

創業前 疾患推測エンジン

f:id:sys1yagi:20201222104134p:plain:w200
最初のサービス

  • 創業前(およそ2年)
  • ソフトウェアエンジニアの数:1人
  • サービスの数:1個
  • プロダクトの数:0個
  • 不確実性:症状群の入力による疾患推測が実現可能か

創業1年〜 toC 症状チェッカー Androidアプリ

f:id:sys1yagi:20201222104540p:plain:w300
AndroidアプリとAPI

  • 創業1年~
  • ソフトウェアエンジニアの数:2〜3人
  • サービスの数:2個 (Androidアプリも1個と数える)
  • プロダクトの数:2個
  • 不確実性:症状に基づいた疾患推測にニーズがあるのか

創業2年〜 toB AI問診サービス 病院向け

f:id:sys1yagi:20201222105152p:plain:w350
病院向けのフロントエンドを追加

  • 創業2年~
  • ソフトウェアエンジニアの数:3〜7人
  • サービスの数:3個
  • プロダクトの数:2個
  • 不確実性:症状チェッカーを病院につなげることがそもそもできるのか

疾患推測エンジンの実現、症状チェッカーの価値検証を経た後、出口としては 実際に患者さんが病院に受診する/しないことが重要となってきます。この時点で医療機関にとっては、症状チェッカーは患者さんの受診行動に影響を与えるかもしれませんが、業務上の課題には特に貢献しません。病院に受診した患者さんは改めて1から問診を行うからです。そこで医療機関の業務上の課題解決にフィットするプロダクトの検証が始まりました。

創業2.5年〜 toC 症状チェッカーサービス(テスト版)

f:id:sys1yagi:20201222124624p:plain:w500
チームが複数生まれてサービスも分割されていった

  • 創業2.5年~
  • ソフトウェアエンジニアの数:7〜12人
  • サービスの数:8個 (toC, toB, 疾患推測の単位で分割開始)
  • プロダクトの数:2個
  • 不確実性:症状に基づいた疾患推測ニーズのスケーラビリティ

医療機関向けのプロダクトの形がある程度見えてきた頃、症状チェッカーのリプレースが始まりました。Androidアプリは廃止し、Webサービスとして作り直しています。アプリの場合、症状チェックをするために症状の発現 -> 症状で検索などをする -> アプリの認知 -> インストール -> チェック という風にかなりの数の手続きを踏まなければなりません。症状があるユーザにとってはかなりの負担です。Webサービスにすることで症状の発現 -> 症状で検索などをする -> ランディング -> チェック とスムーズに症状チェックができるようになりました。同時にその形態でスケールは可能なのかという点の検証が必要となります。

創業3年〜 toB AI問診サービス クリニック向け

f:id:sys1yagi:20201222130549p:plain
病院向けにクリニック向けが乗っかる形

  • 創業3年~
  • ソフトウェアエンジニアの数:12~18人
  • サービスの数:12個
  • プロダクトの数:3個
  • 不確実性:クリニックでスケールするための特有の普遍的な課題が存在するか

病院とは入院施設としてベッド数が20床以上、医師3名以上の機関を指します。それ以外は診療所となります。街に沢山あるクリニックや医院は診療所です。国内の病院はおよそ8000件で、診療所は100000件です。病院診療所では来院患者数や医療従事者の規模が異なります。業務上の課題や関心事も大きく異なるのではないか、という仮説のもと、プロダクトを分けて検証をはじめました。

創業4年〜 toB AI問診サービス アジア向け、症状チェッカーと AI問診サービスの接続

f:id:sys1yagi:20201222131505p:plain
あっという間に15個

  • 創業4年~
  • ソフトウェアエンジニアの数:18~24人
  • サービスの数:15個
  • プロダクトの数:4個
  • 不確実性:
    • AI問診サービスが、海外の医療環境においても課題解決に貢献できるのか
    • 症状チェッカーをトリガーとした、受診をする/しないが起こるのか

国内の医療機関への導入が徐々に進んできたところで、医療制度が近しい国においてもAI問診サービスが役に立つのか検証をはじめました。また国内においては症状チェッカーで行った問診をAI問診サービスを導入している病院に直接送ることができるようになりました。2つのプロダクトが繋がり、サービスの関連図には現れてこない複雑さも生まれ始めています*3

現在起こっている現象

ソフトウェアエンジニアの人数、サービスの個数、プロダクトの数が着々と増えていく中、開発において起こっている現象が沢山あるわけですが、代表的なものとしては次の通りです。

  • 暗黙知の部分のキャッチアップや変更コストが増加
    • 特に文脈を知らない新メンバーは大変そうです。新メンバーはみんな荒野でも生き抜けるパワーを持っていますがとはいえ力を発揮するリードタイムはだんだん増加していっています。
  • プロダクト間で共用している箇所が存在し、壊れやすい
    • 共通ではなく共用となっています。一言でいうと1ロジックに2プロダクトの知識が詰まっていたりします。即日壊れます。
  • 新しいアイデアの検証をするときのインベストが大きい領域がある
    • たとえば、問診を聴取していくフローは症状チェッカーと医療機関向けプロダクトの両方の知識を有していて、さらにそれぞれが複数のパターンを持っているので、分岐が複雑になっています。特定の診療科向けに柔軟に質問を追加したり省略するといったことを気軽に試すのは難しい状態となっています。

技術的負債という視線

個別に現象に対処して行ってもいいですが、現在の人数やプロダクトの増加速度を鑑みると、もう少し中長期目線で考えたほうがよさそうだなぁということで、技術的負債の観点でそれぞれの現象を見直してみました。

ここでいう技術的負債とは、技術的負債の言葉の生みの親であるウォード・カニンガム氏の次の定義に準じます。

「もしも自分たちが書いているプログラム(WyCash)を、金融の世界に関する正しい捉え方だと自分たちが理解した姿と一致させることができなくなれば、自分たちは絶えずその不一致につまずき続けることになり、開発スピードは遅くなっていくでしょう。それはまるで借金の利子を払い続けるかのようです」

t-wada.hatenablog.jp

それぞれ 正しい捉え方だと自分たちが理解した姿と一致していないのではないか という観点で見直すと、

  • 暗黙知の部分のキャッチアップや変更コストが増加
    • システムが、正しい捉え方だと自分たちが理解した姿と一致していない形であることで、リバースエンジニアリング的なアプローチによる理解を困難にしているのではないか。本当に複雑なのか、一致していないのか見直す必要があるのではないか
  • プロダクト間で共用している箇所が存在し、壊れやすい
    • 共用している部分が、利用者にとって独立した共通のものなのか、似ている別のものなのかが曖昧。あるべき姿にできていないか、あるべき姿をまだ見いだせていない可能性があるのではないか。
  • 新しいアイデアの検証をするときのインベストが大きい領域がある
    • システムが、あるべき姿の解像度が低い段階の時のままになっていることで大きく結合してしまっているのではないか。そのために不確実性の高いものを部分的に足し合わせる時に必要な変更が大きくなるのではないか。

不確実性の高い部分を素早く検証するために、不一致を許容するのは重要である一方で、不確実性が下がった後もその部分を放置しておくと、やがて様々な症状が現れてくるのかなと思います。

f:id:sys1yagi:20201222162344p:plain
不確実性の混在を避ける

逆にこれらを解決していけば、現象の解消や防止ができるのではないかと考えました。

ROIで考える

正しい捉え方だと自分たちが理解した姿と一致させ続けることはとても重要だと考えつつも、とはいえリソースと時間の制約があるので、どこまでなにをするかをどう決めていくかは大事です。Ubieでは皆2言目にはROIだROIだと言っています。

f:id:sys1yagi:20201222163521p:plain
ポジショントーク用のポンチ絵

図はほとんど意味を持っていませんが、つまり、複雑度を上げるような追加変更は線形に増えていきますが、開発のインベストはいつの間にか指数関数的に増加していくので、インベストが爆発するまえになんとかしたい、ということです。同時にこれを予防できればある程度の負債は許容してもよさそうです。

なぜインベストの増加を予防したいのかというと、当然速度やコストに効いてくるからですが、それ以外にも意思決定の歪みを防ぐという観点があるかと思います。

f:id:sys1yagi:20201222164024p:plain
issueの質が高くて低インベストの領域にフォーカスしたい

技術的負債によってインベストが増加すると、質の高いissueであっても優先度が下がったりします。重要な検証の優先度が下がるのは時にクリティカルになります。

f:id:sys1yagi:20201222164027p:plain
issueの質が高いのに高インベストのために後回しになる

ということで、直近で解くべき課題は

  1. 現在すでにインベストが高くなっている箇所の解消
  2. 将来インベストが高くなると予見される箇所などの可視化
  3. 不確実性が高い場所と低い場所が共存できるカタチを見つける(機動的な検証が可能な状態)

かなと定義しました。これによって人数やサービスやプロダクトが増えても速度を落とさない、むしろ加速するような状態を作っていきます。

マイクロサービスアーキテクチャとDDD(ドメイン駆動設計)に入門する

守破離ということで、すでにややマイクロサービスぽく分割していることもあって、マイクロサービスアーキテクチャについて改めてしっかりと入門することにしました。

マイクロサービスアーキテクチャの序盤の章では、サービス分割の観点でDDDを参照しています。

DDDの考え方は、技術的負債のあるべき姿と一致させるという考え方と似ています。エリック・エヴァンスのドメイン駆動設計 では歯を食いしばって真のモデルとシステムを一致させるといった言葉が何度も出てきます。

マイクロサービスアーキテクチャの各種ノウハウを取り入れる前に、まずは現在のシステムとあるべき姿のギャップを、DDDにおけるコンテキストとその境界を描くことで可視化していきました。

あるべき形をコンテキストマップで可視化する

f:id:sys1yagi:20201222173856p:plain
境界づけられたコンテキストを考えていく

コアドメインはなんだろうというところから初めて、徐々に現在のサービス群が何を提供しているかなどを考えながら付け足していきました。

実際の作業はmiroで複数人で行っています。

f:id:sys1yagi:20201222174652j:plain
実際の図。めっちゃぼかしてます。

あんまり現実のシステムを意識せず、理想状態を考えるとスムーズに行くなぁという感想です。同時にあまりにギャップありすぎてちょっと引くみたいな時もあります。

コンテキスト境界と現実の乖離が分かってくる

コンテキストマップを書いていくと、実際のコンテキストとサービスが横断している場所が見えてきました。次の画像は症状チェッカーと医療機関向けプロダクトが連携する箇所ですが、複数のサービスが1つのコンテキストに対して同時に携わっていることがわかります。実際にこの部分は壊れやすく、慎重な変更が必要になってしまっています。

f:id:sys1yagi:20201222174932p:plain
複数のプロダクトが交差する場所

価値創出の単位と業務フロー

また、コンテキストマップを描いていく中で、1つの業務フローに対して、いくつかの独立したコンテキスト達が複数組み合わせられていることに気づきました。

f:id:sys1yagi:20201222180152p:plain
一つの業務フローに対して複数のコンテキストが組み合わさっている

それぞれのコンテキストは個別に価値を生み出せそうな単位でありますが、現状はプロダクトの特定の業務フローのなかに埋まっています。これらを価値創出の単位として切り出せそうです。

f:id:sys1yagi:20201222180600p:plain
それぞれのコンテキストが独立して価値を生み出す

価値創出の単位を自由に組み合わせることができるようになれば、考えてもみなかった、あるいは実現が難しいと思っていたプロダクトをどんどん作り出せるのではないか、と期待できます。

不確実性を内包するためのモジュラモノリスの考え方を取り入れる

コンテキストマップによって現在すでにインベストが高くなっている箇所の解消のためのアクションの洗い出しや、将来インベストが高くなると予見される箇所などの可視化ができました。不確実性が高い場所と低い場所が共存できるカタチを見つけるについてはまだまだこれからですが、価値創出の単位がそれぞれ確からしいかどうかを判断したり、新しい不確実性をどのように追加していくかについて、モジュラモノリスの考え方が役に立つのではないかと思っています。

www.infoq.com qiita.com

モジュラモノリスモノリスの中でモジュールによって境界を分離していくものです。すでにUbieは複数のサービスが分かれているので、本当のモジュラモノリスにしていくぞというのは現実的ではありません。しかし複数のコンテキストを持っていそうなサービスにおいて、モジュールによる分離をまずは行うというアプローチは非常にコスパが良いのかなと思っています*4

価値創出を掛け算可能にするシステムを作る

ここから先はまだこれからです。ということでおそらく大小様々な課題と直面していくと思いますが、一連の活動を価値創出を掛け算可能にするシステム の第1歩目と定義し、医療の領域の課題解決を加速していきたいと考えています*5。プロダクト開発もエンジニアリングも好きという方は是非一緒にやっていきませんか!?

note.com

待ってます。

*1:症状に基づいた疾患推測エンジンの研究が、現在のUbieのプロダクトの根幹となっています

*2:もちろん失敗してる場合も沢山あります!

*3:サービスの関連図に現れてないということはどこかのサービスが複数の関心事を取り扱っていることになりますが、まさにそうです!

*4:まだ何も試してないので本当に雰囲気で良さそうって思ってるだけです

*5:正直来年の今頃入社するメンバーがうらやましい!