本质上是在搭建一个RAG 知识库检索系统。
所谓 RAG,可以简单理解为:
用户提问时,系统先从企业知识库里找出最相关的资料,再把这些资料交给大模型生成回答。
在这个链路里,text-embedding-v4、LanceDB、OSS分别负责三件完全不同的事情:
text-embedding-v4:负责把文字变成向量LanceDB:负责根据向量做相似度检索OSS:负责存储向量、原文、元数据和索引文件下面先讲专业概念,再讲销售知识库案例。
一、先理解几个核心专业概念
- 什么是 Embedding?
Embedding,中文一般叫:
嵌入向量。
它的作用是:
把一段文字转换成一组数字。
例如:
客户觉得我们太贵了,怎么办?经过 embedding 模型处理后,会变成类似这样的向量:
[0.021, -0.318, 0.772, ..., -0.056]如果使用text-embedding-v4的默认配置,通常可以生成1024 维向量。
也就是说,一句话会被转换成:
1024 个浮点数这些数字不是随机的,而是表达了这句话的语义特征。
- 为什么文字要变成向量?
因为普通数据库只能做关键词匹配。
例如用户问:
客户嫌贵怎么接?但文档里写的是:
当客户提出价格异议时,应优先强调 ROI 和长期价值,而不是直接降价。这两句话没有完全相同的关键词,但语义非常接近。
传统搜索可能搜不到。
但是 embedding 可以识别:
客户嫌贵价格异议报价太高竞品更便宜预算不足这些表达在语义上是接近的。
所以,向量的价值是:
让系统不再只看“字面是否一样”,而是看“意思是否接近”。
- 什么是 text-embedding-v4?
text-embedding-v4是阿里云百炼里的嵌入模型,属于 Qwen3-Embedding 系列。
它在这个系统里的定位是:
语义翻译官。
它不负责保存数据,也不负责搜索数据。
它只负责一件事:
中文 / 英文 / 混合文本 ↓语义向量例如:
客户说我们比竞品贵 30%,怎么回复?转换成:
[0.034, -0.217, ..., 0.891]这个向量后续会交给 LanceDB 检索。
- text-embedding-v4 常见关键参数
在销售知识库场景里,最重要的参数有几个。
1)dimensions:向量维度
text-embedding-v4支持多种维度,例如:
2048、1536、1024、768、512、256、128、64维度越高,表达能力通常越强,但也会带来几个问题:
存储更大索引更大检索更慢成本更高对于销售知识库这种通用语义检索场景,通常建议从:
1024 维开始。
原因是:
精度够用成本可控索引体积不会过度膨胀不要一开始就直接上 2048 维。数据量一旦变大,向量文件和索引文件都会明显膨胀。
2)batch size:批量条数
Embedding 接口通常支持批量输入。
你提供的信息里,text-embedding-v4一次最多处理:
10 条文本所以批量入库时,应该按 10 条一批调用接口。
3)单行 token 上限
单条文本不能无限长。
你提供的信息里,单行上限是:
8192 token但在知识库里,不建议直接把一整篇 PDF 扔进去做 embedding。
更合理的做法是:
先切片,再 embedding例如每段 200 到 500 字左右。
- 什么是向量数据库?
向量数据库就是专门用来做这类查询的数据库:
给我一个向量找出数据库里最相似的几个向量这类查询叫:
向量相似度检索。
例如:
用户问题向量:[0.034, -0.217, ..., 0.891]数据库中有几万、几十万、几百万条资料,每条资料也都有一个向量。
向量数据库要做的事情是:
从海量向量中找出最相似的 Top-K 条比如 Top 5:
第 1 条:客户价格异议处理话术第 2 条:竞品贵 30% 的应对方式第 3 条:ROI 价值证明案例第 4 条:售后服务价值说明第 5 条:总拥有成本 TCO 对比- LanceDB 是什么?
LanceDB 是一个开源向量数据库,底层基于 Lance 数据格式。
在这套系统里,它的定位是:
带索引能力的向量检索引擎。
它负责:
创建表写入向量、原文、元数据创建向量索引执行向量相似度搜索返回最相关结果需要注意一个细节:
LanceDB 不是 OSS,OSS 也不是 LanceDB。
LanceDB 负责组织数据、管理索引、执行检索。
OSS 负责保存 LanceDB 产生的数据文件。
也就是说:
LanceDB 是干活的OSS 是放东西的- 什么是 OSS?
OSS 是阿里云对象存储。
你可以把它理解成:
云上的大硬盘。
它适合存:
PDF图片视频日志数据文件索引文件.lance 文件但是 OSS 不擅长做计算。
它不会帮你做:
向量相似度计算Top-K 排序语义搜索索引召回所以不要理解成:
把向量放进 OSS,然后 OSS 帮我搜这是错误理解。
正确理解是:
LanceDB 负责搜索OSS 负责存储- LanceDB 为什么可以接 OSS?
LanceDB 支持使用 S3 兼容存储作为后端。
阿里云 OSS 也提供 S3 兼容接口。
所以可以通过类似下面的方式连接:
s3://your-bucket/sales-kb/lancedb但实际 endpoint 指向的是阿里云 OSS:
https://oss-cn-hangzhou.aliyuncs.com这里有一个关键点:
LanceDB 不能直接识别
oss://协议,要通过 S3 兼容方式访问 OSS。
所以路径写的是:
s3://bucket/path但 endpoint 配的是:
阿里云 OSS 的 S3 兼容 endpoint- 什么是索引?
如果没有索引,LanceDB 每次查询都可能需要和所有向量逐个比较。
假设有:
100 万条销售资料片段用户问一句话,系统就要比较:
1 次问题向量 × 100 万条资料向量这会很慢。
索引的作用是:
提前把向量组织起来,让查询时不用全量扫描。
可以把索引理解成图书馆目录。
没有目录时,你要一本一本找。
有目录时,你先定位到几个可能相关的书架,再从这些书架中找最相关的书。
- IVF-PQ 是什么?
LanceDB 可以使用 IVF-PQ 这类向量索引。
不用先被名字吓住。
可以拆开理解。
IVF:先分区
IVF 的思路是:
先把所有向量分成很多个区比如:
价格异议相关售后服务相关产品功能相关合同条款相关竞品对比相关真实系统不是按文字标签这么分,而是按向量空间自动聚类。
查询时,系统先判断用户问题最接近哪些分区。
这样就不用查所有数据。
PQ:压缩向量
PQ 的作用是:
把原始高维向量压缩成更小的表示为什么要压缩?
因为向量太大。
例如:
100 万条 × 1024 维数据量会很大。
PQ 可以减少内存和存储压力,加快粗筛速度。
但是压缩会有一定精度损失,所以通常检索过程会分两步:
先用压缩向量快速粗筛再用原始向量做精确重排- 什么是粗筛和精排?
这是向量检索里非常重要的概念。
粗筛
粗筛就是:
先快速找出一批可能相关的候选结果例如从 100 万条中先筛出 100 条。
这个阶段追求的是:
快不是绝对精确。
精排
精排就是:
对粗筛出来的候选结果重新精确计算相似度例如从 100 条里选出最相关的 5 条。
这个阶段追求的是:
准所以完整流程是:
100 万条 ↓ 粗筛100 条候选 ↓ 精排Top 5二、三者的准确分工
现在把三个角色钉死。
- text-embedding-v4:翻译官
它负责:
把人类语言翻译成向量语言例如:
客户嫌贵怎么办?变成:
[0.034, -0.217, ..., 0.891]它不负责:
保存数据创建索引查询数据库返回原文- LanceDB:检索管理员
它负责:
保存向量表结构写入向量、原文、元数据创建索引根据 query vector 做相似度搜索返回 Top-K 结果它像一个仓库管理员。
它知道:
哪些资料在哪些区域哪些资料和用户问题最接近应该先查哪些候选最后返回哪几条- OSS:数据仓库
它负责:
保存 LanceDB 的物理数据文件例如:
向量数据原文片段元数据索引文件.lance 文件它不负责:
语义理解向量计算索引调度Top-K 排序三、销售知识库案例:从 0 到 1 跑完整链路
- 业务场景
公司有 5000 份销售资料,包括:
产品手册 PDF销售 FAQ竞品对比文档客户异议处理话术成功案例培训 Markdown现在销售员希望直接提问:
客户说我们比竞品贵 30%,怎么接?系统返回最相关的 5 段原文,例如:
1. 当客户提出价格异议时,先不要急于降价,应引导客户关注 ROI。2. 如果客户认为竞品更便宜,可以从售后响应、实施成功率、长期维护成本三个维度对比。3. 对于预算敏感型客户,可以提供分阶段采购方案。这就是一个典型销售知识库检索系统。
- 阶段一:文档抽取
原始资料可能是:
PDFWordMarkdownHTMLExcel第一步要做的是:
把这些文档里的正文抽出来例如从 PDF 中抽出:
当客户说价格太高时,先不要急着降价,而是引导客户关注 ROI。从 Markdown 中抽出:
Q:你们比竞品贵 30% 凭什么?A:我们的售后响应是 2 小时内,竞品通常是 24 小时内。- 阶段二:文本切片
不要把一整篇文档直接丢给 embedding 模型。
应该先切片。
比如:
chunks = [ { "text": "当客户说价格太高时,先不要急着降价,而是引导客户关注 ROI...", "source": "价格异议处理手册.pdf", "page": 12, "category": "销售话术" }, { "text": "Q: 你们比竞品贵 30% 凭什么?A: 我们的售后响应是 2 小时...", "source": "竞品对比FAQ.md", "page": 3, "category": "竞品对比" }]每个 chunk 最好保存:
原文 text来源 source页码 page分类 category更新时间 updated_at权限信息 permission不要只存 text。
否则后续返回结果时,你不知道这段话来自哪里,也不好做权限控制。
- 阶段三:调用 text-embedding-v4 生成向量
每个切片都要转换成向量。
示例代码:
from openai import OpenAIimport osemb_client = OpenAI( api_key=os.getenv("DASHSCOPE_API_KEY"), base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")def embed(texts): """ texts: list[str] 建议每批最多 10 条 """ resp = emb_client.embeddings.create( model="text-embedding-v4", input=texts, dimensions=1024, encoding_format="float" ) return [d.embedding for d in resp.data]然后批量处理:
all_data = []for i in range(0, len(chunks), 10): batch = chunks[i:i + 10] batch_texts = [c["text"] for c in batch] batch_vectors = embed(batch_texts) for chunk, vector in zip(batch, batch_vectors): all_data.append({ "vector": vector, "text": chunk["text"], "source": chunk["source"], "page": chunk["page"], "category": chunk["category"] })此时每条数据长这样:
{ "vector": [0.034, -0.217, ..., 0.891], "text": "当客户说价格太高时,先不要急着降价...", "source": "价格异议处理手册.pdf", "page": 12, "category": "销售话术"}这一步结束后,销售资料已经从“普通文字”变成了“可以被语义检索的数据”。
- 阶段四:LanceDB 连接 OSS
现在要把这些数据写入 LanceDB。
但我们不想把数据存在本地磁盘,而是存到阿里云 OSS。
所以连接时要使用 S3 兼容方式。
示例:
import lancedbdb = lancedb.connect( "s3://your-bucket/sales-kb/lancedb", storage_options={ "region": "oss-cn-hangzhou", "endpoint": "https://oss-cn-hangzhou.aliyuncs.com", "aws_access_key_id": "你的OSS_ACCESS_KEY", "aws_secret_access_key": "你的OSS_SECRET_KEY", })这里要注意:
s3://your-bucket/sales-kb/lancedb只是 LanceDB 使用的 S3 兼容路径。
真正访问的是:
阿里云 OSS endpoint也就是:
https://oss-cn-hangzhou.aliyuncs.com- 阶段五:创建 LanceDB 表并写入数据
创建表:
table = db.create_table( "sales_knowledge", data=all_data, mode="overwrite")这一步之后,OSS 中会出现 LanceDB 相关数据文件。
可以理解为:
LanceDB 负责把向量、原文、元数据组织成表OSS 负责保存这些表对应的物理文件后续有新资料时,可以增量追加:
table.add(more_data)- 阶段六:创建向量索引
数据写入后,如果数据量较大,需要创建索引。
例如:
table.create_index( vector_column_name="vector", config=lancedb.Index.ivf_pq( num_partitions=256, num_sub_vectors=64, ))这里两个参数先简单理解。
num_partitions
表示把向量空间分成多少个分区。
可以粗略理解为:
仓库分成多少个区域数据越多,通常分区数可以适当增加。
几万条数据,不需要太大。
几百万条数据,就要认真调参。
num_sub_vectors
这是 PQ 压缩相关参数。
可以粗略理解为:
把一个大向量拆成多少段来压缩它影响:
索引大小检索速度召回效果不要一开始乱调,建议先用中等配置跑通,再通过测试集评估效果。
- 阶段七:销售员提问
销售员输入:
客户说我们比竞品贵 30%,怎么接?系统第一步不是直接查数据库,而是先把这个问题也转换成向量。
注意:
入库文档用什么 embedding 模型,查询问题也要用同一个 embedding 模型。
示例:
def search(question: str, top_k=5): q_vector = embed([question])[0] results = ( table .search(q_vector) .limit(top_k) .to_pandas() ) return results[["text", "source", "page", "category"]]调用:
hits = search("客户说我们比竞品贵30%,怎么接", top_k=5)for i, row in hits.iterrows(): print(f"{i + 1}. {row['text']}") print(f"来源:{row['source']} 第 {row['page']} 页")四、完整查询链路拆解
现在把整个查询链路拆开。
用户问:
客户说我们比竞品贵 30%,怎么接?第一步:text-embedding-v4 把问题转成向量
客户说我们比竞品贵 30%,怎么接? ↓[0.034, -0.217, ..., 0.891]这一步发生在阿里云百炼 embedding API。
第二步:LanceDB 拿到 query vector
LanceDB 收到的不是文字,而是:
1024 维 query vectorLanceDB 不理解“贵不贵”这个中文意思。
它只知道:
我要找和这个向量最接近的向量第三步:LanceDB 用索引粗筛
LanceDB 会根据 IVF-PQ 索引快速判断:
这个问题最可能落在哪些向量分区例如:
256 个分区 ↓挑出最接近的若干个分区 ↓在这些分区里快速扫描候选这个阶段的目标是:
快点缩小范围不是马上得到最终答案。
第四步:LanceDB 从 OSS 读取候选数据
粗筛后,LanceDB 可能得到几十条或几百条候选。
然后它会从 OSS 中读取这些候选对应的数据,包括:
原始向量原文 text来源 source页码 page分类 category这里一定要理解:
不是 OSS 在做向量搜索,而是 LanceDB 决定要读哪些数据,然后去 OSS 取。
OSS 的角色只是:
你要哪个文件、哪段数据,我给你。第五步:LanceDB 做全精度重排
候选数据取回来后,LanceDB 会做更精确的相似度计算。
例如:
候选 100 条 ↓精确计算相似度 ↓排序 ↓取 Top 5最后返回:
最相关的 5 段销售资料五、用一张图记住完整链路
销售员提问:“客户说我们比竞品贵 30%,怎么接?” │ ▼text-embedding-v4把问题转成 1024 维向量 │ ▼LanceDB拿 query vector 查 IVF-PQ 索引 │ ▼LanceDB粗筛出几十条 / 几百条候选 │ ▼OSS按需读取候选数据 │ ▼LanceDB对候选做全精度重排 │ ▼返回 Top 5 原文片段六、入库链路和查询链路要分开理解
很多小白会把这两个流程混在一起。
其实知识库有两条链路。
- 入库链路
入库链路发生在:
准备知识库数据时流程是:
PDF / Markdown / Word ↓抽取正文 ↓文本切片 ↓text-embedding-v4 生成向量 ↓LanceDB 写表 ↓OSS 保存 .lance 数据文件 ↓LanceDB 创建索引入库不是每次用户提问都做。
通常是:
新增资料修改资料定期同步才做。
- 查询链路
查询链路发生在:
用户每次提问时流程是:
用户问题 ↓text-embedding-v4 生成问题向量 ↓LanceDB 查索引 ↓OSS 读取候选 ↓LanceDB 精排 ↓返回 Top-K 原文用户每问一次,就会走一次查询链路。
七、为什么这套组合适合销售知识库?
- 中文语义检索能力强
销售话术里经常有大量中文表达:
太贵了预算不够竞品便宜价格异议ROI 不明显投入产出比低这些话字面不同,但业务意思接近。
Embedding 模型可以把它们映射到接近的向量空间。
- LanceDB 适合轻量级知识库场景
销售知识库一般不是每秒大量写入的交易系统。
它更像:
文档相对稳定按天或按周更新查询频繁LanceDB 这种嵌入式向量数据库比较适合这种场景。
- OSS 适合存放持续增长的知识库数据
销售资料会不断增加:
新产品资料新竞品对比新客户案例新话术模板如果全放本地磁盘,后期迁移、扩容、备份都会麻烦。
放到 OSS 后:
存储容量弹性更好成本更低多计算节点可以共享同一份数据- 存算分离,后期更容易扩展
OSS 负责存储。
LanceDB 运行在应用服务或检索服务里。
当查询并发上升时,可以扩多个检索服务实例:
检索服务 A检索服务 B检索服务 C ↓共同访问同一个 OSS bucket这就是存算分离的好处。
数据不用搬。
计算节点可以横向扩展。
八、几个容易踩坑的点
- 不要直接用 oss://
LanceDB 连接 OSS 时,不是直接写:
oss://your-bucket/path而是使用 S3 兼容方式:
s3://your-bucket/path然后在storage_options里配置 OSS endpoint。
- 入库和查询必须用同一个 embedding 模型
如果入库时用:
text-embedding-v4,1024 维查询时也要用:
text-embedding-v4,1024 维不要入库用 1024 维,查询用 768 维。
也不要入库用一个模型,查询用另一个模型。
否则向量空间不一致,检索效果会很差,甚至直接报错。
- 文档不要切得太碎,也不要太长
切得太碎:
上下文不完整答案容易断裂切得太长:
噪声太多embedding 表达不聚焦召回不精准销售知识库可以先从:
200 到 500 字一段开始试。
- 元数据一定要存
不要只存:
vectortext建议至少存:
source:来源文件page:页码category:分类updated_at:更新时间permission:权限标识否则后期会遇到问题:
不知道答案来自哪个文件无法展示出处无法按部门做权限隔离无法做文档更新无法删除旧版本- 不要以为向量检索等于最终答案
LanceDB 返回的是:
相关资料片段不是完整回答。
如果你要让系统像智能客服一样回答,还需要把 Top-K 片段交给大模型,例如:
请根据以下资料回答用户问题,不要编造。这一步才是完整 RAG 的生成环节。
九、最终用一句话总结
这套系统可以这样理解:
text-embedding-v4 是翻译官:把销售问题和销售资料都翻译成向量。LanceDB 是检索管理员:根据向量相似度快速找到最相关的资料。OSS 是仓库:负责保存 LanceDB 的数据文件、原文、向量、元数据和索引。销售员问:
客户嫌贵怎么办?系统实际做的是:
先把问题转成向量再用 LanceDB 查相似向量再从 OSS 取回候选资料最后返回最相关的销售话术真正要记住的是:
OSS 只负责存储,LanceDB 负责检索,text-embedding-v4 负责把文字变成向量。
这三者合起来,才构成一个可落地的销售知识库语义检索系统。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~