去年の夏に作ったリポジトリのビューアには、最初の一週間にコミットが八つあります。最初の四つはアプリのコードに一行も触れていません。自分のテンプレートからの init と、ドキュメントのコミット三つです。五つ目でいきなりアプリ全体です。
規律ではありません。文書を書いている最中に、連携についての頭の中のモデルが間違っていると気づいたからです。そしてそれを .md の中で直すのは二日ではなく二十分で済みました。
他社の API 連携をコードから始める間違い
ロジックが自分のものなら、コードを読むことが最良のドキュメントです。他社の API に依存するなら違います。知る必要があることは、自分のコードにも相手のコードにもありません。制限、クォータ、非推奨のパラメータの中にあります。
このビューアでは、同じプロバイダの二種類の接続をしばらく混同していました。ログイン用の OAuth と、API を読むためのサーバートークンです。同じものに見えて別物です。片方は人間が入るためのもの、もう片方はサーバーが読むためのもの。壊れ方も違います。文書でそれを二つの節に分けて書いたことで、公開リポジトリのビューアには後者しか要らないと気づけました。
コードから始めていたら、これに気づくのは三度目の 401 のときだったでしょう。
最初の一行の前に何を書くか
自分のアプリの設計は書きません。自分が制御できないものを書きます。具体的には次のとおりです。
- 本当の制限。引用ではなく実測。 サイトから「1時間あたり 5,000 リクエスト」をコピーするだけでは足りません。クォータのエンドポイントに聞きました。未認証で 60/時、認証済みで 5,000/時、検索は 30/分。そして
304 Not Modifiedはクォータを消費しないことも測りました。条件付きリクエストで 4972、4972、4972、If-None-Matchなしの同じ呼び出しで 4971。この繰り返される数字が文書の中心的な論拠であり、実行しなければ手に入りません。 - 自動化できないこと。 OAuth App は CLI では作れません。作成用のエンドポイントもなければ、client secret を読むエンドポイントもなく、それはブラウザで一度だけ表示されます。手作業の手順であり、環境を作り直す日には忘れています。
- 本番で驚く上限。 トークン作成は1時間に 2,000 件。これはリクエストの天井ではなくログインの天井です。それと、あるユーザーが1時間に十回入ると強制的に再認可されること。どちらもハッピーパスを読んでいる限り出てきません。
- その判断が解決しないこと。 ログインを必須にしても条件付きキャッシュの必要性は消えないと書き留めました。ユーザーのバケットは、その人の PAT や、その人の名義で動く他のアプリと共有だからです。書かなければ、その判断が偽りの安心を与えます。
どれも意見の問題ではありません。確かめるか、でっち上げるかのどちらかしかない事実です。
cookbook: 統合する前に各部品を単独で試す
文書解析の AI サービスでは、同じことを別の形でやりました。どの部品もサービスに入る前に cookbook を持ちます。その部品を単独で実行し、出力をフォルダに書き、run_all_cookbooks に登録されるスクリプトです。PDF のパーサー、チャンク分割、埋め込み、数値の検出、検証可能な抽出。部品ごとにひとつ。
価値はテストであることではありません。チャンク分割の出力の形が変わったとき、三層上での失敗ではなくテキストファイルの中で見えることです。パイプラインを非同期にしたとき、cookbook は asyncio.run のランナーになり、移行は一気にではなく部品ごとに進みました。
コストは、価値を失ったら消さなければならないことです。数か月後には非推奨の cookbook を削除するコミットがあります。もう部品に対応していない cookbook は、ないよりも悪いものです。
あとから監査するための真実の源としてのドキュメント
UI のコンセプトを並べたギャラリーでは、まず部品の設計ガイドを書きました。サイズ、余白の段階、グレーのスケール、どのプリミティブを何に使うか。そのあとでコードをガイドに照らして監査しました。
面白いのは、監査がコードだけでなくガイドのほうも正したことです。.md が言い足りていなかったことが三つありました。付随するグレーは二段階ではなく五段階であること。余白の段階は三段ではなく四段であること。三段と呼んだせいで、正当な用例が六つも逸脱扱いになっていたからです。そして三つのダイアログは実際には同じダイアログで、同じ箱と同じヘッダーを持つこと。それを書いていなかったせいで、修正がひとつにしか適用されていませんでした。
先に文書がなければ、この三つの発見は存在しません。比べる相手がなく、見つかるものはすべて「私はこう思う」になります。
これが時間の無駄になるとき
使っている基準はこうです。
- 連携が端から端まで自分のものなら、先に書かない。 コードが真実であり、文書は古びます。
- 捨てるつもりのプロトタイプでも書かない。 一日で書いたゲームには何も文書がありませんが、それでいいのです。
- 公式リファレンスに書いてあることを繰り返すだけの文書なら、書かない。 自分の実測、自分のバージョン、自分が踏んだ罠が入っているときにだけ価値があります。
そして高くついた失敗がひとつあります。先に書いた文書には、自分の思い込みが入り込みます。あのビューアでは、ホスティングの節がサーバーレスのプラットフォームを前提に書かれていました。依頼をまとめるときに私がそう決めつけたからで、誰かが決めたからではありません。長期稼働のコンテナに訂正したら、結論がまるごと変わりました。サーバーレスではエージェントの SDK が収まらず、リクエストの上限が十五分のワーカーなら収まったのです。
だから次の手順は省けません。文書を生きた情報源に照らして検証することだけを目的としたコミットがあります。ガイドに載っているクエリを実行し、無効な API バージョンを送って API 自身に有効なものを列挙させ、per_page=500 が黙って 100 に切り詰められることを確かめ、strict モードでコンパイルできなかったスニペットに型を付ける。そのコミットで、返ってきた「issue」20 件のうち 18 件は実はプルリクエストだと分かりました。
検証していない文書は、見た目の整った思い込みです。検証した文書は、半年後に嘘をつかない唯一の部分です。
