ソフトウェア開発の不確実性と決断
ソフトウェア開発には大きな不確実性がつきものであることはすでに現代では広く知られている。
この不確実性とどのように向き合っていくか、ということも多く語られていて、いわゆるスクラム開発というフレームワークは、不確実性に対して「適応性」を高めていくために用いられるフレームワークだったりする。また、「不確実性の高い部分と低い部分があるなら、高い部分を先にやっつけてしまう」というようなテクニックも当然有用だろう。あるいは、高度な技術力のある人間の高度な設計力によって、不確実性を軽減するアーキテクチャを導入できることもある。
このように不確実性に立ち向かいコントロールしていくことが重要なのはいうまでもないけれど、一方で、不確実性のコーンを引用するまでもなく、結局のところ、リリースするまで不確実性は「なくならない」ということに眼を向ける必要も同時にあると思う。どれだけ適切に不確実性に立ち向かっても、必ず、どこかで「不確実性を不確実性のまま飲み込む必要」が出てくる。これはまさに判断と決断の話でいうところの「決断」のことだ(c.f. 判断と決断の違いと決断のコツ - そーだいなるらくがき帳 )。わたしはいろんなところで「適切な判断をしたい」と「不確実性がなくならない」の間でデッドロックになってしまう、というシチュエーションを結構多く見かけることがある。「不確実性が多いから、判断ができない」「決定がなされないから変数が増えてしまい不確実性がいつまでたっても小さくならない」というデッドロックだ。
このとき必要なのは結局「不確実性を不確実性として飲み込んで決断することで変数を減らしてものごとを前に進めること」だ。これは「十分に不確実性が少なくなった時点での判断」よりも失敗の可能性は当然高い。なので、決断したら「その決断を成功にするためにできること」に対しても努力しないといけない。このふたつを担う、というのは結構大変なことだし、「自分がそんな博打やっていいのかな」と思うことも多い。だけど、もし「あなたの現場」でその決断をするひとがおらず、「あなたは」決断をするべきだと考えているのであれば、多分それが「その場で」できるひとはあなたしかいない。あるいは、たまたま、その現場でのリーダーという立場があなたなのであれば、それは「あなたしかそれをやるひとがいない」のだから、腹をくくってやるしかない。そして、そういうことをやった場合にもし失敗しても、その失敗はあなたの経験となるので、あなたにとっては無駄にはならない。「けど事業や会社や仲間にとっては無駄になるじゃん」、という考え方は大変に正しいし、わたしもそれで足がすくんだり悲しくなったりすることが結構あるのだけれど、そういうときには同僚が以前いってくれた、「その場で、その決断をする人間、あるいは別の決断をする人間が他にいなかったのであれば、どういう結果になったとしてもそれがこの組織にとってのベストであって、なのであればそのベストが失敗したところでもう他の誰がやったところでダメってこと。"もっとうまくやるひと"が仮にどこか別の組織や別の世界にいたとしても、そのひとはいまここにいないのだから、あなたがベストなのだ」という言葉を思い出している。
#lacolacoユーザーの声 しんぺいの場合
TL; DR
lacolaco 1on1は、「課題の解き方を考えたいとき」以上に「課題を見定めたいとき」に有用
この記事は何?
この記事に対するアンサーソングです。
lacolacoさんとの関係
Classiで同僚として働いています。わたしはVPoTという立場であり、組織体制的にはlacolacoさんの1on1を私がする、というのが自然に見えるかもしれませんが、
- わたしは直接の部下を持っていないのでわたしがlacolacoさんをマネジメントしているわけではない
- あまりにlacolaco 1on1が有用
ということで、わたしが頼んで制度としての1on1というよりは野良1on1をしてもらっているという状態です。
lacolaco 1on1 ユーザーレビュー
VPoTを拝命してからは、id:Soudai さんとlacolacoさんによく1on1してもらっています。そーだいさんの1on1とlacolacoさんの1on1はどちらも大変有用ですが、かなり違った特徴があります。
そーだいさんの1on1は、どちらかというと、「導く」1on1と言っていいでしょう。課題があるときに、どうその課題に向き合えばいいのか迷ったときに、「こういうアプローチをしてみてはどうか」という助言や、その問題を解く際に役立つ考え方を助言してもらうことが多いです。以下のツイートなんかはまさにそーだいさんから「導かれて」わたしの判断軸として身についていったことだったりします。
判断の話で言うとぼくはそーだいさんがしてくれた「判断と決断は違う」という話がだいぶ実になっていて、「情報を集めれば理屈で答えが出せるのが判断、今は情報を集めることができない中で答えを出さないといけないのが決断、リーダーがやらなければならないのは決断」という話をかなり大事にしている
— しんぺいくんさん (@shinpei0213) 2021年12月10日
そーだいさんがぼくに教えてくれた二大大事なこと「判断と決断は違う」と「ロールバック可能なことはどんどん試せばいい、ロールバックが難しいことは慎重に」です
— しんぺいくんさん (@shinpei0213) 2021年12月10日
一方、lacolacoさんとの1on1は、導かれる、というよりも、探索的に進んでいくことが多いです。「それならこういうふうにしたらどうですか」だとか「それにはこういう考え方が効くと思います」という会話は比較的少なく(当然lacolacoさんは問題解決のエキスパートでもあるので、こういう会話がないわけではないですが)、「問い」の形で進んでいくことが多いです。だいたい「今のマインドシェアってどうなってます?」という質問から始まり、自分の脳を今占めている問題について私がつらつらと話し始める、というところから1on1が始まるのですが、本当にいいタイミングで「XXで困っている、と言ってるけど、それってなぜ困っているんですか? 問題視している理由は?」とか「Aという前提からBという結論が導かれているけど、その接続が自分にはよくわからなかったからもう少し言語化してみてほしい」という「合いの手」が入ります。この合いの手が本当に絶妙で、自分が無自覚に飛躍しているところや、無自覚にバイアスがかかっているところに「効き」ます。実際、lacolacoさんとの1on1を通して、「問いの立て方がシャープではなかったな」「本当に問うべきはこちらか」という理解ができたときには、その問いを解決することで大きな成果につながっている実感があります。間違えた問題を解いたところで、なにも解決しないですからね。
というわけで、lacolacoヘヴィユーザーの声としては、lacolaco壁打ちは「問題の解決ではなくて探索に効く」というおすすめの声をあげておきたいと思います。
もちろん、これはlacolacoさんが「しんぺいさん向け」に行なっている1on1であり、他の効力もきっと他のところで発揮しているのでしょう。そのあたりのレビューは他のlacolacoユーザーの声にお任せすることにします。
継続的に価値あるサービスを提供するために意思決定者が押さえておくべきコストの話
社内で書いた内容から、一般化できる話だけを抜き出して書いた記事です。
TL;DR
意思決定者は、
- 仕様が複雑になればなるだけ、指数関数的かつ継続的にコストがかかることを理解する必要がある。
- ユーザーの要求や利便性について優先順位をつける必要がある。
- それらを揃えた上で「いっちゃんいいバランスで顧客要望に応える」必要がある。
コストについて
サービスあるいは機能の一生
サービスあるいは機能は以下のライフサイクルを辿る
- 初回リリース以前
- 初回リリース以後、クローズ以前
- クローズ
実は一番コストがかかるのが「初回リリース以後、クローズ以前」の部分。なぜならサービスの一生のうちほとんどの時期がここなので……。
初回リリース以前にかかるコスト
- いわゆる「初期開発」が行われる。
- 当然、この時に仕様がシンプルであればあるだけ初期開発にかかるコストは低くなるし、仕様が複雑であればあるだけ初期開発にかかるコストは高くなる。
- このコストは線形に増えるわけではなく、指数関数的に増える
- 初期開発のコストは大きく分けて設計にかかるコスト、実装にかかるコスト、テストにかかるコストがある。
設計にかかるコスト
- 互いに関連する要素の数に対して、指数関数的にコストが上がるのがポイント。
- 要素が1つならば、一貫性を気にする必要はゼロ
- 要素がふたつならば、ふたつの間の一貫性を気にする必要がある
- みっつになったら、AとB、BとC、CとAの間の一貫性を気にする必要がある
- よっつになったら、いつつになったら、という感じで組み合わせ爆発が起こる
- 複数の主体(チームや企業)にまたがる設計が生じると爆発的にコストが上がる
- 異なる立場での優先順位などの調整、異なるポリシーのすり合わせなどが必要となるため
- 設計をなるべくシンプルにすることで仕様の複雑さによるコストを「軽減」することは可能だけど、取り返すことは不可能である
実装にかかるコスト
- ここは仕様の複雑さに対して線形にコストが上がることが多い
- ここだけしか見えていないことでのちのち爆発炎上する事案は世間にすごく多い
- 実装をなるべく綺麗にすることで、m仕様の複雑さ、設計の複雑さによるコストを「軽減」することは可能だけど、取り返すことは不可能である
テストにかかるコスト
- 設計と同じく、互いに関連する要素が増えれば指数関数的にコストが上がる
- なぜなら、考えるべきパターンが組み合わせ爆発を起こすので
初回リリース以後、クローズ以前にかかるコスト
- 大きく分けて、メンテナンスとサービス運用とサービス改善(追加開発)にかかるコストがある。
- 前述の通り、サービスの一生の中で一番長い時間留まる部分だし、一番コストがかかる部分である
- 後述するが、「仕様の複雑さ」がありとあらゆる変更にかかるコストの「ベースライン」を上げてくる。
- いちばん長い時間、一番コストがかかるところのベースラインをいかに上げないかを考えなければ競合に改善スピードがどんどん追い抜かれていく
メンテナンスにかかるコスト
- そのサービスが依存しているもの(DBなどのミドルウェア、ライブラリ、フレームワーク、言語など)は、日々アップデートされていく
- このアップデートについていかないとなにが起こるか
- セキュリティ上の問題が起こる(いっちゃんやばい)
- パフォーマンスが相対的に悪くなる(競合はもっといいバージョンを使っているぞ)
- サービス改善のスピードが相対的に悪くなる(競合はもっと使いやすいバージョンを使っているぞ)
- このアップデートについていかないとなにが起こるか
- このバージョンアップ作業には、「計画、実装、テスト」のコストがかかる
- 計画については、関連する要素の数に応じて指数関数的に計画が難しくなる。理由は初期開発と同じ。
- 実装についてはやるだけなので、仕様の大きさに対してかかるコストは大きくみれば線形である傾向がある。
- テストについては、関連する要素の数に応じて指数関数的にテストすべき内容が増える。理由は初期開発と同じ。
サービス運用にかかるコスト
- 問い合わせがあったら調査をする必要がある。
- ここはテストに似ていて、関連する要素の数に応じて、考慮すべきパターンが指数関数的に増える
- 障害があったらそれに対応する必要がある
- 障害が起こる可能性は、「障害が起こりうる点」がどれだけ多いかに関連する。障害点はコード量、ミドルウェアの数に応じて増えるし、要素間の関連の数に応じて増える。
- 障害から復旧するためには、原因調査が必要である。
- 原因調査の難易度は考慮すべきパターンの数に依存するので、関連する要素の数に応じて指数関数的に増える
サービス改善、追加開発にかかるコスト
- サービス改善や追加開発は、実は新規開発よりも難しい。なぜなら、新規開発の場合は「すでにある仕様」との一貫性をとる必要がないが、追加開発ではその必要があるからである。
- つまり、「現状の仕様の複雑さ」が「追加開発にかかるコストのベースライン」となる。
- このベースラインのコストはいままで見たきた通り、仕様の複雑さに対して線形ではなく指数関数的に増える
- このベースラインが上がっていくと、どんどん「借金で首が回らない」という状態になっていく
- 「既存のシステムが絡まっていて、手をつけられない、あるいは競合に対して大変動きが遅い」となっている仕組み、世の中にたくさんありますね。
- これは別にエンジニアが無能なわけではなくて既存のシステムが「足枷」になっているということ
クローズにかかるコスト
- サービスをバツっと閉じてしまうならコストはかからない
- しかし現実はそうではないことが多い
- 代替となる新機能や新サービスを作るならば、そのための新規開発のコストがかかる
- 代替となる別サービスに移行するならば、移行のための追加開発のコストがかかる
上述のコストを考えた上で意思決定する必要がある
- 仕様が複雑になればなるだけ、言い換えればつまり「関連する要素」が増えれば増えるだけ指数関数的にかつ継続的にコストがかかるようになっていく
- 「ユーザーの利便性のためならなんでもやる」も「コストがかかるから仕様をシンプルにすることだけ考える」も意思決定ではない
- 「ユーザーの利便性」と「継続的にかかるコスト」を天秤にかけて、「じゃあどこがバランスするか」を決断するのが意思決定である。
- エンジニア的観点では、「ユーザーの利便性や要求」について理解をしようとする必要がある。その上で、なるべく各要素の関連を少なくするようなシンプルな仕様、実装で、ビジネスに求められるラインを提案し、実現するために知恵を絞るべきである。だし、自分が意思決定者でないのであれば、その仕様にすることでなぜ将来にわたるコストが低いのかを意思決定者に説明する必要がある。
- ビジネス的観点では、エンジニア的観点から導かれた「将来にわたるコスト」について理解をする必要がある。また、「なにが本当に必要なもので、なにを足すと"将来の足枷"が増えるのか」よく理解した上でユーザーの利便性や要求について優先順位を明確にする必要がある。
- 良い意思決定は、このふたつ両方が理解されて初めてなされる
奥田民生『たばこのみ』のコード進行が不思議
奥田民生の名曲のひとつに『たばこのみ』という曲がある。サイケな音像のギターがリズムを立てて、まるまるとした音質のベースが縦横無尽に駆け回り、たぶんメロトロンかな? 鍵盤がちょっとドリーミーな雰囲気を与えて、ドラムのフィルインはちょっとリンゴ・スターっぽい訛りかたをしている、中期ビートルズに多大なリスペクトを払ったであろう楽曲だ。
しかしこの曲、コード進行もなんだか変だ。ジョン・レノンもこういう変なコード進行をよくするけれど、それにしてもどう解釈すればいいんだろう?
楽曲はGで始まる。最初はなんてことはない、普通にキー:Gメジャーの楽曲として解釈してまったく問題ない感じで始まるのだけれど、歌い出しの「だれがなんと言おうとたばこを愛している」の最後の「る」でいきなりm3rdの音がでてきて、コードもGmになる。いきなりIm? という感じだ。つづいて「それはもうナイスな」でコードはCにいく。キー:Gメジャーとしてとらえたらこれはそんなに変ではない。そこから一瞬コードはCmに。これもGメジャーで捉えたらサブドミナントマイナーなのでおかしくない。が、次にF7 -> B♭と進むので、やはりこれをGメジャーとしてとらえるのはちょっと無理があるだろう。
ところで、この Cm -> F7 -> B♭ はよくみるとキー:B♭におけるIIm -> V -> I となっている。メロディもここで解決するような動きをしているので、キーB♭としてとらえてみるとどうだろうか? GはVIのメジャー、Cはドッペルドミナントであると解釈することができる。こっちのほうが自然だと思う。しかし当然VIメジャーはダイアトニックコードではなくて、「曲のド頭にノンダイアトニックコード、しかも3rdをメジャーにしたもの」を持ってくるのはかなり大胆な発想がないとできない気がする。
また、曲の最後は「G7 C7」の繰り返しになっていて、これをキー:B♭で解釈するのもかなり厳しいものがある気がする。
そう考えると、この曲はたぶん「キー:G」で始まって、そのあといきなり突拍子もなく「同主調であるGm、あるいはその平行調であるB♭に転調している」と捉えるのが自然なんじゃないだろうか。出てくるコードはだいたいキー:Gとして捉えるかキー:B♭として捉えると違和感なく解釈できるようになっているんだけど、そう捉えると今度は「同主調(とその平行調)をフラフラといったりきたりしている」という感じになって、この「落ち着きどころがよくわからない感じ」がこの曲の独特の雰囲気に一役かっている、という感じだろうか。この、同主調をふらふらといったりきたりしていると捉えられるようなコード進行はジョン・レノンもよくやる気がする。そのあたりもやはり中期ビートルズリスペクトなんだろうな。
正直かなり不思議なコード進行で、ほんとうにこういう解釈の仕方でいいのかな? という感じはしている。識者がなんかいい解説してくれないかな。
#phpconfuk 2024に登壇してきました
スライドは以下にアップロードしてあります。
過去や未来を扱うのは難しい? 過去と未来に立ち向かうための勘所
過去や未来を扱うとき、ソフトウェア開発やサービス運用はその難易度が上がります。サービス運用をしていく中で困らないように、あるいは、今後もコードの改修を伴うサービス改善を行うときに困らないようにするためには、過去や未来を扱う際にどんなことを考えてソフトウェアを作っていくべきか、というテーマです。
ベテランからすると、ともすると「当たり前」のように感じる内容の気もしますが、その「当たり前」は意外と言語化されてきていない気もしており、知見の継承という観点でも、われわれ(とは?)のようなおじさん世代が「当たり前をちゃんと言語化していく」ことには意味があるだろう、という気持ちで登壇させていただきました。
発表の中で紹介した様々な事例はフィクションですが、我ながらかなりリアリティがあるというか、長くシステム開発運用に関わってきた方ならばどれも「あるある」という感じの事例だったのではないかと思っています。なるべく地に足のついた、それでいて特定のケースのみに役立つHowではなく(「それはHowなんよ」を発表の中に入れ損ねた!!)、初めて見るケースや問題に対しても応用が効くような内容にしたいと思っていましたが、それが成功しているかどうかはみなさまからのフィードバックを待ちたいと思います(ブログ書いてね!)。
発表を聴く立場としては、PHPでデータベースを作ってみたという発表を最も楽しんで聴かせていただきました。「だってたのしそうだから」で自分の興味のままに物を作り、動かして楽しむ、という、ソフトウェア作りの楽しさの根源みたいなものを思い出させてくれる素敵な発表だったと思います。わたしもなんか作りたくなった。
クロージングでも触れられていましたが、「カンファレンスがあることは当たり前ではない」というのは本当にその通りだと思っています。自分のスタンスの話をすると、技術コミュニティとの関わり方に悩んでいる、というのは以前のブログ記事でも一度書きましたが、いまだにその悩みはクリアになったわけではありません。ただ、それがクリアになっていないとはいえ、「カンファレンススタッフに対しては感謝の思いがある」ということと、「自分はやはり登壇して知見のサイクルを回すお手伝いをするという形での貢献をしたい」ということには間違いがないな、と改めて思いました。またなんらかのカンファレンスにこのような形で関われればと思いますので、その際はぜひ宜しくお願いします。
音楽と生成技術 2024春
生成技術の発展が本当に日進月歩ですごい。音楽に関しても、もう「なになに風の音楽を作って」というものについてはあと一歩で実用レベルだな、と思わせるところまで来ている。以前もこのブログで以下のように書いた。
「こんなイメージで、という指示」をインプットにして、アレンジ済みトラックを出力するような仕事、あるいは「こういう用途で使います」「こういうイメージで」をインプットに、BGMを出力するような仕事は、「よほどのこだわりがある場合」を除いて、生成AIによって早晩奪われていくだろうと思っている。
生成AIによって、演奏の仕事が置き換えられていく可能性は低いと思う。が…… - 猫型の蓄音機は 1 分間に 45 回にゃあと鳴く
なんならLogic11の新しい機能のSessionPlayerなんかはもう「アレンジ済みの演奏を出力する」「ベーシストとして楽曲制作のお手伝いをする」みたいな私の仕事を一部置き換えてしまったと言っていいのではないかと思う。
この流れは多分止まらなくて、思ったよりも早く「劇伴」とかBGMの仕事の総量は減っていきそうだ(全てが置き換えられる、ということもまた起こらないのだろうと思うが)。イラストの世界ではすでに、「文章を売っている」「音声を売っている」みたいなタイプの個人制作の作品におけるイメージ画像(イメージ画像、という言葉を使うときいつも、「イメージイメージ……」と思って違和感を得るんだけど他にいい言い換えをしらない)や挿絵などが、生成技術によって生み出されたもので置き換えられつつあるが、それと同じことが多分あと一年かそこらで音楽でも起こると思う。
さて、ぼくはある意味では生成技術によって「金銭を得る手段」をひとつ潰された立場にあるわけだけれど、一方でこれらの生成技術に対して現在あまり嫌悪感を持っていない。それどころか、ちょっとワクワクすらしている。たぶんそれは、ぼくが音楽以外に生業を持っているからというのはあって、自分はあくまで「作りたいから音楽を作っている」という立場だからなのだと思う。音楽の仕事が奪われた(あるいは奪われる)とはいえ、それで生活に困るかといえばそうではない立場、言い換えれば、簡単に「趣味のひと」に戻れるという立場だ。
「趣味のひと」の立場から言えば、「音楽を作るための技術を磨くこと」そのものが楽しいので、別に生成技術がいかに「努力なし」でクオリティの高い成果物を出そうがあまり自分の楽しみとは関係ない(そもそも生成技術を使えば努力なしで良い出力が得られる、というのもぼくは疑問視しているが、それはまた別の話)。というか、「結果」よりも「過程」を楽しんでいるから趣味なわけで(結果を出さなければいけないならばそれはもうお仕事ですよ)、「結果だけ欲しいならばすっ飛ばしてもいいような過程を、自分の楽しみのためにわざわざやる」という酔狂なことをしている限り、生成技術によって自分の楽しみが奪われることはない。これはDTMの打ち込みによって「演奏しなくていい機会」が増えたのに「わざわざ演奏したがる(しかも素人なので打ち込みよりもなんなら下手)」という酔狂なひとがいまだにたくさんいることと相似な気がするし、あるいは買った方が安いしうまいし手間もかからないのに、わざわざ自分でお菓子を作る人がたくさんいるのとも相似かもしれない。趣味なんだからそれでいいんだよな。
雑文なのでなにか強く主張したいことがあるというわけではなくて、「生成技術がおもったよりも早くまともな音楽を作っていっているなあ」という感想と「それに伴って自分のスキルが思ったよりも早く相対的に金になりにくくなるな〜」という感想と、「とは言え趣味人としてはノーダメージだなあ」という感想を書いておきたかったので書いた。そしてぼくは今日も、趣味人として自分のバンドのレコーディングに赴くのであった。