Skip to main content
Lesson 8 of 12 · Grok Vision: Understanding Images

Multi-Image Comparison

Lesson 8 of 12 Updated July 30, 2026 Beginner
On this page
  1. Analyze Multiple Images in a Single Request
  2. Multi-Image Request Structure
  3. Use Case: Before/After Comparison
  4. Use Case: Temporal Tracking
  5. Use Case: Quality Control
  6. Use Case: Competitive Analysis
  7. Optimizing Multi-Image Requests
  8. Key Takeaways

Analyze Multiple Images in a Single Request

One of Grok Vision’s key strengths is the ability to send an unlimited number of images in a single request. This opens up unique possibilities for comparison, temporal tracking, and cross-analysis that single-image APIs cannot offer.

Multi-Image Request Structure

The format is simple: add as many input_image objects as needed to the input array, interleaving them with text to guide the analysis:

response = client.responses.create(
    model="grok-4.5",
    input=[
        {"type": "input_text", "text": "Image A:"},
        {"type": "input_image", "image_url": url_image_a},
        {"type": "input_text", "text": "Image B:"},
        {"type": "input_image", "image_url": url_image_b},
        {"type": "input_text", "text": "Compare these two images in detail."}
    ]
)

Labeling each image with text (“Image A”, “Image B”) helps the model structure its response and clearly reference each image.

Use Case: Before/After Comparison

Ideal for project tracking, renovation, design, or quality control:

def comparer_avant_apres(url_avant, url_apres):
    prompt = """Compare these two images (before and after) and identify:

1. The main changes
2. Elements that have not changed
3. Visible improvements
4. Any potential issues introduced

Present your response as a structured list."""

    response = client.responses.create(
        model="grok-4.5",
        input=[
            {"type": "input_text", "text": "BEFORE:"},
            {"type": "input_image", "image_url": url_avant, "detail": "high"},
            {"type": "input_text", "text": "AFTER:"},
            {"type": "input_image", "image_url": url_apres, "detail": "high"},
            {"type": "input_text", "text": prompt}
        ],
        store=False
    )
    return response.output_text

Use Case: Temporal Tracking

Track the evolution of a location, product, or process over time:

def analyser_evolution(images_chronologiques):
    """images_chronologiques: list of {"url": ..., "date": ...}"""
    input_data = []

    for img in images_chronologiques:
        input_data.append({
            "type": "input_text",
            "text": f"Photo from {img['date']}:"
        })
        input_data.append({
            "type": "input_image",
            "image_url": img["url"],
            "detail": "auto"
        })

    input_data.append({
        "type": "input_text",
        "text": """Analyze the chronological evolution visible in
these images. Identify progressive changes, trends,
and any notable events between the different dates."""
    })

    response = client.responses.create(
        model="grok-4.5",
        input=input_data,
        store=False
    )
    return response.output_text

Use Case: Quality Control

Compare a manufactured product to its reference model:

def controle_qualite(url_reference, url_produit):
    prompt = """Compare the photographed product to the reference model.

Identify:
1. Compliance (what matches the model)
2. Non-compliance (deviations, defects, differences)
3. Severity of each non-compliance (minor, major, critical)

Return a JSON with:
{
  "compliant": true/false,
  "score": 0-100,
  "compliances": [...],
  "non_compliances": [
    {"description": "...", "severity": "minor|major|critical"}
  ]
}"""

    response = client.responses.create(
        model="grok-4.5",
        input=[
            {"type": "input_text", "text": "REFERENCE (expected model):"},
            {"type": "input_image", "image_url": url_reference, "detail": "high"},
            {"type": "input_text", "text": "PRODUCT to check:"},
            {"type": "input_image", "image_url": url_produit, "detail": "high"},
            {"type": "input_text", "text": prompt}
        ],
        store=False
    )
    return response.output_text

Use Case: Competitive Analysis

Compare interfaces, packaging, or product presentations from competitors:

def analyser_concurrence(images_concurrents):
    """images_concurrents: [{"brand": "...", "url": "..."}]"""
    input_data = []

    for concurrent in images_concurrents:
        input_data.append({
            "type": "input_text",
            "text": f"{concurrent['brand']}:"
        })
        input_data.append({
            "type": "input_image",
            "image_url": concurrent["url"],
            "detail": "auto"
        })

    input_data.append({
        "type": "input_text",
        "text": """Compare these competitor products/interfaces.
For each, identify visual strengths and weaknesses.
Provide a positioning recommendation."""
    })

    response = client.responses.create(
        model="grok-4.5",
        input=input_data,
        store=False
    )
    return response.output_text

Optimizing Multi-Image Requests

When you send many images, token consumption increases rapidly. Here are a few optimization strategies:

Adjust the Detail Level

Use low for general comparisons and high only when analyzing fine details:

# Global comparison: low is sufficient
detail = "low"  # ~256 tokens per image

# Defect analysis: high required
detail = "high"  # ~1024-1792 tokens per image

Limit the Number of Images per Request

Even though there is no hard limit, with more than 10-15 images the analysis quality may decrease. The model has a finite context and must distribute it across all images:

# If more than 10 images, process in batches
def analyser_par_lots(images, taille_lot=10):
    resultats = []
    for i in range(0, len(images), taille_lot):
        lot = images[i:i + taille_lot]
        resultat = analyser_lot(lot)
        resultats.append(resultat)
    return fusionner_resultats(resultats)

Resize Images

If you are comparing high-resolution photos for general analysis, resize them before sending to reduce tokens:

def preparer_pour_comparaison(chemin, taille_max=(800, 800)):
    img = Image.open(chemin)
    img.thumbnail(taille_max)
    # ... encode to base64

Key Takeaways

  • The number of images per request is unlimited — this is a key advantage of the xAI API
  • Label each image with text to structure the analysis
  • Adjust the detail parameter to the type of comparison
  • Beyond 10-15 images, process in batches to maintain quality
  • Use cases include: before/after, temporal tracking, quality control, competitive analysis