generative-ai-for-beginners 第15课精解RAG 与向量数据库——把私有数据“锚定”进 LLM 的完整实战【免费下载链接】generative-ai-for-beginners21 Lessons, Get Started Building with Generative AI项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai-for-beginners本文基于 generative-ai-for-beginners 课程的第 15 课RAG and Vector Databases展开先讲清检索增强生成RAG为什么能把你的私有数据“接地”到大型语言模型LLM中再按照课程配套 Notebook notebook-rag-vector-databases.ipynb 的完整代码链路从文本分块、向量化、构建检索索引、相似度检索到最终生成答案与评估完整复现一个可运行的 RAG 应用。读完本文你可以独立搭建一个基于向量数据库的检索增强问答系统并理解分块策略、相似度度量与重排序对回答质量的影响。课程定位与学习目标在课程第 8 课《构建搜索应用》中见 08-building-search-applications/README.md我们初步了解了如何把自己的数据接入 LLM。第 15 课则深入三件事RAG 的入门它是什么、为什么在 AI 应用中被广泛使用理解向量数据库Vector Database的本质并为自己的应用创建一个一个把 RAG 集成进应用的实际示例课程用 Python 实现了完整链路运行环境为 Python 3.10依赖openai、azure-cosmos、pandas、scikit-learn等均可在配套 Notebook 中看到安装与调用方式。学完本课你将能够解释 RAG 在数据检索与处理中的意义搭建一个 RAG 应用把自己的数据“锚定”ground到 LLM 上在 LLM 应用中有效地集成 RAG 与向量数据库。课程场景用“我自己的笔记”增强 LLM本课的演示场景来自课程整体的“教育创业公司”背景向应用中加入学习者自己的笔记让聊天机器人对各门学科掌握更多信息从而帮助学习者更好地复习备考例如根据笔记生成练习测验、复习卡片和简明摘要。为实现该场景课程选用如下技术栈组件作用Azure OpenAI作为 LLM 驱动聊天机器人Notebook 中通过 OpenAI SDK 的 v1 兼容端点访问《AI for beginners》的神经网络课程材料作为“私有数据”来源即要被锚定的知识仓库内实际提供了三篇 Markdown 文档Azure AI Search与Azure Cosmos DB作为向量数据库存储数据并创建搜索索引仓库中真实存在的数据文件即为课程的知识库样例位于15-rag-and-vector-databases/data/目录下data/perceptron.md——感知机Perceptron入门包含模型定义、感知机判据与训练算法data/own_framework.md——多层感知机Multi-Layer Perceptrondata/frameworks.md——神经网络框架NumPy、Keras 等。这三篇文档构成了 Notebook 中 RAG 应用的完整输入语料所有分块、嵌入、索引与检索都发生在这些真实文件之上。RAG检索增强生成的工作原理为什么需要 RAG由 LLM 驱动的聊天机器人会处理用户提示并生成回答它被设计为交互式地覆盖广泛话题。但其回答受限于两点上下文与训练数据的边界例如 GPT-4 的知识截止日期是 2021 年 9 月此后的事件它一无所知训练数据不含私有信息用于训练 LLM 的数据排除了个人笔记、公司产品手册这类机密内容。如果你的目标是部署一个“能从我的笔记生成测验”的聊天机器人就必须有一条通路连接知识库——这正是 RAG 的价值所在。四个阶段知识库、查询、检索、增强生成RAG 按如下流程运作知识库Knowledge base检索发生之前文档需要先被摄取ingest和预处理——通常把大文档拆分成小块chunk、把每个块转成文本嵌入embedding、再存入数据库用户查询User Query用户提出一个问题的过程检索Retrieval用户提问时嵌入模型从知识库中取出与问题相关的信息为提示词补充上下文增强生成Augmented GenerationLLM 基于检索到的数据增强其回答——生成的内容不只依赖预训练知识还利用了附加上下文中的相关信息最后把答案返回给用户。从源码即 Notebook 的执行流可以看到这四步的对应关系文档加载与分块split_text→ 逐块调用嵌入接口create_embeddings→ 用NearestNeighbors建索引并对查询向量做kneighbors检索 → 把检索出的 chunk 拼进messages调用 LLM。编码器-解码器架构与两种 RAG 范式RAG 的架构基于 Transformer 实现由编码器和解码器两部分组成当用户提问时输入文本被“编码”为捕捉词语含义的向量这些向量再对照文档索引被“解码”基于用户查询生成新文本。LLM 借助编码器-解码器模型完成输出生成。按照原始论文提出的两种实现范式RAG-Sequence利用检索到的文档一次性预测对用户查询最可能的完整回答RAG-Token利用文档逐个生成下一个 token边生成边检索以逐步回答用户查询。为什么选择 RAG信息丰富度保证文本回答是最新、当下的通过访问内部知识库提升在特定领域任务上的表现减少胡编乱造利用知识库中可验证的数据为用户查询提供上下文降低幻觉成本效益相比对 LLM 做微调fine-tuningRAG 更经济——你只需要维护知识库而无需重新训练模型。创建知识库一向量数据库什么是向量数据库向量数据库不同于传统数据库它是专门设计用来存储、管理和检索嵌入向量的数据库保存的是文档的数值化表示。把数据拆解成数值嵌入使 AI 系统更容易理解和处理这些数据。为什么必须存在向量数据库这一层因为 LLM 对可接收的输入 token 数有上限。你无法把整个知识库塞给 LLM所以需要把数据拆成块chunk当用户提问时只把与问题最相似的若干块随提示词一起返回。分块同时也降低了每次调用传给 LLM 的 token 数量与成本。课程列举的流行向量数据库包括Azure Cosmos DB、Clarifyai、Pinecone、ChromaDB、ScaNN、Qdrant 和 DeepLake。课程以 Azure Cosmos DB 为例给出用 Azure CLI 创建实例的命令az login az group create -n resource-group-name -l location az cosmosdb create -n cosmos-db-name -r resource-group-name az cosmosdb list-keys -n cosmos-db-name -g resource-group-name在配套 Notebook 中客户端初始化代码如下凭据通过环境变量注入避免把密钥写进代码from azure.cosmos import CosmosClient # Initialize Cosmos Client url os.getenv(COSMOS_DB_ENDPOINT) key os.getenv(COSMOS_DB_KEY) client CosmosClient(url, credentialkey) # Select database database_name rag-cosmos-db database client.get_database_client(database_name) # Select container container_name data container database.get_container_client(container_name)值得说明的是Notebook 的本地演示为了降低门槛先用 pandas DataFrame 充当“本地向量库”列包含path、text、chunks、embeddings、indices、distances把 Cosmos DB 作为生产环境的替代方案呈现。这一“先本地后上云”的编排方式在从源码结构看也是课程刻意保留的——检索与生成的代码逻辑在两种存储后端之间完全一致只替换存取层即可迁移。从文本到嵌入分块策略数据入库前必须先转成向量嵌入。如果你处理的是大文档或长文本需要按预期查询方式做分块。分块可以在句子级或段落级进行由于块的意义依赖于其周边词可以给块补充额外上下文例如附上文档标题或包含该块前后的部分文字。课程给出的分块函数如下max_length/min_length控制每块的字符数区间def split_text(text, max_length, min_length): words text.split() chunks [] current_chunk [] for word in words: current_chunk.append(word) if len( .join(current_chunk)) max_length and len( .join(current_chunk)) min_length: chunks.append( .join(current_chunk)) current_chunk [] # 若最后一个块未达到最小长度仍将其加入 if current_chunk: chunks.append( .join(current_chunk)) return chunks在 Notebook 中该函数以split_text(x, 400, 300)的取值作用于三篇数据文档——即每个块大致落在 300~400 字符之间随后用df.explode(chunks)把“每行一个 chunk 列表”展平成“一行一个 chunk”的扁平表flattened_df为逐块计算嵌入做准备。分块完成后用嵌入模型把文本向量化。可选模型包括word2vec、OpenAI 的 ada-002text-embedding-ada-002、Azure Computer Vision 等。模型选择取决于所用语言、编码的内容类型文本/图像/音频、可编码的输入规模、以及输出嵌入的长度。使用 OpenAItext-embedding-ada-002模型对单词“cat”做嵌入的效果示意如下Notebook 中嵌入的实际调用封装在create_embeddings中def create_embeddings(text, modelNone): # 使用你的嵌入部署为每个文档块创建嵌入 model model or embeddings_deployment embeddings client.embeddings.create(inputtext, modelmodel).data[0].embedding return embeddings其中客户端按 v1 兼容端点配置适用于 Azure OpenAI / Foundry 资源from openai import OpenAI endpoint os.getenv(AZURE_OPENAI_ENDPOINT) client OpenAI( api_keyos.getenv(AZURE_OPENAI_API_KEY), base_urlf{endpoint.rstrip(/)}/openai/v1/, ) embeddings_deployment os.getenv(AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT) chat_deployment os.getenv(AZURE_OPENAI_DEPLOYMENT)从源码结构看AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT与AZURE_OPENAI_DEPLOYMENT两个部署名被显式分离说明课程鼓励嵌入模型与对话模型独立部署与替换——更换嵌入模型时只需改一个环境变量。检索与向量搜索当用户提问时检索器用查询编码器把问题转成向量然后在文档搜索索引中查找与输入相关的向量完成后再把查询向量对应的内容与文档向量对应的文本都还原为文本一并交给 LLM。三种检索方式关键词检索Keyword search面向文本精确匹配向量检索Vector search用嵌入模型把文档从文本转换为向量表示支持基于词义的语义搜索检索时查询“向量表示与用户问题最接近”的文档混合检索Hybrid关键词检索 向量检索的组合。检索的一个典型难题是当数据库中没有与查询相似的应答时系统只能返回“能拿到的最佳信息”。对策包括设置相关性最大距离阈值或使用混合检索。本课的 Notebook 演示采用向量检索路径sklearn 近邻索引并在概念上推荐混合检索数据同时以包含 chunk 文本与嵌入向量的 DataFrame 列存储为两种检索方式都留好了字段。向量相似度度量检索器在知识库中寻找彼此靠近最邻近的嵌入因为它们对应相似文本。用户查询先被嵌入再与相似嵌入匹配。衡量向量间相似度的常用方法余弦相似度Cosine similarity基于两个向量之间的夹角最常用欧氏距离Euclidean distance两个向量端点之间的直线距离点积Dot product两个向量对应元素乘积之和。本地搜索索引在检索前需要为知识库构建搜索索引索引保存所有嵌入即便库很大也能快速取出最相似的块。课程用 scikit-learn 的NearestNeighbors在本地实现from sklearn.neighbors import NearestNeighbors embeddings flattened_df[embeddings].to_list() # 创建搜索索引 nbrs NearestNeighbors(n_neighbors5, algorithmball_tree).fit(embeddings) # 查询索引可使用 kneighbors 方法 distances, indices nbrs.kneighbors(embeddings)参数说明n_neighbors5表示每个查询返回 5 个最近邻algorithmball_tree选用球树加速近邻搜索适合中小规模、欧氏距离语义下的数据集。在 Notebook 中检索结果会被写回 DataFrame 的indices与distances两列使每条记录都能看到自己的 5 个最近邻及其距离实际运行输出中首个非零距离约在 0.45~0.57 区间即“次近邻”与“自身”之间的差距。重排序Re-ranking查询数据库之后你可能需要按相关性对结果重新排序。重排序模型利用机器学习把结果从“最相关”到“次相关”排列使用 Azure AI Search 时重排序由语义重排序器自动完成。用最近邻实现重排序效果的示例# 找到最相似的文档 distances, indices nbrs.kneighbors([query_vector]) index [] # 打印最相似的文档 for i in range(3): index indices[0][i] for index in indices[0]: print(flattened_df[chunks].iloc[index]) print(flattened_df[path].iloc[index]) print(flattened_df[distances].iloc[index]) else: print(fIndex {index} not found in DataFrame)这段代码与 Notebook 中的查询演示单元格逐行对应对问题 “what is a perceptron?” 检索后打印出的前三条命中全部来自data/perceptron.md与data/own_framework.md且按距离升序排列0.0、约 0.45、约 0.52……直观展示了“距离越近、语义越相关”的排序结果。汇总把 LLM 接进来得到“锚定”的答案最后一步是引入 LLM使回答基于私有数据生成。课程给出的完整实现user_input what is a perceptron? def chatbot(user_input): # 把问题转换为查询向量 query_vector create_embeddings(user_input) # 找到最相似的文档 distances, indices nbrs.kneighbors([query_vector]) # 把检索到的文档加入查询以提供上下文 history [] for index in indices[0]: history.append(flattened_df[chunks].iloc[index]) # 组合检索到的上下文与用户输入 history.append(user_input) # 构造消息对象 messages[ {role: system, content: You are an AI assistant that helps with AI questions.}, {role: user, content: \n\n.join(history) } ] # 调用 LLM 生成回答 response client.responses.create( modelgpt-4o-mini, temperature0.7, max_output_tokens800, inputmessages, storeFalse, ) return response.output_text chatbot(user_input)两个值得注意的实现细节上下文拼接方式history先放入 5 个检索块再追加用户问题最后用\n\n.join(history)拼成一个 user 消息——即“检索证据在前、问题在后”让模型先看到依据再回答问题生成参数temperature0.7保留一定多样性max_output_tokens800限制输出长度控制成本。Notebook 中该步骤的实际运行输出是一段准确的回答“A perceptron is a type of artificial neural network model…… It is a simple algorithm used for binary classification tasks……”——与 data/perceptron.md 中“感知机是二分类模型”的定义一致验证了回答确实被知识库“锚定”。评估你的 RAG 应用课程列出四个评估维度回答质量回答是否自然、流畅、像人写的数据锚定度Groundedness回答是否基于所提供的文档相关性Relevance回答是否与所提问题匹配、相关流畅度Fluency回答在语法上是否讲得通。在配套 Notebook 中评估还落地为一套可运行的基准用sklearn.metrics.average_precision_score计算多个测试用例的平均精度均值MAP, Mean Average Precision。测试用例覆盖 “What is a perceptron?”、What is machine learning? 等问题每个用例标注了相关应答与不相关应答如 “A perceptron is a type of fruit.” 作为负样本最终对chatbot的生成结果计算相关性得分——Notebook 记录的实际运行结果为0.5。这提醒我们即便架构正确RAG 的答案质量仍需要持续的量化评测。RAG 与向量数据库的典型应用场景RAG 能改善的应用形态包括问答QA把公司数据锚定到聊天机器人供员工提问内部知识推荐系统匹配最相似取值例如电影、餐厅推荐聊天机器人服务存储聊天历史基于用户数据个性化对话基于向量嵌入的图像搜索适用于图像识别与异常检测。小结与练习本课覆盖了 RAG 的核心领域把数据加入应用分块 → 嵌入 → 建索引、处理用户查询向量检索 → 重排序、以及生成输出LLM 锚定回答。若要简化 RAG 的搭建可以使用 Semantic Kernel、LangChain 或 AutoGen 等框架。课程布置的练习延续学习用你选定的框架为这个应用构建前端使用 LangChain 或 Semantic Kernel 框架重新实现本课应用。配合本文的阅读路径建议概念以 15-rag-and-vector-databases/README.md 为准代码以 notebook-rag-vector-databases.ipynb 为准语料直接查看data/目录下的三篇 Markdown。需要自行准备AZURE_OPENAI_ENDPOINT、AZURE_OPENAI_API_KEY、两个部署名以及可选的COSMOS_DB_ENDPOINT/COSMOS_DB_KEY环境变量后再运行 Notebook。【免费下载链接】generative-ai-for-beginners21 Lessons, Get Started Building with Generative AI项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai-for-beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考