一、Embedding 原理详解1. 什么是 Embedding定义将一段文本转换为 float[] 数组如1536个浮点数这个数组即为文本的“语义指纹”。类比如同每个人有独一无二的指纹每段文本也有独特的向量。语义越接近的文本其向量在空间中的距离越近。关键认知向量中的每个数字本身没有具体含义例如你无法解释第37个数代表什么但整体方向代表了语义。经典实验语义关系的捕获能力向量(国王) - 向量(男人) 向量(女人) ≈ 向量(女王)这说明向量空间能够捕捉语义关系而不仅是字面匹配。关键词搜索 vs 语义搜索本质区别用户问题Java多线程有哪些最佳实践 关键词搜索只能找到包含“多线程”字样的文档 语义搜索可命中《并发编程指南》、ExecutorService文档、synchronized教程 ——即使文档未出现“多线程”字样只要语义相关就能命中RAG 相比传统全文搜索的核心优势即在于此。2. 什么是余弦相似度定义衡量两个向量方向相似度的指标取值范围[-1, 1]。1完全相同方向语义一致0垂直语义无关-1完全相反方向公式cos(θ) (A·B) / (|A| × |B|)经验阈值参考相似度范围含义典型场景0.85 ~ 1.0高度相似同义改写、重复内容0.70 ~ 0.85语义相关同一主题不同表述0.50 ~ 0.70弱相关广泛关联领域 0.50基本无关不同主题2.1 余弦相似度计算工具类Java实现在 Spring AI 项目中新建工具类手动实现余弦相似度计算便于理解底层原理public class VectorUtils { /** * 余弦相似度值域 [-1, 1]越大越相似 */ public static double cosineSimilarity(float[] a, float[] b) { if (a.length ! b.length) { throw new IllegalArgumentException(向量维度不一致: a.length vs b.length); } double dotProduct 0.0, normA 0.0, normB 0.0; for (int i 0; i a.length; i) { dotProduct a[i] * b[i]; normA a[i] * a[i]; normB b[i] * b[i]; } return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); } public static void main(String[] args) { // 模拟两组向量验证计算逻辑 float[] v1 {1.0f, 0.0f, 0.0f}; float[] v2 {0.9f, 0.1f, 0.1f}; float[] v3 {0.0f, 1.0f, 0.0f}; System.out.println(v1与v2相似度: cosineSimilarity(v1, v2)); // 应该很高 System.out.println(v1与v3相似度: cosineSimilarity(v1, v3)); // 应该为0 } }3. 主流 Embedding 模型选型模型提供商维度中文效果费用text-embedding-v3通义千问1024优秀按量计费有免费额度BGE-large-zhBAAI开源1024优秀免费本地部署text-embedding-3-smallOpenAI1536一般按量计费重要提醒Embedding 模型和对话模型不要求同厂商。例如可用通义千问的 Embedding DeepSeek 对话模型组合。这也是 Spring AI 统一抽象带来的灵活性。二、向量数据库选型对比PGVectorPostgreSQL扩展运维成本低适合中小规模推荐入门首选Redis Stack毫秒级延迟适合对实时性要求高的场景Milvus百亿级向量检索适合大规模生产环境三、Docker 部署 PGVector 与基础操作1. 启动 PGVector 容器# 该镜像已内置 pgvector 扩展无需手动安装 docker run -d --name pgvector \ -p 5432:5432 \ -e POSTGRES_USERpostgres \ -e POSTGRES_PASSWORDpostgres \ -e POSTGRES_DBspring_ai \ pgvector/pgvector:pg172. 连接数据库# 进入容器内的 psql 命令行 docker exec -it pgvector psql -U postgres -d spring_ai3. 创建扩展和测试表-- 启用 pgvector 扩展 CREATE EXTENSION IF NOT EXISTS vector; -- 创建测试表3维向量便于理解 CREATE TABLE test_vectors ( id serial PRIMARY KEY, content text, embedding vector(3) ); -- 插入测试数据 INSERT INTO test_vectors (content, embedding) VALUES (Java多线程编程, [1.0, 0.0, 0.0]), (Java并发编程指南, [0.9, 0.1, 0.0]), (Spring框架入门, [0.0, 1.0, 0.0]), (红烧肉的做法, [0.0, 0.0, 1.0]); -- 查询与“Java并发”最相似的文档余弦距离越小越相似 SELECT content, embedding [0.95, 0.05, 0.0] AS distance FROM test_vectors ORDER BY embedding [0.95, 0.05, 0.0] LIMIT 4;查询结果示例content | distance ----------------------------------------- Java多线程编程 | 0.001382167413583435 Java并发编程指南 | 0.0016858262888576059 Spring框架入门 | 0.9474411652632639 红烧肉的做法 | 1 (4 rows)4. 理解三种距离度量余弦距离衡量方向相似度文本场景首选- 欧氏距离衡量空间距离# 内积负数衡量向量乘积在文本语义搜索场景统一推荐使用余弦距离COSINE_DISTANCE。四、Embedding模型选型补充推荐模型text2vec、bge-m3中文优化、multilingual-e5可根据业务需求和语种选择最佳模型欢迎补充交流如有疑问欢迎留言讨论