エッセイ・ソフトウェア

見積もりはやはり嘘だ

この記事はClaudeによって英語原文から翻訳されたものです。

ホフスタッターの法則:物事はいつも予想より長くかかる。ホフスタッターの法則を考慮に入れたとしても、なお長くかかる。

―― ダグラス・ホフスタッター『ゲーデル、エッシャー、バッハ――あるいは不思議の環』

人が嘘をつく現場を見たければ、開発者にこう聞いてみるといい。「機能を作るのに、あるいはバグを直すのに、どれくらいかかりますか?」と。

「ウィジェットの出荷までどれくらいかかりますか?」と訊いたとき、返ってくる答えは、相手の経験の浅さや深さによって変わってくる。

ジュニア開発者: 今日中にウィジェットを終わらせます。

ミドル開発者: あのウィジェット、長くても三日で仕上げます。

シニア開発者: 仕様を先に固めてもらえて、想定外のトラブルがなければ、ウィジェットの出荷までは二日から一週間ほど見ています。

プログラマとしてのキャリアを始めたばかりの頃は、人を喜ばせたくてたまらない。自分の仕事について約束をしたいし、その約束を守りたい。生産的で、頼れる、給料に見合う人間だと見られたい。

そういう願望は、すぐに叩き出される。ソフトウェアは、多くの創造的な知的作業と同じく、スケジュールを予測することがそもそも不可能なものだ。

誰だって、自分の約束を破りたくはない。だから、約束自体をしなくなる。問い詰められれば、開発者は見積もりに余裕を盛り、曖昧な範囲を答え、あるいは嘘をつく。相手が聞きたい答えを返しておきながら、結局その仕事はかかるだけかかる。

開発者がそうするのは、訊いてくる側がソフトウェア開発についての根本的な事実を受け入れていないからだ――それは、どれくらいかかるかを正確に見積もるのは、極めて難しいということ。

見積もりが嘘である理由

人はどんな仕事の見積もりも下手だ。 未来の作業にかかる時間を予測するとき、人間には楽観バイアスが働く。これは計画錯誤と呼ばれている。

計画錯誤は、企業ブログの記事を書くことから、シドニーのオペラハウスを建設することまで、あらゆる場面に現れる。この記事を書くのに私は一時間と見積もったが、初稿が仕上がるのに一週間かかった。シドニーのオペラハウスは1963年に完成する予定だったが、規模を縮小したものが完成したのは十年後だった。

計画錯誤の理由については、いくつかの仮説がある。万事が計画通りに進む「ハッピーパス」を、より厄介な可能性よりも高く見積もってしまうのかもしれない。過去のパフォーマンスを実際より良く記憶していて、うまくいった仕事だけを基準にして次を予測しているのかもしれない。場合によっては、見積もりが低いほど受注しやすく、承認も得やすいと無意識のうちに感じているため、事実を歪めているのかもしれない。

困ったことに、計画錯誤について知っているだけでは、それを克服することはできない。他のあらゆる認知バイアスと同じで、対抗するためには具体的な手段が必要だ。

「完成」の定義は、人によって違う。要件定義の粒度をどれだけ細かくしても、あなたが欲しかったものと、開発者が作ったものとの間には、必ずズレが生じる。それがソフトウェア開発という営みの本質だ。ソフトウェアを正確に記述できる唯一の仕様書は、ソフトウェアそのものである。

仮にジェーンという開発者がいて、彼女がソフトウェアの作業をすべて完璧に見積もれるとしよう。彼女が見積もりを出し、それを期限内に本番にデプロイし、「完成」と宣言したあと、何が起こるか。あなたは本番環境を触り、欲しかったものと彼女が作ったものとの違いをいくつも見つける。

あなたの視点からすれば、その変更点を反映するまで機能は「完成」していない(それが最初から欲しかったものなのだから)。修正にかかる作業は、当然、最初の見積もりに含まれていなければならない。

ジェーンの視点からすれば、彼女が出した見積もりは、彼女が理解した範囲の作業についてのものであり、その範囲は期限内に出荷されている。あなたが要求している変更は別の作業であり、見積もりも別に出すべきものだ。

ここに本質的な食い違いがある。これを直接解消する方法は、あまりない。開発者の頭の中で見積もりが完璧に正しいとしても、あなたから見れば嘘なのだ。

ソフトウェアの実装作業は、本質的に予測できない。クライアントが何を欲しているかを正確に理解できたとしても、それを作るのにかかる時間を予測するのは極めて難しい。ソフトウェアは、人類が理解し操作しようとしてきた中で、もっとも複雑なシステムだからだ。

今日のコンピュータは非常に複雑で、それを設計し製造するためには、わずかに複雑さの劣る別のコンピュータが必要となる。そしてその設計と製造に使われるコンピュータもまた複雑で、さらに複雑さの劣る別のコンピュータがなければ作れない。ゼロから組み上げることが可能なレベルまで遡るには、こうしたループを何回も辿らなければならない。

現代の機器がどのように動き、どのように作られているかを理解しはじめると、その奥底の深さに眩暈を覚えずにはいられないし、マーフィーの法則に従えばこれは動かないはずなのに動いていることに、畏怖の念を抱かずにはいられない。

現代のソフトウェアシステム同士の相互作用は、人工物のそれよりも、生物のそれに近いとさえ言える。あまりに複雑すぎて、その全体像を一人の人間が把握できるものではない。

これがあなたとあなたのプロジェクトにとって意味するのは、開発者にとっても、ある作業がどれくらいかかるかという直感は、せいぜい当てずっぽうにすぎないということだ。たまに運がよく、複雑な機能が予想より早く終わることもある。だがほとんどの場合は運悪く、簡単に見えた変更が、複雑さの渦を解きほぐすところから始めなければならないことに気づかされる。

ソフトウェアはこの先も単純になりそうにない。だからこの問題も、すぐにはなくならない。

見積もりのリスクは、つねにあなたのもの

ソフトウェアを世に出すという目的があるとき、選択肢はいくつかある。自分で袖をまくって作るのもいい。フリーランスや社員を雇って代わりに作らせるのもいい。開発会社と組んで、プロセス全体を案内してもらいながら作ってもらうのもいい。

どの場合であっても、関係をどう組み立てたかにかかわらず、プロジェクトが予算をオーバーするリスクは、つねにあなたが負っている。エージェンシーが何を約束しようと、開発者が何を言おうと、予算超過のリスクはあなたのものだ。

なぜなら、どのような契約が結ばれていようと、ソフトウェアはかかるだけかかるし、それに支払うのはあなただからだ。開発者を雇うときには――それが社員でもフリーランスでも代理店経由でも――あなたは時間と原材料に対して支払う。同じ時間と原材料からは、同じソフトウェアが出てくる。そしてそのソフトウェアがどういうものかは、出荷されたあとにしかわからない。

解決策はない

ここまで読んでくれた方には、ソフトウェアの見積もりがいかに難しいかという話をしてきた。

残念ながら、私にこの問題を解く良い答えはない。そもそも答えはないのだと思っている。私たちは儀式めいた手順を編み出して問題の周囲を踊ってみせるが、本当のところは、見積もりが手に負えないという現実とどうにか折り合いをつけようとしているにすぎない。ソフトウェアの納品責任を負う非開発者がこの現実を受け入れられないとき、私たちは彼らの不満に対して、プロセスや曖昧さや、最終的には嘘で応える。

ここまで、ソフトウェアの見積もりが難しい理由として、次の三つを挙げた。

  • 私たちは皆、計画錯誤に陥りやすい。
  • クライアントが欲しいものと、開発者がクライアントが欲しいと信じているものとの間にズレがある。
  • ソフトウェアは怪物のように複雑である。

そして、決まった予算の中でソフトウェアを納品する責任を負っているのがあなたであるなら、その予算が要件を満たすソフトウェアになるかどうかのリスクは、あなただけが背負うものだとも言った。

私たちはこのことを必ずしも口に出してクライアントに説明するわけではないが、経験を積んだ開発者にとってはこれが真実だと知っている。私たちは過去に不正確な見積もりで職業上の信用を試され、二度と同じことを繰り返さないと学んでいる。

それと同時に、私たちは自分を雇ってくれる人たちに成功してほしい。これは、仕事のできるプロでありたいという真面目な動機からでもあるし、純粋な欲からでもある――誰もソフトウェアを作りたがらなければ、私たちには仕事が来ない。雇用主であれ、フリーランスのクライアントであれ、コントリビュートしているオープンソースのプロジェクトであれ、同じことだ。

そこで私たちは、予算とスケジュールのリスクを完全になくすのではなく、リスクを下げ、管理するための手段を取る。時を経るうちに、そのための習慣がいくつか身についていく。

理不尽なまでにスコープを削る。私たちはクライアントと一緒に、機能を絶対の最小まで削っていく。機能が単純になるほど、誤解しうる要件は減り、出荷は速くなる。

要件を、個別に納品し検証できる最小単位まで分解する。機能の塊が小さいほど、実装も、テストも、改善のサイクルも、すべて速くなる。

早く、頻繁に納品する。大きなマイルストーンで機能をまとめて出すかわりに、進行中の作業をできるだけ早く出していく。こうすると、私たちが作るものとクライアントが望むものとのズレを、プロセスの早い段階で見つけることができる。理解のズレを早く把握できるほど、要件を満たすソフトウェアに早く近づける。

提案されている解決策よりも、より単純な代替案を提示する。クライアントが何かの機能を求めてきたとき、その背後にある本当の要求を時間をかけて聞き出すと、八割を満たしながらスケジュールのリスクを大幅に下げる別の解を提案できることが多い。

できるだけ詳細に計画する。一連の機能の要件が固まったあとで、可能な限り詳細に計画を立てると、実装を長引かせかねない厄介事を事前に見つけられる。

見積もりを水増しする。経験を積んだ開発者は、自分が見積もりを下手にするとわかっているから、見積もりを求められたら十分な余裕を持たせる。クライアント側としては、フィードバックと反復の余地を見て、彼らの出してきた見積もりを倍にして考えるのがいい。

あなたのと同じようなソフトウェアを出荷したことのある開発者と組む。スケジュールのリスクの一部は、開発者が見たことのない問題に出会う可能性から来る。あなたの問題領域での経験がある開発者は、たぶんあなたが直面する問題の多くを既に見ている。だから、そういう開発者と組めばリスクは下がる。

あなたの問題領域でよく使われている、定評のあるツールを使う。あなたの問題に、たぶん最先端の技術は必要ない。実績ある技術を選ぶことで、新しすぎる道具では得られない既存のライブラリや知見の蓄積を利用できる。

納品後はできるだけ早くフィードバックを返す。クライアントは、新しく納品されたソフトウェアを試して、可能な限り早く開発者にフィードバックを返すべきだ。そうすれば開発者は反復の時間を多く取れ、クライアントが欲しいものに近づきやすくなる。

こうした習慣は、ソフトウェアプロジェクトの計画における不確実性を下げてくれるが、それを完全になくすことはできない。どれだけ良いチームを組み、どれだけ綿密に計画し、どれだけ早く納品し、どれだけ早くフィードバックを返したとしても、確実に言えるのはただ一つ――あなたのプロジェクトが計画通りに進むことはないということだ。