TinyPilot: Month 42

Michael Lynch

TinyPilot:42か月目

一言サマリー

どうすれば、もっとうまく委任できるだろうか?

ハイライト

  • プロダクトの意思決定やドキュメント作成を、もっとうまく委任する方法について考えました。
  • Nixを学んだ経験とZigを学んだ経験を比較しました。

目標の成績表

毎月のはじめに、その月に達成したいことを宣言しています。結果は次のとおりでした。

TinyPilotのライセンスチェックの設計を完了する

  • 結果: 設計書が完成し、レビューも終わりました。
  • 評価: A

これで、TinyPilotのお客様が最新バージョンへアップデートする前に、有効なライセンスをお持ちかどうかを確認する計画ができました。サードパーティのライセンス管理サービス(現在はKeygenを有力候補として検討しています)を決めれば細部を詰める必要がありますが、大枠は固まりました。

新デバイスの製造ロットごとに抜き取り検査のプロセスを作る

  • 結果: 手をつけられませんでした。
  • 評価: F

理由の一つは時間不足です。ベンダー側で予期せぬ問題がいくつか発生し、その対応に時間を取られました。

もう一つの理由は、気が進まない作業だったので先延ばしにしてしまったことです。製造上の不具合を早期に見つけるためには重要な作業なのですが、3PLに特別なお願いをする必要があり、これまであまり協力的ではなかった経緯があるのです。

TinyPilotの年末の税務処理を片付ける

  • 結果: すべてのベンダーからW-9フォームを回収しました。
  • 評価: A-

これで完了です。誰からW-9を取得する必要があるのかも理解できました。今後は直前になって慌てることがないようにできます。

TinyPilotの統計

指標2023年11月2023年12月増減
ユニーク訪問者数6,4006,700+300 (+5%)
販売売上$84,055.05$75,198.00-$8,857.05 (-11%)
エンタープライズサブスクリプション$290.70$290.700
ロイヤリティ$2,824.46$1,792.51-$1,031.95 (-37%)
総売上$87,170.21$77,281.21-$9,889.00 (-11%)
利益-$5,407.96-$59,117.41-$53,709.45 (-inf%)

売上は11月からやや減少しましたが、これは毎年見られる季節的な動きです。平常時の売上は月7万5000〜9万ドル程度なので、今回はその下限に近いものの、心配するほどではありません。

利益の数字は一見すると不安になりますが、これはまだ現金主義で帳簿をつけているためです。外部の製造委託先へ移行したことで、製造にかかる費用を前払いで大きく支出しています。第4四半期にTinyPilotは材料費と製造費で15万ドルを支出しましたが、これは四半期として過去最高額です。売上原価(COGS)ベースで見ると、12月の利益は実際には9,000ドル(プラス9,000ドル)でした。

とはいえ、外部の製造・フルフィルメント業者への移行対応に追われ、マーケティングはおろそかになっていました。幸いTinyPilotはここ数か月、マーケティングにあまり投資せずとも成長してきましたが、いつまでもそれに頼るわけにはいきません。1月の目標の一つは、新たなマーケティングチャネルを開拓することです。

難しいプロダクトの意思決定は委任できるか?

最近、自分の時間がどこに使われているかを振り返ると、多くが「難しいプロダクトの意思決定」に費やされていることに気づきます。TinyPilotにどんな機能が必要か、そこにどれだけ投資するか、予期せぬ事態が起きたときにどうリソースを再配分するか――そういったことを考える時間です。

この難しい意思決定をTinyPilotチームに委任しようとしてきましたが、あまりうまくいっていません。

もし、機能のコストとユーザー満足度を示すグラフを作り、「この線より上に収まるようにして」とチームに伝えられれば理想的です。

顧客満足度と開発コストの曲線を定義して、「この曲線より上にいればいい」とチームに伝えられたらどんなに楽だろう、と思います。

しかし、新機能にどれだけ投資するかを決める際には、他にも多くの要素があります。例えば次のようなものです。

  • この機能は、必要としないユーザーにとって混乱や煩雑さを招かないか?
  • この機能を長期的に維持する負担はどれくらいか?
  • この機能はサポートチームにどんな影響を与えるか?

仮にこうした多次元のグラフを作れたとしても、すべての変数を意味のある精度で見積もるのは困難です。ある人は「この機能の恩恵を受けるのはユーザーの5%」と考える一方で、同じくらい合理的な別のメンバーは「15%」と見積もるかもしれません。たった一つの変数で機能の価値が3倍も変わってしまうのです。すべての変数を掛け合わせれば、二人の投資対効果の見積もりが100倍も食い違うことさえあります。

少し大げさに聞こえるかもしれませんが、最終判断を下す人には「プロダクトビジョン」が求められます。顧客、開発チーム、サポートチームのすべてとつながっている必要があるのです。そしてTinyPilotでは、その立場にいるのは私しかいません。

一つの解決策は、プロダクトマネージャーを雇うことです。ハイレベルな戦略を計画に落とし込み、チームと共に実行するのがその役割です。しかし、これはあまり現実的ではありません。管理すべき人が一人増え、チームとのコミュニケーションの輪にも加えなければならないからです。現在6人をマネジメントしていますが、これが私が効果的に管理できる上限だと感じています。

別の可能性として、既存のチームメンバーにプロダクトマネージャーの役割を担ってもらうことも考えられますが、これも現実的ではないと感じています。朝の郵便物を取りに行くような単純な雑務とはわけが違います。顧客やチームとのやり取りのほぼすべてに関わる必要があり、週に10〜20時間の追加業務になるからです。仮にそうしたとしても、的確なプロダクト判断ができるレベルまで育成できるかどうかも分かりません。

今のところの計画は、これまでどおり開発チームにハイレベルな戦略と、バグ修正や機能開発に使える大まかな工数予算を提示し続けることです。このやり方はうまくいっていますが、チームがより自律的に意思決定できるようにする方法を、引き続き模索しています。

ドキュメント作成の委任をもっとうまくできるだろうか?

私はドキュメントにはこだわりがあります。改善できる点が見つかれば、できる限り良くするまでは公開したくないのです。

今でもTinyPilotのブログ記事、FAQ、チュートリアルはすべて私がレビューしており、公開のボトルネックになることがよくあります。創業者としての時間の多くが、ドキュメントレビューに費やされている感覚です。

単純な作業時間が多いというより、「深く考える」ためのエネルギーをレビューに大きく使っている感覚です。私が集中して文章を書けるのは1日1時間程度です。他人の文章をレビューする方が、自分で書くよりもさらに消耗します。アイデアをどう表現するかを考えるだけでなく、なぜその表現を選ぶのかまで考えなければならないからです。

以前はコードレビューでも完璧主義に悩み、細かいことは流すことを学ぶ必要がありました。コードは多少美しくなくてもユーザー体験には影響しないので、それで構いません。しかしドキュメントは誰の目にも触れます。Aランクの文章とBランクの文章には、はっきりとした違いがあるのです。

では、どうすれば自分を依存先にせずに、文章の質を高く保てるのでしょうか?

フリーランスのテクニカルライターを入れることも考えました。しかし、それでは執筆プロセスが複雑になってしまいます。専任のライターがいると、かえってメンバーが文章力を磨こうとしなくなるのではないかという懸念もあります。「とりあえず書いておけば、後はライターが直してくれる」という意識になってしまうかもしれません。

文章をレビューしていて難しいと感じることの一つは、私の頭の中にある「典型的なTinyPilotの顧客像」を、他人に正確に伝える方法が分からないことです。そして、そのモデルを理解してもらえたとしても、その顧客像に合った書き方をしてもらうのは簡単ではありません。

平均的なTinyPilotのお客様に向けて書く。平均的なTinyPilotのお客様が理解している用語:Ethernet、WiFi、ローカルネットワーク、キーボード/マウス入力、USB/USB-C/USB 3.0、ACアダプター、HDMI/VGA、ルーター/スイッチ、ウェブブラウザ、SSH。平均的なTinyPilotのお客様は次の用語・概念を理解していないと想定してください:cached、PCB/HAT、audio breakout board、VPN、EDID、仮想ディスプレイ、NTPサーバー。お客様を混乱させない最善の方法は、お客様がすでに理解している言葉で話すことです。どうしても無理な場合は、お客様が知らないかもしれない用語を使っても構いませんが、まずは定義してから使ってください。

TinyPilotの社内スタイルガイドから、技術的な専門用語の使用レベルについての抜粋

一つの改善策は、過去のレビューを振り返ってパターンを見つけることかもしれません。パターンが見えれば、「レビューに出す前に、スクリーンショットがあった方が分かりやすくなる箇所はないか、新しい用語を使う前に説明しているか、などをチェックしてほしい」と伝えられます。

チームではGrammarlyのサブスクリプションを契約していますが、私たちのワークフローにはあまり馴染みません。初稿の段階では使う人もいますが、編集のたびに記事全体をコピー&ペーストしてGrammarlyにかけるのを面倒がるのです。開発者向けのValeも調べてみましたが、Grammarlyに比べるとかなりシンプルに感じます。ノイズの少ないチェックだけを設定すれば使えるかもしれないので、試してみようと思います。

Nixを学ぶこととZigを学ぶこと

TinyPilotの製造とフルフィルメントを外部ベンダーに移管した結果の一つとして、新しい技術を学ぶ時間と心の余裕が生まれました。ここ2年ほど遠くから注目していた技術が二つあり、NixZigです。2023年の後半に、ようやく両方を試すことができました。

両方を初心者レベルまで学んだ今、Nixを学んだ経験とZigを学んだ経験を比較するのは興味深いです。

Zigは推論で学び、Nixはコピペで学ぶ

Zigについてよく聞く不満の一つに、ドキュメントが貧弱だという声があります。確かにドキュメントはかなり簡潔で、開発者というよりコンパイラ設計者の視点で書かれていると感じます。それでも、議論を漁ったり試行錯誤したりするうちに、Zigについて正確なメンタルモデルを築くことができました。

一方で、Nixを半年使っても、依然としてメンタルモデルはぼんやりしたままです。いくつもの解説を読んできましたが、概念がなかなか腑に落ちません。Nixファイルを作るときも、既存のサンプルをコピーして自分の目的に合わせて調整するしかありません。ファイルの大部分は定型文(ボイラープレート)で、なぜそうなっているのか理解できていないのです。

Zigでエラーに遭遇したときは、たいてい論理的に考えてコンパイラが何を伝えようとしているのか理解できます。Nixでエラーが出たときは、まったくお手上げだと感じます。

大きな違いの一つは、私がC系の言語での開発経験は豊富ですが、純粋関数型言語の経験はまったくないことだと思います。ZigはCやC++の開発者を対象にしているので、10年間そうした言語で働いてきた私には概念がすんなり理解できます。

NixはHaskellなどの関数型言語に強く影響を受けているように見えますが、私はそれらを学んだことがありません。Haskellの開発者にとってはNixの方が直感的で、むしろ関数型言語ではあまり前面に出てこないポインタやメモリアロケータに焦点を当てるZigに戸惑うかもしれません。

Zigの開発体験は狭く深く、Nixは広く浅く感じる

Zigにはパッケージ管理やコードカバレッジのためのツールがありません。これまでのZigでの残念な点の一つは、マイクロコントローラのサポートがほとんどないように見えることです。

ZigはRaspberry Pi Picoを除く主要なマイクロコントローラのほとんどで、サポートが未成熟か、そもそも存在しません。

ただ、Zigが「できる」と謳うことについては、しっかりやり遂げます。gccのドロップイン置換になれるという主張には懐疑的でしたが、gcczigに置き換えるたびに、何の問題もなく動きました。Zigは.cファイルをそのままZigファイルにインポートできると謳っていますが、実際にできます

一方、NixはNode.jsプロジェクトのビルドのようなシンプルなことから、OS全体の構築や管理といった壮大なことまで、はるかに幅広いことをやろうとしている印象です。

プロジェクトがNixのツールが想定しているとおりにぴったり合致すれば、すべてがうまく動きます。しかし、私の環境が想定と少しでもずれると、途端に行き詰まってしまいます。例えば、いまだに分からないのですが、任意のPythonプロジェクトをNix上で動かす方法が分かりません。

Nixで最も驚いた欠落の一つは、インストールしたいパッケージのバージョンを指定する公式な方法がないことです。8年間議論が続いていますが、解決策はおろか、これを修正するのかしないのかという公式な見解さえ見当たりません。

Nixのリーダーシップは分散型、ZigにはBDFLがいる

Andrew KellyはZigの生みの親です。他にも何人かがプロジェクトに加わっていますが、Andrewは今も実質的に終身の慈悲深き独裁者(BDFL)です。Zigのドキュメントやヘルプを探すと、GitHubのissueやフォーラムでの議論で、Andrew本人やプロジェクトの公式メンバーが回答しているのをよく見かけました。

初めてNixのことを聞いたとき、Eelco DolstraがNixのBDFLなのだろうと思っていました。しかし、少なくとも表向きはそうではないようです。

NixはEelcoの2006年の博士論文から生まれた、彼のアイデアです。EelcoはNix Foundationの代表を務めていますが、同時にNixを推進するサードパーティのコンサルティング企業であるDeterminate Systemsでも働いています。ただしDeterminate Systemsはあくまでサードパーティであり、Nixの中核ではありません。彼らがリリースするものが、Nix内部のチームの取り組みと物議を醸す形で衝突することもあります。

Zigが中央集権的に計画されていると感じる一方で、Nixは舵取り役がいないように感じます。分からないことがあって検索すると、GitHubやNix Discourseフォーラムでのとりとめのない議論にたどり着くことがよくあります。会話はいつも、誤って発見してしまった異星のテクノロジーについて語り合っているかのようです。Nixのコアチームの誰かが意見を述べているのを見たことがなく、そもそもコアチームが存在するのかどうかも分かりません。

古い解決策はNixでもZigでもたいてい動かない

Zigはまだ安定版の1.0をリリースしていないため、コンパイラのアップデートで破壊的な変更が入るのは一般的です。Zig 0.8.0で有効だったコードが、Zig 0.11.0では無効になっていることもあります。私の経験では、Zigのツールは自動でコードを修正してくれる精度は比較的高いですが、100%正確ではありません。

Nixでも同様に、古いサンプルで問題に遭遇しました。Nixはflakesという、比較的新しくまだ正式ではない機能をめぐって、物議を醸す変革の真っ只中にあります。しかし最近のガイドはすべてflakesを使い、古い議論はすべてflakes以前のものなので、flakes以前の解決策をflakes以降の環境に適用するのに苦労します。

Zigはチーム全体の合意が必要だが、Nixは部分的導入がしやすい

Nixの良い点の一つは、自己完結していることです。プロジェクトの一つにflake.nixを置くだけで、他には何も変えずに依存関係を自動管理できますし、チームメンバーに何も頼む必要もありません。

たとえチームでNixを使っているのが私だけでも、flake.nixは他の誰にも負担をかけず、新しいツールの使用を強いることもなく、私にとって大きな価値をもたらします。プロジェクトに.vscodeディレクトリを追加するようなものです。VS Codeを使う人には便利ですが、他の人にとっては特に邪魔になりません。

一方、Zigはコミットメントとチーム全体の合意が必要です。CやC++のプロジェクトがあり、Zigに切り替えたいと思っても、自分だけ良いツールを使ってチームメイトが加わるのを待つ、というわけにはいきません。プロジェクトにZigのコードを一つでも入れれば、全員がC/C++コンパイラではなくZigコンパイラでビルドしなければならなくなるからです。

これはZigのせいではありませんが、Zigに触れるのは、コードをいじったりZigプロジェクトを見たりと、わざわざZigの世界を訪れたときだけだということを意味します。一方でNixは、今ではどこへ行くにも一緒です。

まとめ

何ができたか?

学んだこと

  • ドキュメントレビューの定期的なメタレビューが役立つかもしれません。
    • 現在は記事ごとの改善しか議論していませんが、複数の記事にまたがって現れるパターンを振り返ることで、チーム全体のライティングスキルがより向上するかもしれません。
  • Valeはレビュー前に細かな問題を見つけるのに役立つかもしれません。

来月の目標

  • 年次振り返りを公開する。
  • 5名のブロガーにTinyPilotとのコラボについて連絡する。
  • 2023年分の税務申告に向けて記録を整える。

お願い

原文は Michael Lynch により に公開されました。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。