Janus-Pro-7B与数据库联动实战构建带图像搜索功能的商品管理系统你是不是也遇到过这样的烦恼电商后台里商品图片成千上万想找个特定款式或者相似风格的商品只能靠记忆里的关键词去搜结果要么搜不到要么搜出一堆不相关的。或者用户上传一张心仪的图片想找找你家有没有同款你却只能干瞪眼因为传统的搜索框只认文字。今天我们就来解决这个痛点。不用复杂的算法团队也不用昂贵的商业软件我们用一个开源的视觉语言大模型Janus-Pro-7B加上大家熟悉的MySQL数据库就能亲手搭建一个能“看懂”图片的商品管理系统。简单来说就是让系统学会“以图搜图”和“用文字描述搜图”。整个过程就像教一个聪明的助手认识你的商品库先让它“看”每一张商品图并说出它的特征生成描述向量然后把这些“特征笔记”存进数据库。当需要搜索时无论是来了一张新图还是一段文字描述助手都能快速找出“笔记”最相似的那些商品。下面我就带你一步步实现它。1. 从想法到蓝图系统要做什么在动手写代码之前我们先得把思路理清楚。这个系统核心要解决的就是“跨模态搜索”——让图片和文字能在同一个维度上对话。想象一下你经营一个家具网店。传统的做法是给每个沙发、茶几打上“北欧风”、“真皮”、“三人座”这样的标签。用户搜索“灰色的布艺沙发”系统就去标签库里匹配。但如果用户直接上传了一张客厅的网红图想找里面同款的单人椅传统系统就无能为力了。我们的新系统是这样工作的入库环节上传一个商品比如“云朵沙发”。系统不仅保存商品图片和文字信息还会请Janus-Pro-7B模型“端详”这张图片并生成一段浓缩了视觉特征的“数字指纹”也就是向量。搜索环节以图搜图用户上传一张沙发照片。系统同样用Janus-Pro-7B为这张查询图片生成“数字指纹”然后去数据库里找出那些“指纹”最接近的商品。文本搜图用户输入“一个柔软蓬松的米白色沙发有慵懒的感觉”。系统先将这段文字转换成“数字指纹”再去数据库进行匹配。这里的魔法在于无论是图片还是文字经过Janus-Pro-7B处理都被转化成了同一套数学语言高维向量。比较向量之间的相似度比如计算余弦相似度就成了比较图片和文字内容相似度的桥梁。接下来我们看看如何用数据库来承载这个想法。2. 设计数据仓库MySQL表结构设计虽然专门的向量数据库如Milvus, Pinecone处理向量搜索更专业但对于很多中小型项目来说引入新组件会增加复杂度。好消息是标准的MySQL 8.0及以上版本支持JSON类型和向量计算函数完全能胜任我们初期的需求。我们追求的是快速验证和落地。假设我们的商品products表原来就有基础信息我们现在需要增加一个字段来存放模型的“数字指纹”。Janus-Pro-7B生成的描述向量通常是几百到上千维的浮点数数组。我们可以这样设计表CREATE TABLE products ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL COMMENT 商品名称, description TEXT COMMENT 商品文字描述, image_url VARCHAR(500) COMMENT 商品图片存储路径或URL, price DECIMAL(10, 2), category VARCHAR(100), -- 新增的向量字段用于存储图片特征向量 -- 使用JSON类型存储浮点数数组例如 [0.12, -0.05, ..., 0.78] feature_vector JSON COMMENT 由Janus-Pro-7B生成的图像特征向量, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_category (category), -- 为向量相似度搜索建立索引简化处理实际生产环境需考虑专用索引 INDEX idx_vector ((CAST(feature_vector AS CHAR(255)))) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT商品信息表;这里有几个关键点feature_vector字段我们选择JSON类型来存储向量数组。它灵活易于读写。维度的选择取决于你使用的Janus-Pro-7B的具体输出。通常模型会提供一个固定维度的嵌入向量。索引的考量在MySQL中对JSON数组进行高效的相似度搜索如余弦相似度是比较挑战的。上面的普通索引可能效果有限。对于数据量不大比如几万条的场景全表扫描计算相似度尚可接受。如果数据量巨大就需要考虑使用MySQL的SPATIAL索引如果将向量视为多维空间点。或者更专业的做法是引入一个轻量的向量数据库作为辅助MySQL只存业务数据向量单独存。但这超出了本篇“快速联动”的范畴我们先以最简单的单库模式实现核心流程。表设计好了接下来就是重头戏如何让Janus-Pro-7B模型为我们工作。3. 核心引擎调用Janus-Pro-7B生成图像向量Janus-Pro-7B是一个多模态模型它既能理解图像也能理解文本并能将二者映射到同一个语义空间。我们需要利用它的视觉编码器部分来提取图片的向量表示。这里不涉及复杂的模型部署和微调我们假设你已经有一个可以通过API访问的Janus-Pro-7B服务。很多云平台或开源项目都提供了简单的调用方式。以下是一个使用Python的示例展示如何调用服务并获取向量。import requests import json import numpy as np from PIL import Image import io # 配置Janus-Pro-7B模型的API端点示例地址需替换为实际地址 JANUS_API_URL http://your-janus-server:port/generate_embedding API_KEY your-api-key-if-any # 如果需要认证 def get_image_vector_from_janus(image_path): 调用Janus-Pro-7B API获取图片的特征向量。 参数: image_path: 本地图片路径或图片的二进制数据。 返回: np.ndarray: 图像特征向量。 # 1. 准备图片数据 if isinstance(image_path, str): # 从文件路径读取 with open(image_path, rb) as f: image_data f.read() else: # 假设image_path已经是字节数据 image_data image_path # 2. 构建请求根据实际API调整 files {image: (product.jpg, image_data, image/jpeg)} headers {Authorization: fBearer {API_KEY}} if API_KEY else {} try: response requests.post(JANUS_API_URL, filesfiles, headersheaders, timeout30) response.raise_for_status() # 检查HTTP错误 result response.json() # 3. 解析响应提取向量。这里需要根据API实际返回格式调整。 # 假设返回格式为: {embedding: [0.1, -0.2, ...]} if embedding in result: vector_array np.array(result[embedding], dtypenp.float32) return vector_array else: raise ValueError(API响应中未找到 embedding 字段) except requests.exceptions.RequestException as e: print(f请求Janus API失败: {e}) return None except (KeyError, json.JSONDecodeError) as e: print(f解析API响应失败: {e}) return None # 示例用法处理一张新商品图片 if __name__ __main__: new_product_image_path path/to/your/new_sofa.jpg feature_vector get_image_vector_from_janus(new_product_image_path) if feature_vector is not None: print(f向量维度: {feature_vector.shape}) print(f向量前5个值: {feature_vector[:5]}) # 接下来就可以将这个向量存入数据库的feature_vector字段了这段代码做了几件事读取商品图片。调用Janus-Pro-7B的API假设API接收图片文件并返回嵌入向量。从响应中提取出向量数组。重要提示你需要根据实际部署的Janus-Pro-7B服务的API文档来调整请求格式和响应解析逻辑。有些服务可能需要以Base64编码的形式发送图片或者返回的数据结构不同。拿到向量后我们就可以把它和商品的其他信息一起存入数据库了。4. 连接与存储将向量存入MySQL现在我们需要把上一步得到的向量连同商品信息写入到之前设计好的products表中。向量是numpy.ndarray格式我们需要将其转换为MySQLJSON字段能接受的列表格式。下面是一个完整的商品入库函数示例import mysql.connector from mysql.connector import Error import numpy as np def save_product_to_db(product_info, image_vector): 将商品信息及其图像特征向量保存到MySQL数据库。 参数: product_info: 字典包含商品名称、描述等信息。 image_vector: np.ndarray, Janus-Pro-7B生成的图像向量。 connection None cursor None # 数据库配置 db_config { host: localhost, user: your_username, password: your_password, database: your_database } try: # 1. 连接数据库 connection mysql.connector.connect(**db_config) cursor connection.cursor() # 2. 准备数据 # 将numpy数组转换为Python列表以便序列化为JSON vector_list image_vector.tolist() if image_vector is not None else None insert_query INSERT INTO products (name, description, image_url, price, category, feature_vector) VALUES (%s, %s, %s, %s, %s, %s) product_data ( product_info.get(name), product_info.get(description), product_info.get(image_url), product_info.get(price), product_info.get(category), json.dumps(vector_list) if vector_list else None # 将列表转为JSON字符串 ) # 3. 执行插入 cursor.execute(insert_query, product_data) connection.commit() print(f商品 {product_info.get(name)} 入库成功ID: {cursor.lastrowid}) except Error as e: print(f数据库操作失败: {e}) if connection: connection.rollback() finally: if cursor: cursor.close() if connection and connection.is_connected(): connection.close() # 示例入库一个新商品 if __name__ __main__: # 假设我们已经从图片生成了向量 sample_vector np.random.randn(512).astype(np.float32) # 用随机向量模拟 new_product { name: 慵懒云朵沙发, description: 一款设计柔软、造型如云朵般的单人沙发适合休闲阅读。, image_url: /static/images/cloud_sofa_001.jpg, price: 2999.00, category: 沙发 } save_product_to_db(new_product, sample_vector)这样每当有新品上架这个流程就能自动为其生成“视觉身份证”并归档。我们的数据库就从单纯的文字仓库变成了一个拥有“视觉记忆”的智能仓库。5. 实现智能搜索两种搜索模式实战仓库建好了最关键的一步来了怎么从里面快速找到想要的东西我们将实现两种搜索函数。5.1 文本搜图将文字描述转化为搜索指令用户输入一段文字我们要先让Janus-Pro-7B理解这段文字并生成对应的文本向量。注意这里需要调用模型的文本编码器部分。为了简化我们假设同一个API也能处理文本输入或者有另一个文本端点。def get_text_vector_from_janus(text_description): 调用Janus-Pro-7B API获取文本描述的特征向量。 参数和返回格式与get_image_vector_from_janus类似。 # 此处省略具体实现逻辑与图片向量化类似 # 向文本编码API发送POST请求包含文本内容 # 解析返回的文本嵌入向量 # 假设返回一个numpy数组 pass def search_by_text(text_query, top_k10): 根据文本描述搜索相似商品。 参数: text_query: 用户输入的文本描述。 top_k: 返回最相似的商品数量。 返回: list: 相似商品的信息列表。 # 1. 将文本查询转换为向量 query_vector get_text_vector_from_janus(text_query) if query_vector is None: return [] # 2. 在数据库中计算余弦相似度并排序 # 注意在MySQL中直接计算高维向量的余弦相似度效率不高这里演示原理。 # 生产环境应考虑将向量预计算归一化或使用扩展/向量数据库。 connection mysql.connector.connect(**db_config) cursor connection.cursor(dictionaryTrue) # 先取出所有商品的向量和基本信息数据量大时需分页或优化 cursor.execute(SELECT id, name, image_url, feature_vector FROM products WHERE feature_vector IS NOT NULL) all_products cursor.fetchall() similarities [] for product in all_products: db_vector np.array(json.loads(product[feature_vector])) # 计算余弦相似度 cos_sim np.dot(query_vector, db_vector) / (np.linalg.norm(query_vector) * np.linalg.norm(db_vector)) similarities.append((product, cos_sim)) # 按相似度降序排序 similarities.sort(keylambda x: x[1], reverseTrue) # 返回top_k个结果 top_results [item[0] for item in similarities[:top_k]] cursor.close() connection.close() return top_results5.2 以图搜图让图片自己“开口”寻找同伴这个过程与文本搜索异曲同工只是查询输入从文字变成了图片。def search_by_image(image_path, top_k10): 根据图片搜索相似商品。 参数: image_path: 查询图片的路径或二进制数据。 top_k: 返回最相似的商品数量。 返回: list: 相似商品的信息列表。 # 1. 将查询图片转换为向量 query_vector get_image_vector_from_janus(image_path) if query_vector is None: return [] # 2. 与数据库中的商品向量进行相似度计算 # 此处计算逻辑与search_by_text函数核心部分完全一致可抽象为公共函数 return _search_by_vector(query_vector, top_k) def _search_by_vector(query_vector, top_k): 内部函数根据查询向量进行搜索。 connection mysql.connector.connect(**db_config) cursor connection.cursor(dictionaryTrue) cursor.execute(SELECT id, name, image_url, feature_vector FROM products WHERE feature_vector IS NOT NULL) all_products cursor.fetchall() similarities [] for product in all_products: db_vector np.array(json.loads(product[feature_vector])) cos_sim np.dot(query_vector, db_vector) / (np.linalg.norm(query_vector) * np.linalg.norm(db_vector)) similarities.append((product, cos_sim)) similarities.sort(keylambda x: x[1], reverseTrue) top_results [item[0] for item in similarities[:top_k]] cursor.close() connection.close() return top_results5.3 性能优化初探上面的示例为了清晰采用了“取出全部再计算”的方式这在商品数量稍多时就会成为瓶颈。在实际应用中你必须优化向量归一化入库前就将所有向量进行L2归一化使模长为1。这样余弦相似度计算简化为向量点积极大简化计算。使用向量索引这是质变的一步。可以考虑MySQL方案将归一化后的向量存储在BLOB类型中并利用SPATIAL索引需将向量转换为空间数据类型或第三方插件进行近似最近邻搜索。混合方案保留MySQL存储商品业务信息同时将归一化的向量和商品ID存入一个专门的向量数据库如ChromaDB, Qdrant它们对向量搜索有原生高效支持。搜索时先用向量数据库快速找出最相似的ID再用ID从MySQL拉取完整的商品信息。这种架构更清晰性能也更好。6. 总结走完这一趟你会发现构建一个带图像搜索功能的商品管理系统并没有想象中那么遥不可及。核心思路就是利用像Janus-Pro-7B这样的多模态大模型作为“翻译官”把图片和文字都转换成它能理解的“向量语言”然后借助数据库进行存储和比对。我们这次用最基础的MySQL起步实现了从模型调用、向量生成、数据入库到相似度搜索的完整闭环。这非常适合作为原型验证或者数据量不大的内部系统。它能让你快速看到效果理解整个技术链条。当然当你的商品库膨胀到十万、百万级别时全表扫描计算肯定行不通了。那时就该考虑引入专业的向量索引或者向量数据库了比如把向量存到ChromaDB里让它来负责高速的相似度检索MySQL只当个可靠的信息仓库。这会是性能上一次很大的升级。不过技术选型永远要服务于业务场景。对于很多中小电商、内容管理平台来说本文介绍的MySQL方案已经能解决大部分“找图难”的问题投入产出比非常高。你不妨就从手头的一个商品分类开始试试看看这个能“看懂”图片的系统能不能给你的工作流带来一些新的惊喜。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
Janus-Pro-7B与数据库联动实战:构建带图像搜索功能的商品管理系统
发布时间:2026/6/3 3:56:05
Janus-Pro-7B与数据库联动实战构建带图像搜索功能的商品管理系统你是不是也遇到过这样的烦恼电商后台里商品图片成千上万想找个特定款式或者相似风格的商品只能靠记忆里的关键词去搜结果要么搜不到要么搜出一堆不相关的。或者用户上传一张心仪的图片想找找你家有没有同款你却只能干瞪眼因为传统的搜索框只认文字。今天我们就来解决这个痛点。不用复杂的算法团队也不用昂贵的商业软件我们用一个开源的视觉语言大模型Janus-Pro-7B加上大家熟悉的MySQL数据库就能亲手搭建一个能“看懂”图片的商品管理系统。简单来说就是让系统学会“以图搜图”和“用文字描述搜图”。整个过程就像教一个聪明的助手认识你的商品库先让它“看”每一张商品图并说出它的特征生成描述向量然后把这些“特征笔记”存进数据库。当需要搜索时无论是来了一张新图还是一段文字描述助手都能快速找出“笔记”最相似的那些商品。下面我就带你一步步实现它。1. 从想法到蓝图系统要做什么在动手写代码之前我们先得把思路理清楚。这个系统核心要解决的就是“跨模态搜索”——让图片和文字能在同一个维度上对话。想象一下你经营一个家具网店。传统的做法是给每个沙发、茶几打上“北欧风”、“真皮”、“三人座”这样的标签。用户搜索“灰色的布艺沙发”系统就去标签库里匹配。但如果用户直接上传了一张客厅的网红图想找里面同款的单人椅传统系统就无能为力了。我们的新系统是这样工作的入库环节上传一个商品比如“云朵沙发”。系统不仅保存商品图片和文字信息还会请Janus-Pro-7B模型“端详”这张图片并生成一段浓缩了视觉特征的“数字指纹”也就是向量。搜索环节以图搜图用户上传一张沙发照片。系统同样用Janus-Pro-7B为这张查询图片生成“数字指纹”然后去数据库里找出那些“指纹”最接近的商品。文本搜图用户输入“一个柔软蓬松的米白色沙发有慵懒的感觉”。系统先将这段文字转换成“数字指纹”再去数据库进行匹配。这里的魔法在于无论是图片还是文字经过Janus-Pro-7B处理都被转化成了同一套数学语言高维向量。比较向量之间的相似度比如计算余弦相似度就成了比较图片和文字内容相似度的桥梁。接下来我们看看如何用数据库来承载这个想法。2. 设计数据仓库MySQL表结构设计虽然专门的向量数据库如Milvus, Pinecone处理向量搜索更专业但对于很多中小型项目来说引入新组件会增加复杂度。好消息是标准的MySQL 8.0及以上版本支持JSON类型和向量计算函数完全能胜任我们初期的需求。我们追求的是快速验证和落地。假设我们的商品products表原来就有基础信息我们现在需要增加一个字段来存放模型的“数字指纹”。Janus-Pro-7B生成的描述向量通常是几百到上千维的浮点数数组。我们可以这样设计表CREATE TABLE products ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL COMMENT 商品名称, description TEXT COMMENT 商品文字描述, image_url VARCHAR(500) COMMENT 商品图片存储路径或URL, price DECIMAL(10, 2), category VARCHAR(100), -- 新增的向量字段用于存储图片特征向量 -- 使用JSON类型存储浮点数数组例如 [0.12, -0.05, ..., 0.78] feature_vector JSON COMMENT 由Janus-Pro-7B生成的图像特征向量, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_category (category), -- 为向量相似度搜索建立索引简化处理实际生产环境需考虑专用索引 INDEX idx_vector ((CAST(feature_vector AS CHAR(255)))) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT商品信息表;这里有几个关键点feature_vector字段我们选择JSON类型来存储向量数组。它灵活易于读写。维度的选择取决于你使用的Janus-Pro-7B的具体输出。通常模型会提供一个固定维度的嵌入向量。索引的考量在MySQL中对JSON数组进行高效的相似度搜索如余弦相似度是比较挑战的。上面的普通索引可能效果有限。对于数据量不大比如几万条的场景全表扫描计算相似度尚可接受。如果数据量巨大就需要考虑使用MySQL的SPATIAL索引如果将向量视为多维空间点。或者更专业的做法是引入一个轻量的向量数据库作为辅助MySQL只存业务数据向量单独存。但这超出了本篇“快速联动”的范畴我们先以最简单的单库模式实现核心流程。表设计好了接下来就是重头戏如何让Janus-Pro-7B模型为我们工作。3. 核心引擎调用Janus-Pro-7B生成图像向量Janus-Pro-7B是一个多模态模型它既能理解图像也能理解文本并能将二者映射到同一个语义空间。我们需要利用它的视觉编码器部分来提取图片的向量表示。这里不涉及复杂的模型部署和微调我们假设你已经有一个可以通过API访问的Janus-Pro-7B服务。很多云平台或开源项目都提供了简单的调用方式。以下是一个使用Python的示例展示如何调用服务并获取向量。import requests import json import numpy as np from PIL import Image import io # 配置Janus-Pro-7B模型的API端点示例地址需替换为实际地址 JANUS_API_URL http://your-janus-server:port/generate_embedding API_KEY your-api-key-if-any # 如果需要认证 def get_image_vector_from_janus(image_path): 调用Janus-Pro-7B API获取图片的特征向量。 参数: image_path: 本地图片路径或图片的二进制数据。 返回: np.ndarray: 图像特征向量。 # 1. 准备图片数据 if isinstance(image_path, str): # 从文件路径读取 with open(image_path, rb) as f: image_data f.read() else: # 假设image_path已经是字节数据 image_data image_path # 2. 构建请求根据实际API调整 files {image: (product.jpg, image_data, image/jpeg)} headers {Authorization: fBearer {API_KEY}} if API_KEY else {} try: response requests.post(JANUS_API_URL, filesfiles, headersheaders, timeout30) response.raise_for_status() # 检查HTTP错误 result response.json() # 3. 解析响应提取向量。这里需要根据API实际返回格式调整。 # 假设返回格式为: {embedding: [0.1, -0.2, ...]} if embedding in result: vector_array np.array(result[embedding], dtypenp.float32) return vector_array else: raise ValueError(API响应中未找到 embedding 字段) except requests.exceptions.RequestException as e: print(f请求Janus API失败: {e}) return None except (KeyError, json.JSONDecodeError) as e: print(f解析API响应失败: {e}) return None # 示例用法处理一张新商品图片 if __name__ __main__: new_product_image_path path/to/your/new_sofa.jpg feature_vector get_image_vector_from_janus(new_product_image_path) if feature_vector is not None: print(f向量维度: {feature_vector.shape}) print(f向量前5个值: {feature_vector[:5]}) # 接下来就可以将这个向量存入数据库的feature_vector字段了这段代码做了几件事读取商品图片。调用Janus-Pro-7B的API假设API接收图片文件并返回嵌入向量。从响应中提取出向量数组。重要提示你需要根据实际部署的Janus-Pro-7B服务的API文档来调整请求格式和响应解析逻辑。有些服务可能需要以Base64编码的形式发送图片或者返回的数据结构不同。拿到向量后我们就可以把它和商品的其他信息一起存入数据库了。4. 连接与存储将向量存入MySQL现在我们需要把上一步得到的向量连同商品信息写入到之前设计好的products表中。向量是numpy.ndarray格式我们需要将其转换为MySQLJSON字段能接受的列表格式。下面是一个完整的商品入库函数示例import mysql.connector from mysql.connector import Error import numpy as np def save_product_to_db(product_info, image_vector): 将商品信息及其图像特征向量保存到MySQL数据库。 参数: product_info: 字典包含商品名称、描述等信息。 image_vector: np.ndarray, Janus-Pro-7B生成的图像向量。 connection None cursor None # 数据库配置 db_config { host: localhost, user: your_username, password: your_password, database: your_database } try: # 1. 连接数据库 connection mysql.connector.connect(**db_config) cursor connection.cursor() # 2. 准备数据 # 将numpy数组转换为Python列表以便序列化为JSON vector_list image_vector.tolist() if image_vector is not None else None insert_query INSERT INTO products (name, description, image_url, price, category, feature_vector) VALUES (%s, %s, %s, %s, %s, %s) product_data ( product_info.get(name), product_info.get(description), product_info.get(image_url), product_info.get(price), product_info.get(category), json.dumps(vector_list) if vector_list else None # 将列表转为JSON字符串 ) # 3. 执行插入 cursor.execute(insert_query, product_data) connection.commit() print(f商品 {product_info.get(name)} 入库成功ID: {cursor.lastrowid}) except Error as e: print(f数据库操作失败: {e}) if connection: connection.rollback() finally: if cursor: cursor.close() if connection and connection.is_connected(): connection.close() # 示例入库一个新商品 if __name__ __main__: # 假设我们已经从图片生成了向量 sample_vector np.random.randn(512).astype(np.float32) # 用随机向量模拟 new_product { name: 慵懒云朵沙发, description: 一款设计柔软、造型如云朵般的单人沙发适合休闲阅读。, image_url: /static/images/cloud_sofa_001.jpg, price: 2999.00, category: 沙发 } save_product_to_db(new_product, sample_vector)这样每当有新品上架这个流程就能自动为其生成“视觉身份证”并归档。我们的数据库就从单纯的文字仓库变成了一个拥有“视觉记忆”的智能仓库。5. 实现智能搜索两种搜索模式实战仓库建好了最关键的一步来了怎么从里面快速找到想要的东西我们将实现两种搜索函数。5.1 文本搜图将文字描述转化为搜索指令用户输入一段文字我们要先让Janus-Pro-7B理解这段文字并生成对应的文本向量。注意这里需要调用模型的文本编码器部分。为了简化我们假设同一个API也能处理文本输入或者有另一个文本端点。def get_text_vector_from_janus(text_description): 调用Janus-Pro-7B API获取文本描述的特征向量。 参数和返回格式与get_image_vector_from_janus类似。 # 此处省略具体实现逻辑与图片向量化类似 # 向文本编码API发送POST请求包含文本内容 # 解析返回的文本嵌入向量 # 假设返回一个numpy数组 pass def search_by_text(text_query, top_k10): 根据文本描述搜索相似商品。 参数: text_query: 用户输入的文本描述。 top_k: 返回最相似的商品数量。 返回: list: 相似商品的信息列表。 # 1. 将文本查询转换为向量 query_vector get_text_vector_from_janus(text_query) if query_vector is None: return [] # 2. 在数据库中计算余弦相似度并排序 # 注意在MySQL中直接计算高维向量的余弦相似度效率不高这里演示原理。 # 生产环境应考虑将向量预计算归一化或使用扩展/向量数据库。 connection mysql.connector.connect(**db_config) cursor connection.cursor(dictionaryTrue) # 先取出所有商品的向量和基本信息数据量大时需分页或优化 cursor.execute(SELECT id, name, image_url, feature_vector FROM products WHERE feature_vector IS NOT NULL) all_products cursor.fetchall() similarities [] for product in all_products: db_vector np.array(json.loads(product[feature_vector])) # 计算余弦相似度 cos_sim np.dot(query_vector, db_vector) / (np.linalg.norm(query_vector) * np.linalg.norm(db_vector)) similarities.append((product, cos_sim)) # 按相似度降序排序 similarities.sort(keylambda x: x[1], reverseTrue) # 返回top_k个结果 top_results [item[0] for item in similarities[:top_k]] cursor.close() connection.close() return top_results5.2 以图搜图让图片自己“开口”寻找同伴这个过程与文本搜索异曲同工只是查询输入从文字变成了图片。def search_by_image(image_path, top_k10): 根据图片搜索相似商品。 参数: image_path: 查询图片的路径或二进制数据。 top_k: 返回最相似的商品数量。 返回: list: 相似商品的信息列表。 # 1. 将查询图片转换为向量 query_vector get_image_vector_from_janus(image_path) if query_vector is None: return [] # 2. 与数据库中的商品向量进行相似度计算 # 此处计算逻辑与search_by_text函数核心部分完全一致可抽象为公共函数 return _search_by_vector(query_vector, top_k) def _search_by_vector(query_vector, top_k): 内部函数根据查询向量进行搜索。 connection mysql.connector.connect(**db_config) cursor connection.cursor(dictionaryTrue) cursor.execute(SELECT id, name, image_url, feature_vector FROM products WHERE feature_vector IS NOT NULL) all_products cursor.fetchall() similarities [] for product in all_products: db_vector np.array(json.loads(product[feature_vector])) cos_sim np.dot(query_vector, db_vector) / (np.linalg.norm(query_vector) * np.linalg.norm(db_vector)) similarities.append((product, cos_sim)) similarities.sort(keylambda x: x[1], reverseTrue) top_results [item[0] for item in similarities[:top_k]] cursor.close() connection.close() return top_results5.3 性能优化初探上面的示例为了清晰采用了“取出全部再计算”的方式这在商品数量稍多时就会成为瓶颈。在实际应用中你必须优化向量归一化入库前就将所有向量进行L2归一化使模长为1。这样余弦相似度计算简化为向量点积极大简化计算。使用向量索引这是质变的一步。可以考虑MySQL方案将归一化后的向量存储在BLOB类型中并利用SPATIAL索引需将向量转换为空间数据类型或第三方插件进行近似最近邻搜索。混合方案保留MySQL存储商品业务信息同时将归一化的向量和商品ID存入一个专门的向量数据库如ChromaDB, Qdrant它们对向量搜索有原生高效支持。搜索时先用向量数据库快速找出最相似的ID再用ID从MySQL拉取完整的商品信息。这种架构更清晰性能也更好。6. 总结走完这一趟你会发现构建一个带图像搜索功能的商品管理系统并没有想象中那么遥不可及。核心思路就是利用像Janus-Pro-7B这样的多模态大模型作为“翻译官”把图片和文字都转换成它能理解的“向量语言”然后借助数据库进行存储和比对。我们这次用最基础的MySQL起步实现了从模型调用、向量生成、数据入库到相似度搜索的完整闭环。这非常适合作为原型验证或者数据量不大的内部系统。它能让你快速看到效果理解整个技术链条。当然当你的商品库膨胀到十万、百万级别时全表扫描计算肯定行不通了。那时就该考虑引入专业的向量索引或者向量数据库了比如把向量存到ChromaDB里让它来负责高速的相似度检索MySQL只当个可靠的信息仓库。这会是性能上一次很大的升级。不过技术选型永远要服务于业务场景。对于很多中小电商、内容管理平台来说本文介绍的MySQL方案已经能解决大部分“找图难”的问题投入产出比非常高。你不妨就从手头的一个商品分类开始试试看看这个能“看懂”图片的系统能不能给你的工作流带来一些新的惊喜。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。