先说一个普遍遇到的场景:公司内部有两百份运维文档,当同事问“电脑蓝屏怎么办”时,传统站内搜索往往会返回标题或正文里刚好包含“蓝屏”字样的结果,而像“系统崩溃”“开机黑屏”“dump文件”这类语义接近但字面不同的提问,经常什么都搜不到。这就是关键词检索的“词不达意”问题。要让机器理解问题背后的意图,而不是单纯匹配字符,就涉及 Embedding、向量数据库、语义搜索和 RAG 这一整套技术栈。本文会把这几个概念串起来讲明白,并提供一个可以直接跑通的 Python 实战示例,帮你快速搭出一个 AI 知识库的最小系统。
1. 为什么需要向量数据库:传统搜索的瓶颈
1.1 传统关键词搜索无法解决的语义问题
传统搜索引擎和数据库的检索方式,本质上是“字符串匹配”。你输入一个词,系统在数据中找出包含这个词的文本。这个方案对精确查询有效,但面对真实业务场景时问题很明显:
- 同义词无法关联。用户搜“工资怎么算”,文档里写的是“薪酬计算规则”,字面不匹配。
- 表达方式无法对齐。用户问“如何重置密码”,文档里写的是“修改登录凭证并重新初始化”,字面差异很大。
- 多语言、口语化文本难以处理。“咋登录不上去”“Connection failed”可能描述同一件事,但关键词匹配完全失效。
- 短查询容易出噪音。输入“Java 内存”,返回的结果可能包含大量无关内容,因为没有理解用户想找的是内存模型、内存泄漏还是 JVM 参数。
传统方案也能通过分词、同义词词典、布尔查询做一定程度的增强,但这种方式维护成本高,且无法覆盖变化的、模糊的自然语言表达。当我们要构建的是 AI 知识库、智能客服、企业问答系统时,检索就必须从“字面匹配”升级为“语义匹配”。
1.2 向量数据库的核心能力
向量数据库并不是一个全新的数据库种类,而是一类专门为“存储向量 + 计算相似度”而优化的数据库。它的核心工作方式是:
- 把文本、图片、音视频等数据通过 Embedding 模型转化为高维向量。
- 将向量连同原始数据、元数据一起存储。
- 用户查询时,也把查询语句转化为向量。
- 数据库基于向量距离,返回最相似的前 N 条数据。
相比普通数据库,向量数据库在索引结构和距离计算上做了大量优化。它能支撑数百万甚至数十亿级别的向量检索,并提供毫秒级响应。常见的索引算法包括 HNSW、IVF、PQ 等,本文后面会结合实战解释。
向量数据库解决的不只是“换个搜索方式”,它让数据能被大模型理解和引用。这也是 RAG 技术能落地的基础之一。
1.3 AI知识库技术栈总览
一个完整的 AI 知识库系统,通常由四层组成:
- 数据层:原始文档、数据库记录、网页内容。
- 向量化层:Embedding 模型负责把数据转换为向量。
- 存储检索层:向量数据库存储向量并支持快速检索,必要时配合关键词检索做混合召回。
- 生成层:大语言模型接收检索到的上下文,生成最终答案。
围绕这一技术栈,我们可以看到很多相关名词:Embedding、语义搜索、RAG、向量数据库选型、Agentic RAG、GraphRAG 等。它们不是相互独立的概念,而是一条流水线上的不同环节。后续章节会逐个拆开讲。
2. 彻底搞懂Embedding
2.1 Embedding的本质
Embedding 翻译成中文常称为“嵌入”或“向量化”。它做的事情,是把文字、图片等非结构化数据映射到一组实数数组,也就是向量。例如一句话“系统启动失败”可能被转换成一个 768 维或 1024 维的向量:
[0.012, -0.034, 0.087, ..., 0.056]这个向量不是随便生成的,它是 Embedding 模型根据大量语料训练出来的结果。向量的空间位置包含了语义信息:语义相近的文本,在向量空间中的距离更近;语义无关的文本,距离较远。
我们可以这样理解:普通数据库保存的是“文本本身”,向量数据库保存的是“文本的意思”。这个区别看起来简单,但它是语义搜索和大模型知识库的根基。
2.2 Embedding是怎么生成的
Embedding 模型有很多种。常见的有:
- BGE 系列:如 BAAI/bge-small-zh、BAAI/bge-m3,中文语义理解表现稳定。
- OpenAI 的 text-embedding 系列。
- 其他开源模型:text2vec、m3e、GTE 等。
以 BGE-M3 为例,它支持长文本、多语言和多种检索方式,适合中英文混合的知识库场景。实际项目中,模型的选择取决于语言、领域、硬件资源和成本。
使用 Python 加载一个文本 Embedding 模型,通常只需要几行代码。以 sentence-transformers 为例:
from sentence_transformers import SentenceTransformer model = SentenceTransformer("BAAI/bge-small-zh-v1.5") text = "系统启动失败" vector = model.encode(text) print(vector.shape) print(vector[:10])运行这段代码会输出向量的维度,以及向量前 10 个数值。这里需要注意的是:模型首次加载会从网络下载权重,具体大小取决于模型版本,建议在项目初始化阶段预先下载并缓存。
2.3 向量相似度如何计算
向量存储好之后,如何判断“相似”?最常用的是余弦相似度和欧氏距离。
余弦相似度计算的是两个向量之间的夹角,取值范围在 -1 到 1 之间,值越大表示方向越一致、语义越接近。欧氏距离计算的是向量在高维空间中的直线距离,距离越小越相似。
在实际向量数据库中,我们通常会在创建集合时指定距离函数。例如使用余弦相似度,还是内积,还是欧氏距离。选择哪种取决于 Embedding 模型训练时的归一化方式。大多数情况下,余弦相似度是比较稳妥的默认选择。
一个直观的类比:把“苹果”“香蕉”“汽车”想象成三维空间中的点。“苹果”和“香蕉”距离很近,因为它们同属水果;“汽车”则离它们很远。高维向量空间也是同理,只是无法直接可视化了。
3. 语义搜索:向量检索的核心场景
3.1 语义搜索工作流程
语义搜索不是传统搜索的替代品那么简单。它与 RAG 知识库结合后,工作流程通常如下:
- 预处理:把文档按结构或固定大小切块。
- 离线向量化:用 Embedding 模型把每个文本块转换成向量。
- 写入向量库:保存向量、文本内容、来源路径、标题等元数据。
- 在线检索:用户输入问题后,对问题做同样的向量化。
- 相似度召回:向量数据库返回与问题最相似的前 K 个文本块。
- 后处理排序:可选的 Rerank 环节,对召回结果做更精细的排序。
在很多生产系统中,第 6 步非常重要。召回阶段为了速度,往往只做粗略筛选,Rerank 模型会结合用户问题与候选文档做交叉编码打分,进一步修正排队顺序。
3.2 语义搜索与关键词搜索的对比
为了更直观地理解,我们把两种方式放到一起对比:
| 维度 | 关键词搜索 | 语义搜索 |
|---|---|---|
| 匹配基础 | 字面字符 | 语义向量 |
| 同义词处理 | 依赖词典 | 模型天然支持 |
| 多语言理解 | 困难 | 跨语言模型可处理 |
| 索引难度 | 较低 | 需要向量化流程 |
| 适合场景 | 精确查询、代码搜索 | 问答、知识库、智能推荐 |
需要说明的是,这两者并不是互斥的。企业知识库往往采用“关键词 + 向量”的混合检索方式:先用关键词召回精确匹配结果,再用向量召回语义相似结果,最后用 Rerank 模型统一排序。这样能兼顾精确性和模糊语义理解。
3.3 影响检索效果的关键点
语义搜索的效果不只看向量数据库本身,以下几个因素往往影响更大:
- Embedding 模型是否适合当前语言和领域。中文场景用英文原版模型,效果通常差一截。
- 切块粒度是否合理。块太大,语义混杂;块太小,上下文不完整。
- 是否保留了结构信息。切块时直接切在正文中间,可能把标题和正文内容分开。
- 召回数量设置。返回太少容易漏,返回太多容易引入噪音。
很多刚接触向量数据库的开发者,第一反应是换更强的模型,但实际操作中,“切块策略不合理”是更常见的原因。
4. RAG:大模型如何借助知识库回答
4.1 为什么大模型需要RAG
大语言模型虽然知识丰富,但有几个明显问题:
- 知识有截止日期,无法自动获取最新信息。
- 企业内部私密知识不在训练数据中。
- 对精确数据、数字、事件细节容易编造。
- 长尾业务问题容易出现“一本正经地胡说”。
RAG,全称 Retrieval-Augmented Generation,也就是检索增强生成。核心思路是:不直接让大模型硬答,而是先从知识库中检索出相关内容,把它拼进提示词,让大模型基于这些资料作答。
这样做的好处很多:答案有据可依,降低幻觉;可以及时更新知识库而不用重新训练模型;还能在回答中附上来源,方便用户溯源验证。
4.2 RAG的核心链路
一个最小可用的 RAG 系统包含以下环节:
- 文档导入与切块。
- Embedding 向量化入库。
- 用户问题向量化。
- 向量库检索 Top-K 文档。
- 将文档拼接到 Prompt 中。
- 大模型生成回答。
从第 3 步到第 6 步是在线链路,延迟要求较高;第 1、2 步是离线准备,可以批量执行。
目前社区也出现了 Agentic RAG、GraphRAG 等进阶形态。Agentic RAG 让大模型自主决定检索什么、检索几次、是否追问;GraphRAG 则把知识图谱与向量检索结合,处理多跳关系和全局性问题。但无论形态怎么变,底层的检索与生成框架仍是核心。
4.3 向量数据库在RAG中的角色
在 RAG 链路中,向量数据库承担的是“记忆存储”的作用。大模型本身没有长期记忆,也没有项目专属知识,向量数据库补上的正是这个缺口。
可以这样理解:向量数据库不是给用户搜索用的后台系统,而是给大模型提供“外部资料”的检索层。它决定了模型能看到哪些信息,从而直接决定回答质量。如果检索阶段返回的内容不相关,那么再强的大模型也答不出好东西。
因此,“检索质量 = 向量数据库性能 + Embedding模型质量 + 切块策略 + 排序策略”这个公式,是 RAG 工程优化的基本框架。
5. 向量数据库选型:从轻量到生产
5.1 常见向量数据库对比
目前向量数据库生态已经非常丰富,不同定位各有侧重:
| 数据库 | 定位 | 适合场景 |
|---|---|---|
| Chroma | 轻量级嵌入式向量库 | 本地开发、学习原型、小型知识库 |
| Milvus / Zilliz Cloud | 大规模分布式向量库 | 生产环境、海量向量检索 |
| Qdrant | 向量检索服务 | 中小规模生产部署 |
| Weaviate | 带模式定义的向量搜索 | 需要丰富元数据过滤的场景 |
| pgvector | PostgreSQL 扩展 | 已有 PostgreSQL 体系,需要复用 |
| Elasticsearch | 全文搜索引擎扩展向量能力 | 已有 ES 体系,需要混合检索 |
这里并没有“哪个最好”的答案。开源与云服务版本也在持续迭代,选择前需要结合团队技术栈、数据规模、运维能力综合判断。
5.2 选型建议
如果你只是学习 RAG、验证想法,Chroma 是最低门槛的选择。它安装简单,可以直接嵌入 Python 进程,数据存在本地文件,免去部署服务器的时间。
如果你的知识库文档数量达到百万级,或需要高并发查询,建议关注 Milvus、Qdrant 这类独立向量数据库服务。它们的索引构建、分片、副本管理更成熟。
如果你已经在使用 PostgreSQL,且数据量不大,可以先用 pgvector 验证效果,避免引入额外中间件。但要注意,向量检索与业务查询混在同一个数据库,资源竞争问题需要提前评估。
如果你的搜索场景本身就有大量关键词查询需求,还需要同时支持向量检索,可以考虑 Elasticsearch 的向量能力,统一检索入口。
5.3 引入前要评估的维度
真正做技术选型时,要从以下维度评估:
- 数据规模:向量条数、每个向量的维度。
- 查询并发:QPS 要求。
- 过滤需求:是否频繁按来源、类型、时间过滤。
- 运维复杂度:能否接受额外部署一个数据库服务。
- 数据更新频率:是离线批量导入,还是频繁增量更新。
- 技术栈契合度:团队成员是否熟悉该工具的 API 和生态。
选型没有绝对标准,核心是“在可维护的前提下,先跑通最小系统,再根据瓶颈演进”。
6. 实战:用Chroma搭建一个AI知识库检索系统
6.1 环境准备
本文示例将以 Python 3.9+ 环境为例,使用了以下依赖:
- chromadb:轻量级向量数据库。
- sentence-transformers:加载本地 Embedding 模型。
安装命令如下:
pip install chromadb sentence-transformers注意:sentence-transformers 会依赖 PyTorch,安装体积较大。如果你的机器不方便安装,也可以改用其他 Embedding 服务,只需在代码中替换 Embedding 函数即可。本文示例中,我们使用 BGE 中文模型演示中文知识库场景。
版本方面,chromadb 和 sentence-transformers 迭代较快,建议以你安装时官方文档的最新稳定版本为准。
6.2 项目结构
一个最小项目可以这样组织:
ai_kb/ ├── docs/ # 原始文档目录 │ ├── 运维手册.md │ └── 产品常见问题.md ├── vector_store/ # Chroma 持久化目录 ├── chunk.py # 文档读取与切块 ├── build_index.py # 向量化入库脚本 ├── search.py # 语义检索脚本 └── rag_answer.py # RAG 问答脚本6.3 文档读取与切块
切块是决定语义检索质量的重要环节。下面实现一个简单的文档加载和切块函数:
# 文件路径:chunk.py from pathlib import Path def load_docs_from_dir(dir_path: str): docs = [] for path in Path(dir_path).glob("*.md"): docs.append({ "path": str(path), "text": path.read_text(encoding="utf-8") }) return docs def chunk_text(text: str, chunk_size: int = 200, overlap: int = 50): """ 按固定字符长度切块,overlap 是相邻块之间的重叠字符数。 重叠部分能减少切在语义边界导致的上下文丢失问题。 """ if chunk_size <= 0: raise ValueError("chunk_size 必须大于 0") if overlap >= chunk_size: raise ValueError("overlap 必须小于 chunk_size") chunks = [] start = 0 while start < len(text): end = start + chunk_size chunks.append(text[start:end]) if end >= len(text): break start += chunk_size - overlap return chunks这里需要注意,按固定长度切分是通用兜底方案。对中文文档,按字符切分比较直接;对英文文档,建议基于句子或段落切分,避免把单词从中间断开。如果文档自带 Markdown 标题结构,可以按二级标题或章节切块,效果通常更好。
6.4 生成Embedding并写入向量库
将文本切块后,接下来生成向量并写入 Chroma。
Chroma 的常用写法如下:
# 文件路径:build_index.py import chromadb from chromadb.utils.embedding_functions import SentenceTransformerEmbeddingFunction from chunk import chunk_text, load_docs_from_dir client = chromadb.PersistentClient(path="./vector_store") embedding_fn = SentenceTransformerEmbeddingFunction( model_name="BAAI/bge-small-zh-v1.5" ) collection = client.get_or_create_collection( name="it_kb", embedding_function=embedding_fn, metadata={"hnsw:space": "cosine"} ) docs = load_docs_from_dir("./docs") ids = [] documents = [] metadatas = [] for doc in docs: chunks = chunk_text(doc["text"], chunk_size=200, overlap=50) source_name = doc["path"].replace(".md", "").replace("\\", "/") for idx, chunk in enumerate(chunks): ids.append(f"{source_name}#{idx}") documents.append(chunk) metadatas.append({ "source": doc["path"], "chunk_index": idx, "length": len(chunk) }) collection.upsert( ids=ids, documents=documents, metadatas=metadatas ) print(f"写入完成,共 {len(ids)} 个文本块")这里有几个关键点:
PersistentClient(path="./vector_store")表示数据会持久化到本地目录。get_or_create_collection第一次运行创建集合,之后重复运行会复用。metadata={"hnsw:space": "cosine"}指定索引空间为余弦相似度,适合文本语义检索。upsert按 id 插入或更新,重复执行不会产生重复数据。
运行入库脚本:
python build_index.py如果没有报错,输出如下:
写入完成,共 27 个文本块具体块数取决于你的文档长度和切块参数。
6.5 语义检索测试
入库后,我们可以写一个检索脚本验证效果:
# 文件路径:search.py import chromadb from chromadb.utils.embedding_functions import SentenceTransformerEmbeddingFunction client = chromadb.PersistentClient(path="./vector_store") embedding_fn = SentenceTransformerEmbeddingFunction( model_name="BAAI/bge-small-zh-v1.5" ) collection = client.get_or_create_collection( name="it_kb", embedding_function=embedding_fn ) query = "电脑蓝屏怎么解决" results = collection.query( query_texts=[query], n_results=3 ) for i, doc in enumerate(results["documents"][0]): metadata = results["metadatas"][0][i] print(f"\n第 {i + 1} 条结果,来源:{metadata['source']}") print(doc)运行后会输出与问题最相似的三个文本块。如果你输入的文档中包含“蓝屏”“系统崩溃”等内容,即使问题里没有出现这些精确字样,向量检索也能把它们召回。
这种能力本质上来自 Embedding 模型的语义理解,而不是向量数据库本身。但向量数据库保证了高维空间中的检索效率。
6.6 对接大模型:一个最小RAG问答实现
有了检索结果,再接入大模型,就构成了一个最小 RAG 问答链路。
下面以 OpenAI 兼容接口为例,你可以把base_url和api_key替换成自己使用的模型服务:
# 文件路径:rag_answer.py import chromadb from chromadb.utils.embedding_functions import SentenceTransformerEmbeddingFunction from openai import OpenAI # 1. 检索 client = chromadb.PersistentClient(path="./vector_store") embedding_fn = SentenceTransformerEmbeddingFunction( model_name="BAAI/bge-small-zh-v1.5" ) collection = client.get_or_create_collection( name="it_kb", embedding_function=embedding_fn ) query = "电脑蓝屏怎么解决" results = collection.query(query_texts=[query], n_results=3) context = "\n\n".join(results["documents"][0]) # 2. 构造提示词 prompt = f"""你是一个企业知识库助手。请基于下面的资料回答用户问题。 如果资料中没有答案,请直接说“知识库中未找到相关信息”,不要编造。 资料: {context} 问题:{query} """ # 3. 调用大模型 llm = OpenAI( api_key="sk-your-api-key", base_url="https://your-model-endpoint" ) resp = llm.chat.completions.create( model="your-model-name", messages=[ {"role": "system", "content": "回答要准确、简洁,并尽量给出依据。"}, {"role": "user", "content": prompt} ], temperature=0.2 ) print(resp.choices[0].message.content)运行说明:你需要先在环境变量或代码中配置可用的模型服务。如果你使用的是 OpenAI 官方服务,需要自行确认网络与账户权限;如果使用国内大模型平台,通常也提供 OpenAI 兼容接口,把base_url和model换成对应值即可。
到这里,一个“文档切片 → 向量化 → 相似度检索 → 上下文增强 → 大模型回答”的最小 RAG 系统就完成了。
7. 常见问题与排查思路
7.1 高频问题清单
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 检索结果不相关 | 切块太大,块内包含多主题 | 缩小 chunk_size,或按章节、段落切块 |
| 中文效果差 | 使用了英文预训练模型 | 换成 bge-small-zh、bge-m3 等中文模型 |
| 模型下载失败 | 网络环境无法访问模型仓库 | 提前下载模型权重到本地,或使用模型推理服务 |
| 查询速度慢 | 数据量大,且未优化索引参数 | 调整 HNSW 参数,增加元数据过滤条件 |
| 更新文档后仍检索到旧内容 | 旧向量未删除,upsert id 不固定 | 使用稳定且唯一的文档块 id,并清理旧节点 |
| 返回结果中同一篇文档占据多个名额 | 相邻文本块重复度高 | 按 source 对结果做去重,或降低 overlap |
| 接入大模型后回答仍然不对 | 检索本身不准确,prompt 设计不够清晰 | 先单独检查检索结果,再分析 prompt 问题 |
7.2 排查思路
遇到“回答不对”的问题,不要先怀疑大模型,先按下面顺序排查:
- 打印检索结果,看返回的上下文是否相关。
- 如果检索结果不相关,检查切块策略和 Embedding 模型。
- 如果检索结果相关但回答错误,检查 Prompt 是否明确要求“仅基于资料回答”。
- 如果回答中包含大量无关信息,考虑增加 Rerank 环节或减少 Top-K。
- 如果是性能问题,检查是否有慢查询、索引是否生效、数据分布是否倾斜。
关键理念是:RAG 系统是“检索 + 生成”的流水线,上游的检索质量决定了下游回答质量的上限。因此不建议跳过检索效果直接调 Prompt。
8. 最佳实践与工程建议
8.1 切块策略:最容易被忽视的一环
切块是 RAG 项目中最容易踩坑的地方。经验上可以遵循几个原则:
- 优先按文档结构切块。Markdown 的二级标题、HTML 的段落标签,都是天然的边界。
- 固定大小切块时,保留 10% 到 20% 的重叠,降低切断语义的风险。
- 块大小需要考虑 Embedding 模型的输入上限。BGE 系列通常可以接受较长的文本,但超长输入会稀释语义。
- 对 FAQ 型文档,最好以“一问一答”为单位切块,不要把多个问题混在一个块里。
- 对超长表格或代码块,需要单独处理,不要与正文混在一起。
切块参数没有标准答案,需要结合自己的数据做小规模实验。可以在一个测试集上对比不同参数下的召回准确率。
8.2 元数据过滤与混合检索
向量检索返回结果时,不要只返回相似内容,还可以充分利用元数据过滤。例如:
- 按部门过滤:只检索“运维部”的文档。
- 按时间过滤:只检索最近 30 天更新的内容。
- 按文档类型过滤:区分操作手册、产品 FAQ、会议纪要。
在生产环境中,建议同时维护关键词索引和向量索引。先用关键词精确筛选,再用向量语义召回,最后用 Rerank 模型统一排序。这样能兼顾“精确”与“模糊”。
8.3 更新、删除与数据一致性
知识库不是一次写完就结束的,文档会持续更新。要做好:
- 文档切块后为每个块生成稳定的 id,最好包含文档级版本号。
- 全量更新时,先删除旧文档所有分块,再写入新分块。
- 增量更新时,只对变更文档重新切块和向量化。
- 如果有多个服务同时对同一集合写入,需要注意向量数据库的并发一致性能力。
如果使用 Chroma 这类嵌入式数据库,建议由单一写入方负责索引更新,避免并发写冲突。
8.4 性能与成本
向量检索的性能受多个因素影响:
- 索引类型:HNSW 在查询速度和构建成本之间比较均衡。
- 向量的维度:维度越高,占用的内存和计算越多。
- 数据量:尽量为低频查询数据添加过滤条件,减少候选集。
- 查询并发:服务端向量数据库通常比嵌入式库更适合高并发。
成本控制方面,Embedding 模型的向量化过程通常比大模型推理便宜,但当文档量非常大时,也需要关注存储成本和离线批处理耗时。
8.5 安全与合规
企业知识库往往包含敏感信息。接入 RAG 系统时要注意:
- 数据脱敏:文档入库前先去除身份证号、手机号、密钥等敏感信息。
- 权限控制:向量检索接口需要做鉴权,不能让用户检索超越权限的文档。
- 日志审计:记录用户查询和系统返回结果,便于事后追溯。
- 合规审查:确认数据存储在合规区域,不将敏感数据发送到未批准的模型服务。
这里有一条基本原则:不要把所有数据无条件塞进一个向量库,再通过一个普通接口暴露出来。知识库的权限边界必须在检索层就做好控制,不能完全信任 Prompt。
9. 总结与学习路线
9.1 本文核心要点
回顾全文,我们需要掌握以下几个关键点:
- 向量数据库解决的是“语义相似度检索”问题,是 AI 知识库的存储底座。
- Embedding 是连接自然语言与向量空间的桥梁,模型选择会影响检索效果。
- 语义搜索让检索从“字面匹配”升级为“意图匹配”,但不能完全替代关键词检索。
- RAG 通过“先检索、再生成”的方式,为大模型提供外部知识,减少幻觉。
- 一个最小可用的 AI 知识库,可以拆成文档切块、向量化、入库、检索、生成这五个环节。
- 实际项目中,切块策略、元数据过滤、混合检索、权限控制往往比换更强的模型更优先。
9.2 后续学习方向
如果你希望继续深入,可以按下面几个方向展开:
- 使用 Milvus 等分布式向量数据库,把知识库从本地单机扩展到生产环境。
- 引入 Rerank 模型,优化召回结果排序。
- 研究 GraphRAG,让知识库具备多跳关系推理能力。
- 尝试 Agentic RAG,让大模型根据问题自主决定检索策略。
- 了解多模态 Embedding,把图片、音频也纳入知识库检索范围。
向量数据库和 RAG 的技术迭代很快,但核心原理相对稳定。你先跑通本文的最小系统,再逐步替换组件、调优参数,就能形成一个适合自己业务的 AI 知识库。如果觉得这篇教程对你有帮助,欢迎收藏备用,后续遇到相关项目可以随时回来对照。