Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

2025年の振り返りと2026年の抱負

昨年の振り返りと抱負はこちら。技術書典への個人出展は2回やりましたし、マネジメントスキルの棚卸しや実行も1年間みっちりやりましたので、当初想定はやり切りました。

今年のトピックはだいたいこんなところ↓だと思うので、掘り下げていきます。

  1. 副業をやめた
  2. 執行役員(VPoT)になって成果を出した
  3. 自分の強みと無関心を見つめ直した
  4. 生成AIの使い方が板についてきた
  5. 子どもの親として色々考えた

副業をやめた

今年のはじめ、前職つながりでいただいていた副業をお断りすることにしました。不義理を働いてしまい、当時は結構落ち込んでました。いや業務委託なんてそんなもんでしょという話はあるんですが、それはそれ、これはこれというやつです。

辞めた理由は本業がめちゃくちゃ忙しくなったからで、それは次の理由によるものです。

執行役員(VPoT)になって成果を出した

1月からVPoTを拝命し、3月からVPoEを兼務しました。SREのマネジメントも引き続きやっていたし途中から責務も増えたので、実質4足のわらじを履いてました。

前回の振り返りで書いてた「マネジメントスキルの棚卸し」が必要になっていたのも、転職後に離れていた「マネジメントのマネジメント」を再開する必要があったからです。

自分がマネジメントのマネジメントに思うことは昨年「組織という仕組みで解決することの難しさ、あるいはマネジメントに超人を求めるのは間違っているだろうか」に書いた通りで、助けになるフレームワークやツールはあるものの結局は状況と組織に合わせて様子を見ながら試行錯誤するものであり、とにかくまぁ難しく複雑なものであると思っています。それを兼務なので、明らかにキャパシティを超えた挑戦でした。

とりあえずこの1年ではすべて理想通りにやりきることはできないと早々に諦め、VPoEなのに採用をリードしなかったり、VPoTなのに技術戦略を描かなかったりと、5年後の自分が見たら指さして笑うだろうなという感じの戦術を採りました。ただそのおかげで最も外してはならない権限委譲の実践によるスケールする組織を実現できました。組織は1年間で完成するものではないため引き続きケアは必要ですが、会社として事業戦略をクリアに描けるようになった遠因を作れたことは誇れます。

生成AIが手に馴染んできた

今年もXでは生成AIの話はほとんどしてませんでした。このスピードについていく心理的コストは払えないから、レイトマジョリティになって長いものに巻かれようというスタンスです。実際自分が役割を演じる上で重要なのは応用なので、そういった情報のキャッチアップは同僚に任せて、製品化された事例を主に追っていました。

プロダクトとしてはCursor, OpenAI, Anthropic, Perplexity, Slack AI, Notion AI, Dify に Vertex AIあたりを薄く広く触っていましたが、コーディングに常用しているのはGitHub Copilotです。個人的にいまのMicrosoftとGitHubを信頼しており、技術的には最先端ではないかもしれないが体験を統合させたプロダクトを提供してくれるだろうと期待していて、実際Agent HQは良いものだと思います。

自分もMacbook ProのMAXを個人端末として所有しているので手元で色々動かそうと思えばできるはずですが、今のところはGitHubのUIからCopilot使ったり、Codespacesを活用してそもそもコードのチェックアウトすら省いたりとできるだけクラウド側で完結させるようにしています。Codespacesを使い倒せば全部インターネットの向こう側で完結して便利そうなんですが、流石にランニングコスト高そうですね。

あとSRE業務への応用という観点では7月のSRE Nextで見たTopotalさんのデモが良かったのと、SRE自動化ハンドブックで紹介されていた業務自動化がいま想像できる理想だなと思っています。HoneycombとDevelocityのMCPサーバが実装されたようなので、来年色々試してみたいです。

2026年の抱負

子どもが学校でPython3をやっているので、共通の話題としてのPythonをしばらくやっていこうと思います。ひとまずpgzeroで壁打ちゲーム(pong)をフルスクラッチで書くところまで来ました。

またバイナリを作成・配布する基盤としてのRustも再入門が必要だと考えて、今週 rustup で環境のセットアップを終えました。作りたいCLIはまだ見つかってないんですが(ちょいちょい思いつくけどコレジャナイになりやすい) tokio くらいちゃんと使えるようになろうと思います。

2025年に読んでよかった本

前回に続いて、今年読んでよかったなと思った本をいくつか。

医療関係

病院という組織の動きと未来を知るうえで「病院経営の教科書」が良かったです。3版まででていて、定番として信頼されているのでしょうね。実際にはヒトが占めるウェイトがかなり大きいとので現地訪問必須とは思っているんですが、現地訪問時の観察眼や質問を研ぎ澄ませるためにもこういう知識は有効だろうと思いました。

エンジニアリングで地域医療を支えるうえでその構造を理解することが重要なのは疑いないことですが、「地域医療の経済学」は今ある構造や課題だけでなく解決の提案も含まれていて面白かったです。その解決が日本の未来かというとたぶん違うんだろうなぁと思いつつ、かかりつけ医の機能を日本の医療でどう実現していくか?は間違いなく今後のアツい課題のひとつだと思うので継続的に考えていきたいです。

自分には機序が明確な印象のある西洋医学に対して、東洋医学にはあんま根拠が明確でない印象があります。自分は昔読んだインタビューマンガの「絶望に効くクスリ」で東洋医学を研究してエビデンスを作っていく動きがあることは知っていたのですが、このブルーバックス「東洋医学はなぜ効くのか」を読むことでその精度がかなり高まっていて納得できる範囲がかなり広くなっていると感じました。 鍼も漢方も、ここまで判明させるのはかなり大変だったろうなと門外漢でも容易に想像できるところです。特に漢方についてはかなり体質によるという点と、生薬の流通・管理に課題があるとは個人的に感じているところなので、体内で作られる成分そのものの精製や関連する腸内菌とセットで服用できるような工夫が今後一般的になると良いなと思います。

その他

図書館で読んだ古めの本です。自分は社会課題解決をする破壊的イノベーションをもたらすスタートアップで働きたいと思っているヒトなのですが、この本を読んで事業そのものが社会課題解決になるスキームそのものがかなり新しいのかもしれないと思いました。というのもこれに掲載されているのは、従業員に対する福利厚生や売上を利用した寄付を用いて社会課題解決に繋げている話なんですよね。もちろんチョコレート製品という食品を通じて社会貢献していたことは想定されますが、カカオ生産に様々な問題があったことは知られているとおりなので、色々と考えさせられました。

「誰が書いたコードか当てまShow!!」出題者による解説

勤務先のブログで紹介されていますが、Kotlin Fest 2025で出題したクイズに向けてKotlinコードを書いていました。本記事では自分で自分のコードを解説してみます。企画のネタバレを含みますので、先に企画紹介記事を読んでいただければ幸いです。

ヒントは「メソッドチェーン」「Kotlinのプロ、じゃない」

まず自分のコードを再掲します。パッと見でメソッドチェーン風だということがわかり、リアクティブプログラミングの経験があるひとにはAっぽいなと伝わる雰囲気を醸し出しています。

fun solve(input: String): String {
    var prevScore: Int? = null
    var prevRank = 1
    return input.split("\n")
        .map { it.split(" ") }
        .groupBy({ it[0] }, { it[1].toInt() })
        .mapValues { it.value.sum() }
        .toList()
        .sortedWith(compareByDescending<Pair<String, Int>> { it.second }.thenBy { it.first })
        .mapIndexed { index, (name, score) ->
            val rank = if (prevScore == null || prevScore > score) {
                index + 1
            } else {
                prevRank
            }

            (rank to "$name $score").also {
                prevScore = score
                prevRank = rank
            }
        }.takeWhile { it.first <= 3 }
        .joinToString("\n") {
            "${it.first}. ${it.second}"
        }
}

ひとつずつ見ていきましょう。まず目につくのが変数名です:

fun solve(input: String): String {
    var prevScore: Int? = null
    var prevRank = 1

prev は previous の短縮形です。このくらいなら短縮せずに previousScore としたほうが良いかもしれませんね。このくらいの変数なら特にコメントで意図を説明する必要はないかなと思って、ドキュメンテーションコメントは何も書いていませんでした。

なおBのコードでは previous ではなく last が使われており、どちらが良い命名なのかを議論するのも面白そうです。

さて次の行が大きなヒントになっています:

    return input.split("\n")

これとてもJavaっぽい書き方で、実際他の方の回答だと lineSequence() が使われているんですよね。ここで少なくとも「AはKotlinのプロであるタケハタのコードじゃないな」とバレるようになっています。なぜ lineSequence() を使わなかったのかって?だって、知 ら な い そ ん な 函 数!勉強になりました。

なおここで「OSがCRLFのような他の改行コードで動いてたらどうするんだ」ってツッコミは可能なんですが、この手の出題でそこが問題になることはないだろうと判断しました。厳密には System.lineSeparator() あたりを参照したほうが良いですね。

ちなみにJavaで似たような問題を解くと必ずと言っていいほど Scanner が出てくるんですが、さすがKotlin、流れるように処理を書き下せました。便利。

さて次のコードです:

        .map { it.split(" ") }
        .groupBy({ it[0] }, { it[1].toInt() })
        .mapValues { it.value.sum() }
        .toList()
        .sortedWith(compareByDescending<Pair<String, Int>> { it.second }.thenBy { it.first })

ここはまぁ、普通ですね。 Pair を引き回すと可読性が落ちるので、Dのようにクラスを定義して使うのも良さそうですが、今回はまぁいいでしょという気持ちになりました。今見返すと、 .groupBy({ it[0] }, { it[1].toInt() }) がだいぶ厳しいか。

あと compareByDescending() については、3分くらい「GuavaならOrderingなんだけどな〜」って検索してました。無事に便利函数が見つかって良かったです。

さて次は誰からも突っ込まれなかったコードです:

            (rank to "$name $score").also {
                prevScore = score
                prevRank = rank
            }

この also の使い方、だいぶ独特な感じに仕上げたつもりなんですが、見事にスルーされました。クリーンアップ処理を他のコードと違う場所にまとめて書ける、かつ finally と比較したときに例外の発生を想定してないことを伝えられる、ということでわりと悪くない書き方だと思うんですけどね。

最後はこのコードです:

        }.takeWhile { it.first <= 3 }
        .joinToString("\n") {
            "${it.first}. ${it.second}"
        }
}

お題を見たときに takeWhile() が出てくることは決めていました。一番最初に書けたコードだとも言えますね。あとは特に変わったところはなく、普通に joinToString() して終わりです。

他の人のコードへのツッコミどころ

ということで、以上で出題者による解説でした。楽しんでいただけたでしょうか。

なお他の人のコードにもツッコミどころというか、個性を感じるところは多々あります。ぜひ皆さんも考えてみてください。私が思ったのは次のような感じでしたが、人によって意見は異なると思いますので、ご参考まで:

  • 名前つき引数、いい。わかりやすい。IDEAで書いてるとなかなか気付けない気配りポイント。印刷前提だったので、自分も書いたほうが良かった。
  • String.split(String) は正規表現のコンパイルが走る可能性があるので、ループ内では呼ばないクセをつけたほうが良いかも
  • return@foobar は可読性が落ちるので、個人的には避けたい
  • tailrec すごくいい
  • コメントがいちいち意味ない!(たぶんツッコミ待ちなんだけど気になる)
  • is-a と has-a は違うんですよ!(たぶんツッコミ待ちなんだけど気になる)
  • 函数の引数の型はできるだけ抽象に寄せたいなぁ、なんで HashMap なんだっけ……(たぶんツッコミ待ちなんだけど気になる)

エンジニアに必要な「根拠のない自信」と、挑戦を支えるマネジメント

自分は以前、意思決定というのは「腹をくくる」「清水の舞台から飛び降りる」のように不可逆的かつ一定のダメージを覚悟する・リスクを負う行為だと思っていました。そして意思決定が関わる戦略が長期的であればあるほど、情報を集めても考えを深めても不確実性を下げることはほぼできませんから、意思決定の難度も高くなっていきます。この長期的な意思決定の代表例が企業の経営戦略でありスタートアップの企業理念なので、自分は企業経営に対して強い苦手意識を持っています。不可逆なリスクを負うには覚悟が必要で、その覚悟はどっから持ってくるんだ?というのが未解決問題だったわけです。

ただ最近、不可逆的にリスクを取りに行くだけが経営ではないというか、もうちょっと違う解釈への投影もできるんだなと思ったので、ちょっと書いておきます。

ビジョンは未来予測じゃない

我々はどのような企業になる、弊社の製品はどのような課題を解決する……といったビジョンの策定と発信はマネジメントの大きな仕事です。個人的には創業経営者の仕事はほとんどこれだと思っています。ビジョンに共感する人材を集めて目標をつっこむとアウトカムが生産される、それがスタートアップというやつでしょう。

このビジョンはもちろん想像可能・達成可能なものである必要はありますが、別にそれは「腹をくくる」ようなものである必要はない……というと語弊があるんですよね。当人は腹をくくって強いリーダーシップを発揮するべきですし、考え抜かれたメッセージと行動を通じて課題を実際に個人として組織として解決しなければなりませんので、腹はくくるべきです。投資家が投資先を選ぶうえで必ず見るものとして創業経営者の人柄が挙げられるようですが、それには腹をくくれるか、ビジョンを誰よりも信じて実行に突っ込める人物かを見ている側面は間違いなくあるでしょう。

自分が言いたいのは、この意思決定を100%実現可能だと信じることは重要だが、この意思決定した内容が100%実現されることはそんなに問題ではないということです。自分はここを混同していたのですが、世の中を見るとこうしたビジョンを途中で変えたり、実現する前に退場したりという結果に至った経営は多数あります。 わかりやすいところではGoogleのビジョンでは2000年代に one-click という単語を使っていましたが、今は使っていません。実際音声入力やマルチタッチスクリーンが当たり前になってきた現在において one-click と言っていたら、違和感が強いでしょう(当時もキーボードで全部やる人はいましたが、ここではクリックしない調べ物がより一般ユーザに浸透したと考えます)。しかしこのビジョンの変更について、one-clickだと言っていたじゃないか!と怒るような人は投資家にもいないんじゃないかと思うんですよね*1。クリックが主要なインタラクションではなくなる未来を読めなかったことや、20年使えるビジョンを提示できなかったことは問題ではないわけです。

結局重要なのはビジョンを出して実行することを通じて、従業員や顧客、市場といったものを動かしていくことです。one-clickという言葉を通じて強いシンプルさへのこだわりだとかユーザインタフェースの削ぎ落としだとか、そういったものの重要性を強く示して世界に働きかけることが重要だったわけです。だから今までの自分が「one-clickでできると思うけど、万が一できなかったらどうしよう」みたいな心配をして苦手意識を持っていたのはちょっとズレていたなと思います。

根拠のない自信の効用

自分が打ち立てたビジョンを信じられるのは、決して楽観的だからではないと思っています。まぁそういう人もいるでしょうが、どちらかというとまぁなんとかできるやろ的な根拠のない自信が多いんじゃないかと思うんですよね。そして根拠のない自信を持つことはシニアエンジニア、というか人を巻き込んで動いていく開発者には結構大事なんだなと思います。

根拠のない自信というと深く考えないことや痛みを気にしないことのような「鈍感力」のイメージもあると思いますが、自分が今回考えているのは「全く同じじゃないけど、似たようなことは経験してきた」「失敗しそうなポイントをざっと洗って、あらかじめ対処を考えられた」という、確実ではないけど一定の工夫はした、でも根拠と言うには薄くないか?みたいなそういうやつです。経験者の肌感とか、職人の感覚とか、そういうやつです。テスト駆動開発がすべてのバグを防ぐわけじゃないけど、前に進む自信をくれるのと似ているでしょうか。

一応テクニックとして「失敗してもダメージを許容できるようにする」、つまり撤退条件をあらかじめ定めるなどのコンティンジェンシープランの検討は使えます。使えるし、使うんですが、コンティンジェンシープランは次善の策であって本丸の確度を上げるものではないので、自分で打ち立てたビジョンを頭から信じる根拠にはならないと思うんですよね。のでテクニックとしてつくるコンティンジェンシープランの向こう側に、マインドとしての「まぁなんとかできるやろ」的な根拠のない自信は一定必要になるはずです。そして「根拠がない」ことを気にしすぎないでまず一歩踏み出すことが必要なんだと思います。

生存バイアスを作ればいいんだよ、というアドバイスをしないために

この根拠のない自信は理詰めでは身につきません。ではどうするのか?一番シンプルな答えは「とりあえずやってみて、転んだらそこから学べばいい」というものです。確かにこれは短期的には有効で、コードを書いて壊して直して覚えるような開発者の学び方とも相性がいい。

ただ、この考え方には落とし穴があります。生き残った人だけが「転んで学んだ」と語れるのであって、再起不能になるケースも多いのです。これがいわゆる生存バイアスというやつですが、ビジネスや組織運営では持続可能な方法が求められることから、「千尋の谷に突き落とす」ようなコミュニケーションは避けるべきです。

levtech.jp

だからこそ大事なのは、「安全に転べる環境を用意する」ことです。歴史から学ぶのが理想ですが、それが難しいときには上司や仲間とのコミュニケーションでセーフティネットを作る。例えば「まず1週間自由にやってみて、うまくいかなければこのプランに切り替える」といった撤退条件を決める。「失敗したら一緒に謝りに行こう」と保証する。そうすることで挑戦のリスクを許容でき、持続可能に第一歩を踏み出せるのだと思います。

blog.kengo-toda.jp

こうしたセーフティネットと合わせてもうひとつ大切なのが、周囲からのフィードバックによる“外付けの自信”です。根拠のない自信を持たない部下は、新しい一歩を踏み出しにくい状況にあるかもしれません。その場合は「君ならできると思うよ、だってあのときもああやって解決できたじゃん」などと、普段見ているからこそできるフィードバックを通じて背中を押しましょう。

根拠のない自信が自分で作れないなら、まぁアイツが言ってたからやってみるか……という外付けの自信を持たせてあげる。それで第一歩を踏み出せたらしめたものでしょう。

まとめ:リスクはゼロにできないから、根拠のない自信をうまく使う

リスクをゼロにすることは必要は多くの場合不可能ですし、不要です。企業経営のような難しい意思決定であっても、リスクをゼロにすることではなく行動を通じて課題解決を個人として組織として前に進めることが求められます。これは楽観的になってリスクを軽視しろという意味ではなく、自分ならなんとかできるだろうという根拠のない自信をうまく使うことが大切だという意味です。

もちろんリスクを管理するために、コンティンジェンシープランを定めたりダメージコントロールしたりすることは必要です。これらが自分でできない部下に対しては、上司としてこれを助けることが欠かせないでしょう。加えて根拠のない自信を外付けで持たせてあげることで、リスクを伴う挑戦に一歩踏み出せるように支援できると理想的だなと思いました。

*1:don't be evil の方は知らん

医療向け基幹システムを提供するスタートアップに入社して3年経った

医療向け基幹システムを提供するスタートアップに入社して丸3年経ちました。入社した目的はどの程度達成されたのか、今後どうしていくのかをまとめておきます。

入社した目的の振り返り

入社エントリに書いてるのですが、今回の入社には大きく分けて3つの目的がありました:

  1. 顧客と開発現場から学び、製品とチームを継続的に改善する
  2. 製品を通じて社会の課題を解決する
  3. ドメインの課題を解決する手段とプロセスを理解する

リーンに社会課題を解決するワザを研ぎ澄ませること、新しい技術で新しいアプローチを実現することで難しい社会的課題を解決すること、ドメインの課題を噛み砕いて実行可能な計画に落とし込むことがだいたいの理由というところです。そして前職の先輩方からさんざん聞いていた創業時のカオスを楽しみたかった、というのも大きかったですね。

リーンに社会課題を解決するという点で期待以上の動きができている

これは直近の記事でも公共政策について触れていましたが、リーンに社会課題を解決するための動きは当初の期待を超えた広がりを見せてくれています。スクラムをちゃんとやる、組織を大きくする、社会課題に真正面から取り組むといった機会が山のようにあります*1

医療という社会課題を選んだのも結果的に良かったと感じます。課題の大きさや市場としての複雑さはもちろんですが、2040年という節目を国が挙げていることもあり*2ここから15年間に何が問題になるかが考えやすく、少なくともマクロでは傾向や課題は掴みやすい領域です(と思っていたんだけどそうではない領域がたくさんある、という話が今読んでる本に書かれているようなので楽しみ)。

お金と生命を預かるシステムなので難しさは当然あるのですが、そこは前職から変わらずです。ただ要配慮個人情報を扱う一方で医療機関側に専門家が少ないという業界の課題については、事業での解決は難しいなと思っています。

ドメインの課題を解決する手段とプロセスに驚きはない

過去記事「組織という仕組みで解決することの難しさ、あるいはマネジメントに超人を求めるのは間違っているだろうか」で書いたことほぼそのままです。ドメインの課題を解決する手段にも、それを適用するプロセスにも、大きな驚きはありません。たぶんどこに行ってもこれは変わらないんだろうと思いますし、生成AI時代でも使えるスキルというのはこういうものを指すのかもしれません。

結局これをどこまで泥臭く、丁寧に、飽きずに情熱を持って徹底できるかどうかで課題が解決されるか決まります。内発的動機づけが重要な理由はだいたいこれだと思ってますし、創業経営者が重要な理由もだいたいこれだと思ってますし、社会課題解決の現場にしばしば継続可能性が怪しい活動が出てくるのもこれだと思ってます。だからこそ信念を持って継続できる、興味と関心を保ち続けられる社会課題を探すことが大切だと思いますし、中間管理職としては理想と継続可能性の両方に目を配らなければなりません。ロイヤリティとかエンゲージメントとかの横文字が出てくるのも、この複雑さに起因するのでしょう。

結論、やりたいことはだいたいできてる

連結ウン千人のメガベンチャーで社員番号1000番台だった3年前と比べて、100数人のスタートアップで社員番号20番台をやってる今のほうが事業と社会課題解決にまっすぐ向き合えている感覚があります。前職の先輩からさんざん聞かされていた体験をいままさにできていて、良かったと思います。

もちろん全て理想的に事が運んでいるわけではなく、色々とやりきれてない部分はまだ多々あるのですが、ひとつずつ解決していきます。

*1:具体的な内容については個人ブログの範囲を超えるので、勤務先のカンパニーデックに譲ります

*2:最近公開された医療提供体制等についてという資料がわかりやすい

ガバクラにおけるモダン化の定義について考えたこと

Twitter (X) でデジタル庁が出したnoteについての議論があり、様々な立場からの意見が集まっています。自分が感じたこと考えたことを残しておくと私自身の勉強になりそうなので、このブログでもちょっとまとめてみます。

一応コンテキストとして書いておくと、私はオンプレミスパッケージ製品の開発運用経験がある、クラウドネイティブSaaSのSRE 兼 セキュリティ担当です。

文脈

この情報の初出は今年の2月で、そういう意味では新しい情報ではないでしょう。ガバクラのコストの高さなどに注目が集まったタイミングで拡散しやすいnoteに情報が載った、という文脈が今回の注目量の背景にあると思います。

xtech.nikkei.com

note.com

最近の流れを汲めていない内容になっているのは、2月に決まっていた内容をほぼそのまま載せたから、と考えられそうです。

この定義の着眼点

モダン化に限らず情報システムの評価においては、様々な着眼点というか切り口が存在します。私はこの定義を見て、サービス運用者の目線で書かれているなと思いました。モダンではないサービスの運用現場で何が起こっているかと言うと、私の知る限りでは:

  • シングルテナントであり、テナント(顧客)ごとに環境が必要になる
  • テナントごとに環境が複数存在する(SAPで言う3-system landscape)
  • 環境ごとにサービスのバージョンが異なる
  • 更新にサービス停止が必要で、サービスを止められるタイミングは各テナントの都合で決まる
  • 環境(サーバ、クライアント共に)のスペックやOSは各テナントの都合で決まる
  • 実行ファイル(クライアント)がDBに直接接続しているので、DBスキーマ変更には全クライアントの停止と一括更新が必要になりがち
  • 複数のシステムが連携しており、ひとつの失敗が複数のシステムや業務に容易に波及する
  • ストレージやメモリなどの増設には顧客の対応と出費が必要で難度が高い
  • サーバが状態を持っており水平スケール(スケールアウト)できないので、垂直スケール(スケールアップ)が必要で高スペックマシンが必要になりがち
  • サーバは必ずしも設備が整ったサーバ室で実行されているわけではない
  • サーバのハードウェアは必ずしも冗長化や管理が行われてはいない
  • サービスの実行環境は顧客のものであり、アクセスや変更の手順が重い

たとえば100テナントそれぞれが3環境持っていたらそれだけ300環境になります。それらの環境には少なくても5年前のOSやハードウェアが含まれ、最新のライブラリやフレームワークが使えないことが前提になってきます。またサポートコストを減らすなどの理由から最古のメジャーバージョンのメンテナンスを停止する場合、100以上ある環境それぞれに対してマイグレーション手法やスケジュールを提案し、それぞれに対してオペレーションを適用する必要が出てきます。そんなコストはなかなか払えないので破壊的変更を入れる頻度を下げざるを得ず、魅力的な実装を届けるハードルが上がり、魅力のないマイナーバージョン更新は顧客を惹きつけないので最新のマイナーバージョンを使ってもらえず、在野に放たれるマイナーバージョンが更に増えていきます。

そんな状況でLog4Shellのような緊急度の高い脆弱性が報告されたらどうなるか。サポートしているすべてのマイナーバージョンに対してパッチをあてて動作確認をし、全環境に適用する……というコストが突発的に発生します。スモークテストやリグレッションテストは当然手動ですから、数日から数週間は非常に厳しい状況に陥るでしょう。このような想定があるため、サービスのサポート体制はどうしても厚くせざるを得ません。サポート体制が厚いということは、人件費が高いということです。自動化や効率化のためのITシステムなのに、その維持には人手が必要だという自己矛盾に陥りがちだと言えるでしょう。

ところでデジタル庁のnoteで挙げられているモダン化の利点は、先程挙げた運用現場の課題にそれぞれ対応しているように思われます:

現行のシステム モダン化されたシステム
ひとつのシステムの失敗が複数のシステムや業務に容易に波及する 複数のシステムが互いの処理完了を待たずに、それぞれが独立して処理を進める
クライアントがDBに直接接続しているので、DBスキーマ変更には全クライアントの停止と一括更新が必要になりがち フロントエンドとバックエンドを疎結合化することで、開発やデプロイを独立して実施
サーバが状態を持っているため高スペックマシンが必要になりがち ステートレスなアーキテクチャ&オートスケールを活用する
サービスの実行環境は顧客のものであり、アクセスや変更の手順が重い コンテナを活用する
人件費が高い 定型作業は手順書ではなくコード化する。コード化することで、自動化も容易になる。
サーバ実行環境の貧弱さ マネージドサービスの活用

これが私が「サービス運用者の目線によるモダン化」について書かれていると感じる理由です。noteではアーキテクチャと運用のモダン化だとしていますが、アーキテクチャも実行性能やランニングコストではなく「サービス運用の容易性」で選ばれているように感じます(後述しますが、夜間バッチを逐次処理に置き換えるとクラウドでもコストは高くなるため)。この理屈でいうとマルチテナントやclear change processについても言及があってしかるべきではありますが、さすがにすべてがマルチテナントになるべきとはまだ言いにくい*1のかもしれません。

この定義があると誰がどう嬉しいのか

デジタル庁によってこうした定義が提示されると、誰がどう嬉しいのでしょうか。もちろんサービス運用者には溜飲の下がる人が多いかもしれませんが、サービス運用者の意見だけでサービスの実態が変わることはまずありません。サービスのオーナーである企業経営者や、サービスを求める発注者にとっての利点があって、はじめてモダン化の重要性が認められモダン化が進むと思われます。

私はこのモダン化の定義によって、サービスの「モダン化度」を測るチェックリストを作れることが嬉しいのかなと思いました。いまサービスを運営している人が「モダン化にあたり、いまの課題はどこなのか」を専門家である第三者に教えてもらえる、モダン化のためのロードマップが引ける、そして顧客にその必要性を説明できるための素材になるのではないかなと。特にアーキテクチャの具体についてある程度触れることで、工数見積をやりやすくしているのではないかと思います。

これについては色々思うことも無いではないのですが、大号令によって市場を形成してITシステム開発の大勢を変えていく手段としてはアリなのかもしれません。私も情報セキュリティの専門家であることをお客様に伝えるとき、Log4Shell対応などで縦横無尽に活躍したかを語るよりはただひとこと「国家資格持ちです」と言う方が効果的だということを身にしみていますので、やっぱり「難しいのは重々承知してますが、デジタル庁が言ってますんで」のひとことが言えるだけで助かる現場があるんだろうなとは想像するところです。

個別の要素について

ここまで来ると個別の技術的記載に突っ込むのは野暮な気がしてきますが、自分自身他の方々のご意見を拝見してとても勉強になったので、気になったところをいくつか書いておきます。

非同期APIについて

要件について説明が不足していると感じます。このAPIは少なくとも次のような構成要素を持つはずです:

  1. APIを提供し、リクエストパラメータをジョブキューに積むサービス(FaaSっぽいがそれに限られない)
  2. ジョブキューから情報を取り出し、その内容を処理する冪等なサービス
  3. リクエストした内容がどこまで処理されたかを確認するためのAPIや画面

1つめはAPIの可用性を上げるために重要です。このAPIはリトライすればなんとかなる程度の短いMTTRを実現する必要があるため、できるだけマネージドサービスに寄せて実装を薄くすることが求められます。採番ルールなんて気にせず、粛々とUUIDを返すAPIであるべきです。またファイルや巨大なペイロードを処理するAPIの場合は、ファイルをアップロードする別のAPIが必要でしょう。

2つめは処理の本体です。冪等に実装する必要があり、多くの場合は既存コードの流用は難しいでしょう。モダン化のハードルのひとつだと言えそうです。

またAPIを使った人はその進捗や結果を確認したいことがほとんどなので、3つめも必要になります。数10分かかるとわかっている処理であれば、その進捗度を知りたいというニーズもあるでしょう。1と3はほとんどのサービスで共通の構造になりますが、2の持つ入力や出力の仕様が染み出してくるところがあるため、必ずしも共通基盤として括り出せるかはわかりません。

さてこのように構成要素を整理したうえで、モダン化システムはかならず非同期APIを使うべきか?と問えば、まぁNOでしょう。業務要件によっては同期的なAPIも必要になるからです。

単純に情報を取得するAPI、ファイルをアップロードするAPI、ロックを取得するAPI、ログインやログアウトをするAPIなどはイメージしやすいでしょうか。他にもリクエストパラメータが間違っていることを最初にvalidateして返したいAPIなんかは、システム間連携でも同期APIにしたいかもしれません。非同期APIの使い所として帳票を生成したり複数のシステムを活用するAPIなんかは思いつきましたが、すべてのAPIがそうあるべきとは思いませんでした。

フロントエンド・バックエンドアーキテクチャ

これ自分は「UIもビジネスロジックもひとつの実行ファイルで動かしているパターン」、まぁDelphiなんですけど、を想定して読みました。ので責務を分けるという言葉が単なるプログラミング言語的な意味での開発速度向上ではなく、サーバとクライアントとを独立して保守・更新できるという意味での開発速度向上だと理解しました。

ただ私とは異なる理解をしている方も多かったようなので、仮に私の理解が正しいのであれば、バックエンドが互換性の維持に気を使ったAPIを提供することの重要性や、現在のシステムとして想定しているものが何かをもう少し書くと良かったのかもしれません。

イベントドリブン処理

このあたりの話は、みずほ銀行さんの一件を思い出しますね。結論としては、夜間バッチでも良いと思います。

xtech.nikkei.com

オンライン処理、というか逐次処理にしてしまうと、単純に計算回数が増加します。たとえば勤怠管理のための打刻処理を考えます。その人の勤務時間は退勤時に計算できますので、オンライン処理の場合は退勤時に計算することになります。しかし運用によっては休憩時に退勤手続きを行うこともありますし、無事に退勤したがオンコールで呼び出されてしまった場合などは複数回の出勤・退勤を記録することになりますから、退勤時に走る勤務時間計算処理も2回3回と実行されます。オンライン処理よりも計算回数が増えるわけですね。

また非同期処理のためにメッセージキューやらDBのトリガーやらCloud Tasksやらを導入しますから、構成要素が増えて可用性が下がることも想像できます。たしかに夜間バッチには処理を相対的に計算機資源が空いている夜間にシフトするという物理資源節約の側面もあるのですが、コストや運用の観点からも合理的なことがあるわけです。

オートスケール

オートスケールが嬉しいかどうかは業界というかシステムによりそうです。どちらかといえばローリングアップデートができることの方が、clear change processやコンテナの活用などを念頭に置くと一般的に重要なように思われます。ただランニングコストを下げるという錦の御旗を考えると、スケールダウンできるように作りましょうと言いたいのは理解します。

定型作業を自動化する

これも要件というか「定型作業」の具体が読み手によって異なるために、混乱を生んでいるように思います。年1回しかデプロイしない想定ならデプロイ作業を自動化する意味は薄いですし、1次対応を外注している想定なら自動化によるコストダウンや確実さは重要でしょう。

おわりに

デジタル庁のモダン化の定義は運用現場の課題を解決する道筋を示すチェックリストとしての価値があるのではと感じました。一方で、同期API vs 非同期API、夜間バッチ vs イベントドリブンといった検討は、必ずしも全サービスにそのまま当てはまるわけではありません。各組織や案件ごとに業務要件やリスク許容度を見極め、バランスを取る必要がありそうです。そのバランスが難しいから、ひとまず道を示しているのかもしれませんが……。

今回の議論は私にとって、普段とは違うシステム構成について検討し、私達の今後のシステム開発を考える良いきっかけになりました。業務の効率化はITシステムの開発・保守・活用すべての局面において求められています。私としては、それぞれバランスよく検討できるだけの知恵と経験をつけていきたいです。

*1:厚生労働省は医療情報システムについてマルチテナントに踏み込んで発言をしているので、ドメイン固有の問題が知られている業界を念頭に置いているのだろうと思います

システムで世界を変えるにはシステムだけでは足りない話

現職でPodcastの放送が始まりまして、私と id:Songmu さんで開発しているプロダクトや開発技術や開発体制、課題などの開発の現状について話しました。

本ブログ読者の方には「音声よりも活字だぜ!」という私みたいな方も多いのではと思います。先日文字起こしも出ましたので、お好きな方をご覧いただけば幸いです。

システムでは手が届かない部分と、システムエンジニアのレゾンデートル

さてこのポッドキャストでもちょっと触れたんですが、ITシステムを通じたイノベーションに取り組んでいると「ITシステムでは手が届かない部分」がどうしても出てきます。というか届かない部分がほとんどです。

たとえば育児休業や児童手当の申請手続。こうした制度はそもそも設計が複雑で、自治体ごとにフォーマットが違ったり、必要書類がバラバラだったりと、利用者の立場からすれば非常に“遠い”存在でした。マイナポータルのようなオンライン窓口は以前からありましたが、書類は郵送、申請は窓口、必要情報は自分で調べてね、という状況が長く続いていました。情報システムの力があっても、制度や慣習という「壁の向こう側」に手が届かない例のひとつだと言えます。

もちろんITシステムが手を出せる領域はセンサーや自然言語処理といった技術革新によって徐々に増えてきていますし、まさに生成AIによるブレークスルーが激しいフィールドではあります。それでも人間社会の課題はまだまだシステムだけでは解決できない問題が数多く残ることは確信できます。我々がやりたいのはデータをこねくり回すことではなく、未だ社会に横たわる課題をぶっ壊すことなので、情報技術をどう使うと人間をより幸せに近づけられるかという「解決ではないモノを解決を生むために使う」ための工夫が必要です。そしてその工夫は「人間の不完全さ」にも「ITシステムの融通利かなさ」にも歩み寄れる、またITシステムでは手が届かない「壁の向こう側」に飛び込める、我々システムエンジニアから今後も出ていくことでしょう。

公共政策という粘り強い根本解決

で、最近感じているのはただ「壁の向こう側」に飛び込むだけではなく、壁を壊す、壁を作り直すといった「壁を動かす」アプローチがけっこう有効なのかもしれないということです。もちろん人間を完全な存在にするとかシステムに融通を利かせるとかそういう話ではなく、業界の慣習や人間社会の在り方といった活動を通じて壁に働きかけるという話です。

たとえば先ほどの例では、マイナポータルを通じて育児や介護に関する各種申請がオンラインで完結できる仕組みが整いつつあります。これは単に「ITシステムを作った」ではなく、各自治体が提出書式や確認プロセスをすり合わせ、法制度も見直されたからこそ成り立っているものです。技術は以前から存在していたけれど、それが“届く範囲”は制度設計によって大きく左右されます。これはまさに「壁を動かす」ような話です。

どの業界にもまず間違いなく、長い歴史と積み重ねられたシステムがあります。中には血で書かれたものもあり、軽い気持ちで変えるべきものではないことは明らかです。一方で情報技術や社会の変遷についてこれていないものも少なからずあり、それが「壁の向こう側」を作っている現実もあります。

そして個人的には意外だったこととして、国や関係機関はその問題を認めて行動しようとしています。前述の例もそうですし、医療関係で言えば省庁が医療情報システム向けに出しているガイドラインもシステムの流行り廃りを踏まえて更新されています。そして企業はデータや実際の運用を握っていますから、改善のモチベーションを持っている国や関係機関とのコミュニケーションを間違えなければ互助関係を構築できるはずなのです。前職でも国や大学とのコラボレーションはやっていましたが、今回より高い解像度で公共政策を見ることができて、とても勉強になっています。

人がソリューション、ITシステムはテコ

まとめると、壁の手前側にしか影響できないITシステムで壁の向こう側を巻き込んだ課題解決をすることはもともと困難ですが、イノベーションによる社会課題の解決にはこれが不可欠です。このときに壁を所与の条件として扱うのではなく解決可能なものとして捉えて協調することで、どのような業界でもより良い課題解決に繋がるのではと感じます。

そして壁を動かすのも壁の向こう側に飛び込むのも人なので、ITシステムはいかにそういった人を助けるかとか、壁を動かしたあとのワークフローをきちんと自動化するとか、そういう人間の在り方や能力を拡張する補助的な存在になっていくべきなんだろうなと思います。私もやはり仕様や機能について議論しがちなんですが、ITシステムが運用された結果として人がどう嬉しくなるのか、に改めて着目してITシステムの開発と運用に関わっていければと思います。