0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

# LLMのゴミ出力を自動検出。v1.6で「失敗から学ぶ」MCPサーバーに進化した話

Posted at

はじめに

前回の記事で紹介した Code Intelligence MCP Server が、v1.6 まで大幅に進化しました。

前回は「調べずに書くを物理的に禁止する」フェーズゲート方式を紹介しましたが、今回は以下の機能を追加しました:

  • v1.2: Git ブランチによるゴミ検出
  • v1.3: 設計ドキュメントから自動でルールを抽出するサブエージェント
  • v1.4: 検証ループでハマった時の介入システム
  • v1.5: 実装後の品質レビュー
  • v1.6: stale ブランチ警告とブランチライフサイクル管理

v1.2: Git ブランチによるゴミ検出

問題:LLMは「ついでに」余計なものを書く

LLMにコード修正を依頼すると、こんなことがよく起こります:

# 依頼: AuthService のバグ修正

# LLMが書いたコード
def login(self, username, password):
    print(f"DEBUG: username={username}")  # ← デバッグログ
    print(f"DEBUG: password={password}")  # ← 本番に入れたらまずい
    # 以下修正コード...

他にも:

  • console.log() が残ったまま
  • 古いコードがコメントアウトで残っている
  • 依頼していないファイルまで修正している
  • test.pydebug.html が生成されている

解決策: Git ブランチ + PRE_COMMIT フェーズ

v1.2 では、LLMの書き込みを Git ブランチで隔離し、コミット前に全変更をレビューできるようにしました。

┌──────────────────────────────────────────────────────────┐
│  Base Branch (例: main, feature/xxx)                      │
│  └── タスク開始時の状態                                   │
├──────────────────────────────────────────────────────────┤
│  Task Branch (llm_task_{session_id}_from_{base})          │
│  └── LLMの変更がここに蓄積                                │
└──────────────────────────────────────────────────────────┘

新しいワークフロー

EXPLORATION → ... → READY → PRE_COMMIT → QUALITY_REVIEW → Finalize
                      ↓         ↓              ↓
                   実装完了   ゴミ検出      品質チェック
                              keep/discard

PRE_COMMIT フェーズでできること:

# 全変更を確認
mcp__code-intel__review_changes

# 結果例
{
  "changes": [
    {"path": "auth/service.py", "change_type": "modified", "diff": "..."},
    {"path": "debug.log", "change_type": "added", "diff": "..."},  # ← 怪しい
    {"path": "auth/test_tmp.py", "change_type": "added", "diff": "..."}  # ← 怪しい
  ]
}

# keep/discard を指定してコミット
mcp__code-intel__finalize_changes
  reviewed_files: [
    {"path": "auth/service.py", "decision": "keep"},
    {"path": "debug.log", "decision": "discard", "reason": "デバッグ出力"},
    {"path": "auth/test_tmp.py", "decision": "discard", "reason": "一時ファイル"}
  ]
  commit_message: "fix: AuthService の認証バグを修正"

Git ブランチ統合

  1. start_session → 元ブランチを記録
  2. begin_phase_gatellm_task_{session_id}_from_{base} ブランチ作成
  3. 実装中 → タスクブランチに変更が蓄積
  4. finalize_changes → keep のみをコミット、discard は破棄
  5. merge_to_base → 元ブランチにマージ、タスクブランチ削除

中断時のクリーンアップ:

# 中断したセッションのゴミを一括削除
/code --clean

v1.3: Document Research(設計ドキュメント自動調査)

問題:プロジェクトルールが多すぎて伝えきれない

大規模プロジェクトでは、守るべきルールが散在しています:

docs/
├── Architecture/
│   ├── app.md           ← "イベント/リスナーパターンを使え"
│   └── notes.md         ← "Octane環境ではファイルセッションNG"
├── DB/
│   └── customers.md     ← "会員は仮登録/本登録の2状態がある"
└── Security/
    └── auth.md          ← "パスワードは必ずHash::make()"

これらを毎回プロンプトに書くのは現実的ではないし、タスクに関係ないルールまで入れると無駄にコンテキストを消費します。

解決策: サブエージェントによる動的ルール抽出

v1.3 では、実装開始前にサブエージェントが設計ドキュメントを調査し、そのタスクに関係するルールだけを抽出します。

┌────────────────────────────────────────────────────────┐
│  Layer 1: project_rules (常に適用)                      │
│  └── CLAUDE.md から抽出した DO/DON'T リスト            │
│      例: "Service層でビジネスロジック"                  │
│          "Controllerに複雑なロジック禁止"               │
└────────────────────────────────────────────────────────┘
                         ↓
┌────────────────────────────────────────────────────────┐
│  Layer 2: mandatory_rules (タスク固有)                  │
│  └── サブエージェントが docs/ を調査して抽出            │
│      例: "会員登録 → customers.md の2状態ルール必須"    │
│          "メール送信 → Events/Listeners パターン必須"   │
└────────────────────────────────────────────────────────┘

実際の動作

ユーザー: /code 会員登録機能を実装して

[DOCUMENT_RESEARCH フェーズ]
サブエージェント: docs/ を調査中...
  → docs/DB/customers.md を発見
  → "会員は provisional/active の2状態" (line 127-130)
  → docs/Architecture/app.md を発見
  → "メール送信は Events/Listeners" (line 495-574)

mandatory_rules:
  - R1: "Members have two states: provisional and active" (customers.md:127)
  - R2: "Use Events/Listeners pattern for email" (app.md:495)

[EXPLORATION フェーズ]
submit_understanding:
  rule_acknowledgment: ["R1", "R2"]  ← 必須
  rule_compliance_plan:
    R1: "Member モデルに status enum を追加"
    R2: "MemberRegistered イベントを作成"

ルール適用の強制

acknowledge しないと先に進めない:

// NG: ルール無視で submit_understanding
{
  "error": "rule_acknowledgment_missing",
  "missing_rules": ["R1", "R2"],
  "hint": "All mandatory_rules must be acknowledged"
}

v1.4: Intervention System(介入システム)

問題:検証が通らずにループする

LLMが実装 → 検証失敗 → 修正 → 検証失敗... を繰り返すことがあります。同じアプローチで何度もリトライしても解決しません。

解決策: 介入プロンプト

3回連続で検証に失敗すると、介入プロンプトが発動します:

実装 → 検証失敗 → 修正 → 検証失敗 → 修正 → 検証失敗
                                              ↓
                                     介入プロンプト発動
                                     「別のアプローチを試せ」

.code-intel/interventions/ にプロンプトを配置:

.code-intel/interventions/
├── verification_loop.md  ← 検証ループ時の介入
└── custom.md             ← カスタム介入

介入プロンプト例(verification_loop.md):

## 検証が3回連続で失敗しました

現在のアプローチでは解決できていません。以下を試してください:

1. エラーメッセージを再度確認
2. 根本的に異なるアプローチを検討
3. 必要なら EXPLORATION に戻って調査

v1.5: Quality Review(品質レビュー)

問題:コードは動くけど品質が低い

検証は通ったけど、こんなコードが残っていることがあります:

  • 未使用の import
  • デッドコード
  • ハードコードされた秘密情報
  • 命名規則違反

解決策: QUALITY_REVIEW フェーズ

PRE_COMMIT(ゴミ検出)の後に、品質チェックを追加しました:

READY → POST_IMPL_VERIFY → PRE_COMMIT → QUALITY_REVIEW → Finalize
                                              ↓
                                         問題あり?
                                              ↓
                                         READY に戻る

品質レビューのチェック項目(.code-intel/review_prompts/quality_review.md):

カテゴリ チェック項目
Code Quality 未使用 import、デッドコード、重複コード
Conventions CLAUDE.md ルール、命名規則、ファイル構造
Security ハードコード秘密、ログに機密情報、入力検証
Performance N+1 クエリ、不要ループ、メモリリーク

問題があれば READY に戻してやり直し:

// 品質レビュー結果
{
  "issues_found": true,
  "issues": [
    "Unused import 'os' in auth/service.py:3",
    "console.log left in auth/service.js:45"
  ],
  "next_action": "Fix the issues in READY phase"
}

v1.6: Branch Lifecycle(ブランチライフサイクル)

問題:前回のタスクブランチが残ったまま

セッションが中断された場合、llm_task_* ブランチが残ったまま次のタスクを始めようとすることがあります。

解決策: begin_phase_gate での stale ブランチ検出

v1.6 では、ブランチ作成を begin_phase_gate に分離し、stale ブランチ警告を追加しました:

start_session (ブランチ作成なし)
    ↓
begin_phase_gate
    ↓
[stale ブランチあり?] → ユーザーに確認
    ↓                    ├─ 削除して続行
    ↓                    ├─ マージして続行
    ↓                    └─ そのまま続行
ブランチ作成 → フェーズゲート開始

ユーザーへの確認:

前回のタスクブランチが残っています:
  - llm_task_xyz_from_main (3 commits)

どうしますか?
1. 削除して続行(変更を破棄)
2. マージして続行(変更を取り込む)
3. そのまま続行(前回のブランチは残す)

フェーズマトリックス

各オプションで何が有効になるかの一覧:

オプション 探索 実装 検証 介入 ゴミ取 品質 ブランチ
(デフォルト)
--no-verify
--no-quality
--fast / -f
--quick / -q

コマンドフラグ(v1.6)

# フルモード(全フェーズ実行)
/code add login feature

# 高速モード(探索スキップ、ブランチあり、既知の修正向け)
/code -f fix known issue in login validation

# クイックモード(探索スキップ、ブランチなし、単純タスク向け)
/code -q change button color to blue

# 検証のみ(既存コードをテスト)
/code -v sample/hello.html

# 検証スキップ
/code --no-verify fix typo

# 品質レビュースキップ
/code --no-quality quick fix

# ドキュメント調査をカスタマイズ
/code --doc-research=security,database add user management

# ドキュメント調査をスキップ
/code --no-doc-research fix README typo

# 介入システムをスキップ
/code -ni fix obvious bug

# クリーンアップ(中断セッションのゴミ削除)
/code -c

# フルリビルド(インデックス再構築)
/code -r

セットアップ

新規セットアップ

# 1. MCP サーバーをクローン
git clone https://github.com/tech-spoke/llm-helper.git
cd llm-helper
./setup.sh

# 2. プロジェクト初期化
./init-project.sh /path/to/your-project

# 3. .mcp.json 設定(init-project.sh の出力をコピー)

# 4. スキルをコピー(オプション)
cp .claude/commands/*.md /path/to/your-project/.claude/commands/

# 5. Claude Code 再起動

作成されるディレクトリ:

your-project/
└── .code-intel/
    ├── config.json        ← 設定
    ├── context.yml        ← プロジェクトルール・ドキュメント調査設定
    ├── chroma/            ← ChromaDB データ
    ├── agreements/        ← 成功パターン保存
    ├── logs/              ← DecisionLog, OutcomeLog
    ├── verifiers/         ← 検証プロンプト
    ├── doc_research/      ← ドキュメント調査プロンプト
    ├── interventions/     ← 介入プロンプト
    └── review_prompts/    ← 品質レビュープロンプト

既存ユーザーのアップグレード(v1.2 以前から)

新規セットアップの場合は不要です。init-project.sh がすべてのディレクトリを作成します。

# 1. MCP サーバー更新
cd /path/to/llm-helper
git pull
./setup.sh

# 2. スキル更新
cp .claude/commands/*.md /path/to/your-project/.claude/commands/

# 3. 不足ディレクトリ作成
cd /path/to/your-project
mkdir -p .code-intel/{logs,verifiers,doc_research,interventions,review_prompts}

# 4. テンプレートコピー(既存ファイルは上書きしない)
cp -n /path/to/llm-helper/.code-intel/verifiers/*.md .code-intel/verifiers/
cp -n /path/to/llm-helper/.code-intel/doc_research/*.md .code-intel/doc_research/
cp -n /path/to/llm-helper/.code-intel/interventions/*.md .code-intel/interventions/
cp -n /path/to/llm-helper/.code-intel/review_prompts/*.md .code-intel/review_prompts/

まとめ

バージョン 追加機能 解決する問題
v1.1 マークアップ緩和 UI修正に過剰な調査
v1.2 Git ブランチ + PRE_COMMIT デバッグログ、ゴミファイル混入
v1.3 Document Research プロジェクトルールの伝達漏れ
v1.3 Verifier 書いて終わり、テストしない
v1.4 Intervention System 検証ループでハマる
v1.5 Quality Review コードは動くけど品質が低い
v1.6 Branch Lifecycle 前回のブランチが残ったまま

「調べて→書いて→確認して→品質チェック→クリーンアップ」の全工程を強制することで、LLMは単なるコード生成機ではなく、責任あるエンジニアの思考プロセスをトレースするようになります。


リンク


タグ

Claude MCP AI コード生成 開発効率化 オープンソース LLM Git コードレビュー 品質管理

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?