diff --git a/src/infrastructure/ai/ClaudeAIProvider.js b/src/infrastructure/ai/ClaudeAIProvider.js index c35b09b..d92d5b8 100644 --- a/src/infrastructure/ai/ClaudeAIProvider.js +++ b/src/infrastructure/ai/ClaudeAIProvider.js @@ -112,7 +112,7 @@ class ClaudeAIProvider extends IImageTaggingService { You are an elite real estate property analyst AI with comprehensive expertise in architectural photography, interior design, property valuation, and regional market knowledge (Dubai, Mumbai, Singapore, London, NYC). -CORE MISSION: Generate exactly 30 precise, high-confidence tags from property images that drive listing performance and buyer engagement. +CORE MISSION: Generate 25-30 precise, high-confidence tags from property images that drive listing performance and buyer engagement. Quality over quantity - omit categories that are absent rather than adding placeholder tags. ## QUALITY STANDARDS - Every tag must be visually verifiable (>92% expert accuracy) @@ -199,12 +199,15 @@ Adjust for image quality: poor (-0.10), excellent (+0.05), multiple confirmation 7. Luxury tags → neutral/monochrome color scheme more likely ## TAG DISTRIBUTION -**Exactly 30 tags total**: +**Target: 25-30 tags total** (maintain consistent quality): - High prominence (3-4 each): Furnishing, Style, Features, Lighting - Medium (2-3 each): Room Type, Flooring, Color Scheme, View - Standard (2-3 each): Kitchen, Condition -Dynamic adjustment: Kitchen not visible → redistribute to Features/Furnishing/Style +Dynamic adjustment: +- Kitchen not visible → redistribute to Features/Furnishing/Style +- View not visible → redistribute to Features/Furnishing/Style +- Category completely absent → OMIT that category, do NOT add placeholder tags ## SUMMARY GENERATION **Structure**: [Room Type] + [Key Feature 1] + [Key Feature 2] + [Style/Condition] @@ -218,9 +221,10 @@ Examples: ## EDGE CASES - Unfurnished: tag unfurnished (0.95+), compensate with architectural Features/Flooring - Multiple rooms: tag all visible rooms (3-4), add "open-plan" to Features -- No view: use "no exterior view" (0.85+) or redistribute tags -- Kitchen not visible: tag "not visible" (0.85+) or redistribute +- No view: OMIT View category entirely, redistribute tags to other categories +- Kitchen not visible: OMIT Kitchen category entirely, redistribute tags to other categories - Poor quality: reduce all confidence scores by 0.10, use broader tags +- **CRITICAL**: Never add placeholder tags like "not visible" - if category is absent, omit it and maintain tag quality ## OUTPUT FORMAT Return ONLY valid JSON (no markdown, explanations, or additional text): @@ -233,7 +237,7 @@ Return ONLY valid JSON (no markdown, explanations, or additional text): {"category": "Furnishing", "value": "fully furnished", "confidence": 0.96}, {"category": "Furnishing", "value": "contemporary", "confidence": 0.93}, {"category": "Furnishing", "value": "luxury", "confidence": 0.90}, - {"category": "Kitchen", "value": "not visible", "confidence": 0.85}, + {"category": "Furnishing", "value": "modern", "confidence": 0.88}, {"category": "Flooring", "value": "marble", "confidence": 0.94}, {"category": "Flooring", "value": "polished", "confidence": 0.91}, {"category": "Flooring", "value": "light colored", "confidence": 0.87}, @@ -297,10 +301,10 @@ Ready to analyze. Execute complete framework and return only JSON.`; throw new AIServiceError('Invalid response: tags array is required'); } - // Validate exactly 30 tags as per enhanced prompt requirements - if (parsed.tags.length !== 30) { + // Validate tag count (25-30 range to allow for missing categories) + if (parsed.tags.length < 25 || parsed.tags.length > 30) { this.logger.warn('Claude returned unexpected number of tags', { - expected: 30, + expectedRange: '25-30', actual: parsed.tags.length }); }