Skip to main content

Product Photo Alt Text Writer

Generate SEO-friendly, accessible alt text and tags for product images.

Problem Statement

Who: E-commerce teams, content managers, accessibility specialists
Why: Good alt text improves accessibility and SEO. Manual writing is time-consuming at scale.

What You’ll Build

A recipe that analyzes product images and generates descriptive alt text with relevant tags.

Input/Output Contract

InputTypeRequiredDescription
image_pathstringYesPath to product image
brand_tonestringNoBrand voice (default: neutral)
localestringNoTarget locale (default: en-US)
OutputTypeDescription
alt_textstringGenerated alt text
tagsarrayRelevant product tags
okbooleanSuccess indicator

Prerequisites

export OPENAI_API_KEY=your_key_here
pip install praisonaiagents

Step-by-Step Build

1

Create Recipe Directory

mkdir -p ~/.praison/templates/product-photo-alt-text-writer
cd ~/.praison/templates/product-photo-alt-text-writer
2

Create TEMPLATE.yaml

name: product-photo-alt-text-writer
version: "1.0.0"
description: "Generate accessible alt text for product images"
author: "PraisonAI"
license: "MIT"

tags:
  - image
  - accessibility
  - ecommerce
  - seo

requires:
  env:
    - OPENAI_API_KEY
  packages:
    - praisonaiagents

inputs:
  image_path:
    type: string
    description: "Path to the product image"
    required: true
  brand_tone:
    type: string
    description: "Brand voice for alt text"
    required: false
    default: "neutral"
    enum:
      - neutral
      - luxury
      - casual
      - technical
  locale:
    type: string
    description: "Target locale for alt text"
    required: false
    default: "en-US"

outputs:
  alt_text:
    type: string
    description: "Generated alt text"
  tags:
    type: array
    description: "Relevant product tags"
  ok:
    type: boolean
    description: "Success indicator"

cli:
  command: "praison recipes run product-photo-alt-text-writer"
  examples:
    - 'praison recipes run product-photo-alt-text-writer --input ''{"image_path": "product.jpg"}'''

safety:
  dry_run_default: false
  requires_consent: false
  overwrites_files: false
  network_access: true
  pii_handling: false
3

Create recipe.py

# recipe.py
import os
from praisonaiagents import Agent, Task, PraisonAIAgents

def run(input_data: dict, config: dict = None) -> dict:
    """Generate alt text for product images."""
    image_path = input_data.get("image_path")
    brand_tone = input_data.get("brand_tone", "neutral")
    locale = input_data.get("locale", "en-US")
    
    if not image_path:
        return {"ok": False, "error": {"code": "MISSING_INPUT", "message": "image_path is required"}}
    
    if not os.path.exists(image_path):
        return {"ok": False, "error": {"code": "FILE_NOT_FOUND", "message": f"Image not found: {image_path}"}}
    
    try:
        tone_guidelines = {
            "neutral": "Clear, factual descriptions",
            "luxury": "Elegant, sophisticated language emphasizing quality",
            "casual": "Friendly, approachable descriptions",
            "technical": "Precise specifications and features"
        }
        
        # Create vision agent
        vision_agent = Agent(
            name="Product Analyst",
            role="Visual Product Expert",
            goal="Analyze product images accurately",
            instructions=f"""
            You are a product image analyst.
            - Identify the product type and category
            - Note colors, materials, and features
            - Describe the product's appearance
            - Consider the {brand_tone} tone: {tone_guidelines[brand_tone]}
            """,
        )
        
        # Create alt text writer
        alt_writer = Agent(
            name="Alt Text Writer",
            role="Accessibility Specialist",
            goal="Write effective alt text for screen readers",
            instructions=f"""
            You are an accessibility expert writing alt text.
            - Keep alt text under 125 characters
            - Be descriptive but concise
            - Include key product details
            - Use {brand_tone} tone
            - Write for {locale} audience
            - Don't start with "Image of" or "Picture of"
            """,
        )
        
        # Create tag generator
        tagger = Agent(
            name="Product Tagger",
            role="E-commerce SEO Specialist",
            goal="Generate relevant product tags",
            instructions="""
            You are an e-commerce tagging expert.
            - Generate 5-10 relevant tags
            - Include category, color, material, style
            - Use lowercase, hyphenated format
            - Focus on searchable terms
            """,
        )
        
        # Define tasks
        analyze_task = Task(
            name="analyze_image",
            description=f"Analyze the product image at: {image_path}",
            expected_output="Detailed product description",
            agent=vision_agent,
        )
        
        alt_task = Task(
            name="write_alt_text",
            description="Write accessible alt text based on the analysis",
            expected_output="Alt text under 125 characters",
            agent=alt_writer,
            context=[analyze_task],
        )
        
        tag_task = Task(
            name="generate_tags",
            description="Generate product tags for SEO",
            expected_output="List of 5-10 tags",
            agent=tagger,
            context=[analyze_task],
        )
        
        # Execute
        agents = PraisonAIAgents(
            agents=[vision_agent, alt_writer, tagger],
            tasks=[analyze_task, alt_task, tag_task],
        )
        
        result = agents.start()
        
        # Parse tags
        tags_text = result.get("generate_tags", "")
        tags = [t.strip().lower().replace(" ", "-") for t in tags_text.split(",") if t.strip()]
        if not tags:
            tags = [t.strip() for t in tags_text.split("\n") if t.strip() and not t.startswith("-")]
        
        return {
            "ok": True,
            "alt_text": result.get("write_alt_text", "").strip()[:125],
            "tags": tags[:10],
            "artifacts": [],
            "warnings": [],
        }
        
    except Exception as e:
        return {"ok": False, "error": {"code": "PROCESSING_ERROR", "message": str(e)}}
4

Create test_recipe.py

# test_recipe.py
import pytest
from recipe import run

def test_missing_image_path():
    result = run({})
    assert result["ok"] is False
    assert result["error"]["code"] == "MISSING_INPUT"

def test_file_not_found():
    result = run({"image_path": "/nonexistent.jpg"})
    assert result["ok"] is False
    assert result["error"]["code"] == "FILE_NOT_FOUND"

def test_brand_tones():
    valid_tones = ["neutral", "luxury", "casual", "technical"]
    for tone in valid_tones:
        assert tone in valid_tones

@pytest.mark.integration
def test_end_to_end():
    import os
    test_image = os.environ.get("TEST_IMAGE_PATH")
    if not test_image:
        pytest.skip("No test image available")
    
    result = run({"image_path": test_image, "brand_tone": "neutral"})
    assert result["ok"] is True
    assert len(result["alt_text"]) <= 125
    assert len(result["tags"]) > 0

Run Locally

# Basic usage
praison recipes run product-photo-alt-text-writer \
  --input '{"image_path": "shoe.jpg"}'

# With brand tone
praison recipes run product-photo-alt-text-writer \
  --input '{"image_path": "watch.png", "brand_tone": "luxury", "locale": "en-GB"}'

Deploy & Integrate: 6 Integration Models

from praisonai import recipe

result = recipe.run(
    "product-photo-alt-text-writer",
    input={"image_path": "product.jpg", "brand_tone": "luxury"}
)

if result.ok:
    print(f"Alt: {result.output['alt_text']}")
    print(f"Tags: {result.output['tags']}")

Troubleshooting

Try using a more specific brand_tone or ensure the image is clear and well-lit.
The vision model works best with clear, well-composed product photos on neutral backgrounds.

Next Steps