Ein Repository-Viewer, den ich letzten Sommer gebaut habe, hat acht Commits in seiner ersten Woche. Die ersten vier fassen keine einzige Zeile Anwendungscode an: Es sind das Init aus meiner Vorlage und drei Dokumentations-Commits. Der fünfte ist dann die komplette App.
Das war keine Disziplin. Beim Schreiben des Dokuments habe ich gemerkt, dass mein mentales Modell der Integration falsch war, und das in einer .md zu korrigieren kostete zwanzig Minuten statt zwei Tage.
Der Fehler, bei einer fremden Integration mit dem Code anzufangen
Wenn die Logik deine ist, ist den Code zu lesen die beste Dokumentation, die es gibt. Wenn sie von einer fremden API abhängt, nicht: Was du wissen musst, steht weder in deinem Code noch in ihrem. Es steht in den Limits, den Kontingenten und den deprecated Parametern.
In diesem Viewer habe ich eine Weile zwei Verbindungen zum selben Anbieter verwechselt. Das OAuth fürs Login und das Server-Token zum Lesen der API sehen gleich aus und sind es nicht. Das eine dient dazu, dass ein Mensch hereinkommt, das andere dazu, dass der Server liest. Sie scheitern unterschiedlich. Es in einem Dokument in zwei getrennten Abschnitten aufzuschreiben, hat mir gezeigt, dass ein Viewer für öffentliche Repos nur das zweite braucht.
Hätte ich mit dem Code angefangen, hätte ich das beim dritten 401 entdeckt.
Was genau ich vor der ersten Zeile dokumentiere
Ich dokumentiere nicht das Design meiner App. Ich dokumentiere das, was ich nicht kontrolliere. Konkret:
- Die echten Limits, gemessen, nicht zitiert. Es reicht nicht, "5.000 Anfragen pro Stunde" von der Website abzuschreiben. Ich habe den Kontingent-Endpoint gefragt: 60/h unauthentifiziert, 5.000/h authentifiziert, 30/min bei der Suche. Und ich habe gemessen, dass ein
304 Not Modifiedkein Kontingent verbraucht — 4972, 4972, 4972 mit Conditionals, und 4971 beim selben Aufruf ohneIf-None-Match. Diese sich wiederholende Zahl ist das zentrale Argument des Dokuments, und ohne sie auszuführen hast du sie nicht. - Was sich nicht automatisieren lässt. Die OAuth App lässt sich nicht per CLI anlegen: Es gibt keinen Endpoint zum Erstellen und keinen zum Lesen des Client Secret, das genau einmal im Browser gezeigt wird. Das ist ein manueller Schritt, und an dem Tag, an dem du die Umgebung neu aufsetzt, wirst du ihn vergessen haben.
- Die Obergrenzen, die in Produktion überraschen. 2.000 Token-Erstellungen pro Stunde, was eine Obergrenze für Logins ist, nicht für Anfragen. Und erzwungene Neuautorisierung, wenn ein Nutzer zehnmal in einer Stunde hereinkommt. Keines von beiden taucht auf, wenn du den Happy Path liest.
- Was die Entscheidung NICHT löst. Ich habe notiert, dass Login-Zwang die Notwendigkeit eines Conditional Cache nicht beseitigt, weil das Kontingent des Nutzers mit seinem PAT und mit anderen Apps geteilt wird, die in seinem Namen handeln. Wenn du das nicht aufschreibst, gibt dir die Entscheidung falsche Sicherheit.
Nichts davon ist Meinungssache. Es sind Fakten, die du entweder überprüfst oder dir ausdenkst.
Die Cookbooks: jedes Teil isoliert testen, bevor es integriert wird
In einem KI-Dienst für Dokumentenanalyse habe ich dasselbe auf andere Weise gemacht. Bevor irgendein Teil in den Dienst kam, hatte jedes ein Cookbook: ein Skript, das es allein ausführt, seine Ausgabe in einen Ordner schreibt und sich in einem run_all_cookbooks registriert. PDF-Parser, Chunker, Embeddings, Zahlenerkennung, verifizierbare Extraktion. Eins pro Teil.
Der Wert liegt nicht im Test. Er liegt darin, dass man es in einer Textdatei sieht, wenn sich die Form der Chunker-Ausgabe ändert, statt in einem Fehler drei Schichten weiter oben. Beim Umstieg des Pipelines auf asynchron wurden die Cookbooks zu Runnern mit asyncio.run, und die Migration lief Stück für Stück, nicht auf einen Schlag.
Der Preis ist, dass man sie löschen muss, wenn sie nichts mehr wert sind. Monate später gibt es einen Commit, der die veralteten Cookbooks entfernt. Ein Cookbook, das nicht mehr zu seinem Teil passt, ist schlimmer als gar keins.
Dokumentation als Quelle der Wahrheit für spätere Audits
Für eine Galerie von UI-Konzepten habe ich zuerst einen Designleitfaden für das Stück geschrieben — Größen, Abstandsleiter, Graustufen, welches Primitiv wofür — und danach den Code dagegen auditiert.
Das Interessante ist, dass das Audit den Leitfaden korrigiert hat, nicht nur den Code. Drei Dinge, bei denen die .md zu wenig sagte: dass das begleitende Grau in fünf Stufen abgestuft wird und nicht in zwei; dass die Abstandsleiter vier Sprossen hat und nicht drei, weil sie mit dreien sechs legitime Verwendungen zu Abweichungen erklärt hätte; und dass die drei Dialoge in Wirklichkeit derselbe Dialog sind, mit derselben Box und derselben Kopfzeile, und dass die Korrektur, weil das nicht dastand, nur auf einen davon angewandt worden war.
Ohne vorheriges Dokument gibt es diese drei Funde nicht. Du hast nichts, wogegen du vergleichen kannst, und alles, was du findest, ist "finde ich halt".
Wann das Zeitverschwendung ist
Das Kriterium, das ich benutze:
- Wenn die Integration von vorn bis hinten deine ist, dokumentiere nicht vorher. Der Code ist die Wahrheit und das Dokument altert.
- Wenn es ein Prototyp ist, den du wegwirfst, auch nicht. Ein Spiel, das ich an einem Tag geschrieben habe, hat nichts Geschriebenes, und das ist gut so.
- Wenn das Dokument nur wiederholt, was die offizielle Referenz sagt, schreib es nicht. Es bringt nur etwas, wenn deine Messungen, deine Versionen und die Fallen darin stehen, die dich erwischt haben.
Und es gibt einen Fehler, der mich teuer zu stehen kam: Das vorher geschriebene Dokument trägt deine Annahmen in sich. In dem Viewer beschrieb der Hosting-Abschnitt eine Serverless-Plattform, weil ich das beim Verfassen des Auftrags vorausgesetzt hatte, nicht weil jemand es entschieden hätte. Die Korrektur auf einen langlebigen Container veränderte die ganze Schlussfolgerung: Serverless passte das Agenten-SDK nicht hinein; in einen Worker mit fünfzehn Minuten Anfragenlimit schon.
Deshalb ist der nächste Schritt nicht optional. Es gibt einen Commit, dessen einzige Aufgabe es ist, das Dokument gegen lebende Quellen zu verifizieren: die Abfrage ausführen, die im Leitfaden steht, eine ungültige API-Version schicken, damit die API selbst die gültigen aufzählt, prüfen, dass per_page=500 stillschweigend auf 100 gekürzt wird, das Snippet typisieren, das im Strict Mode nicht kompilierte. Dieser Commit hat gefunden, dass 18 von 20 zurückgegebenen "Issues" in Wirklichkeit Pull Requests waren.
Ein unverifiziertes Dokument ist eine hübsch formatierte Annahme. Ein verifiziertes Dokument ist der einzige Teil der Integration, der dich in sechs Monaten nicht anlügen wird.
