语义检索技术:让AI更懂自然语言
语义检索技术:让AI更懂自然语言
一、引言:从“关键词匹配”到“语义理解”的革命
1.1 一个真实的痛点场景
假设你想查“苹果的价格走势”,用传统搜索引擎检索时,结果可能包含:
- 苹果公司(Apple Inc.)的股价波动
- 苹果手机(iPhone)的价格下跌新闻
- 水果苹果的市场报价(占比很小)
问题出在哪里? 传统检索依赖关键词匹配,无法区分“苹果”的多义性(公司/手机/水果),也不理解“价格走势”的真正意图(你可能想知道近期水果价格是否会上涨)。
而如果用语义检索,系统会:
- 分析“苹果”在“价格走势”语境下的含义(更可能是水果)
- 理解“价格走势”的语义(时间序列的变化趋势)
- 返回更符合你真实需求的结果(比如“2024年夏季苹果批发价预测”)
1.2 什么是语义检索?
语义检索(Semantic Retrieval)是一种基于自然语言语义理解的信息检索技术,它通过将文本转化为机器可理解的语义表示(如向量),并基于语义相似性而非关键词匹配来检索信息。
其核心逻辑可以概括为:
用户查询 → 语义编码(转化为向量) → 向量数据库检索(找语义最相似的文档) → 结果排序(返回最相关的内容)
1.3 语义检索 vs 传统检索:本质区别
| 维度 | 传统检索 | 语义检索 |
|---|---|---|
| 理解方式 | 关键词匹配(字面意义) | 语义表示(深层意图) |
| 多义性处理 | 无法区分(如“苹果”) | 结合语境消歧 |
| 相似性衡量 | 词频统计(如TF-IDF) | 向量空间相似性(如余弦相似度) |
| 效果依赖 | 用户输入的准确性 | 模型对语义的理解能力 |
二、语义检索的核心原理:从“文本”到“语义向量”的魔法
2.1 基础:语义表示——语言的“数学指纹”
语义检索的第一步,是将文本(词、句、文档)转化为高维向量(Embedding)。这些向量的神奇之处在于:
- 语义相似的文本,向量距离更近(如“猫”和“狗”的向量比“猫”和“汽车”更近);
- 语义相关的文本,向量方向一致(如“吃苹果”和“啃水果”的向量夹角很小)。
2.1.1 词嵌入:从“one-hot”到“分布式表示”
早期的词表示用one-hot向量(如“猫”=[1,0,0,0],“狗”=[0,1,0,0]),但无法捕捉词之间的语义关系(如“猫”和“狗”都是动物,但one-hot向量的余弦相似度为0)。
分布式表示(Distributed Representation)解决了这个问题,它将每个词映射到一个低维连续向量(通常是100-768维),向量中的每个维度代表词的某种语义特征(如“是否有生命”“是否是动物”)。
经典模型:Word2Vec
Word2Vec是2013年Google提出的词嵌入模型,核心思想是“上下文预测目标词”(CBOW模型)或“目标词预测上下文”(Skip-gram模型)。
以CBOW(连续词袋模型)为例,其目标是通过上下文词(如“我”“喜欢”“吃”)预测中心词(如“苹果”)。模型的数学定义如下:
- 输入:上下文词的one-hot向量(x1,x2,...,xnx_1, x_2, ..., x_nx1,x2,...,xn);
- 隐藏层:通过权重矩阵WWW(V×NV \times NV×N,VVV是词汇表大小,NNN是嵌入维度)将输入转化为嵌入向量(h=1n∑i=1nWxih = \frac{1}{n} \sum_{i=1}^n W x_ih=n1∑i=1nWxi);
- 输出层:通过权重矩阵W′W'W′(N×VN \times VN×V)将隐藏层向量转化为词汇表概率分布(y=softmax(W′h)y = softmax(W' h)y=softmax(W′h));
- 损失函数:交叉熵损失(L=−∑i=1Vtilog(yi)L = -\sum_{i=1}^V t_i \log(y_i)L=−∑i=1Vtilog(yi),tit_iti是中心词的one-hot向量)。
Word2Vec的输出WWW矩阵的每一行,就是对应词的嵌入向量。例如,“猫”的嵌入可能是[0.8,−0.2,0.5,...][0.8, -0.2, 0.5, ...][0.8,−0.2,0.5,...],“狗”的嵌入是[0.7,−0.1,0.6,...][0.7, -0.1, 0.6, ...][0.7,−0.1,0.6,...],两者的余弦相似度很高(约0.9),说明它们语义相似。
2.1.2 句/文档嵌入:从“词向量”到“文本向量”
词嵌入只能表示单个词的语义,而语义检索需要处理更长的文本(如句子、文档)。句嵌入的目标是将整个句子转化为一个固定长度的向量,保留其整体语义。
经典模型:Sentence-BERT
BERT(2019年Google提出)是基于Transformer的预训练模型,能捕捉上下文语义,但直接用BERT的[CLS] token向量作为句嵌入的效果并不好(因为BERT是为分类任务设计的)。
Sentence-BERT(2020年提出)对BERT进行了优化,通过对比学习(Contrastive Learning)训练句嵌入:
- 输入:一对句子(如“我喜欢吃苹果”和“苹果是我最喜欢的水果”,视为正例;“我喜欢吃苹果”和“今天天气很好”,视为负例);
- 输出:两个句子的嵌入向量(uuu和vvv);
- 损失函数:三元组损失(L=max(0,∣∣u−v+∣∣2−∣∣u−v−∣∣2+α)L = \max(0, ||u - v^+||^2 - ||u - v^-||^2 + \alpha)L=max(0,∣∣u−v+∣∣2−∣∣u−v−∣∣2+α),其中v+v^+v+是正例嵌入,v−v^-v−是负例嵌入,α\alphaα是margin)。
Sentence-BERT的句嵌入效果显著优于传统方法(如平均词向量),在语义相似性任务(如STS-B)上的Pearson相关系数从0.75提升到0.85。
2.2 关键:语义匹配——如何衡量“语义相似性”?
有了文本的语义向量,下一步是计算查询向量与文档向量的相似性,从而找到最相关的文档。
2.2.1 常用相似性度量
-
余弦相似度(Cosine Similarity):计算两个向量的夹角余弦值,范围[-1,1],值越大越相似。公式:
cosine(u,v)=u⋅v∣∣u∣∣∣∣v∣∣ \text{cosine}(u, v) = \frac{u \cdot v}{||u|| ||v||} cosine(u,v)=∣∣u∣∣∣∣v∣∣u⋅v
例如,查询“如何学习Python”的向量uuu,与文档“Python入门教程”的向量vvv的余弦相似度为0.9,说明两者语义高度相关。 -
点积(Dot Product):计算两个向量的点积,范围[-∞, +∞],值越大越相似。公式:
dot(u,v)=u⋅v=∑i=1nuivi \text{dot}(u, v) = u \cdot v = \sum_{i=1}^n u_i v_i dot(u,v)=u⋅v=i=1∑nuivi
点积的计算速度比余弦相似度快(不需要计算模长),但对向量的长度敏感(如果向量长度差异大,点积可能不准确)。 -
欧氏距离(Euclidean Distance):计算两个向量的直线距离,范围[0, +∞],值越小越相似。公式:
euclidean(u,v)=∣∣u−v∣∣=∑i=1n(ui−vi)2 \text{euclidean}(u, v) = ||u - v|| = \sqrt{\sum_{i=1}^n (u_i - v_i)^2} euclidean(u,v)=∣∣u−v∣∣=i=1∑n(ui−vi)2
欧氏距离对异常值敏感,通常不如余弦相似度常用。
2.2.2 两种匹配策略:Bi-Encoder vs Cross-Encoder
-
Bi-Encoder(双编码器):分别将查询和文档转化为嵌入向量,然后用相似性度量(如余弦相似度)计算匹配得分。
- 优点:速度快(嵌入生成后,查询只需一次向量计算),适合大规模数据;
- 缺点:精度略低(因为没有直接交互查询和文档的语义)。
- 代表模型:Sentence-BERT、LaBSE(多语言句嵌入)。
-
Cross-Encoder(交叉编码器):将查询和文档拼接成一个序列(如“[CLS] 查询 [SEP] 文档 [SEP]”),输入到Transformer模型中,直接输出匹配得分(0-1之间的概率)。
- 优点:精度高(能捕捉查询和文档之间的细粒度语义交互);
- 缺点:速度慢(每个查询需要与所有文档拼接计算),不适合大规模数据。
- 代表模型:Cross-Encoder(基于BERT)、T5-Cross-Encoder。
实践中的策略:用Bi-Encoder做粗检索(从百万级文档中快速找到Top 1000相关文档),再用Cross-Encoder做精排序(从1000个文档中选出Top 10最相关的),兼顾速度和精度。
2.3 支撑:向量数据库——语义检索的“索引引擎”
当文档数量达到百万级甚至亿级时,直接计算查询向量与所有文档向量的相似性(线性检索)会非常慢(时间复杂度O(N)O(N)O(N))。向量数据库(Vector Database)通过索引技术(如KD-Tree、IVF、HNSW)将时间复杂度降低到O(logN)O(\log N)O(logN)或O(N)O(\sqrt{N})O(N),实现快速相似性检索。
2.3.1 向量数据库的核心功能
- 向量存储:存储文档的语义向量(如Sentence-BERT生成的768维向量);
- 索引构建:通过索引算法将向量组织成高效的检索结构;
- 相似性查询:给定查询向量,快速返回Top K语义最相似的文档;
- 元数据过滤:支持结合元数据(如文档类型、时间、作者)进行筛选(如“返回2024年发布的Python教程”)。
2.3.2 主流向量数据库对比
| 数据库 | 类型 | 优点 | 缺点 |
|---|---|---|---|
| Faiss | 本地库(C++/Python) | 速度极快(支持GPU加速),内存占用低 | 无分布式支持,无元数据管理 |
| Milvus | 分布式(Go/Python) | 支持分布式存储,元数据管理,多语言SDK | 部署复杂,资源占用高 |
| Pinecone | 云服务 | 完全托管,弹性扩展,支持实时检索 | 成本高(按向量数量收费) |
| Weaviate | 开源(Go) | 支持知识图谱融合,多模态检索 | 社区较小,文档不够完善 |
三、语义检索系统架构:从“数据”到“结果”的全流程
3.1 系统架构图(Mermaid)
graph TD
A[数据采集] --> B[数据预处理]
B --> C[语义嵌入生成]
C --> D[向量数据库存储]
E[用户查询] --> F[查询预处理]
F --> G[查询嵌入生成]
G --> H[向量数据库检索(粗排)]
H --> I[Cross-Encoder精排]
I --> J[结果返回]
3.2 各模块详细说明
3.2.1 数据采集
- 来源:网页爬取(如Scrapy)、数据库导出(如MySQL)、文件上传(如PDF、Word);
- 示例:采集Wikipedia的Python相关文档(约10万条)。
3.2.2 数据预处理
- 步骤:
- 清洗:去除HTML标签、特殊字符、重复内容;
- 分词:中文用jieba(如“如何学习Python”→“如何/学习/Python”),英文用NLTK(如“Learn Python”→“Learn/Python”);
- 截断/分段:处理长文档(如超过512 tokens的文档,用滑动窗口分段,每段512 tokens,重叠100 tokens)。
3.2.3 语义嵌入生成
- 工具:Hugging Face Transformers(加载预训练模型);
- 代码示例(用Sentence-BERT生成句嵌入):
from sentence_transformers import SentenceTransformer # 加载预训练模型(支持多语言) model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') # 输入文本(文档列表) documents = [ "Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。", "Python的设计哲学强调代码的可读性和简洁性。", "学习Python的最佳方式是动手做项目。" ] # 生成嵌入向量(shape: [3, 768]) embeddings = model.encode(documents, convert_to_tensor=True) # 打印第一个文档的嵌入向量(前5维) print(embeddings[0][:5]) - 输出:
tensor([-0.0321, 0.0456, -0.0123, 0.0789, -0.0234])
3.2.4 向量数据库存储
- 工具:Faiss(本地存储,适合小数据量);
- 代码示例(将嵌入向量存入Faiss索引):
import faiss import numpy as np # 将Tensor转换为numpy数组(Faiss要求输入为float32) embeddings_np = embeddings.cpu().numpy().astype('float32') # 构建Faiss索引(IVF_FLAT,适合百万级数据) index = faiss.IndexIVFFlat( d=embeddings_np.shape[1], # 向量维度(768) nlist=100, # 聚类中心数量(根据数据量调整) metric=faiss.METRIC_COSINE # 相似性度量(余弦相似度) ) # 训练索引(需要随机样本) index.train(embeddings_np) # 添加向量到索引 index.add(embeddings_np) # 保存索引到本地 faiss.write_index(index, 'python_docs.index')
3.2.5 查询处理与检索
-
步骤:
- 查询预处理:与文档预处理一致(清洗、分词、截断);
- 查询嵌入生成:用同样的Sentence-BERT模型生成查询向量;
- 粗检索:用Faiss索引快速找到Top 1000语义相似的文档;
- 精排序:用Cross-Encoder对Top 1000文档进行重新排序,得到Top 10最相关的文档。
-
代码示例(查询“如何学习Python”):
from sentence_transformers import CrossEncoder # 加载Cross-Encoder模型(用于精排) cross_encoder = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2') # 用户查询 query = "如何学习Python" # 生成查询嵌入 query_embedding = model.encode(query, convert_to_tensor=True).cpu().numpy().astype('float32') # 粗检索:从Faiss索引中找到Top 1000文档(参数nprobe=10,提高检索精度) k = 1000 distances, indices = index.search(query_embedding.reshape(1, -1), k) # 获取粗检索的文档(假设documents列表与索引顺序一致) candidate_documents = [documents[i] for i in indices[0]] # 精排序:用Cross-Encoder计算查询与候选文档的匹配得分 cross_encoder_input = [[query, doc] for doc in candidate_documents] scores = cross_encoder.predict(cross_encoder_input) # 按得分降序排序,取Top 10 top_10_indices = scores.argsort()[::-1][:10] top_10_documents = [candidate_documents[i] for i in top_10_indices] # 打印结果 print("Top 10相关文档:") for i, doc in enumerate(top_10_documents): print(f"{i+1}. {doc}")
3.2.6 结果返回
- 格式:JSON(包含文档内容、相似度得分、元数据);
- 示例:
{ "query": "如何学习Python", "results": [ { "document": "学习Python的最佳方式是动手做项目。", "score": 0.98, "metadata": { "source": "Wikipedia", "timestamp": "2024-05-01" } }, { "document": "Python的设计哲学强调代码的可读性和简洁性。", "score": 0.85, "metadata": { "source": "Wikipedia", "timestamp": "2024-05-01" } } ] }
四、项目实战:搭建一个智能知识库语义检索系统
4.1 项目目标
搭建一个基于语义检索的智能知识库,支持用户用自然语言查询知识库中的文档(如产品手册、技术文档),返回最相关的内容。
4.2 技术栈
- 后端:FastAPI(构建RESTful接口);
- 语义嵌入:Sentence-BERT(多语言支持);
- 向量数据库:Milvus(分布式支持,适合大规模数据);
- 前端:Streamlit(快速构建可视化界面);
- 数据:产品手册PDF(如“Python SDK使用指南”)。
4.3 步骤1:环境搭建
- 安装依赖:
pip install fastapi uvicorn sentence-transformers pymilvus streamlit pdfplumber - 启动Milvus(用Docker-compose):
wget https://github.com/milvus-io/milvus/releases/download/v2.3.0/milvus-standalone-docker-compose.yml -O docker-compose.yml docker-compose up -d
4.4 步骤2:数据预处理(PDF转文本)
- 代码示例(用pdfplumber提取PDF内容):
import pdfplumber def extract_text_from_pdf(pdf_path): text = "" with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text += page.extract_text() + "\n" return text # 提取产品手册内容 pdf_path = "python_sdk_guide.pdf" document_text = extract_text_from_pdf(pdf_path) # 分段(每段512 tokens) from sentence_transformers import util sentences = util.split_into_sentences(document_text, language='zh') chunks = [] current_chunk = [] current_length = 0 max_length = 512 for sentence in sentences: sentence_length = len(sentence.split()) if current_length + sentence_length > max_length: chunks.append(" ".join(current_chunk)) current_chunk = [sentence] current_length = sentence_length else: current_chunk.append(sentence) current_length += sentence_length if current_chunk: chunks.append(" ".join(current_chunk)) print(f"共提取{len(chunks)}段文档")
4.5 步骤3:生成嵌入并存入Milvus
- 代码示例(用Sentence-BERT生成嵌入,存入Milvus):
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection # 连接Milvus connections.connect("default", host="localhost", port="19530") # 定义集合 schema(包含文档ID、嵌入向量、文档内容、元数据) fields = [ FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True), FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=768), FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=4096), FieldSchema(name="metadata", dtype=DataType.JSON) ] schema = CollectionSchema(fields=fields, description="产品手册知识库") # 创建集合 collection_name = "product_manuals" collection = Collection(name=collection_name, schema=schema) # 生成嵌入向量 model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') embeddings = model.encode(chunks, convert_to_tensor=True).cpu().numpy().astype('float32') # 准备数据(文档内容、元数据) data = [ embeddings, # embedding字段 chunks, # text字段 [{"source": "python_sdk_guide.pdf", "page": i+1} for i in range(len(chunks))] # metadata字段 ] # 插入数据到Milvus collection.insert(data) # 构建索引(IVF_FLAT,适合余弦相似度) index_params = { "index_type": "IVF_FLAT", "metric_type": "COSINE", "params": {"nlist": 100} } collection.create_index(field_name="embedding", index_params=index_params) # 加载集合到内存(用于检索) collection.load()
4.6 步骤4:构建FastAPI接口
- 代码示例(定义检索接口):
from fastapi import FastAPI, Query from pymilvus import Collection app = FastAPI(title="智能知识库语义检索接口") # 加载Milvus集合 collection = Collection(name="product_manuals") collection.load() # 加载Sentence-BERT模型 model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') @app.get("/search") async def search( query: str = Query(..., description="用户查询"), top_k: int = Query(10, ge=1, le=100, description="返回结果数量") ): # 生成查询嵌入 query_embedding = model.encode(query, convert_to_tensor=True).cpu().numpy().astype('float32') # 语义检索(粗排) search_params = { "metric_type": "COSINE", "params": {"nprobe": 10} } results = collection.search( data=[query_embedding], anns_field="embedding", param=search_params, limit=top_k, output_fields=["text", "metadata"] # 返回文档内容和元数据 ) # 整理结果 search_results = [] for hit in results[0]: search_results.append({ "text": hit.entity.get("text"), "score": hit.score, "metadata": hit.entity.get("metadata") }) return { "query": query, "results": search_results } if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
4.7 步骤5:构建Streamlit前端
- 代码示例(快速构建可视化界面):
import streamlit as st import requests # 设置页面标题 st.title("智能知识库语义检索系统") # 用户输入框 query = st.text_input("请输入查询(如“如何使用Python SDK上传文件?”)") # 检索按钮 if st.button("检索"): if not query: st.warning("请输入查询内容!") else: # 调用FastAPI接口 response = requests.get("http://localhost:8000/search", params={"query": query, "top_k": 5}) results = response.json()["results"] # 展示结果 st.subheader("检索结果:") for i, result in enumerate(results): st.write(f"**{i+1}. 相似度:{result['score']:.2f}**") st.write(f"内容:{result['text'][:200]}...") # 截断显示前200字 st.write(f"元数据:{result['metadata']}") st.divider()
4.8 运行效果
- 启动FastAPI:
uvicorn main:app --reload; - 启动Streamlit:
streamlit run frontend.py; - 访问
http://localhost:8501,输入查询“如何使用Python SDK上传文件?”,即可看到相关的文档片段。
五、语义检索的实际应用场景
5.1 智能客服:快速定位知识库
- 问题:用户问“我的订单为什么还没发货?”,传统客服系统需要人工查找知识库中的“订单发货规则”;
- 解决:语义检索能快速匹配“订单发货”相关的文档(如“订单发货时间:付款后48小时内”),自动回复用户。
5.2 推荐系统:个性化内容推荐
- 问题:用户浏览了“Python数据分析教程”,传统推荐系统可能推荐“Python编程入门”(关键词匹配);
- 解决:语义检索能理解“数据分析”的语义,推荐“Pandas数据处理实战”(语义更相关)。
5.3 代码检索:根据自然语言找代码
- 问题:用户想找“用Python实现快速排序”的代码,传统代码库需要搜索“快速排序 Python”;
- 解决:语义检索能理解“实现快速排序”的意图,返回相关的代码片段(如GitHub中的star最多的快速排序实现)。
5.4 学术文献检索:精准找到研究论文
- 问题:研究者想找“基于Transformer的语义检索”的论文,传统学术搜索引擎需要搜索“Transformer 语义检索”;
- 解决:语义检索能理解“基于Transformer的语义检索”的语义,返回相关的顶级会议论文(如ACL、SIGIR中的论文)。
六、语义检索的挑战与未来趋势
6.1 当前挑战
- 嵌入的泛化能力:预训练模型(如Sentence-BERT)在通用领域表现好,但在专业领域(如医疗、法律)的语义理解能力不足(如“心肌梗死”的语义在医疗领域与通用领域不同);
- 实时性:在亿级数据量下,向量数据库的检索延迟可能超过1秒(无法满足实时应用需求);
- 多模态语义检索:当前语义检索主要处理文本,无法处理图像、语音等多模态数据(如“找一张猫玩球的图片”);
- 隐私问题:语义嵌入可能泄露敏感信息(如用户查询中的个人信息),需要隐私保护技术(如联邦学习、同态加密)。
6.2 未来趋势
- 领域自适应预训练:针对专业领域(如医疗、法律)训练专用的预训练模型(如BioBERT、LegalBERT),提升嵌入的泛化能力;
- 高效向量检索算法:研究更快速的向量索引算法(如HNSW的优化版、GPU加速的向量检索),降低检索延迟;
- 多模态语义检索:结合文本、图像、语音的语义表示(如CLIP模型,能将图像和文本映射到同一向量空间),实现多模态检索;
- 知识图谱融合:将知识图谱中的结构化知识(如“苹果→水果→食物”)融入语义嵌入,提升语义理解的准确性(如“苹果的价格”更准确地匹配水果价格);
- 自监督学习优化:用更先进的自监督学习方法(如SimCSE、ELECTRA)训练句嵌入,提升语义相似性的捕捉能力。
七、工具与资源推荐
7.1 预训练模型库
- Hugging Face Transformers:包含Sentence-BERT、BERT、CLIP等预训练模型,支持多语言;
- TensorFlow Hub:包含LaBSE(多语言句嵌入)、USE(通用句嵌入)等模型。
7.2 向量数据库
- Faiss:适合本地小规模数据,速度极快;
- Milvus:适合分布式大规模数据,支持元数据管理;
- Pinecone:适合云原生应用,完全托管。
7.3 可视化工具
- TensorBoard:可视化嵌入向量的分布(如用TSNE将768维向量降维到2维);
- Weights & Biases:跟踪语义检索模型的训练过程(如损失函数、准确率)。
7.4 数据集
- MS MARCO:大规模信息检索数据集(包含100万条查询和10亿条文档);
- Natural Questions:谷歌发布的自然语言问答数据集(包含8万条真实用户查询);
- STS-B:语义文本相似性数据集(包含5000对句子,标注了相似性得分)。
7.5 书籍
- 《深度学习自然语言处理》(李航):详细讲解自然语言处理的基础理论和方法;
- 《语义网基础》(Grigoris Antoniou):讲解语义网的核心概念(如RDF、OWL),适合理解早期语义检索技术;
- 《向量数据库实战》(Milvus团队):讲解向量数据库的原理和实践,适合搭建大规模语义检索系统。
八、总结:语义检索——AI理解自然语言的关键一步
语义检索技术的出现,标志着信息检索从“关键词匹配”进入“语义理解”的新时代。它通过将文本转化为语义向量,结合向量数据库和深度学习模型,实现了对自然语言意图的精准理解。
从技术演进的角度看,语义检索的未来将朝着更高效、更精准、更多模态的方向发展。对于开发者来说,掌握语义检索技术不仅能提升自己的技术能力,还能为用户带来更智能、更便捷的体验。
最后,用一句话总结语义检索的价值:
语义检索不是“找关键词”,而是“懂你的心”。
(全文完)
字数:约12000字
更多推荐



所有评论(0)