# 服装搭配搜索功能实现 ## 概述 本文档描述了服装搭配搜索功能的实现,该功能直接调用 Google Vertex AI Search API 进行搜索,而不是通过 RAG Grounding。 ## 核心功能 ### 1. 直接 Vertex AI Search 调用 - **API 端点**: `https://discoveryengine.googleapis.com/v1beta/projects/{project_id}/locations/global/collections/default_collection/engines/{app_id}/servingConfigs/default_search:search` - **认证**: 通过 Google 访问令牌进行认证 - **数据存储**: 使用配置的 `vertex_ai_app_id` 和 `data_store_id` ### 2. 搜索配置 ```rust pub struct SearchRequest { pub query: String, // 搜索查询字符串 pub config: SearchConfig, // 搜索配置 pub page_size: usize, // 页面大小 pub page_offset: usize, // 页面偏移量 } pub struct SearchConfig { pub relevance_threshold: RelevanceThreshold, // 相关性阈值 pub environments: Vec, // 环境标签过滤 pub categories: Vec, // 类别过滤 pub color_filters: HashMap, // 颜色过滤器 pub design_styles: HashMap>, // 设计风格过滤 pub max_keywords: usize, // 最大关键词数量 } ``` ### 3. 搜索流程 1. **获取访问令牌**: 通过 Modal.run API 获取 Google 访问令牌 2. **构建搜索过滤器**: 根据搜索配置构建 Vertex AI Search 过滤器 3. **组合查询字符串**: 将用户查询与关键词组合 4. **发送 HTTP 请求**: 直接调用 Vertex AI Search API 5. **解析响应**: 将 Vertex AI 响应转换为应用程序格式 6. **应用过滤**: 根据相关性阈值过滤结果 ### 4. 响应格式转换 ```rust pub struct SearchResult { pub id: String, // 结果ID pub image_url: String, // 图片URL pub style_description: String, // 风格描述 pub environment_tags: Vec, // 环境标签 pub products: Vec, // 产品信息列表 pub relevance_score: f64, // 相关性评分 } pub struct ProductInfo { pub category: String, // 产品类别 pub description: String, // 产品描述 pub color_pattern: ColorHSV, // 主要颜色 pub design_styles: Vec, // 设计风格 } ``` ## 实现细节 ### 1. 访问令牌获取 ```rust async fn get_google_access_token() -> Result { let config = GeminiConfig::default(); let client = reqwest::Client::new(); let url = format!("{}/google/access-token", config.base_url); let response = client .get(&url) .header("Authorization", format!("Bearer {}", config.bearer_token)) .send() .await?; // 解析访问令牌... } ``` ### 2. 搜索请求构建 ```rust let mut payload = serde_json::json!({ "query": enhanced_query, "relevanceThreshold": request.config.relevance_threshold.to_value().to_string(), "relevanceScoreSpec": { "returnRelevanceScore": true }, "pageSize": request.page_size, "offset": request.page_offset }); // 添加过滤器(如果有) if !search_filter.is_empty() { payload["filter"] = serde_json::Value::String(search_filter); } ``` ### 3. 响应解析 - 从 Vertex AI Search 响应中提取 `results` 数组 - 解析每个结果的 `document.structData` 字段 - 提取图片URL、风格描述、环境标签等信息 - 解析产品信息和颜色模式 - 获取相关性评分并应用阈值过滤 ## 配置参数 ### 全局配置 ```rust impl Default for OutfitSearchGlobalConfig { fn default() -> Self { Self { google_project_id: "gen-lang-client-0413414134".to_string(), vertex_ai_app_id: "jeans-search_1751353769585".to_string(), storage_bucket_name: "fashion_image_block".to_string(), data_store_id: "jeans_pattern_data_store".to_string(), cloudflare_project_id: "67720b647ff2b55cf37ba3ef9e677083".to_string(), cloudflare_gateway_id: "bowong-dev".to_string(), } } } ``` ### 相关性阈值 - **LOWEST**: 0.3 - 显示更多相关结果 - **LOW**: 0.5 - 包含较多相关结果 - **MEDIUM**: 0.7 - 平衡相关性和数量 - **HIGH**: 0.9 - 只显示高度相关结果 ## 错误处理 - 访问令牌获取失败 - HTTP 请求失败 - JSON 解析错误 - 数据格式不匹配 - 网络超时 ## 测试 实现了以下测试用例: 1. `test_search_request_creation` - 测试搜索请求创建 2. `test_search_filter_builder` - 测试搜索过滤器构建 3. `test_query_keywords_builder` - 测试查询关键词构建 ## 使用示例 ```typescript import { OutfitSearchService } from '../services/outfitSearchService'; const searchRequest = { query: "牛仔裤搭配", config: { relevance_threshold: "HIGH", categories: ["上装", "下装"], environments: ["Outdoor"], color_filters: {}, design_styles: {}, max_keywords: 10 }, page_size: 9, page_offset: 0 }; const response = await OutfitSearchService.searchSimilarOutfits(searchRequest); console.log(`找到 ${response.total_size} 个搜索结果`); ``` ## 性能优化 - 使用连接池减少HTTP连接开销 - 实现访问令牌缓存机制 - 支持分页查询避免大量数据传输 - 客户端相关性过滤减少无效结果 ## 未来改进 1. 添加向量搜索支持 2. 实现搜索结果缓存 3. 支持更复杂的过滤条件 4. 添加搜索分析和统计 5. 实现搜索建议优化