5.7 KiB
Recommendation AI Production Readiness
This runbook covers the production prerequisites for the Skinbase recommendation AI stack:
- vision analysis via
VISION_GATEWAY_URLor CLIP/YOLO endpoints - embedding generation
- vector upsert/search via the vector gateway
- hybrid discovery feed v2/v3
- upload-triggered AI processing
1. Required runtime services
You need these services available before enabling the stack:
- Laravel queue workers
- a configured public files/CDN base so artwork derivatives resolve to public URLs
- a vision gateway for
/analyze/all, or CLIP and YOLO services individually - a vector gateway exposing
/vectors/upsertand/vectors/search - a queue backend suitable for async jobs, preferably Redis in production
2. Required environment variables
Core queue and upload
QUEUE_CONNECTION=redis
UPLOAD_QUEUE_DERIVATIVES=true
VISION_QUEUE=vision
RECOMMENDATIONS_QUEUE=recommendations
DISCOVERY_QUEUE=discovery
If you do not want dedicated queues, leave the queue names unset or set them to default.
Vision analysis
VISION_ENABLED=true
VISION_IMAGE_VARIANT=md
VISION_GATEWAY_URL=https://vision.example.com
VISION_GATEWAY_TIMEOUT=10
VISION_GATEWAY_CONNECT_TIMEOUT=3
CLIP_BASE_URL=https://clip.example.com
CLIP_ANALYZE_ENDPOINT=/analyze
CLIP_EMBED_ENDPOINT=/embed
YOLO_ENABLED=true
YOLO_BASE_URL=https://yolo.example.com
YOLO_ANALYZE_ENDPOINT=/analyze
YOLO_PHOTOGRAPHY_ONLY=true
Notes:
VISION_GATEWAY_URLis the preferred unified path because the app can ingest CLIP tags, BLIP caption, and YOLO objects from/analyze/all- CLIP embedding generation still uses the CLIP embed endpoint configured in
config/recommendations.php
Vector search and indexing
VISION_VECTOR_GATEWAY_ENABLED=true
VISION_VECTOR_GATEWAY_URL=https://vector.example.com
VISION_VECTOR_GATEWAY_API_KEY=replace-me
VISION_VECTOR_GATEWAY_COLLECTION=images
VISION_VECTOR_GATEWAY_UPSERT_ENDPOINT=/vectors/upsert
VISION_VECTOR_GATEWAY_SEARCH_ENDPOINT=/vectors/search
VISION_VECTOR_GATEWAY_DELETE_ENDPOINT=/vectors/delete
Discovery and rollout
DISCOVERY_V2_ENABLED=true
DISCOVERY_V2_ALGO_VERSION=clip-cosine-v2-adaptive
DISCOVERY_V2_ROLLOUT_PERCENTAGE=100
DISCOVERY_V3_ENABLED=true
DISCOVERY_V3_CACHE_TTL_MINUTES=5
DISCOVERY_V3_VECTOR_SIMILARITY_WEIGHT=0.8
DISCOVERY_V3_VECTOR_BASE_SCORE=0.75
DISCOVERY_V3_MAX_SEED_ARTWORKS=3
DISCOVERY_V3_VECTOR_CANDIDATE_POOL=60
Embeddings
RECOMMENDATIONS_EMBEDDING_ENABLED=true
RECOMMENDATIONS_EMBEDDING_MODEL=clip
RECOMMENDATIONS_EMBEDDING_MODEL_VERSION=v1
RECOMMENDATIONS_ALGO_VERSION=clip-cosine-v1
RECOMMENDATIONS_MIN_DIM=64
RECOMMENDATIONS_MAX_DIM=4096
3. Queue worker coverage
The AI stack dispatches jobs onto these queue families:
visionviaAutoTagArtworkJobrecommendationsvia embedding generation, vector backfill, and similarity jobsdiscoveryvia feed cache regenerationdefaultif dedicated queue env vars are not set
The example worker configs in deploy/ now listen on:
forum-security,forum-moderation,vision,recommendations,discovery,mail,default
If you run separate workers per queue, ensure all configured queue names are consumed somewhere.
4. Upload pipeline behavior
Upload finish dispatches these async jobs after derivatives exist:
AutoTagArtworkJobGenerateArtworkEmbeddingJob
If UPLOAD_QUEUE_DERIVATIVES=true, derivative generation is also queued before those jobs can run. That means a broken worker setup can block the entire AI post-processing chain even if uploads themselves succeed.
5. Database and schema expectations
Confirm the database includes the current AI/discovery schema:
- artwork AI metadata columns on
artworks last_vector_indexed_atonartworks- artwork embeddings table
- discovery cache and event tables used by feed generation
Recommended checks:
php artisan migrate --force
php artisan schema:audit-migrations
6. Deployment checklist
Run these after deploy:
php artisan config:cache
php artisan route:cache
php artisan queue:restart
php artisan optimize
If you changed frontend assets, also ensure the Vite manifest exists before smoke-testing browser flows.
7. Smoke tests
Recommended application-level checks:
php artisan artworks:vectors-index --limit=1
php artisan artworks:vectors-search {artwork_id} --limit=5
vendor/bin/pest tests/Feature/Vision/GenerateArtworkEmbeddingJobTest.php
vendor/bin/pest tests/Feature/Vision/AiArtworkSearchApiTest.php
vendor/bin/pest tests/Feature/Discovery/FeedEndpointV2Test.php
Recommended HTTP checks:
GET /api/art/{id}/similar-aiPOST /api/search/imageGET /api/v1/feed?algo_version=clip-cosine-v2-adaptive&limit=12
8. Failure modes to watch
Uploads succeed but AI fields stay empty
Likely causes:
- workers are not running
- workers do not consume
visionorrecommendations VISION_ENABLED=false- derivative URLs are not publicly reachable by the vision services
Similar AI endpoints return 503
Likely causes:
VISION_VECTOR_GATEWAY_ENABLED=false- missing
VISION_VECTOR_GATEWAY_URL - missing
VISION_VECTOR_GATEWAY_API_KEY
Feed works but has no vector influence
Likely causes:
DISCOVERY_V3_ENABLED=false- vector gateway search unavailable
- no recent user seed artworks
- artworks have local embeddings but were never upserted
Vector repair/backfill stalls
Likely causes:
RECOMMENDATIONS_QUEUEis set but workers do not listen on it- queue backend is unhealthy
9. Operational recommendation
For first rollout, keep the queue names explicit but simple:
VISION_QUEUE=default
RECOMMENDATIONS_QUEUE=default
DISCOVERY_QUEUE=default
Once the stack is stable, split them into dedicated workers only if queue volume justifies it.