コーディングエージェントの価値は「速く書くこと」ではなかった
個人OSS「karasu」(テキストベースのアーキテクチャモデリングツール)を、コーディングエージェント Claude Code と3ヶ月開発しました。その間、意図的に「ドキュメント駆動開発」を方法論として徹底し、ADR、Design Doc、テスト観点ライブラリ(TPL)、acceptance test をすべて同じリポジトリで回しました。本稿はそのふりかえりです。
コーディングエージェントの最大の価値は、コードを速く書くことではなく、人間の思考の穴を先に露出させることでした。 そして、それを引き出す装置がドキュメント駆動開発でした。
なぜ「ドキュメント駆動開発」を行うことにしたのか
きっかけは、AIを使ったコーディングからの学びでした。
Devin は自律的にコードを書きます。ただ、指示が曖昧だと実験的なコミットを積み重ねるばかりで、作業が収束しません。こちらの想定するゴールが曖昧だと、欲しい機能にもなりません。なんとなく「動くもの」はできあがりますが、触ってみるとほしいものから程遠い、というケースが散見されました。
Cursor は良い環境で、特に rules(プロジェクト固有のルール定義)の効果を強く実感しました。当時のプロジェクトでは設計ドキュメントを Notion に集約し、機能開発の前に設計を済ませていました。Cursor にそのドキュメントの URL を貼って読み込ませてはいたものの、設計そのものへの関与は弱く、関連ドキュメントを自律的に辿って整合性を保つことまでは期待できませんでした。
Claude Code も試したいと思い、実践 Claude Code 入門 を読みました。そこでは仕様駆動開発という手法が紹介されていました。仕様だけでなく、直前の操作内容を記録したステアリングファイルもリポジトリにコミットし、エージェントがふりかえるための材料として残します。ここから、リポジトリ内にドキュメントを持たせれば、エージェントがそれを活用できると学びました。
ならば、設計ドキュメントとコードを同じリポジトリに置いたら、何が変わるのか。それを体感する実験台として karasu を始めました。
3ヶ月の実績
ふりかえってまず驚くのは密度です。直近90日で 1,032 commits、ADR 244本、acceptance test 210本、TPL 67本。これを個人OSSで、しかも5〜6セッションを並列で回しながら積み上げました。
Claude Code に「効果があったこと」を聞くと、最初に挙げたのは、CLAUDE.md がわずか82行で各ドキュメントへの索引に徹していることでした。コンテキストが毎回リセットされるエージェントにとって、「迷ったらここを見ろ」という地図が最初にあると、探索コストが大きく下がります。逆に指示を詰め込みすぎると読み飛ばしを誘発します。この割り切りが効いた、といいます。
開発はどう回っていたか
karasu の開発は、コンセプト出しから始まり、その後は要件出しからテストまでがひとつのループとして回りました。一周を追うと、ADR、AT、TPL がどう積み上がり、エージェントの役割がどう変わっていったかが見えてきます。
コンセプト出しとセットアップ
まず取り組んだのは、自分が karasu に何を求めているのかの言語化でした。このコンセプト出しは Sonnet 4.6 との対話で進めます。テキストでアーキテクチャを書くためのモデリング記法をやりとりしながら固め、初期の技術的な意思決定は ADR にまとめました。
これらの結論を CLAUDE.md と ADR としてリポジトリに残し、Claude Code へ渡してプロジェクトの初期セットアップまで任せました。
要件から実装まで
開発は、要件を GitHub Issue に書き起こすところから始めます。書き起こす段階から、コーディングエージェントと要件を詰めていきます。
Issue のリンクを渡すと、エージェントは実装計画を立ててくれます。ですが、その計画がどんな背景で、どの選択肢を検討した結果なのかは、私からは見えません。そこで、要件から Design Doc を書き起こすよう依頼しました。
Design Doc を書かせてみると、エージェントは検討した選択肢と、設計に足りていない情報を「未解決の問い」として並べるようになりました。おかげで私は、選択肢から方針を選び、未解決の問いから考慮漏れを見つけられるようになりました。実装の前に解ける問いを詰め、方針に合意できたら、実装をエージェントへ依頼します。エージェントは Design Doc に沿って実装を進めます。
レビューと記録
実装が終わると PR が作られます。karasu を始めた当初はコードの細部までレビューしていましたが、途中から code-review スキルを起動するようにしました。このスキルは、直近の git 履歴を確認するサブエージェントなどを立ち上げてレビューを進めます。私がコードを細かく見るのは、このレビューを終えてからになりました。
UI を変えた PR や、MCP や API に関わる PR では、手動確認のチェック項目を必ずエージェントに書いてもらいます。私が実際に操作し、もともと依頼した機能が実現できているかを確かめました。
問題がないと確認できたら PR をマージし、Design Doc の決定事項を ADR としてリポジトリに記録します。ADR を残すのは、次に似た機能の Design Doc を書くとき、過去の技術的な意思決定をもとにエージェントが設計できることを狙ってのことです。
テストと横断的影響
機能が増えるにつれ、手動確認の手順そのものがわからなくなってきました。そこで受け入れテストをリポジトリに残す acceptance-test スキルを足し、実装 PR を作るときに手動テスト手順を残して、PR からはそれを参照させるようにしました。
受け入れテスト(AT)が増えるとリグレッションテストを回せるようになりましたが、毎回手で実施するのは面倒です。そこから自動化できるものをエージェントに選ばせ、E2E テストを導入しました。AT のうち自動化済みのものをマークさせているので、自動テスト率もレポートできるようになりました。
ただ、AT と E2E は、その PR が目的を実現できているかを確かめる手段にすぎません。横断的な影響を伴う変更までは捉えられない、と気づいた瞬間がありました。System 図のレイアウト調整機能を作っていたとき、その変更が Deploy 図や Org 図に反映されていなかったのです。ある図をいじると、構造的に連動するはずの別の図が壊れます。
実際の業務でも、実装の前にテスト観点をまとめ、設計の考慮漏れを先に潰していました。そこで、テスト観点をまとめた TPL(テスト観点ライブラリ)を導入します。TPL は単なるテストの抜け漏れ防止ではなく、「ここを触ったら、連動するあそこが壊れていないか」を設計時に明文化する、横断的影響マップです。既存機能のバグや、横展開が要る新機能では、この観点をエージェントへ書かせました。proactive TPL(新機能が既存機能を壊していないかを先回りで確認する観点)も、この延長にあります。
ADR、AT、TPL が揃ってくると、エージェントはそれらを参照しながら要件出し、設計、実装、テストを回せるようになりました。そして、人の思考の穴を次々に指摘してくるようになったのです。
ボトルネックはどこへ移ったか
ADR と TPL の整合性は、自動チェックする adr-tools と tpl-tools を自作しました。これにより、ドキュメント同士でほとんど崩れませんでした。AT はテストケース不足を減らし、E2E はカバレッジ指標としても働きました。テストと整合性の網は、こうして仕組みで張れるようになったわけです。
すると、課題の所在が変わります。「テストケースの不足」から「仕様そのものの考慮漏れ」へ移りました。残った難しさは「そもそも何を作るべきか」の側に寄っていきます。これはエージェント協働が一段成熟したしるしでしょう。
この変化は、karasu を始める前に Devin で感じた違和感の裏返しでもあります。
- Devin型:走り出す → なんとなく動くものができる → 欲しいものではない
- karasu型:問いを返す → 人間の要件の穴が露出する → 収束する
ドキュメント駆動開発は、「ドキュメントを書く規律」ではありません。人間の思考の穴をリポジトリ内で常時露出させ続ける装置です。
高並列の代償と、守られないルール
良いことばかりではありません。陰の部分を2つ、正直に書きます。
高並列と二重着手
この開発プロセスを回していると、エージェントが判断を求めてくるまでの待ち時間が生まれます。空いた時間で別のタスクを頼むうち、気づけば 5〜6 セッションが常時走るようになりました。
並列で進む量は増えました。ですが、同じ Issue に複数セッションが二重着手する事故を、何度も起こしました。開発アイテムは GitHub Issue で管理し、着手状況をラベルで示していました。開発スキルにも「着手前にラベルを確認し、着手したら更新する」と書いてあります。それでも忙しいとエージェントはこれを忘れ、二重で着手することがありました。
難しいアイテムを複数セッションで投機的に走らせ、最善のものを採るやり方もあります。ですが、それを意図していない場面での二重着手は、ただの無駄です。
散文のルールはなぜ守られないのか
ルールを手順書やスキルに「書いた」ことと、それが「守られる」ことは別物です。エージェントにとって散文の手順は、確率的に従うものであって、保証されるものではありません。
「worktree 配下で作業する」「main へ直接 push しない」が比較的守られるのは、それがメモリとスキルと機械的ガード(lefthook など)で多重化されているからです。ラベル確認が破れるのは、そこだけが散文の約束に留まり、機械的な強制を欠いているからです。
エージェントに守らせたいルールは、文章ではなく仕組みに彫り込むしかありません。ハーネスエンジニアリングが必要になる理由は、ここにあります。
コストをどう捉えるか
品質を検証するために実行していたのは CI / E2E(GitHub Actions)でした。GitHub の Pro プランの枠に加えて、月$20が上乗せされました。ドキュメント駆動で品質は担保できましたが、その品質を検証するコストは小さくありませんでした、というのが生々しい実感です。
ただし、これを人月換算の軸に置くと評価は一変します。3ヶ月でできた karasu は、業務委託で組めば少なくとも 2〜3人のプロジェクト規模です。Claude MAX と GitHub Actions で総額$1,000 程度なら、2〜3人月を畳んだと考えれば破格です。CI の$20超過に驚く一方で、全体は人月比で異様に安いものでした。この二面性が、現時点での正直な結論です。
まとめ
- ドキュメントを同じリポジトリに置くと、エージェントは関連文書を自律的に辿って整合性を保てるようになる
- ドキュメントをリポジトリに置くことは、エージェントへコンテキストを設計して渡すこと。コンテキストはエンジニアリングの対象だ
- CLAUDE.md は索引に徹する。詰め込みは読み飛ばしを生む
- TPL は「テストの抜け漏れ防止」ではなく「横断的影響マップ」として設計する
- エージェントの価値はコードの速さではなく、要件の穴を先に露出させること
- 高並列は二重着手を生む。守らせたいルールは仕組みに彫り込む
- コストは人月換算では破格
コーディングエージェントを「速いコード生成器」として使うと、Devin のように収束しません。ですが「自分の思考を映す鏡」として使えば、話は変わります。エージェントが設計の背景を読み取れるよう、そのためのコンテキストをドキュメントとしてリポジトリに残します。その作り込み、すなわちコンテキストのエンジニアリングが、鏡の解像度を上げます。コードだけでなく、コンテキストそのものをエンジニアリングの対象とすること。これが3ヶ月でたどり着いた、いまの実感です。