Product Photo Alt Text Writer
Generate accessible alt text and tags for product images
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
| Input | Type | Required | Description |
|---|---|---|---|
image_path | string | Yes | Path to product image |
brand_tone | string | No | Brand voice (default: neutral) |
locale | string | No | Target locale (default: en-US) |
| Output | Type | Description |
|---|---|---|
alt_text | string | Generated alt text |
tags | array | Relevant product tags |
ok | boolean | Success indicator |
Prerequisites
export OPENAI_API_KEY=your_key_here
pip install praisonaiagentsStep-by-Step Build
- Create Recipe Directory
bash mkdir -p ~/.praisonai/templates/product-photo-alt-text-writer cd ~/.praisonai/templates/product-photo-alt-text-writer - Create TEMPLATE.yaml
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 - Create recipe.py
python # recipe.py import os from praisonaiagents import Agent, Task, AgentTeam 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 = AgentTeam( 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)}} - Create test_recipe.py
python # 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
Model 1: Embedded SDK
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']}")Model 2: CLI Invocation
# Batch process product images
for img in products/*.jpg; do
praison recipes run product-photo-alt-text-writer \
--input "{\"image_path\": \"$img\"}" --json
doneModel 3: Plugin Mode
class AltTextPlugin:
def generate(self, image_path, tone="neutral"):
from praisonai import recipe
return recipe.run(
"product-photo-alt-text-writer",
input={"image_path": image_path, "brand_tone": tone}
)Model 4: Local HTTP Sidecar
const response = await fetch('http://localhost:8765/recipes/product-photo-alt-text-writer/run', {
method: 'POST',
body: JSON.stringify({ image_path: '/uploads/product.jpg' })
});Model 5: Remote Managed Runner
response = requests.post(
"https://api.ecommerce-tools.com/alt-text",
headers={"Authorization": f"Bearer {api_key}"},
json={"image_url": "https://cdn.example.com/product.jpg"}
)Model 6: Event-Driven
def on_product_image_uploaded(event):
import queue as q
job_queue = q.Queue() # Replace with SQS/RabbitMQ in production
job_queue.put({
"recipe": "product-photo-alt-text-writer",
"input": {"image_path": event['image_path']},
"callback_url": f"https://api.example.com/products/{event['product_id']}/alt-text"
})Troubleshooting
Alt text too generic
Try using a more specific brand_tone or ensure the image is clear and well-lit.
Missing product details
The vision model works best with clear, well-composed product photos on neutral backgrounds.
Next Steps
- Document Summarizer – Summarize product descriptions
- Customer Support Reply Drafter – Handle product inquiries