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?

ClineとMCPサーバーでエビデンスチェック

Last updated at Posted at 2025-09-28

普段はインフラSEをやっております。
インフラ構築の作業では、クラウドやOS、ミドルウェア製品の設定をチマチマと行っておりますが、その作業の中で「設計書と画像エビデンスの内容を比較してチェックする」といった工程も発生します。
正直、メンドクサイです……。
本記事では、そのエビデンスチェック作業をClineを使って自動化できないか?についてまとめてみました。

環境

  • VSCode 1.104.2
  • Cline 3.32.0
  • Python 3.11
  • OpenAIを使用

仕組み

設計書について

設計書としてはExcelで作成したパラメーターシートがよく使われますが、セルが結合されていたり、階層的な構造になっていたりするため、Excelからテキストを抽出して入力とした場合、エビデンス画像との比較がうまくいくか不明です。
そこで、設計書のスクリーンショットと画像エビデンスを直接比較する方式を採用しました。

設計書とエビデンスの比較方法

以下の処理を.clinerulesで定義しておきます。

  • 設計書の画像とエビデンスを比較します。画像比較の処理は生成AIで行います。これをMCPサーバー化します
  • 比較した結果、設計書の内容とエビデンスの内容が一致していれば、進捗ファイルにOKと記録、不一致があった場合はNGと記録します
  • すべての設計書画像のチェックし終えるまで、比較処理を繰り返します

画像比較用のMCPサーバーについて

  • 設計書の画像と画像エビデンスを比較する処理は生成AIを呼び出すMCPサーバーで行っています
  • MCPサーバーの引数は次の通り
    • 1つ目の画像:設計書の画像
    • 2つ目の画像:エビデンスの画像
    • 生成AIに渡すプロンプト:例:「設計書画像とエビデンス画像を比較し、設定値が設計通りかどうかを判定してください。」
  • 戻り値として比較結果を返します
    ソース
@mcp.tool()
async def analyze_two_images_mcp(
    image_path1: Annotated[str, Field(description="1枚目の解析対象画像ファイルの絶対パス。。必ず絶対パスを指定してください。例: /path/to/image1.jpg")],
    image_path2: Annotated[str, Field(description="2枚目の解析対象画像ファイルの絶対パス。必ず絶対パスを指定してください。例: /path/to/image2.jpg")],
    prompt: Annotated[str, Field(description="画像解析用のプロンプト")]
) -> Annotated[ImageAnalysisResponsePair, Field(description="2枚の画像の解析結果")]:
    """
    指定した2枚の画像とプロンプトを用いて画像解析を行い、解析結果を返します。
    """
    response = await ImageChatUtil.generate_image_pair_analysis_response_async(image_path1, image_path2, prompt)
    return response

生成AIによる画像比較の処理は、単純に2つの画像とプロンプトを生成AIに渡して結果を取得するだけです。
ソース

    @classmethod
    async def generate_image_pair_analysis_response_async(cls, path1: str, path2: str, prompt: str) -> ImageAnalysisResponsePair:
        """
        画像2枚とプロンプトから画像解析を行う。各画像のテキスト抽出、各画像の説明、プロンプト応答のCompletionOutputを生成して、ImageAnalysisResponsePairで返す
        """
        if prompt:
            modified_prompt = f"Prompt: {prompt}"
        else:
            modified_prompt = ""
        input_data = f"""
        Extract text from both images, describe both images, and respond to the prompt.
        Please reply in the following JSON format.
        {{
            "image1": {{
                "extracted_text": "Extracted text from first image (empty string if no text)",
                "description": "Description of first image (empty string if not needed)"
            }},
            "image2": {{
                "extracted_text": "Extracted text from second image (empty string if no text)",
                "description": "Description of second image (empty string if not needed)"
            }},
            "prompt_response": "Response to the prompt (empty string if no prompt)"
        }}
        {modified_prompt}
        """
        image1_content_part = cls.__create_image_content_part(path1)
        image2_content_part = cls.__create_image_content_part(path2)
        text_content_part = cls.__create_text_content_part(input_data)
        messages = [
            {"role": "user", "content": [image1_content_part, image2_content_part, text_content_part]}
        ]
        try:
            response = await cls.__chat(messages)
            response_dict = json.loads(response)
        except Exception as e:
            raise RuntimeError(f"Failed to analyze image pair: {e}")
        image1_dict = response_dict.get("image1", {})
        image2_dict = response_dict.get("image2", {})
        return ImageAnalysisResponsePair(
            image1_path=path1,
            image1_extracted_text=image1_dict.get("extracted_text", ""),
            image1_description=image1_dict.get("description", ""),
            image2_path=path2,
            image2_extracted_text=image2_dict.get("extracted_text", ""),
            image2_description=image2_dict.get("description", ""),
            prompt=prompt,
            prompt_response=response_dict.get("prompt_response", "")
        )

.clinerulesについて

エビデンスチェックの進捗管理や、チェック対象フォルダの指定、画像比較に使用するMCPサーバーの設定、処理フローは.clinerulesに記述します。
.clinerules

## 🎯 実行指示とワークフロー
- **Memory Bank** の各ドキュメントは、Clineの行動指針と進捗管理の基盤です。
- ユーザーからの指示に基づき、**Memory Bank** の内容を参照・更新しながら、設計書とエビデンス画像の比較・チェックを行います。
- 進捗や整備内容はすべて **Memory Bank** に記録され、セッション終了後も一貫した情報管理が可能です。
- **Memory Bank**を初期化してという指示があった場合、`memory-bank/` ディレクトリを削除し、再作成してください。
- 「エビデンスをチェックして」と指示されたら、下記ワークフローに従い、設計書画像フォルダ(data/design_doc_images)とエビデンス画像フォルダ(data/evidence_images)を比較してチェックを行い、進捗を`progress.md`に記録してください。
- 2つの画像比較にはMCPツール「analyze_two_images_mcp」を使用してください。
- 1つの画像の内容を確認するにはMCPツールを「analyze_image_mcp」を使用してください。
- エビデンス画像には設計書の内容と関係ない画像が含まれている場合があります。その場合は、設計書とマッチするエビデンスがないか別の画像ファイルを確認してください

実行例

Windowsのタイムゾーン設定が設計書通りになっているかのエビデンスチェックを実施してみます。

cline_mcp_settings.jsonの編集

`cline_mcp_settings.json`に画像比較用のMCPサーバーを登録します。
```json
{
  "mcpServers": {
    "analyze_image_mcp_simple": {
      "disabled": false,
      "timeout": 60,
      "type": "stdio",
      "command": "uv",
      "args": [
        "--directory",
        "<PATH_TO_VENV>",
        "run",
        "-m",
        "analyze_image_mcp_simple.mcp_modules.mcp_app_server"
      ],
      "env": {
        "OPENAI_API_KEY": "sk-****************",
        "OPENAI_COMPLETION_MODEL": "gpt-4.1"
      }
    }
  }
}
```

画像の準備

設計書の画像は以下のとおり
テスト用設計書.png

画像エビデンスは次のとおり。1つ目はダミーの画像で、2枚目が本来チェックしたい画像です。
生成AIが適切な画像に基づいてチェックしてくれるか試すためダミーを入れています。
テスト用エビデンス1.png
テスト用エビデンス2.png

これらのファイルをdata/design_doc_imagesdata/evidence_imagesに格納しておきます。

memory-bankの初期化

エビデンスチェックを始める前にmemory-bankを初期化しておきます。
memory-bankを初期化-1.png

.clinerulesの内容に従い、いくつかファイルが作成されます。エビデンスチェックの進捗を管理するprogress.mdはこんな感じです。
memory-bankを初期化-2.png

エビデンスチェック

clineでエビデンスチェックをしてみます。
エビデンスチェック-01.png

結果は次のとおり。
ダミーのエビデンスは判定不可として、適切なエビデンス画像の内容をチェックしています。
わざと間違った設定を行っていた箇所があるため、正しくNGと判定されました。
エビデンスチェック-02.png

まとめ

  • ClineとMCPサーバーを用いて、設計書画像とエビデンス画像を比較し、エビデンスチェックを自動化してみました。
  • 実行例では、エビデンスチェックがうまく機能しているように見えます。
    ただし、今回の例はチェック対象のパラメーター数や画像数が少ないため、実際のお仕事での利用にはさらなる検証が必要です。
  • 今回作成したMCPサーバーや.clinerulesは、analyze_image_mcp_simpleに公開しています。
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?