- 2016年、UberのBusiness Intelligence組織は、Uber Chinaとの競争に必要なデータを素早く扱うため、Rモデル実行ツールとExcel風UIを作ったが、Uber ChinaがDidiに売却されたことで、その機能はすぐに削除された
- R-Crusherは、データサイエンティストがVerticaのデータをノートPCに落として一晩中Rモデルを回していた不安定な流れを、APIベースの実行ツールに置き換えようとした社内システムだった
- 中国の都市チームは、ドライバーインセンティブ計算用のExcelファイルに慣れており、チームは数百〜数千の数式をJavaScriptへ直接移す代わりに、ブラウザでXLSと数式を実行するスプレッドシートエンジンを実装した
- 結果がExcelと微妙にずれた原因は、データサイエンティストが循環参照で線形回帰を行っていたことにあり、Excelのように収束するまで反復計算する方式に合わせた
- よくできたコードでも、解決しようとしていたビジネス上の問題が消えれば削除されうる。エンジニアリングの価値は、コードの寿命よりも問題解決に近い
Uber Chinaを支えた社内データツール
- 2016年にUberへ入社後、Crystal Ballチームで最初のフロントエンドエンジニアとして働くことになった
- チームは約4人規模で、ほとんどがバックエンド寄りだった
- 役割は、社内ツールを社員が実際に使えるUIにすることだった
- 当時、データサイエンティストはVerticaからデータをダウンロードし、複数のノートPCでRモデルを一晩中実行していた
- 朝になると、モデルが落ちなかったノートPCからだけ、その日に使えるかもしれないデータが得られた
- 失敗したノートPCでは必要なデータが作れず、それは会社の損失につながっていた
- チームが作っていたR-Crusherは、API呼び出しでコードを取得・実行し、結果ファイルを生成する、CIシステムに近いものだった
- R-CrusherのフロントエンドであるWesleyは、参加して数週間で最初のバージョンが準備できた
- その後6〜7か月にわたり、ユーザー向け機能、デバッグツール、フロントエンドチームの拡大が続いた
中国市場とドライバーインセンティブ計算
- 2016年のUber社内における大きな柱は、アプリの再実装/再設計とUber Chinaだった
- Crystal Ballチームの作業は、最終的にUber Chinaを支援するためのものだった
- R-Crusherは、Didiとの競争に必要なデータを確保するためのツールだった
- 中国はUberにとって重要な機会であり、必要なデータの一部はR-Crusherから生み出される予定だった
- 夏になって新たな要件が入ってきた
- 中国の配車需要予測データを一晩で生成するモデルがあった
- このデータは単体では有用ではなく、特定のExcelスプレッドシートのタブに入れると、ドライバーインセンティブを計算するインタラクティブなツールになった
- 財務責任者は、そのスプレッドシートをWesleyの中に組み込むよう求めた
- 都市チームはExcelしか使えないとして、「Excelのように作れ」と求めた
- エンジニアリング時間が足りないと説明したが、毎日このツールがなければ数百万ドルを失うという返答が返ってきた
ブラウザの中でExcelをまねる
- バックエンドでスプレッドシートをPythonやRコードへ移す時間はなく、フロントエンドで大量のJavaScriptを書く状況になった
- 以前Boxで作ったBox Sumsのプロトタイプが土台になった
- ReactベースのシンプルなスプレッドシートUIと基本的な数式エンジンを備えていた
- XLS/XLSXファイルをページにドロップすると、Nodeライブラリで内容を解析していた
- Uber向け実装では、Excelそのものではなく、Excelに近い動作を目標にした
- XLSファイルを入力として読む
- Excel数式をデータの上で実行する
- バックエンドは配車需要データを2次元配列で提供し、フロントエンドはそれを隠しタブのように数式エンジンへ渡す
- ユーザーが操作すべきセル以外は読み取り専用にした
- 核心は、数百〜数千の密な数式をJavaScriptへ直接翻訳しないことにあった
- 実装では、XLSファイルから数式を抽出し、必要な関数や構文を数式エンジンに追加した
-
Excel構文の拡張
- 絶対セル参照
- 他シートのセル参照
- 既存のBoxデモにはなかったスプレッドシート構文
ほぼ合っているのに間違っている数値と循環参照
- 最初の比較では、Excelと自作エンジンの結果がごくわずかに違っていた
- Excelの出力が
3.03 のとき、自作の出力は 3.01
- Excelの出力が
1.002 のとき、自作の出力は 1.000
- 大きく外れた値よりも、ほぼ正しい値のほうが厄介だった
- 単純なロジックバグより、微妙な計算差異の可能性が高かったためだ
- 単体テストは通っており、JavaScriptのdoubleとExcelの浮動小数点表現の違いも原因ではなかった
- データサイエンティストに尋ねたことで、原因が判明した
- スプレッドシートが循環参照を使って線形回帰を実行していた
- Excelは循環参照を常にエラーとして扱うわけではない
- 計算値が特定のepsilon以下の差に収束すれば、反復計算を止めて成功したものとして扱う
- 実装は、循環依存グラフを検出し、前回の計算値と新しい計算値の差を比較する方式に変わった
- 差が十分小さければ新しい値を使う
- そうでなければ反復回数を増やして計算を続ける
- しきい値となる反復回数は1000に設定した
- 変更には1日半ほどかかり、出力はExcelと一致した
- テストを書き、Wesleyに統合した
- プロジェクトは7月第2週に引き渡された
リリース後に出てきたセキュリティ要件と突然の廃棄
- ツールは実際にリリースされ、Uber Chinaの都市チームのメンバーがログインして使っていた
- 生成された数値はドライバーインセンティブに使われたと理解している
- 時期は7月第3週だった
- 7月最終週には、財務責任者がセルをクリックすると数式が見える点を問題視した
- Didiの社員がUber Chinaのインターンに応募してデータを抜き取る、という懸念が伝えられた
- この脅威モデルは事前にエンジニアリングチームへ共有されていなかった
- 数式を完全に保護するには計算をサーバー側へ移す必要があったが、それは依頼範囲の外だった
- ひとまずの修正は、UIでセルをクリックしても数式を見えなくする形で対応した
- 2016年8月第1週、Uber ChinaはDidiに売却された
- 多くの社員はまずニュース通知で知った
- 数時間後、社内メールで取引が告知された
- Uber Chinaがなくなると、そのUIはWesleyから削除された
- 二度と実行されないデータ処理のための特注UIだった
- ブラウザ内でExcelを再現してほしいという依頼は、その後なかった
コードの寿命よりも問題解決
- 当時、大きな喪失感や失望はなかった
- コードをGitHubで公開したいと思ったのが先で、その後は次の仕事へ進んだ
- 労力をかけたコードが短期間しか使われず消えたことに、少しの惜しさはあった
- エンジニアが書くコードは、いずれレガシーコードになる
- いつか誰かがそのコードを削除することに喜びを感じるかもしれない
- よくできたコードでも、長く維持されること自体が目的ではない
- エンジニアとして成長するとは、技術を使ってビジネス価値をよりよく生み出す方向と結びついている
- ビジネス価値は、技術的成果物、協業、メンタリング、チーム支援など、さまざまな形で生まれる
- Uber Chinaがなくなった後、このプロジェクトからさらに生み出せるビジネス価値は残っていなかった
- そのまま押し進めても、個人にも会社にも役立たなかった
- 「Cattle, not pets」というDevOpsの表現は、コードにも当てはまる
- コードは仕事を遂行するための手段であり、その仕事がもはや有用でなければ引退の準備ができているということだ
- 感情のせいでコードをペットのように扱うと、ビジネス理解とは逆方向に進んでしまう
廃棄されたプロジェクトが残す問い
- プロジェクトが削除されたからといって、すぐに失敗と見る必要はない
- 廃棄された仕事は、次の問いを残す
- プロジェクトの制約を満たせないものを作ったのか
- 求められたものは作ったが、そもそも依頼自体が間違っていたのか
- 核心の問題を誤って理解していたのか
- 求められた解決策は、実際の最終利用者のニーズを満たしていたのか
- ステークホルダーに尋ねていない質問があったのか
- 期待値が不正確または曖昧だったのか
- 引き渡しただけの堅牢性が本当に必要だったのか
- もっと単純、あるいはそれほど賢くない解決策で十分だったのか
- 成功基準を誤って設定していたのか
- 「依頼されたものを作る」以外に成功基準はあったのか
- プロジェクト終了を失敗としてしか見なければ、非技術的な問題がどこで噛み合わなかったのかを学ぶ機会を失う
- 精巧に作った部品でも、より大きなシステムの中で滑らかに機能しなければ、取り除かれることがある
1件のコメント
Hacker News のコメント
最高の引用はこれだった。「Didiで働いている人たちがUber Chinaのインターンに応募して、こちらのデータを持ち出している。数式を見せるわけにはいかない。そうしたら、われわれがやっていることをそのままコピーされるからだ!」
これは本当にその通り。米国の人たちは、中国で日々起きている経済・産業スパイ活動の規模をよく分かっていない。2000年代半ばごろ、名前は出せない技術企業の別件の侵害事故に対応していたとき、「新疆に技術センターを開いたのだが、最近、入館証の紛失がやけに多い」と聞かされた。そこで「それは紛失ではなく、金を受け取って売った可能性は考えたか」と尋ねると、沈黙が続いた。
経営陣が分かっていて気にしていないのか、単に無能なのかは分からないが、中国は産業スパイ活動を大規模に製品化している。最近ではGE Aviationも被害に遭っている: https://www.cincinnati.com/story/news/2022/11/16/accused-chi...
その後、中国で会社を立ち上げ、中国の投資家を受け入れ、中国市場向けにほぼ同じ製品を作る。例としては、Thoratec/Abbot Heartmate IIIとCH Biomedical、Auris/Verb/J&J Robotic & Digital SolutionsとRenovo Surgicalのようなケースがある。
皮肉なことに、そうした企業の一部は中国で成功した後、米国や欧州で販売し、競争しようとしている。今では秘密でも裏取引でもなく、われわれの業界では公然と行われ、概ね「そういうもの」として受け止められている雰囲気だ。
もう一つは、外国企業が中国で事業をする際に資産を守るのが非常に難しいという点だ。だから賢明な企業は最初から自分たちでやろうとせず、中国市場向けに中国企業へライセンスすることが多い。そうすれば、すべてを盗まれずに済む可能性だけでも出てくる。
以前、私が働いていたエージェンシーで、iBeaconハードウェア用の見栄えのよいケースを作ろうとして、工業デザイナーを起用したことがある。成果物は素晴らしかった。
中国企業に射出成形を委託し、サンプルもかなり良かったので採用することにしたが、数週間後、Alibaba/AliExpressでわれわれのケースが売られているのを見つけた。
西側や他の国が完璧だと言っているわけではないが、今話しているのはそのことではない。中国の製造・ビジネスと関わったことのある私の知人は皆、「コピーされた」「自分たちの努力を他人に売られた」「合意したものより低いグレードのxを提供された」といった経験をしている。
反論はいつも「それでも西側もXをやっている」か「それは人種差別だ」に行き着く。
中国企業、とりわけAli-Xで商売しているところは、この仕組みを本当に好んでいる。知的財産を無料で手に入れ、本来の機器メーカーを価格で押しのけられるからだ。Tindieなどに載せたメイカーたちの設計もコピーされ、Aliに出てくることが多い。
https://www.nytimes.com/2017/03/03/technology/uber-greyball-...
https://www.theverge.com/2014/8/12/5994077/uber-cancellation...
この記事を読みながら、複雑なカスタムコードが取り除かれて削除される話を期待していたが、筆者は予想と違ってエンジニアとして成長していた
「Cattle, not pets」というDevOpsの格言がここにぴったり当てはまる。コードと、そのコードで作ったプロダクトはペットではなく家畜だ。仕事をしてくれて、その仕事がもはや役に立たなくなれば引退する準備ができているということだ。感傷的な理由でコードをペットのように扱うと、ビジネスの利益に真っ向から反することをしていることになる
多くのコードは書いていて楽しいし、多くの問題は解いていて楽しい。だがビジネス、とりわけスタートアップは極度に集中しなければならない。私のキャリアは実質的に、会議室に座って若く熱意あるエンジニアたちに作るなと言う仕事に近い。少し憂鬱だが、どうしても必要な仕事でもある
良いエンジニアは巧妙なコードでどんな問題でも解ける。優れたエンジニアは、ある問題が実は問題ではなく、毎日更新されるXLSのダウンロードリンクで十分だったかもしれないことを理解する
社内でホスティングしていたサービスの監視システムを作っていたとき、上司が私たちの環境の些細な部分を監視する小さなユーティリティを買おうとしていた。自分で作れるのにお金を払って買おうとしているのが、少し不愉快だった
上司が「これを書いてテストするのにどれくらいかかる?」と聞き、私は「たぶん1週間、厄介なことが出てくればもう少しかかるかもしれません」と答えた。すると「そのツールは500ドルだ。君の40時間分の時給はいくらだ?」と聞かれた
そのとき悟りを得て、それ以来、会社でより安く買えるものを自分で作ったことはない
Substackページ下部のチェックリストも、この程度の要件把握には十分ではない。それらの質問は状況を描写しているだけで、それを尋ねたからといってこの単純な解法にたどり着けたわけではないだろう。チェックリスト式の思考は松葉杖であり、問題を過度に複雑にする
ここで重要なシグナルはすべて組織的・社会的なものであって、プロセスを改善すれば済む問題ではなかった。実装の詳細に関与していない人は、実装の詳細に関する質問には答えられない
「とにかくExcelみたいに作ってほしい」という言葉は、まったく別の目標を持つ人が出す低品質な回答だ。実際のユーザーにより近い人と相談し、そこで反論を組み立てるべきだった。欠けていたのは、弱い仮定を見抜き、すべての当事者が合意できるほど詳細が固まるまで、あえてコードを書かない勇気だった。「責任者」にただイエスと言ってはいけない
2006年にも誰かがその道に進まないよう説得しようと長い会話をしたし、2026年にも誰かがまたそれをやろうとするだろう
「このまさに同じ問題を、他の人はどう解いたのだろう?」と立ち止まって考える能力は、開発者として成長するうえで非常に大きな部分なので、学校でもっと重点を置いてほしい
短い期限内に予定どおり成功裏に完成させたという説明だけで、実装の選択が悪かったと結論づけることはできない。むしろ成功しすぎてExcel機能をあまりにも多く実装し、その後それを取り除いて修正したという話だ。XLSのダウンロードリンクでは、それをどうやって取り除けるというのか?
核心はコードに執着しすぎるなということであり、状況によっては「自分で作らずXLSのダウンロードリンクを使え」かもしれないが、それがすべてではない
「何も起こらなかったが、そのコードをいつか使う日のために取っておいた。私のアイデアは、このコードをUberの用途に合わせて磨き上げることだった」「私の最初の反応はコードをGitHubで公開することだった」という部分が非常に驚きだ
そのコードはBoxかUberの所有物ではないのか? 筆者はMITライセンスで公開する前に許可を得たとは言っていない
Uberが、自分たち由来でもなく、半年以上前の数千行のJavaScriptで、1か月も使っていないコードを欲しいなら、手紙を送ればいい
「ブラウザで動く完全なスプレッドシートエンジンを自分が書いた、ということを彼はどうしても信じられなかった」というくだりは、私にも信じがたい。しかも良い意味ではない。
Apache POIを使えばヘッドレスのExcelを動かせる。Javaからシートを取得してプログラム的に操作できるし、以前の職場でまさに同じ理由で使っていた。関数、セル参照など、すべて問題なく動作していた。
たまたま「circ」問題を見つけられただけだ。今後出くわすであろうExcelの隠れた小さなクセの数々はどうするのか。本当にJSで完全なExcelクローンを作って保守するつもりなのか。それがフロントエンドチームの目標として正しいのか。
少し検索していれば、ここで90%以上の作業は避けられたように思う。おまけにバックエンドチームが担当することもできたはずだ。
Uberは自社データセンターを運用していた。実際のExcelを動かすWindowsマシンやVMを調達するには奇跡が必要だっただろう。私は新しいフロントエンドサービスなら30分ほどで立ち上げられたし、ある程度すでに動いていたコードもあったので、完全にゼロから始めたわけでもなかった。このシステムは、異なるデータセットを持つ複数の人が同時に使う必要があった点も考慮しなければならない。
その後もさらに多くの機能やExcelとの同等性を求められていたなら検討しただろうが、そうはならなかった。
私がした選択を多くの人がするとは期待していない。だがそれは動いたし、驚くほどよく動いた。記事から「大きく複雑なプロジェクトだった」という点だけを受け取ったのなら、私が伝えようとしていたメッセージを記事がうまく伝えられなかったということだ。
私ならUI仕様をもっと詰めて、裏側でExcelを動かす方向を主張したと思う。ただ、数値入力があちこちに多い場合には、慣れたUIではある。
100行のF#でスプレッドシートを作るこの記事は、いつも面白く読んでいる: https://tomasp.net/blog/2018/write-your-own-excel/ ここから必要な機能セットへ拡張するのは、十分手に負える範囲だ。
結局、モデルのUIとして自作の「Excel」クローンを作ったが、その理由は「都市チームはExcelしか使えない」だった。
私なら逆にしただろう。モデルが出力したデータにExcelを接続して、都市チームが本物のExcelを使い続けられるようにしたはずだ。多くの財務チームはこの方式でやっているように思う。
気になる人向けのExcelの循環参照に関する文書: https://support.microsoft.com/en-us/office/remove-or-allow-a...
反復計算に慣れていないなら、循環参照をそのままにしておきたいとは思わない可能性が高い。反復計算を有効にすることはできるが、数式を何回再計算するかを決める必要がある。最大反復回数や最大変化量を変更せずに反復計算を有効にすると、Excelは100回反復した後、または循環参照内のすべての値の変化が反復間で0.001未満になった時点のうち、先に来たほうで計算を停止する。ただし、最大反復回数と許容できる変化量は制御できる。
UberやBoxがそのコードを自分たちのものだと主張していたら、筆者はこの状況を違う見方で捉えたのだろうかと気になる。コードが実際の潜在力を発揮できなかったとしても、少なくとも世界中が見て認められるという事実は、ある程度のカタルシスを与えてくれそうだ
私はインターンとして働いていたとき、プログラミング言語まるごとを作ったことがある。遅延評価でガベージコレクションがあり、引用符なしのMACアドレスが有効な構文になるなど、アプリケーション特化の奇妙さもあった
バイトコードやJITのようなものはなく、インタプリタが構文木をたどりながらスタックに値をpush/popする方式だったが、私たちの用途には十分速かった。インタプリタは純粋なANSI Cで書き、Valgrindも非常に満足していた
完全に忘れ去られたのかもしれないし、その会社の技術インフラの中核になったのかもしれない。そのコードは私が書いたエアギャップの実験室の外に出たことがなく、知るすべはない。3年前、大学を出たばかりの頃、それは私が書いた「実際に役立つソフトウェア」の中で断然いちばんクールなもので、今でも上位に入る。たまに、あれがどうなったのか気になる
筆者は中間管理職、さらには上級管理職に「これ要りますか?」と尋ね、その管理職が「いいえ」と答えたことが、会社に対して法的拘束力を持つと勘違いしているように見える
「特に賢い、あるいは優雅なコードを傑作のように扱うのは簡単だ。実際、美しい装飾品かもしれない。だが私たちエンジニアは、美しい装飾品を作るビジネスではなく、成果を生み出すビジネスにいる」という一文が刺さった
ただし、私のコードを見たことがある人なら誰でも分かるだろうが、私はコードもその機能もとてもきれいであってほしいと思うタイプだ。たいてい自分が保守するコードを書くので、1年後に見ても理解できる必要がある
今、ここで発表するつもりもなく、大きな手柄にするつもりもないプロジェクトの最終段階にいるのだが、本当にすごいものだ。そうなった理由は、誰もお金を払っておらず、誰もそこからお金を稼がないからだ
お金はすべてを台無しにもするし、同時にすべてを可能にもする
かつてのUber BIチームの視点から書かれた、本当に素晴らしい記事だ。私はその時期にVerticaチームにいて、インセンティブに注ぎ込まれた労力の量には気が遠くなるほどだった。ダウンタイム、プロダクト機能、エンジニアリング帯域の面で、1日に数百万ドルが消えていくことはよくある話題だった
特にUber Chinaの時代には、ディレクターがまさにスプレッドシートをUIとして要求するのも、ごく自然なことだったはずだ。私自身も、毎月チームにメールで届くスプレッドシートからFX価格をVerticaにロードしていた。自動収集で制御フローを逆転させるだけの余力がなく、そのプロセスは1年以上残っていた
「今まで見た中で、Uberの社内アプリケーションシステムほどよく設計されたものはない。開始してから
*.uberinternal.comのサブドメインでHello WorldをフルCI/CDで動かすまで、30分もかからなかった」という言葉に、少し心が温かくなった当時Uberでこのすべてに関わっていた