/note/tech

AIが書く「読みづらいADR」に発狂しかけたので、ADRのガイドラインを作った

要約:

■ 1. 背景と問題意識

  • AI時代のADR:
    • AIを使った開発では、意思決定の記録を残す重要性が広く認識されている
    • チームではプロジェクト初期から技術的な意思決定をADRに記録し、運用してきた
    • 最近はADRのドラフト作成もAIに任せている
  • ルール未整備による弊害:
    • ADRを書くルールを整備しないままAIに書かせると、人間が読み返しづらいADRが次々と生まれる
    • ADRは人間がじっくり目を通すべき文書の代表格であり、読みづらいと強いストレスになる
  • 取り組みの内容:
    • ADRの意図を汲み取りやすい状態に保つため、書くべきこと・書くべきでないことを整理したガイドラインを作成した

■ 2. ADRの概要と既存の雛形

  • ADRの起源:
    • 2011年にMichael Nygardがブログ記事『Documenting Architecture Decisions』で提唱した
    • アーキテクチャ上の意思決定を記録する短い文書
  • 原典の4セクション構成:
    • Context: 意思決定に影響する技術的・政治的・社会的な力を中立的な事実として書く
    • Decision: チームの対応を「We will 〜」で始まる能動態の文で書く
    • Status: 提案中、採用済み、後続ADRによる廃止・置換のいずれかを書く
    • Consequences: 決定適用後の状況を、良い影響・悪い影響・中立な影響を含めて書く
  • ガイドライン導入前の雛形:
    • 原典の4セクション構成をベースに、プロジェクト開始直後に用意し運用しながら改良した
    • StatusとDateはメタデータとしてfrontmatterに記載する
    • 本文はContext・Decision・Consequencesの3節で構成する
    • 任意の節として、検討した代替案と不採用理由を書くAlternatives Consideredを加えた

■ 3. AIが書いたADRで起きた問題

  • 雛形だけでは不十分:
    • 雛形があればAIは一見それらしいADRを書く
    • しかし情報が整理されず、意思決定の内容や意図が読み取れないADRが相当の頻度で提出された
  • 問題1 ADRが移行計画・バックログを兼ねる:
    • 現行設計の追認と将来の移行方針を定めるADRで、Decisionに移行の工程図を書き込んでいた
    • さらにブロックごとの作業、対応チケット、ステータスを全23行の表で記載していた
    • AIが手元の情報をできる限り盛り込んだ結果、意思決定の記録とタスク管理が同居した状態
    • ADRは長期間読み返される文書であり、短期間で状態が変わるタスク進捗を記載すべきではない
  • 問題2 ADR単体で判断を読み取れない:
    • 秘密値と秘密でない設定値の置き場所を決めるADRで、Contextが仮定形の一般論にとどまっていた
    • 実際には、セキュアに扱う必要のない値も秘密値と同じサービス上に置かれている状況だった
    • Contextには何が問題で、なぜ今決める必要があるのかを書くべき
    • このプロジェクトで実際に起きており解消すべき問題が、ADR単体で読み取れない状態だった
  • 問題3 Decisionが実装の詳細まで抱え込む:
    • メール送信の検証環境の分担を決めるADRで、誤送信防止策を実装レベルで記述していた
    • 判定を置くメソッド名、環境変数名、カンマ区切りの形式を書き込んでいた
    • 宛先の正規化・照合方法や、ブロック時に例外を投げない挙動まで記述していた
    • 許可外の宛先に送らない、設定漏れ時は送信しない側に倒す、という方針こそが意思決定にあたる
    • 実装の詳細を書くと、照合方法の変更や環境変数のリネームだけでADR本文の書き換えが必要になる
    • 長期的に守りたい意思決定が実装の記述に埋もれる
    • 具体的な方式は仕様書、コードコメント、PRのdescriptionへ移すべき内容だった

■ 4. 人間が読み返せるADRの必要性

  • 正しいが読みにくいADR:
    • 紹介した文面はいずれも正しい情報を含むが、後から読み返して意図を理解する負荷が高い
  • ADRの役割:
    • AIによる自動化が進んでも、意思決定の最終責任は人間が持つ
    • ADRは意思決定の妥当性を確認・検証する拠り所となる文書
    • 後から読み返す動機が湧きやすい状態を保つことは、開発を人間の制御下に置くために不可欠
  • レビュー負荷の増大:
    • 指摘のたびにレビュアーが同じことを書き続けるのは現実的ではない
    • 実際に同じ種類の指摘がPRをまたいで何度も繰り返されていた

■ 5. ガイドライン adr-authoring.md の設計

  • 目的:
    • ADRの記載ルールを1つの正典に集約し、書き手とレビュー側が同じ基準を参照できる状態にする
    • ルールが分散していると、書き手はレビューを受けるまでルールに到達できない
  • 導入前の状態:
    • 記載ルールはCIのAIレビュー用プロンプトや、過去のレビューコメント由来の観点ファイルに散在していた
    • ルールが形式知として整理されておらず、人間からもAIからも同じ指摘が繰り返されるのは当然だった
  • 過去のレビューコメントからの規約抽出:
    • 机上で考えず、過去のPRで実際に入った指摘からルールを抽出した
    • 対象はADRを変更したPR34本と、レビューコメント830件
    • 繰り返し入っている指摘を32件の規約としてリスト化した
  • カテゴリ分けとID付与:
    • 32件の規約を性質ごとにA〜Gのカテゴリに分け、IDを振った
    • A: 参照と記載場所、本文にチケット番号やADR以外へのリンクを書かずReferences節や専用節にまとめる
    • B: 参照先の指し方、行番号や章番号だけに頼らず加筆やファイル移動後も一意に定まる書き方にする
    • C: 事実と根拠、前提事実を一次資料と照合し出典を示してADR単体で読めるようにする
    • D: 意思決定として書くこと・書かないことの線引き、移行計画や実装の詳細を抱え込まない
    • D: 適用範囲・例外の失効条件・影響は過不足なく書く
    • E: ADR同士・一覧との整合、ステータス変化やアーカイブに一覧や参照元を追従させる
    • F: 表記と語彙、用語・タイトル・リンクテキストを揃え、最終更新日など陳腐化しやすい情報を置かない
    • G: Accepted化前の点検、セキュリティ系ADRの完全性を確認し未確定事項を残したまま採用しない
  • 強度の付与:
    • MUSTは満たさなければならない規約
    • SHOULDは原則として満たし、外す場合は理由を説明できる状態にする規約
  • 規約の例:
    • A-1(MUST): 本文にチケット番号・PR/Issue番号を書かない
    • B-1(MUST): 物理行番号で参照しない
    • C-1(MUST): 事実を実コード・一次資料と照合する
    • C-3(MUST): ADR単体で読めるようにする
    • D-1(MUST): 移行計画・進捗・タスク表を書かない
    • D-3(SHOULD): 適用範囲と決定しないことを明記する
    • D-4(SHOULD): Decisionを実装の自由度を奪わない粒度にする
  • IDの効用:
    • レビューで「D-1に反している」と短く指摘できる
    • 指摘された側もガイドラインの該当箇所にすぐ辿り着ける

■ 6. 判定のための工夫

  • 判定に迷わない「問い」:
    • 規約の文言だけでは、どこまで抽象化すべきか判断がつかない
    • D-4には、実現方式を別方式に置き換えたときADR本文の書き換えが必要か、という問いを用意した
    • 書き換えが必要なら、その記述はADRではなくDRまたは仕様書に属する
    • DR(Decision Record)は、ADRほど長期に維持しない実装上の判断をPRのdescription等に残す記録
  • ADRに書かない具体物:
    • 検出アルゴリズム、テスト方式、関数・型の構造、個別対象への権限割り当てなどが該当する
    • ADRから外したものの移送先(PRのdescription、仕様書など)も表で示した
  • 「本 ADR で決定しないこと」節:
    • Decisionの末尾に置き、委譲先を名指しする(D-3)
    • 何を決めていないかを書くことで、意思決定のスコープが読み手に伝わりやすくなる
  • OK/NG例は作例で書く:
    • 各規約にOK/NG例を添えた
    • D-1のNG例は、完了すれば陳腐化する進捗のチェックリストを本文に持つもの
    • D-1のOK例は、移行期間中に旧方式と新方式の両方を読み取れる必要がある、という要件の記述
    • 例はすべて作例とし、現存するADRを引用していない
    • 現存ADRを良い例にすると、そのADRが無効化された際に過去の意思決定がノイズとして残る
    • 規約違反が残るADRを悪い例として固定することも避けたかった

■ 7. 書き手とレビュー側での共有

  • ガイドラインの参照経路:
    • ADRを書くスキル: ドラフト生成時にガイドラインと雛形を読み込む
    • path-scoped rule: Claude Code利用時、ADRディレクトリ配下を扱うときだけガイドラインへの導線を読み込む
    • CIのAIレビュー: レビュー用プロンプトから、ADRに関する観点をガイドラインへ委譲する
  • コンテキスト消費の抑制:
    • path-scoped ruleには導線だけを書き、ガイドライン本文は複製しない
    • ADRの記載ルールはADRを書くときだけ必要な知識であり、無関係な作業のコンテキストを消費させない

■ 8. 導入後のAIレビューによる指摘例

  • 根拠が会議の中にしかない(C-1):
    • Decisionの前提を、特定日の対面レビューで確認した内容として記述していた
    • Referencesも PRへの言及に留まり、会議内容を後から検証できる一次資料がなかった
    • 会議の確認事項は参加者には確かな事実だが、不参加者や半年後の自分には検証できない
    • AIレビューは、第三者が閲覧できる参照先を示す選択肢を提示した
    • あわせて、コードやDB定義で確認できる事実だけを書くか、未確定事項として委譲する選択肢も示した
  • 「決定しないこと」の委譲先が辿れない(D-3):
    • 委譲先として既存文書とテストの実施計画を挙げたが、Referencesには既存文書しかなかった
    • リポジトリ上にも現行のテストの実施計画は存在しなかった
    • 後続の読者がどの文書が正典かを判断できない
    • AIレビューは規約の文言だけでなく、リポジトリの実態と照らし合わせて指摘した
  • 他ADRの参照先が一意に定まらない(B-2):
    • 他ADRの採用判断を、Decision項番号と章題の形式でなく文言で参照していた
    • 文言だけの参照は、参照先の項目の並べ替えや文言変更でどの決定を指すか辿れなくなる
    • 項番号と章題を併記すれば参照先が一意に定まり、参照先の変更にも気づきやすい
  • 規約IDを添えた指摘の効果:
    • 書き手が人間でもAIでも、ガイドラインの該当箇所を読んで同じ基準で修正できる
    • 書き方の指摘をAIレビューに任せたことで、人間のレビュアーが意思決定そのものの妥当性の議論に時間を割ける

■ 9. まとめ

  • AIの特性:
    • ADRには原典以外にも様々なフォーマットやテンプレートが提案されている
    • AIは雛形を埋めるのは得意だが、何をADRに残し何を残さないかを精度高く判断できない
  • フォーマットだけでは不十分:
    • フォーマットを当てはめるだけでは、可読性の高いADRを維持し続けるのは難しい
  • 可読性を保つために重要なこと:
    • ADRに何を残し、何を残さないかの基準を定める
    • その基準を、書き手とレビュアーが同じ場所から参照できるようにする
    • 実際のレビューで繰り返される指摘をもとに、基準を適切なタイミングで更新する