
2026/08/30 4:28
ドメイン指向エージェント
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
大規模言語モデル(LLM)を複雑なレガシーコードベースに直接適用することは、技術的負債が曖昧さを生み出し、AI が誤ったスペルを発明したり、暗黙的なシステムルールを見落としたりする原因となるため、しばしば失敗します。最も重要な洞察は、単独でモデルに依存するのではなく、戦略的人間意思決定と戦術的 AI 実行を分離した専門的なワークフローが必要であるということです。従来型の技術的負債の解決は、単なるクリーンアップのためにエンジニアリング予算の 10〜20% を消費しますが、このアプローチでは
.workflow.json マニフェストと生きている用語集を使用して、正確な用語とプロジェクトの範囲を定義し、意思決定に対する機械的なリファクタリングのコストを大幅に削減します。システム各部分間の語彙を統合すること(例えば、Rust のバックエンドが製品言語の用語を所有し、ウェブフロントエンドはバックエンドの OpenAPI ドキュメントから直接引用されたスクリーン用語を使用するなど)により、明瞭性にとって不可欠な共有言語が確立されます。この分離により、AI エージェントは困難なタスクを効果的に処理でき、人間は高レベルの設計に専念することで、一般的なモデルのハルシネーションを防ぐことができます。最終的に、この方法はドメイン駆動設計(DDD)のプリミティブを使用して複雑なアーキテクチャを安全に移行することを可能にし、戦略層がコンテキストの境界を確定させ、戦術層が定義された変更を実行します。これには、コンテキスト間の境界における機械的なチェックが含まれ、発見された問題は DDD イシューとして記録されます。本文
LLM を活用したレガシーコード改修:戦略的・戦術的分離と DDD による定石化
近年、ソフトウェアエンジニアリングにおいて大規模言語モデル(LLM)を多用するようになりました。グリーンフィールドな新規プロジェクトや小規模案件では LLM は効果的ですが、大量の依存関係や技術的負債を抱えたレガシーコードベースへの導入では生産性が著しく低下します。
本記事では、そのような「ブラウンフィールド」プロジェクトにおける失敗パターンから、LLM を効率的に活用するための戦略と戦術の分離、そして DDD(ドメイン駆動設計)を基盤とした準備手法を紹介します。
レガシーコード改修における LLM の課題
既存システムへのエージェント導入において頻発する失敗には明確なパターンがあります。
- 記述の一貫性の欠如
- グリーンフィールドでは「求人状況ステータス」という要求に対し、即座に生成されます。
- しかしレガシーコードでは、3 つの異なる表記が存在する概念に対し、LLM が 4 つ目の(誤った)綴りを発明してしまいます。
- 原因: コードベース自体がどの表記を「真実」とすべきか決定していないためです。
- 不適切な設計の提案
- 単純な関数呼び出しで済む場所に、過度に複雑なアダプターを記述させることがあります。
- アダプターの本来の役割を無視し、直結した呼び出しを行わせることがあります。
- 推測への依存
- システムが回答していない問いかけに対し、モデルは誤推測を多発します。
これにより、技術的な深さだけでなく、混乱や意味の欠落、共有言語の不在という第二の層に陥ってしまいます。解決策はモデルのアップグレードではなく、**コードベースそのものの「準備状態」**を整えることです。これをインクリーメンタル(漸進的)に行う必要があります。
戦略と戦術の分離
ソフトウェアエンジニアリングにおける課題は、かつて「技術的負債」全体でしたが、現在は役割を分割して対応可能です(ジョン・アウスターハウター『ソフトウェア設計の哲学』より)。
1. 従来のアプローチとの対比
| アспект | 従来の解決策 | 現在の状況 (LLM 活用時) |
|---|---|---|
| 決定 (何を改めるか) | エンジニアリング予算の 10〜20% を割当て (コストは高い) | ほぼ unchanged 依然として重要な判断が必要 |
| 実装 (タイピング作業) | 手動でのコーディング (時間がかかる) | 著しく低下 LLM が機械的な半分を安価に実行 |
- 結論: LLM は「決定」よりも「実装」の部分を安価かつ高速で処理します。エンジニアは**「決定」**の部分に専念できます。
2. ストラテジック vs タクティカル
私は作業を以下のように分割・役割分担しています。
- ストラテジック(戦略的):決定する
- システム全体を理解し、何を変更すべきか思索する。
- 変更がビジネス要件を満たすか判断する。
- 私が行う主要な役割。
- タクティカル(戦術的):実装する
- 決定事項をファイルに反映させる作業。
- コストが安価になった領域。
- AI エージェントやレビューラーとして AI に任せる。
実行フロー
- コードベースの分析: GitHub Issue を作成し、実施すべき変更と機能との整合性を評価する。
- AI による実装と処理:
- Issue は AI システムが「スキル(手順)」および「サブエージェント」で処理します。
- 「スキル」はタスク固有の Markdown ファイルとして定義されます。
- 「サブエージェント」は限定的な任務を持ち、フルコンテキストをダンプしません。
- レビューとマージ: AI が Pull Request (PR) を作成し、私がテストカバレッジや影響範囲を確認してレビューします。
DDD(ドメイン駆動設計)を基盤とする準備
戦略的な層を固めるために、**DDD(ドメイン駆動設計)**を導入し、ビジネス要件と技術実装の間に「共通語」を作ります。
ドメイン・マニフェストの導入
各リポジトリのルートに
を配置し、リポジトリが自身を定義する宣言書(マニフェスト)を作成します。.workflow.json
- 機能: 保持言語、エージェントの読み取り順序、チェック項目などを定義。
- 重要要素: ドメインに関する声明(プロジェクト名の唯一のレジストリ)。
実装例:job-offer-box
フロントエンドマニフェスト
job-offer-box{ "domain": { "project": "job-offer-box", "contexts": [ { "name": "job-box-web", "docs": "CONTEXT.md", "subdomain": "supporting", "edges": [ { "to": "hyperion/job-offer-backend", "direction": "outbound", // Web が Backend を呼び出すため外向き "pattern": "unclassified", "owner": "supplier", // 紛争時は Backend (supplier) が優先 "shape": "codegen from the backend's document...", "note": "conformist on write and an anticorruption layer on read..." } ] } ] } }
コンテキストと用語の標準化
マニフェストを基盤に、各コンテキストごとに
CONTEXT.md を配置します。
- 生きた辞書: 用語の正確な意味と、意図的に排除すべき同義語を定義。
- 上下関係の整理:
- コードを所有するリポジトリ上にファイルを配置。
- コンテキストマップ(
)は生成器スクリプトにより作成され、使い捨て・再生成可能。CONTEXT-MAP.md
- 所有権の明確化:
- バックエンド (
) にはプロダクト言語(Job Offer, Profile など)を所有させる。hyperion - フロントエンド (
) には画面用語(View Model など)のみを所有し、他はjob-box-web
と标记する。[published]
- バックエンド (
両側による宣言と自動整合性チェック
各エッジ(接続)について、両側のリポジトリで宣言を行います。
- 重複のメリット: この二重宣言が全体の意味を構成します。
- 自動照合: スキルとして、マニフェスト変更時やオンボーディング時などに実行。
- サプライヤー側(定義元)とコンシューマー側(利用元)の不一致を検出。
- 不一致は「発見」として記録され、該当リポジトリに DDD Issue として開票されます。
- 自己修復: Issue を修正後、スキルを再実行することで自動的に閉じられます。
まとめ:今後は何が起こるか
この手法により、コードベースの戦略的層が確立されます。
- マップと辞書が定義された後: コードベースに集中してドメインモデルを実装できます。
- LLM の役割変化:
- システム全体の共有理解を可能にするため、LLM は「推測」から「答え」を与える存在へ変化します。
- 「この単語の意味は何か」「誰が所有しているか」「コンテキストの境界はどこか」という問いに対して、コードベース自身が明確な回答を提供します。
- 効果: エージェントの誤推測を防ぎ、レガシーコードへの安全な侵入を可能にします。