mcpField
V
verify-patterns

verify-patterns

github.com/aurite-aiテスト・品質4445 回インストール2 週間前に更新
リポジトリ

verify-patterns について

AI エージェントコードをローカルで検査し、無限ループや過剰なリトライ、ツールの不整合、コンテキスト肥大化につながるパターンを確認するスキルです。対象を絞ったチェックを行い、レポートを生成します。

主な機能

  1. 01一般的なエージェントフレームワークの検出
  2. 02エージェントとプロンプトファイルの特定
  3. 03ループとリトライ上限の確認
  4. 04ツール定義と参照の照合
  5. 05コンテキストサイズとグラフ循環の確認
  6. 06検証レポートの生成

活用シーン

  1. 01エージェントコードの無限ループ確認
  2. 02リトライ上限とツール参照の監査
  3. 03LangGraph の終了経路の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/aurite-ai/agent-verifier --skill verify-patterns

インストール後、Claude Code で/verify-patternsを入力して読み込まれたか確認します。

詳細

エージェントパターンの検証

目的

無限ループ、際限のない再試行、ツールの不一致、コンテキストのオーバーフローにつながる可能性がある、よくあるアンチパターンがAIエージェントのコードにないか検証します。分析はすべてローカルで行われます。

使用するタイミング

ユーザーが次のように依頼した場合に、このスキルを実行します。

  • 「エージェントパターンを検証して」
  • 「エージェントのループを確認して」
  • 「ツールを検証して」
  • 「再試行の上限を確認して」
  • 「エージェントの安全性を検証して」

注記: セキュリティ、品質、言語固有のチェックを含む完全な検証を行うには、ユーザーに 「verify agent」 と入力するよう伝えてください。

プロセス

ステップ 1:エージェントフレームワークを特定する

Python/TypeScript ファイルのインポートを確認し、エージェントフレームワークを特定します。

インポートパターンフレームワーク
from langgraph または import langgraphLangGraph
from crewai または import crewaiCrewAI
from autogen または import autogenAutoGen
from langchain または import langchainLangChain
openai/anthropic SDK のみを直接使用カスタム

フレームワークの設定ファイル langgraph.json、crew.yaml も確認します。

ステップ 2:エージェントのファイルを特定する

分析対象のファイルを探します。

優先ファイル:

  • graph.py、graph.ts — エージェントのワークフロー定義
  • tools.py、tools.ts、tools/*.py、tools/*.ts — ツールの実装
  • state.py、state.ts — 状態スキーマ
  • prompts.py、prompts/*.md、system.md — プロンプトテンプレート
  • agent.py、agent.ts — エージェントの主要ロジック

確認するディレクトリ:

  • src/agent/、agent/、src/、プロジェクトのルート
  • lib/、app/、packages/

分析から除外するもの:

  • skills/ ディレクトリ — これらはスキル定義であり、エージェントシステムプロンプトではありません
ステップ 3:パターンをチェックする
チェックの種類
  • [PATTERN] — 機械的なチェックです。記載どおりに適用します。
  • [HEURISTIC] — 判断が必要です。検出結果を明確に示します。

検出結果にはすべて、パターンの場合は [P]、ヒューリスティックの場合は [H] のタグを付けます。


3.1 [PATTERN] ループの安全性

機械的に適用します。「終了するかもしれないように見える」という理由でループを合格にしてはいけません。

検出するパターン合格条件重大度
Python の while True:同じブロックスコープ内に break 文があるなければ ⚠️ 警告
Go の for { }ブロック内に break または return があるなければ ⚠️ 警告
TS/JS の while (true)ブロック内に break または return があるなければ ⚠️ 警告
関数が自分自身を再帰呼び出しする再帰を伴わない戻り経路(ベースケース)がある、または深さ/カウンターパラメーターがあるなければ ⚠️ 警告

[HEURISTIC] フォールバック:認識されないループパターン

パターン表を適用した後、次の項目も確認します。

  • タイムアウトがなく、終了条件が外部/ランタイムの状態だけに依存するループ
  • 終了条件が文書化されていないまま無期限に yield するジェネレーター関数
  • タイムアウトパラメーターのないイベントループ/ポーリングループ
  • 深さの追跡なしに複数の関数にまたがって再帰呼び出しが連鎖するケース

⚠️ 警告として、次のように報告します。「既知のパターンには該当しない、終了しない可能性のあるループです — 終了条件を手動で確認してください」

3.2 [PATTERN] リトライ上限の適用

機械的に適用してください。必須パラメーターがない場合は、❌ Issue として報告してください。

Python — デコレーター方式:

ライブラリ/パターン必須パラメーター失敗条件
@retry (tenacity)stop=stop_after_attempt(n) または stop=stop_after_delay(n)stop= がない
@backoff.on_exceptionmax_tries=nmax_tries= がない

Python — HTTP クライアントのリトライ:

ライブラリ/パターン必須パラメーター失敗条件
urllib3.Retry(...)total=n(n > 0)total= がない、または total=0
HTTPAdapter(max_retries=Retry(...))Retry オブジェクトに total=n が必要total= がない
httpx.HTTPTransport(retries=n)retries=n(n > 0)retries= がない、または retries=0

Python — AWS SDK(boto3):

ライブラリ/パターン必須パラメーター失敗条件
Config(retries={...})max_attempts > 1max_attempts がない、または ≤ 1

注:明示的なリトライ設定がない boto3 は、SDK のデフォルト(3 回の試行)を使用します。設定がないことを報告しないでください。

JavaScript/TypeScript:

ライブラリ/パターン必須パラメーター失敗条件
retry(...) (async-retry)オプション内の retries: nretries: がない
pRetry(...) (p-retry)オプション内の retries: nretries: がない

カスタムのリトライループ(すべての言語):

検出するパターン合格条件失敗条件
ループ + try/except + continue整数カウンターと最大値チェックがあるカウンターがない → ❌ Issue

[HEURISTIC] フォールバック:認識されていないリトライパターン

パターン表を適用した後、次を確認してください。

  • 上記の表にない、「retry」を名前に含む関数/デコレーター
  • パッケージ名に「retry」を含むインポート済みモジュール(例:stamina、aiohttp_retry)
  • カウンターが見当たらない、スリープ + 例外処理 + 再呼び出しを含むループ
  • max_retries、retry_count、attempts などの設定キー

⚠️ Warning として報告してください:「既知のライブラリに一致しないリトライパターンの可能性があります。リトライ上限を手動で確認してください」


3.3 [PATTERN] ツールレジストリの一貫性

ステップ 1:定義済みのツールを収集する

ツール定義ファイルをスキャンします。いずれかのパターンで見つかった名前は、登録済みとして扱います。

Python — デコレータのパターン:

パターン名前の抽出方法
@tool(LangChain)を def に適用デコレータの下にある関数名
@function_tool(OpenAI Agents SDK)を def に適用デコレータの下にある関数名
@tool(name="...")name= 引数の値を使用

Python — dict/list のパターン:

パターン名前の抽出方法
{"type": "function", "function": {"name": "..."}}(OpenAI)"function" 内の "name" の値
{"name": "...", "input_schema": {...}}(Anthropic)トップレベルの "name"
{"name": "...", "description": "...", "parameters": {...}}トップレベルの "name"
ToolNode([func1, func2, ...])(LangGraph)リスト内の各関数名
tools = [func1, func2] / TOOLS = [...]リスト内の各識別子

TypeScript/JavaScript:

パターン名前の抽出方法
{ type: "function", function: { name: "..." } }(OpenAI)function: 内の name:
tool({ description: "...", parameters: z.object({...}) })const 変数名
new DynamicTool({ name: "...", ... })(LangChain.js)name: の値
zodFunction({ name: "...", ... })name: の値

ステップ 2:プロンプトからツール参照を収集する

.md、.txt、prompts.py をスキャンして、機能を示すバッククォートで囲まれた識別子を探します。

ステップ 3:相互参照する

検出内容重大度
定義リストにない参照❌ 問題(幻覚されたツール)
どのプロンプトにもない定義済みツール⚠️ 警告(ドキュメント化されていないツール)

[HEURISTIC] LLM に一度もバインドされていないツール

ツールの定義場所と LLM の呼び出し場所を探します。ツールが存在するのに LLM 呼び出しに接続されていない場合は、❌ 問題としてフラグを立てます:「ツールは定義されていますが、LLM の呼び出しに接続されていません」

[HEURISTIC] フォールバック:認識されないツール定義

ツールらしき構造をスキャンします。

  • "description" と "parameters" の両方のキーを持つ Dict
  • 構造化された docstring(名前、パラメーター、戻り値)を持つ関数
  • tools、tool_list、available_tools、functions という名前の変数
  • run()、execute()、または __call__() メソッドを持つクラス

件数に含め、次のように記します:「ヒューリスティックによりツールを検出しました。これが意図されたエージェントツールか確認してください。」


3.4 [PATTERN] コンテキストサイズの認識

計算式:token_estimate = len(file_content_chars) / 4

コンテンツ⚠️ 警告のしきい値❌ 問題のしきい値
システムプロンプトファイル> 4,000 tokens> 8,000 tokens
個々のツール説明> 500 tokens> 1,000 tokens
すべてのツール説明の合計> 2,000 tokens> 4,000 tokens

除外対象: skills/ ディレクトリ(オンデマンドで読み込まれ、埋め込まれないため)

[HEURISTIC] フォールバック:しきい値付近および標準外のケース

  • しきい値の 20% 以内の推定値 → トークナイザーの推奨事項とともにフラグを立てます
  • 動的プロンプト(f 文字列、.format())→ テンプレート単独で大きい場合にフラグを立てます
  • 複数のプロンプトを連結している場合 → 合計サイズを推定します
  • インクルードを含むプロンプト → 実効サイズが大きくなる可能性があると記します

3.5 [HEURISTIC] 明示的なツール一覧

システムプロンプトで次の項目を確認します。

  • 「利用可能なツール」や「次の機能を利用できます」のような見出し
  • ツールの機能に関する説明

ツールが定義されているのにシステムプロンプトに記載されていない場合は、フラグを立てます。


3.6 [PATTERN] LangGraph のグラフサイクル分析

(LangGraph が検出された場合のみ)

検出手順:

a. グラフファイル(graph.py、graph.ts、または StateGraph/MessageGraph を含むファイル)を見つけます

b. エッジマップを作成します:

  • workflow.add_edge(source, dest) — 条件なしのエッジ
  • workflow.add_conditional_edges(source, fn, mapping) — マッピングから遷移先を抽出します

c. サイクルを特定します:自身から到達可能なノード

d. 各サイクルについて、条件付きエッジを経由して END(または "__end__")に到達可能かどうかを確認します

条件重大度
サイクルが存在し、条件付きで END に到達可能✅ 合格
サイクルが存在し、END への経路がない❌ 問題
グラフに END ノードがない❌ 問題
ノードに出力エッジがなく、END でもない⚠️ 警告(行き止まり)

例 — 無限サイクル(❌ 問題):

workflow.add_edge("agent", "tools")
workflow.add_edge("tools", "agent")  # no path to END

例 — 終了経路のあるサイクル(✅ 合格):

workflow.add_conditional_edges("agent", should_continue, {
    "continue": "tools",
    "end": END
})
workflow.add_edge("tools", "agent")

[HEURISTIC] フォールバック:LangGraph 以外のグラフ

グラフに似た制御フローをスキャンします:

  • 遷移テーブルを持つステートマシン
  • 暗黙的なサイクルを伴うカスタムルーティング
  • LangGraph.js(キャメルケースのメソッド)
  • CrewAI/AutoGen のエージェント間の引き継ぎ
  • 終了経路のない隣接リスト

⚠️ 警告としてフラグを立てます:"循環している可能性のある制御フロー — 終了条件が存在することを確認してください"


ステップ 4:レポートを生成する
# Agent Pattern Verification Report

**Project:** [name or path]
**Date:** [current date]
**Framework detected:** [LangGraph | CrewAI | AutoGen | LangChain | Custom | None]
**Files analyzed:** [count]

## Summary

✅ X checks passed | ⚠️ Y warnings | ❌ Z issues

## Loop Safety

- [x] All loops have termination conditions
- [ ] ⚠️ Potential unbounded loop at `[file:line]`

## Retry Limits

- [x] All retry mechanisms have explicit limits
- [ ] ❌ Missing retry limit at `[file:line]`

## Tool Consistency

- [x] Tool registry found: X tools defined
- [ ] ❌ Y hallucinated tool references
- [ ] ⚠️ Z undocumented tools

## Context Size

- [x] System prompt within limits (~X tokens)
- [ ] ⚠️ System prompt exceeds recommended size

## Findings

> `[P]` = pattern-matched · `[H]` = heuristic

### ✅ Passing
- `[P]` [Check]: [confirmation]

### ⚠️ Warnings
- `[P|H]` [Check]: [description]
  - **Location:** [file:line]
  - **Suggestion:** [how to fix]

### ❌ Issues
- `[P|H]` [Check]: [description]
  - **Location:** [file:line]
  - **Rule:** [which rule violated]
  - **Fix:** [specific remediation]

## Recommendations

1. [Priority recommendation]
2. [Additional improvements]

セキュリティ、品質、言語固有のチェックを含む完全な検証を行うには、「verify agent」と言ってください。

コメント