はじめに:AIで速くなったのに、なぜ“前と同じ説明”を何度もしてるのか
AIにコードを書かせるの、ほんまに速くなりましたよね。
要件をざっくり伝えたら関数ができて、テストも生えて、リファクタもしてくれる。一年前なら半日かかった作業が、コーヒーを淹れてる間に終わってたりする。
でも、ひとつだけ置いてけぼりになってるものがあるんです。
ドキュメント です。
コードはどんどん変わる。でもREADMEは三ヶ月前のまま。設計メモは「最初のversion」のまま。コメントは、もう存在しない関数の使い方を説明したまま。そして気づいたら、自分が書いたはずのコードなのに、半年後の自分が「これ、なんでこうなってるんやっけ…」って固まってる。
正直に言いましょう。これ、AIで開発が速くなればなるほど、悪化します。
しかも2026年の今、もっと厄介なことが起きてます。そのズレたドキュメントを、今度はAIが読んで、それっぽく間違える んです。
順番にいくと、こういう負のループが回り始めます。
AIでコードを爆速で変更
↓
ドキュメントが追いつかず、こっそりズレる(=ドリフト)
↓
次にAIエージェントが、その“古いドキュメント”を文脈として読む
↓
古い前提で、それっぽく間違ったコードを生成する
↓
人間がレビューで気づいて手戻り(or 気づかず事故)
↓
(最初に戻る)
なんかこれ、もったいなくないですか。せっかくAIで速くなったのに、ドキュメントのズレが原因で、AIの足を引っ張ってる。
この記事では、この負のループを断ち切るための考え方と、明日から仕事で使える具体的な仕組み を、できるだけやさしく整理してみます。専門用語は全部その場で噛み砕くので、「ドキュメント、大事なのは分かってるけど後回しにしてた」という人ほど、最後まで読んでもらえたら嬉しいです。
そもそも「ドキュメントドリフト」って何ですか
まず言葉から。ドキュメントドリフト(documentation drift) とは、コードが変わっていくのに、ドキュメントがそれについていけず、両者が少しずつズレ続けていく現象のことです。「drift」は「漂流」。気づかないうちに、じわじわ離れていく感じですね。
イメージとしては、引っ越したのに、古い住所が書かれた地図を配り続けてる 状態に近いかもしれません。地図そのものはきれいに印刷されてる。でも、その通りに歩いたら、誰もいない空き地に着く。地図が「嘘」になってる。これがドリフトです。
ここで、この記事で出てくる用語を先に整理しておきます。知ってる人は飛ばしてください。
- ドキュメント : コードの使い方・設計・理由を説明する文章全般。READMEもAPIリファレンスもコメントも含みます。
- README : リポジトリの入口に置く「まず読んでね」の説明書。
-
docstring(ドックストリング) : 関数やクラスのすぐ近くに書く説明文。
"""この関数はXをする"""みたいなやつ。 - APIリファレンス : どんな関数・エンドポイントがあって、引数や返り値が何かを並べた仕様の一覧。
- ADR : 「なぜこの設計にしたか」を残す決定の記録。あとで詳しく説明します。
なぜドリフトは起きるのか
理由はシンプルで、コードは「動けば正義」だけど、ドキュメントは動かないから後回しにされる からです。
テストが落ちたら気づく。ビルドが壊れたら気づく。でも、ドキュメントがズレても、何もエラーは出ない。CIも赤くならない。誰も困ってなさそうに見える。だから、後回しにされて、静かに腐っていく。
人を責めてるわけじゃないんです。人間は忘れる生き物だし、締め切り前に「ドキュメントも直そう」と毎回完璧にできる人なんて、ほぼいない。善意に頼る仕組みは、いつか必ず破れる。 これは性格の問題じゃなくて、構造の問題なんですよね。
どれくらいヤバいのか(規模感)
数字も少し見てみましょう。ただし、ここで挙げる割合は厳密な学術調査というより業界のブログや調査の数字なので、「だいたいそういう肌感」くらいで受け取ってください。
- ある業界調査では、ドキュメントの約6割は半年で古くなる と言われています。
- 開発者は、コードを「書く」よりも「読んで理解する」ことに時間の半分以上を使っているとも言われます。
- GitHubでは2025年に約9.86億のコミットがあったそうです。変更が速いほど、ドリフトも速い。当たり前ですよね。
そして、ここが大事なんですが、ドリフトは「気持ち悪い」だけの問題じゃないんです。実際にバグを生みます。
ソフトウェア工学の研究でも、コードとコメントの不整合(inconsistency)がバグの混入につながることが調べられています。たとえば論文「Investigating the Impact of Code Comment Inconsistency on Bug Introducing」(arXiv:2409.10781)では、コメントの不整合がバグ導入に影響することが分析されています。さらに、コード変更時に「このコメント、もう古くなってない?」をコミット前に機械学習で検知しようという研究(Deep Just-In-Time Inconsistency Detection, arXiv:2010.01625)や、code-LLMで不整合を検知・修正する DocChecker(arXiv:2306.06347)など、専用のデータセット(CUP2やJITDATA)まで作られて、長く取り組まれてきたテーマなんです。
つまり、「ドキュメントのズレは、ただの怠慢じゃなくて、品質に効く技術課題」 として、ずっと研究されてきた、ということですね。
2026年の転換:ドキュメントの読者は、もう人間だけじゃない
ここからが、この記事でいちばん伝えたいところです。
ちょっと立ち止まって考えてみてほしいんですけど…今、あなたのドキュメントを読んでるのは、人間だけですか?
違うんですよね。2026年の今、ドキュメントの読者にはAIが加わりました。
CursorやGitHub Copilot、Claude Code みたいなコーディングエージェントが、あなたのコードを触るとき、何を手がかりにしてると思います? そう、README、コメント、APIリファレンス、設計メモ。ドキュメントを“文脈”として読んでる んです。
しかも、読み方が人間と全然違う。
人間は、ドキュメントを上から順に読みます。でもAIは違う。関連しそうな断片(フラグメント)を拾ってきて、自分のコンテキストウィンドウ(=AIが一度に読める作業机の広さ)に差し込んで使う んです。だから、文書がどう構造化されてるかが、そのままAIの回答品質を左右する。ある調査では、ドキュメントの発見経路の3分の1以上が、もうAI経由になってきてるとも言われています。
ここで、さっきの負のループをもう一度見てください。
ドリフトしたドキュメントを、AIが「正しい現在の仕様」だと思って読む。 すると、AIは存在しない関数を呼び、廃止した引数を渡し、もう使ってない設計前提でコードを書く。そしてそれが「それっぽく動きそうに見える」から、レビューで見落とすと、静かに事故る。
だから僕は、こう考え方を切り替えるのがいいと思ってます。
ドキュメントは「人間向けの説明文」ではなく、「人間とAIが共有する文脈資産(shared context)」である。
この一言、地味やけど、けっこう効くんです。「誰かが読むかもしれない文章」だと後回しにしがちやけど、「自分とAIが明日また使う作業の前提」だと思うと、扱いが変わる。
AI向けドキュメントの新しい作法:llms.txt
この流れの中で、2026年に広まってきたのが llms.txt という仕組みです。
これは超ざっくり言うと、「AIエージェント向けの、要点だけまとめた案内板」 です。Webサイトに robots.txt(検索エンジン向けの案内)があるように、AI向けに「うちのドキュメントはここ、要点はこれ」を、AIが読みやすいMarkdown形式で置いておく、という発想ですね。B2A(Business-to-Agent、企業から,AIエージェントへ)の最初の広く使われた規約、なんて呼ばれ方もします。
中身の構造はシンプルです。
# Acme Payments API
> 決済を作成・取得・返金するためのREST API。認証はBearerトークン。
## Authentication
- [認証ガイド](https://docs.example.com/auth.md): APIキーの発行とBearerトークンでのCall方法
## Core endpoints
- [Create a charge](https://docs.example.com/charges/create.md): 決済を作成する。金額・通貨・冪等キーを渡す
- [Refund a charge](https://docs.example.com/charges/refund.md): 決済を返金する。全額・一部に対応
## Errors
- [エラーコード一覧](https://docs.example.com/errors.md): 4xx/5xxの意味とリトライ方針
ポイントは、# タイトル → > 1〜2文の要約 → ## セクション → 各ドキュメントへのリンク、という形で、AIが少ないトークンで全体像をつかめるように整理する こと。マーケティング的な飾り文句は入れず、認証・エンドポイント・エラーみたいな統合に必要な情報に絞ります。リンク集にして軽くする llms.txt と、全文を埋め込んで自己完結させる llms-full.txt を使い分ける、というやり方もあります。
ただ、ここは正直に書いておきます。llms.txt は、W3CやIETFのような標準化団体がオーソライズした“公式規格”ではありません。 あくまでコミュニティ発の慣習で、2026年時点で中央の公式リソースがあるわけでもない。だから「これを置けば未来永劫安心」ではなく、「AI向けに文脈を整理する、という考え方そのもの」を持ち帰るのが正解かなと思います。
補足: リポジトリ直下に置く
AGENTS.md(コーディングエージェント向けの「このリポジトリの歩き方」)も、同じ「AIに渡す文脈」の仲間です。ただあれはリポジトリに常駐する“指示書”。この記事で扱うのは、README・リファレンス・ADRまで含めた、ドキュメント全般を腐らせずに保つ運用 の話です。レイヤーが少し違う、と捉えてもらえれば。
Docs as Code:ドキュメントを「文章」ではなく「ソフトウェア」として扱う
じゃあ、どうやってドリフトを止めるか。出発点になる考え方が Docs as Code(ドキュメント・アズ・コード) です。
名前のまんまで、ドキュメントを、ソースコードと同じやり方で扱う という方針のことです。具体的には、こういうことですね。
- ドキュメントを、別のツールじゃなくて Gitリポジトリの中 に置く
- 変更は プルリクエスト(PR) でレビューしてからマージする
- コードと 同じバージョン で一緒に管理する(v1.2のコードにはv1.2のドキュメント)
- マージしたら 自動でデプロイ されて公開される
なんでこれが効くか。答えはシンプルで、ドキュメントを、コードと同じ場所・同じワークフローに乗せると、同期されやすくなる からです。別のWikiツールに隔離されてると、コードを直してもドキュメントを直しにいくのが「別作業」になって、忘れる。でも同じPRの中にあれば、「コード変えたなら、このドキュメントも変えるよね?」が自然になる。
ディレクトリ構成のイメージはこんな感じです。
my-app/
├── src/ # アプリのコード
│ └── payments/
├── docs/ # ドキュメント(コードと同じリポジトリ内)
│ ├── tutorials/ # チュートリアル(学習用)
│ ├── how-to/ # ハウツー(特定の作業手順)
│ ├── reference/ # リファレンス(仕様)
│ ├── explanation/ # 解説(設計の背景・なぜ)
│ └── adr/ # アーキテクチャ決定記録
├── llms.txt # AIエージェント向けの案内板
└── README.md
「あれ、docs/ の下の分け方、なんか意味ありそう」と思った人、鋭いです。これ、次に説明する Diátaxis という考え方に沿ってます。
何を書くか迷わないための地図:Diátaxisの4分類
ドキュメントを書こうとして、いちばん最初につまずくのが「で、何を書けばええの?」じゃないですか。ぜんぶ説明しようとして、途中で力尽きる。あるあるですよね。
ここで役立つのが Diátaxis(ディアタクシス) というフレームワークです。Daniele Procida さんが提唱したもので、2026年の今、開発ドキュメントの構造として最も広く推奨されてる考え方のひとつです。
Diátaxisは、ドキュメントを読者が「今、何をしたいか」 で4種類に分けます。
| 種類 | 読者の意図 | 答える問い | 例 |
|---|---|---|---|
| Tutorial(チュートリアル) | 学びたい | 「まず何から始めれば?」 | 手を動かして最初の決済を作るまでの一連の流れ |
| How-to(ハウツー) | 特定の問題を解決したい | 「Xをやるには?」 | 「返金処理を実装する手順」 |
| Reference(リファレンス) | 正確な仕様を知りたい | 「この関数の引数は?」 | APIエンドポイント一覧、引数・返り値の仕様 |
| Explanation(解説) | 背景を理解したい | 「なぜこういう設計?」 | 「なぜ冪等キーを必須にしたのか」 |
この4つ、混ぜたらあかんのです。1ページは1種類だけ。 リファレンス(仕様の一覧)に、いきなりチュートリアルの「まずこれをやってみましょう」を混ぜると、仕様だけ知りたい人も、学びたい初心者も、どっちも迷子になる。逆に、種類が分かれてると、読者は「自分が今ほしいのはこれ」とすぐ辿り着ける。
そして面白いのが、この分類はAIにも効く ということ。さっき言ったように、AIはドキュメントを断片で拾って使います。種類がきれいに分かれてると、AIも「仕様が知りたいときはreference、背景が知りたいときはexplanation」と、正しい断片を引きやすくなる。人間にもAIにも親切、というわけですね。
ちなみに、どれをAIに書かせやすいか という観点でいうと、ざっくりこんな感覚です。
- Reference : コードから機械的に生成しやすい。AIに下書きさせるのが得意な領域。
- How-to : AIに手順の下書きをさせて、人間が検証する、が向いてる。
- Tutorial : 「初心者がどこでつまずくか」の感覚が要るので、人間の編集が効く。
- Explanation / なぜ : これは人間が握るべき。 「なぜこの設計にしたか」は、コードのどこにも書いてない判断だから。AIは推測はできても、本当の理由は知らない。
実装①:ドリフトを「仕組み」で検知する
ここからが、いちばん明日使えるパートです。
何度も言いますが、善意でがんばる、はやめましょう。 人は忘れるので。代わりに、「ドキュメントがズレたら、CIが教えてくれる」仕組み に見張ってもらいます。検知のレベルは、ざっくり弱い順にこんな段階があります。
| レベル | 何を検知するか | 難しさ |
|---|---|---|
| 1. リンク切れ | ドキュメント内のリンクが死んでないか | 易しい |
| 2. シンボル存在 | ドキュメントが言及する関数名・ファイルパスが実在するか | 易しい〜普通 |
| 3. コード例の実行 | ドキュメント内のコード例が実際に動くか | 普通 |
| 4. 意味の正しさ | 説明の内容が、コードの実際の挙動と合ってるか | 難しい(AIや人間の出番) |
レベル1〜3は機械で自動化できます。まずここを固めるのが費用対効果が高い。
検知例その1:ドキュメントが言及するファイル・シンボルが実在するか
ドリフトの典型は、「ドキュメントには src/payments/charge.py の create_charge() を使えって書いてあるのに、実際にはもうリネームされてて存在しない」みたいなやつ。これは、ドキュメント内に出てくるファイルパスや関数名が、コードベースに本当にあるかを照合 すれば機械的に検知できます。
# scripts/check_doc_symbols.py
# ドキュメント内で言及されているファイルパスとコードシンボルが実在するか検査する。
# 実在しなければ exit 1(=CIを赤くする)。
import re
import sys
from pathlib import Path
DOCS_DIR = Path("docs")
SRC_DIR = Path("src")
# `src/...` 形式のファイルパスを拾う正規表現(バッククォート内のもの)
PATH_PATTERN = re.compile(r"`(src/[\w/]+\.\w+)`")
# `create_charge()` のような関数呼び出しを拾う
SYMBOL_PATTERN = re.compile(r"`(\w+)\(\)`")
def collect_existing_symbols() -> set[str]:
"""src配下の全Pythonファイルから def/class 名を集める。"""
symbols: set[str] = set()
for py in SRC_DIR.rglob("*.py"):
text = py.read_text(encoding="utf-8")
symbols.update(re.findall(r"^\s*def\s+(\w+)", text, re.MULTILINE))
symbols.update(re.findall(r"^\s*class\s+(\w+)", text, re.MULTILINE))
return symbols
def main() -> int:
existing_symbols = collect_existing_symbols()
problems: list[str] = []
for md in DOCS_DIR.rglob("*.md"):
text = md.read_text(encoding="utf-8")
# 1) 言及されたファイルパスが実在するか
for rel_path in PATH_PATTERN.findall(text):
if not Path(rel_path).exists():
problems.append(f"{md}: 参照先ファイルが存在しません -> {rel_path}")
# 2) 言及された関数が実在するか
for symbol in SYMBOL_PATTERN.findall(text):
if symbol not in existing_symbols:
problems.append(f"{md}: 参照先の関数が見つかりません -> {symbol}()")
if problems:
print("ドキュメントドリフトの疑いを検知しました:")
for p in problems:
print(f" - {p}")
return 1
print("ドキュメントの参照先はすべて実在します。")
return 0
if __name__ == "__main__":
sys.exit(main())
これは完璧な検知ではありません。正規表現で拾える範囲しか見ないし、誤検知もあります。でも、「存在しない関数を案内し続けるドキュメント」みたいな一番痛い嘘 を、コミット前に機械が見つけてくれる。それだけで価値があります。
検知例その2:ドキュメント内のコード例を「実際に動かす」
もうひとつ強力なのが、実行可能ドキュメント(executable documentation) という発想です。ドキュメントに載せたコード例を、ただ載せるだけじゃなくて、CIで実際に動かして、通らなかったら落とす。 こうすると、コード例が嘘になった瞬間に気づけます。
Pythonなら、doctest という標準の仕組みが使えます。docstring(関数のすぐ近くの説明文)の中に、対話例を書いておくと、それがそのままテストになる、というものです。
# src/payments/money.py
def to_cents(amount: float) -> int:
"""金額(円)を最小単位(銭=100分の1円のつもりのサンプル)に変換する。
>>> to_cents(10.00)
1000
>>> to_cents(0.5)
50
"""
return round(amount * 100)
そして、CIや手元でこう実行します。
# docstring内の対話例(>>> の行)をテストとして実行する
python -m doctest -v src/payments/money.py
# README.md 内のコードブロックも対象にしたいとき(pytest利用)
pytest --doctest-glob="*.md" docs/
もし誰かが to_cents の実装を変えて、to_cents(0.5) の結果が 50 じゃなくなったら、ドキュメントのほうが嘘になった瞬間に、テストが赤くなる。 説明と実装が、強制的に同期される。これが「実行できるドキュメント」の気持ちよさです。
検知例その3:GitHub Actionsで「コードだけ変えてドキュメント放置」を見張る
最後に、もう一段ゆるい、でも効く仕組み。「ソースコードを変更したPRなのに、ドキュメントが一切触られてない」場合に、やさしく警告する ものです。落とす(block)んじゃなくて、警告(warning)にするのがコツ。全部のコード変更にドキュメント修正が要るわけじゃないので、止めると邪魔になる。あくまで「ちょっと、ドキュメント大丈夫?」と肩を叩くイメージです。
# .github/workflows/doc-drift-gate.yml
name: doc-drift-gate
on:
pull_request:
branches: [main]
jobs:
check-symbols:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
# 検知例その1のスクリプト:参照先の存在チェック(ここは落とす)
- name: Check doc symbols exist
run: python scripts/check_doc_symbols.py
remind-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# ソースを変えたのにドキュメントを触ってないなら「警告」だけ出す
- name: Remind to update docs
run: |
BASE="origin/${{ github.base_ref }}"
CHANGED=$(git diff --name-only "$BASE"...HEAD)
SRC_CHANGED=$(echo "$CHANGED" | grep -E '^src/' || true)
DOC_CHANGED=$(echo "$CHANGED" | grep -E '^docs/|\.md$' || true)
if [ -n "$SRC_CHANGED" ] && [ -z "$DOC_CHANGED" ]; then
echo "::warning::ソースを変更していますが、ドキュメントの更新がありません。ドリフトしていないか確認してください。"
else
echo "ドキュメントの更新チェックOK(または対象外)。"
fi
ここまでで大事なのは、完璧な検知を目指さないこと。 「リンク切れ」「存在しない関数」「動かないコード例」みたいな、機械で確実に分かる嘘から潰す。 意味の正しさみたいな難しいところは、このあとAIと人間で見ます。
実装②:AIにドキュメントを「書かせる」ときの設計
ドリフトを検知できるようになったら、次は「直す・書く」をどう回すか。ここでAIの出番です。
ただし、ここでも軸はブレさせない。AIは下書きと差分を作る係。人間は「なぜ」と「正確さ」の番人。 ドキュメントは公開されて人間もAIも読む共有資産なので、嘘が混じると被害が広がります。AIが生成したドキュメントには、もっともらしい嘘(ハルシネーション)が混じることがある、という前提で扱うのが安全です。
役割分担を表にするとこんな感じ。
| 工程 | 人間(What / Why) | AI(How) |
|---|---|---|
| 何を書くか決める | ◎ 読者と目的を決める | △ 候補出し |
| Reference(仕様)の下書き | ○ レビュー | ◎ コードから生成 |
| How-toの手順 | ○ 検証して確定 | ◎ 下書き |
| 「なぜ」の言語化 | ◎ 判断は人間 | ○ 言葉にする手伝い |
| ドリフト箇所の洗い出し | ○ 最終判断 | ◎ 差分から候補抽出 |
| 嘘の検知(裏取り) | ◎ 最終確定 | ○ 突き合わせの下作業 |
では、具体的なプロンプトを3本いきます。共通のコツは、AIに断定させず、根拠(どのファイルの何行目を見たか)と「自信がない箇所」を必ず出させる こと。これだけで、AI生成ドキュメントの信頼度がぐっと上がります。
プロンプト例1:コード差分から「直すべきドキュメント」を洗い出す
あなたはドキュメント保守の補助担当です。以下のコード差分(diff)を読み、
更新が必要そうなドキュメントの箇所を洗い出してください。
# 制約
- 各指摘には、根拠となる差分の該当行(ファイル名と行)を必ず添えること。
- 「確実にズレている」「ズレている可能性がある(要確認)」を分けて出すこと。
- 自分で勝手に本文を書き換えないこと。あくまで「どこを・なぜ直すべきか」の指摘まで。
- 確証が持てないものは「不明」と正直に書くこと。
# 入力
- コード差分: {ここにgit diffを貼る}
- 現在のドキュメント一覧: {docs/配下のファイルパス一覧}
# 出力フォーマット
1. 対象ドキュメント / 直すべき箇所 / 根拠(差分の行)/ 確度(確実 or 要確認)
プロンプト例2:Diátaxisの4分類で、散らかったドキュメントを整理し直す
以下のドキュメントを、Diátaxisの4分類(tutorial / how-to / reference / explanation)の
観点で診断してください。
# やってほしいこと
- この文書が、今どの種類に当たるかを判定する。
- 複数の種類が「混ざって」いる箇所を具体的に指摘する(例:referenceの中にtutorial的な手順が混入)。
- どう分割すれば1ページ1種類になるか、章の分け方を提案する。
- 各分割案について、人間とAIのどちらが書くのに向いているかも添える。
# 注意
- 文章の中身を断定的に書き換えない。構造の診断と分割提案までにとどめる。
# 入力
{対象ドキュメント本文}
プロンプト例3:ドキュメントの「嘘」をコードと突き合わせて検知する
これがレベル4(意味の正しさ)への対策です。AIに、ドキュメントの主張とコードの実装を突き合わせさせて、裏が取れない主張を炙り出させる。
あなたはドキュメントのファクトチェッカーです。
以下のドキュメントの記述が、実際のコードと一致しているかを検証してください。
# ルール
- ドキュメントの主張を1つずつ取り出し、対応するコードを引用(ファイル名:行)して照合する。
- 「一致」「不一致」「コード上で確認できない(裏取り不能)」の3つに分類する。
- 不一致・裏取り不能のものだけを、優先度つきで一覧にする。
- 推測で「たぶん合ってる」と埋めないこと。確認できないものは正直に「裏取り不能」と書く。
- 最終的にドキュメントを直すかどうかの判断は人間が行う。あなたは材料を出すだけ。
# 入力
- ドキュメント: {本文}
- 関連コード: {該当ソース}
ポイントは、最後の一行。「直すかどうかは人間が決める。あなたは材料を出すだけ」 を必ず入れること。AIを「判定者」じゃなく「調査係」に固定すると、暴走が減って、人間が判断に集中できます。
ADR:判断の「なぜ」を残す(ここは人間にしか書けない)
ドキュメントの中でも、いちばん腐りにくくて、いちばんAI時代に効くのがADR だと思ってます。
ADR(Architecture Decision Record / アーキテクチャ決定記録) とは、重要な設計判断を、「背景(context)・決定(decision)・結果(consequences)」 の3点セットで短く残す文書のことです。Michael Nygard さんが広めた型で、adr.github.io にテンプレートがまとまっています。
なんでこれが効くか。コードを見れば「何をしているか(What/How)」は分かる。でも、「なぜそうしたか(Why)」は、コードのどこにも書いてない んです。「なぜRDBじゃなくこっちを選んだか」「なぜここをあえて手動にしたか」。この“なぜ”が失われると、半年後の自分も、新しいメンバーも、そしてAIエージェントも、「この変な作りには理由があるのか、ただのミスなのか」が判断できなくなる。
そして2026年的に面白いのが、ADRが、AIエージェントに“なぜ”を渡す文脈源になってきている ことです。「今いちばん重要なアーキ文書は、もう人間向けじゃなくAI向けだ」とまで言う人もいる。だから最近は、ADRに「誰が決めたか(人間か、エージェントか)」「決定したときにエージェントが持っていた文脈」まで書こう、という流れも出てきています。
テンプレートはこんな感じ。
# ADR-0007: 決済処理に冪等キーを必須にする
- ステータス: 承認済み(2026-06-24)
- 決定者: 人間(バックエンドチーム) / AIエージェントは代替案の洗い出しを補助
- 関連: ADR-0003(リトライ方針)
## 背景(Context)
ネットワーク不安定時にクライアントが決済を再送し、二重課金が発生するリスクがある。
リトライは避けられないため、「同じ操作が2回届いても1回しか実行されない」保証が要る。
## 決定(Decision)
すべての決済作成リクエストに冪等キー(idempotency key)を必須とする。
サーバー側で一定期間キーを保存し、重複リクエストは最初の結果を返す。
## 結果(Consequences)
- 良い点: 再送による二重課金を構造的に防げる。
- コスト: クライアント側に冪等キー生成の実装が必要。キー保存のストレージが要る。
- 却下した代替案: クライアント側だけでの重複防止(信頼できないため却下)。
ADRも、初稿はAIに手伝わせていいんです。ただし、決定そのものは人間が握る。
以下の設計上の議論から、ADRの初稿を作ってください。
# 制約
- context / decision / consequences の3部構成にする。
- 「却下した代替案」と「その却下理由」を必ず含める。
- 決定を断定で書かず、[要・人間確認] のタグを残す。最終決定は人間が行う。
- 決定時に参照した情報(どの計測・どの制約)も書き添える。
# 入力
{設計議論のメモやチャットログ(※個人情報・秘密情報は外してから渡すこと)}
安全と、よくある落とし穴
仕組みの話をしてきましたが、ここを外すと事故るので、安全面を最後にまとめます。
安全の鉄則
-
秘密情報・個人情報・固有IDを、ドキュメントやllms.txtに書かない。 これが最重要です。ドキュメントは公開され、AIにも読まれる。つまり「ドキュメントに書く=外に出す」と思っておく。APIキー、内部URL、個人名、社内固有のIDは、ダミーやプレースホルダ(
STRIPE_API_KEY=xxxxxのような)に置き換える。 - AIが生成したドキュメントを、そのまま“最終確定”にしない。 もっともらしい嘘が混じる前提で、必ずコードと裏取り(grounding)する。
- 不可逆な操作の手順書は、人間がレビューする。 「本番DBを消すコマンド」「デプロイ手順」みたいなものをAIに書かせたら、人間が必ず確認。
- 外部から来たテキストは「データ」として扱う。 ドキュメントの中に外部から取り込んだ文章を貼るとき、そこに「これまでの指示を無視して〜」みたいな仕込み(プロンプトインジェクション)が紛れることがある。AIに読ませる文脈に外部テキストを混ぜるときは、命令ではなくデータとして囲う。
よくある落とし穴
| 落とし穴 | なぜダメか | どうする |
|---|---|---|
| 書いて満足して放置 | 書いた瞬間から腐り始める | CIでドリフトを検知する仕組みを先に作る |
| 全部AIに丸投げ | それっぽい嘘が公開資産に混入する | 下書きはAI、確定は人間(裏取り必須) |
| Diátaxisの種類を混ぜる | 人もAIも正しい断片を引けない | 1ページ1種類を徹底 |
| 検知の仕組みがゼロ | 善意に頼ると必ず破れる | リンク切れ・シンボル存在・コード例実行から自動化 |
| 何でも網羅して巨大化 | 誰も読まない&AIのトークンを浪費 | 要点を絞る。llms.txtで案内に徹する |
| 秘密情報の混入 | 公開=流出。AIも学習・参照しうる | ダミー化を徹底。秘密検知ツールも併用 |
撤退ライン(やりすぎ防止)
- ドキュメントの整備が、コードを書くより重くなったら、いったん手を止める。ドキュメントは手段で、目的じゃない。
- ドリフト検知が誤検知だらけで邪魔になったら、ルールをゆるめる(block→warningに落とす)。
- AIの生成ドキュメントの裏取りに時間がかかりすぎるなら、その領域は人間が直接書いたほうが速い、という判断もアリ。
まとめ:ドキュメントは、明日の自分とAIへの「置き手紙」
長くなったので、最後にぎゅっとまとめます。
- ドキュメントドリフトは、AIで開発が速くなるほど悪化する。しかも今は、ズレたドキュメントをAIが読んで、それっぽく間違える 負のループになる。
- だから、ドキュメント=人間とAIが共有する文脈資産(shared context) と捉え直す。
- Docs as Code でコードと同じ場所・同じワークフローに乗せ、Diátaxis で「何を書くか」を4分類に整理する。
- ドリフトは善意でなく 仕組み(CI)で検知 する。存在しないシンボル、動かないコード例から潰す。
- AIには下書きと差分を任せ、「なぜ」と「正確さ」は人間が握る。 根拠と不明点を必ず出させる。
- ADR で判断の“なぜ”を残す。ここは人間にしか書けないし、AIにも効く。
最後に、ちょっとだけ僕の思ってることを。
ドキュメントって、面倒なんですよね。誰も褒めてくれへんし、書かなくても今日は困らない。でも、今日書いた3行のドキュメントは、半年後の自分への“置き手紙” なんです。そして今は、その手紙を読むのが、未来の自分とチームと、次のAIセッション にまで広がった。
僕はこれを「明日の自分があざっす、って言うやつ」って呼んでます。過去の自分がちゃんと残してくれてたら、未来の自分が「あざっす」と言える。ドリフトしてた過去の自分を責めるんじゃなくて、これから、未来の自分に少しずつ親切にしていく。責める軸じゃなくて、思いやりの軸ですね。
そして、こうやってコードと同期し続ける仕組みと、人にもAIにも読める文脈は、消えずに積み上がる資産 になります。書き捨ての説明文じゃなくて、資本(Code as Capital)。何を・なぜ書くかは人間が決めて、どう書くかはAIに手伝ってもらう。その分業が、これからのエンジニアの効きどころかなと思います。
明日からの最初の4ステップ
- リポジトリに
docs/を作り、既存のドキュメントをDiátaxisの4分類に仕分けてみる(まず1個でいい)。 - いちばん大事なコード例に
doctestを1つ付けて、CIで動かす(嘘になったら気づける状態を作る)。 - 「存在しない関数を案内してないか」を検査する小さなスクリプトを1本、CIに足す。
- 直近の大きな設計判断を、ADR 1枚に書き残す。「なぜそうしたか」を、未来の自分とAIに渡す。
完璧じゃなくていいんです。1個ずつ。今日の小さな1行が、未来のあなたとAIを助けます。ほな、また。
参考にした主な情報源
- Diátaxis(ドキュメント4分類フレームワーク): https://diataxis.fr/
- Architecture Decision Records: https://adr.github.io/
- ドキュメントドリフトの検知・管理に関する研究レビュー(IEEE Xplore)、code-comment不整合研究(arXiv:2409.10781 / arXiv:2010.01625 / DocChecker arXiv:2306.06347、CUP2・JITDATAデータセット)
- llms.txt / Docs as Code / AIがドキュメントを断片で読む、に関する2026年の各種技術記事(Fern, Mintlify ほか)
※本記事のコード例・設定例はすべて汎用的なサンプル(example系のダミー名)です。実運用では、ご自身の環境とセキュリティ方針に合わせて調整してください。