Log-Driven Development (LDD)
概要: Log-Driven Development(LDD)は、思考プロセスと作業結果を完全に構造化ログとして記録する運用手法です。codex_prompt_chain、tool_invocations、memory_bankの3要素により、Agent間コンテキスト共有と監査可能性を実現します。
対象読者: 実装者 / Agent開発者 所要時間: 12分 前提知識: Agent階層システム
LDDの目的
3つの主要目標
- 思考プロセスの可視化: AIがどのように考え、判断したかを記録
- 作業履歴の完全追跡: すべてのコマンド実行を監査可能に
- Agent間コンテキスト共有: メモリバンクによる知識継承
従来のログとの違い
| 従来のログ | LDD |
|---|---|
| エラー時のみ記録 | すべての作業を記録 |
| 実行結果のみ | 思考プロセス + 実行結果 |
| ファイル単位 | 構造化YAML/JSON |
| Agent単体 | Agent間共有 |
LDD構成要素
1. codex_prompt_chain
役割: 思考プロセスの構造化記録
codex_prompt_chain:
intent: "タスクの目的を1文で記載"
plan:
- "主要ステップ1(5-7語)"
- "主要ステップ2(5-7語)"
- "主要ステップ3(5-7語)"
implementation:
- "編集/追加したファイル: src/auth/login.ts"
- "編集/追加したファイル: tests/auth/login.test.ts"
verification:
- "実行したテスト: npm run test:unit"
- "検証結果: ESLint 0 errors, TypeScript 0 errors"
実例: Issue #270の記録
codex_prompt_chain:
intent: "Firebase Auth invalid-credential エラーを修正し、E2Eテストを追加する"
plan:
- "Firebase認証エラー原因特定"
- "invalid-credentialエラー修正"
- "E2Eテスト追加(Playwright)"
- "ドキュメント更新"
implementation:
- "src/services/authService.ts: 認証ロジック修正"
- "src/services/authService.ts: エラーハンドリング追加"
- "tests/e2e/auth.spec.ts: E2Eテスト追加"
- "docs/AUTH.md: 認証フロー図更新"
verification:
- "ESLint: 0 errors"
- "TypeScript: 0 errors"
- "Test coverage: 85% (target: 80%)"
- "E2E test: 100% pass"
- "Quality score: 95/100"
2. tool_invocations
役割: 実行コマンド履歴の完全記録
tool_invocations:
- command: "npm run lint"
workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
timestamp: "2025-10-10T12:34:56Z"
status: "passed"
notes: "ESLintエラー0件"
- command: "npm run build"
workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
timestamp: "2025-10-10T12:35:20Z"
status: "passed"
notes: "TypeScriptコンパイル成功"
- command: "npm run test:unit"
workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
timestamp: "2025-10-10T12:36:10Z"
status: "passed"
notes: "全テスト成功、カバレッジ85%"
- command: "git commit -m 'fix: Firebase Auth修正'"
workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
timestamp: "2025-10-10T12:37:00Z"
status: "passed"
notes: "コミット成功 (SHA: abc123)"
JSON形式(機械可読):
{
"tool_invocations": [
{
"command": "npm run lint",
"workdir": "/Users/shunsuke/Dev/Autonomous-Operations",
"timestamp": "2025-10-10T12:34:56Z",
"status": "passed",
"duration_ms": 3500,
"exit_code": 0,
"notes": "ESLintエラー0件"
}
]
}
3. memory_bank_updates
役割: Agent間コンテキスト共有
memory_bank_updates:
- section: "active_tasks"
summary: "Issue #270の実装完了、PR #309作成済み"
timestamp: "2025-10-10T12:40:00Z"
details:
- task_id: "task-270"
- status: "completed"
- next_action: "PR #309のレビュー待ち"
- blocking: []
- section: "known_issues"
summary: "Firebase Auth修正により、既知の認証エラーが解消"
timestamp: "2025-10-10T12:40:30Z"
details:
- issue_id: 270
- resolution: "authService.tsのエラーハンドリング改善"
- impact: "全ユーザーの認証成功率向上"
ログファイル構造
ディレクトリ構成
.ai/
├── logs/ # LDDログ
│ ├── 2025-10-10.md # 日次ログ(人間可読)
│ ├── 2025-10-10-1234-issue-270.yaml # タスクログ(YAML)
│ └── 2025-10-10-1234-issue-270.json # タスクログ(JSON)
├── parallel-reports/ # 並行実行レポート
│ └── agents-parallel-20251010-1234.json
└── issues/ # Issue同期
└── issue-270.md
ログファイル命名規則
.ai/logs/YYYYMMDD-HHMM-{task}.{format}
例:
- 20251010-1234-issue-270.yaml
- 20251010-1234-issue-270.json
- 20251010-1234-pr-309.yaml
ワークフロー
1. タスク開始時
# Step 1: セッション初期化
session:
id: "session-1759552488828"
device: "MacBook Pro 16-inch"
timestamp: "2025-10-10T12:00:00Z"
task: "Issue #270 Firebase Auth修正"
# Step 2: codex_prompt_chain作成
codex_prompt_chain:
intent: "Firebase Auth invalid-credential エラー修正"
plan:
- "認証エラー原因特定"
- "エラーハンドリング修正"
- "E2Eテスト追加"
implementation: [] # 空(実装時に追記)
verification: [] # 空(検証時に追記)
2. 実装中
# Step 3: tool_invocations逐次追記
tool_invocations:
- command: "git checkout -b fix/270-auth-bug"
timestamp: "2025-10-10T12:05:00Z"
status: "passed"
- command: "code src/services/authService.ts"
timestamp: "2025-10-10T12:10:00Z"
notes: "認証ロジック修正開始"
- command: "npm run lint"
timestamp: "2025-10-10T12:20:00Z"
status: "passed"
notes: "ESLint通過"
3. タスク完了時
# Step 4: implementation/verification完成
codex_prompt_chain:
intent: "Firebase Auth invalid-credential エラー修正"
plan: [...]
implementation:
- "src/services/authService.ts: 認証ロジック修正"
- "tests/e2e/auth.spec.ts: E2Eテスト追加"
verification:
- "ESLint: 0 errors"
- "TypeScript: 0 errors"
- "Quality score: 95/100"
# Step 5: memory_bank更新
memory_bank_updates:
- section: "active_tasks"
summary: "Issue #270完了"
next_action: "PR #309レビュー待ち"
@memory-bank.mdc
構造
# @memory-bank.mdc
**保持期間**: 90日
**更新頻度**: タスク完了時
---
## Active Tasks
### Task: Issue #270 Firebase Auth修正
- Status: ✅ Completed
- Completed: 2025-10-10T12:40:00Z
- Quality Score: 95/100
- Next Action: PR #309レビュー待ち
---
## Known Issues
### Issue #270: Firebase Auth invalid-credential
- Resolution: authService.tsのエラーハンドリング改善
- Impact: 全ユーザーの認証成功率向上
- Resolved: 2025-10-10
---
## Technical Decisions
### Decision: Firebase Auth v10.x採用
- Date: 2025-10-08
- Reason: 最新セキュリティパッチ適用
- Impact: 認証フローの安定性向上
---
## Performance Metrics
### 2025-10-10
- AI Task成功率: 97%
- 平均実行時間: 3分
- 品質スコア平均: 92点
更新プロトコル
// scripts/update-memory-bank.ts
export class MemoryBankUpdater {
async update(section: string, content: string): Promise<void> {
const memoryBank = await this.readMemoryBank();
// セクション検索
const sectionIndex = memoryBank.indexOf(`## ${section}`);
if (sectionIndex === -1) {
// 新規セクション追加
memoryBank += `\n\n## ${section}\n\n${content}`;
} else {
// 既存セクション更新
memoryBank = this.replaceSection(memoryBank, section, content);
}
await this.writeMemoryBank(memoryBank);
}
async cleanup(retentionDays: number = 90): Promise<void> {
const memoryBank = await this.readMemoryBank();
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
// 古いエントリ削除
const cleaned = this.removeOldEntries(memoryBank, cutoffDate);
await this.writeMemoryBank(cleaned);
}
}
Quality Gates
品質ゲート定義
| ゲート | 条件 | 承認者 |
|---|---|---|
| PRD承認 | .ai/prd.md チェックボックスが全てON | ユーザー |
| ARCH承認 | .ai/arch.md チェックボックスが全てON | ユーザー |
| テストパス | 主要テストが成功 | コードオーナー |
| 品質スコア | ReviewAgent評価 ≥ 80点 | 自動判定 |
ゲート検証
// scripts/quality-gate.ts
export class QualityGate {
async verify(task: Task): Promise<boolean> {
// 1. PRD承認チェック
const prdApproved = await this.checkPRDApproval();
// 2. ARCH承認チェック
const archApproved = await this.checkARCHApproval();
// 3. テスト成功チェック
const testsPass = await this.checkTests();
// 4. 品質スコアチェック
const qualityScore = await this.getQualityScore(task);
return (
prdApproved &&
archApproved &&
testsPass &&
qualityScore >= 80
);
}
}
Handoff Summary Template
ハンドオフ要約
タスク完了時に次のフォーマットで要約を作成:
## Handoff Summary
### 状態
- Task: Issue #270 Firebase Auth修正
- Status: ✅ Completed
- Quality Score: 95/100
### 対象ブランチ/コミット
- Branch: fix/270-auth-bug
- Commit: abc123def456
- PR: #309 (Draft)
### 未完了作業
- なし
### 推奨次ステップ
1. PR #309のレビュー
2. mainブランチへのマージ
3. 本番環境デプロイ
### 備考
- 認証フローの安定性が向上
- E2Eテスト100%成功
- セキュリティスキャン通過
自動化
LDD自動記録
// agents/base-agent.ts
export abstract class BaseAgent {
protected async recordLDD(action: LDDAction): Promise<void> {
const logFile = this.getLDDLogFile();
// tool_invocation記録
await this.appendToolInvocation(logFile, {
command: action.command,
workdir: action.workdir,
timestamp: new Date().toISOString(),
status: action.status,
notes: action.notes
});
// memory_bank更新
if (action.updateMemoryBank) {
await this.updateMemoryBank(action.section, action.summary);
}
}
protected getLDDLogFile(): string {
const date = new Date().toISOString().split('T')[0];
const time = new Date().toISOString().split('T')[1].slice(0, 5).replace(':', '');
return `.ai/logs/${date}-${time}-${this.taskId}.yaml`;
}
}
定期クリーンアップ
# .github/workflows/ldd-cleanup.yml
name: LDD Log Cleanup
on:
schedule:
- cron: '0 0 * * 0' # 毎週日曜0時
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: 古いログ削除(90日以上)
run: |
find .ai/logs/ -type f -mtime +90 -delete
npm run memory-bank:cleanup
ログ分析
統計データ抽出
# 成功率集計
jq '.tool_invocations[] | select(.status == "passed")' .ai/logs/*.json | wc -l
# 平均実行時間
jq '.tool_invocations[].duration_ms' .ai/logs/*.json | \
awk '{sum+=$1; count++} END {print sum/count "ms"}'
# エラー頻度
jq '.tool_invocations[] | select(.status == "failed") | .command' .ai/logs/*.json | \
sort | uniq -c | sort -nr
ダッシュボード連携
// scripts/dashboard-generator.ts
export class DashboardGenerator {
async generateFromLDD(): Promise<Dashboard> {
// 全ログファイル読込
const logs = await this.readAllLogs();
// 統計算出
const stats = {
totalTasks: logs.length,
successRate: this.calculateSuccessRate(logs),
avgDuration: this.calculateAvgDuration(logs),
qualityScoreAvg: this.calculateQualityScoreAvg(logs)
};
// ダッシュボード生成
return this.generateDashboard(stats);
}
}
ベストプラクティス
1. intent は明確に
# Good
intent: "Firebase Auth invalid-credential エラーを修正し、E2Eテストを追加する"
# Bad
intent: "バグ修正" # 不明確
2. plan は5-7語で簡潔に
# Good
plan:
- "認証エラー原因特定"
- "エラーハンドリング修正"
- "E2Eテスト追加"
# Bad
plan:
- "Firebase Authenticationの認証フローにおいて発生しているinvalid-credentialエラーの根本原因を特定するために、ログファイルとスタックトレースを詳細に分析し..." # 長すぎ
3. tool_invocations は全実行を記録
# Good: すべてのコマンドを記録
tool_invocations:
- command: "git checkout -b fix/270"
- command: "npm run lint"
- command: "npm run test"
- command: "git commit"
# Bad: 一部のみ記録
tool_invocations:
- command: "git commit" # 途中経過が不明
関連ドキュメント
- システム全体像 - 全体構成
- Agent階層システム - Agent構造
- 組織設計原則 - 5原則実装
- Agent運用マニュアル - 運用ガイド
次のステップ
- 組織設計原則 - 5原則の詳細を学ぶ
- Agent運用マニュアル - 実際の運用方法を理解する
最終更新: 2025-10-10 バージョン: 2.0.0 管理者: AI Operations Lead