RAG 与向量数据库实战:在 generative-ai-for-beginners 中用自有数据为 LLM 应用注入知识基础

发布时间:2026/9/5 21:27:13
RAG 与向量数据库实战:在 generative-ai-for-beginners 中用自有数据为 LLM 应用注入知识基础 RAG 与向量数据库实战在 generative-ai-for-beginners 中用自有数据为 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与向量数据库》的阿拉伯语版本文档展开系统讲解 RAG 的工作机制与向量数据库的构建方法并结合仓库中配套的可运行 Notebooknotebook-rag-vector-databases.ipynb与示例数据data/perceptron.md、data/frameworks.md带你完整走一遍文档切块 → 向量化 → 相似度检索 → LLM 接地生成的 RAG 全流程。课程定位与学习目标在搜索应用一课中课程简要介绍了如何把自有数据接入大型语言模型LLM。本课则深入剖析把数据接地grounding到 LLM 应用的完整过程流程背后的机制、数据的存储方式包括嵌入向量与文本两种形态。完成本课后你将能够解释 RAG 在数据检索与处理中的意义搭建 RAG 应用并把你的数据接地到 LLM在 LLM 应用中有效集成 RAG 与向量数据库。本课场景用自有数据增强教育初创公司的 LLM课程设定了一个教育初创公司场景把公司内部的学习笔记接入聊天机器人让学习者能更好地研习不同主题、更高效地复习备考。具体技术选型如下Azure OpenAI用于构建聊天机器人的 LLM面向初学者的 AI 课程中神经网络这一课作为接地 LLM 的知识数据Azure AI Search 与 Azure Cosmos DB作为向量数据库用于存储数据并建立搜索索引。基于这些数据用户可以完成三件事从笔记中生成练习测验practice quizzes、生成复习卡片flash cards、把笔记总结为简洁的概览。在阿拉伯语版课程目录中仓库为 Notebook 准备了阿拉伯语语料translations/ar/15-rag-and-vector-databases/data/perceptron.md 等与英文版使用的神经网络主题文档一一对应。RAG检索增强生成的工作原理由 LLM 驱动的聊天机器人处理用户提示并生成回复它被设计得可以就广泛话题与用户交互。但其回复受限于所给上下文与基础训练数据例如 GPT-4 的知识截止时间为 2021 年 9 月不了解此后的事件同时 LLM 的训练数据天然不包含机密信息个人笔记、公司产品手册等。假设你要部署一个从笔记生成测验的聊天机器人就需要连接知识库——这正是 RAG 的用武之地。RAG 按以下四个环节运转知识库Knowledge base检索之前文档需要先被摄取和预处理——通常是把大文档切分为更小的块chunks、转换为文本嵌入embeddings、再存入数据库用户查询User Query用户提出问题检索Retrieval嵌入模型从知识库中检索相关信息为提示词提供更多上下文增强生成Augmented GenerationLLM 基于检索到的数据增强其回复使输出不仅依赖预训练数据还融合注入的上下文信息最终把答案返回给用户。从架构上看RAG 由**编码器encoder和解码器decoder**两部分构成。当用户提问时输入文本先被编码为捕捉词义关系的向量再解码映射到文档索引上并基于用户查询生成新文本LLM 使用编码器-解码器模型产生最终输出。原始论文《Retrieval-Augmented Generation for Knowledge intensive NLP Tasks》提出两种实现方式RAG-Sequence利用检索到的文档直接预测对用户查询的最佳答案RAG-Token利用文档逐个生成下一个 token边生成边检索以回答用户查询。为什么要用 RAG信息丰富度确保文本回复保持最新、与时俱进通过访问内部知识库增强领域特定任务的表现减少虚构hallucination利用知识库中可验证的数据为用户查询提供上下文成本效益相比微调fine-tuning一个 LLMRAG 在经济上更划算。构建知识库向量数据库本应用基于个人数据即本课程神经网络一课的内容。什么是向量数据库向量数据库不同于传统数据库它是专门设计用于存储、管理和检索嵌入向量的数据库保存的是文档的数值化表示。把数据拆解成数值嵌入让 AI 系统更容易理解和处理。把嵌入存入向量数据库的原因在于LLM 能接受的输入 token 数量有上限无法把全部嵌入一次性传入。因此需要把数据切块chunking——当用户提问时把与问题最相似的嵌入随提示词一起返回。切块同时降低了经 LLM 传输的 token 数量带来的成本。常见的向量数据库包括Azure Cosmos DB、Clarifyai、Pinecone、ChromaDB、ScaNN、Qdrant、DeepLake。使用 Azure CLI 创建 Azure Cosmos DB 资源的命令如下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-group-name仓库配套 Notebook 中演示了如何用azure-cosmosSDK 连接该数据库数据库名rag-cosmos-db、容器名data连接凭据从环境变量COSMOS_DB_ENDPOINT与COSMOS_DB_KEY读取from azure.cosmos import CosmosClient url os.getenv(COSMOS_DB_ENDPOINT) key os.getenv(COSMOS_DB_KEY) client CosmosClient(url, credentialkey) database client.get_database_client(rag-cosmos-db) container database.get_container_client(data)从文本到嵌入在存入数据库之前需要先把数据转换为向量嵌入。如果处理的是大文档或长文本可以按预期的查询方式来切块——切块可以发生在句子级或段落级。由于块的含义来自其周围的词你还可以为块补充额外上下文例如加上文档标题或包含块前后的一些文本。课程给出的切块函数实现如下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)调用——即每个块保持在约 300400 字符的区间内随后用DataFrame.explode(chunks)把每文件一行、块存为列表的宽表展开为每块一行的扁平平铺表flattened_df方便逐块嵌入。切块完成后可以使用不同嵌入模型把文本向量化例如word2vec、OpenAI 的 ada-002、Azure Computer Vision 等。模型选择取决于所用的语言、编码的内容类型文本/图像/音频、可编码的输入大小、以及嵌入输出的维度长度。使用 OpenAItext-embedding-ada-002模型对单词 cat 嵌入的效果示意如下检索与向量搜索当用户提问时检索器retriever先用查询编码器query encoder把问题转换为向量然后在文档搜索索引中查找与输入相关的向量完成后把输入向量与文档向量都还原为文本连同上下文一起交给 LLM。检索Retrieval检索就是系统从索引中快速找出满足搜索条件的文档的过程。检索器的目标是拿到能接地 LLM、为你的数据提供上下文的文档。数据库中常用的搜索方式有三种关键词搜索Keyword search用于纯文本匹配向量搜索Vector search用嵌入模型把文档从文本转为向量表示从而支持基于词义匹配的语义搜索semantic search——检索时查询与用户问题向量表示最接近的文档混合搜索Hybrid关键词搜索与向量搜索的组合。检索的一个难题是当数据库中没有与查询相似的内容时系统只能返回它能拿到的最像的信息。应对手段包括设定相关性的最大距离阈值或使用混合搜索。本课采用的就是混合搜索策略数据会存进一个 DataFrame其中各列分别保存文本块chunks与对应的嵌入向量embeddings。向量相似度检索器会在知识库中寻找彼此靠近、互为最近邻closest neighbour的嵌入——因为它们对应相似的文本。场景流程是用户查询先被嵌入再与相似的嵌入进行匹配。衡量向量之间相似度的常用度量是余弦相似度cosine similarity它基于两个向量之间的夹角。其他可选度量还有欧氏距离两个向量端点之间的直线距离与点积两个向量对应元素乘积之和。搜索索引Search index执行检索前需要为知识库建立搜索索引。索引保存全部嵌入即使数据库很大也能快速取出最相似的块。课程使用 scikit-learn 在本地创建索引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 进一步把indices与distances存回 DataFrame 的对应列供后续展示与调试。重排序Re-ranking查询数据库后可能需要按相关度从高到低对结果排序。重排序模型利用机器学习技术提升搜索结果的相关性。在 Azure AI Search 中重排序由语义重排序器semantic reranker自动完成。用最近邻实现重排序的示例如下# 查找最相似的文档 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)集成 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) } ] # 调用生成接口获得回复 response client.responses.create( modelgpt-4o-mini, temperature0.7, max_output_tokens800, inputmessages, storeFalse, ) return response.output_text chatbot(user_input)这里可以看到完整的 RAG 调用链create_embeddings把用户问题向量化 →nbrs.kneighbors从索引取出最相似的块 → 块文本拼接成带上下文的user消息 → 由 LLM 生成接地后的回答。仓库英文版 Notebook 中的客户端配置展示了 Azure OpenAI 的连接方式以{endpoint}/openai/v1/作为base_url初始化 OpenAI 客户端嵌入与聊天模型的部署名分别从环境变量AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT、AZURE_OPENAI_DEPLOYMENT读取。阿拉伯语版 Notebooktranslations/ar/15-rag-and-vector-databases/notebook-rag-vector-databases.ipynb则以text-embedding-ada-002-2作为嵌入模型、gpt-35-turbo-1106作为聊天模型完成同样的流程阅读两个版本可以直观对比 OpenAI SDK 接口从旧版openai.embeddings.create到新版client.embeddings.create的演进。评估应用RAG 应用怎么算好课程给出了四项评估指标回复质量确保回答听起来自然、流畅、拟人数据接地性Groundedness评估回答是否确实来源于所提供的文档相关性Relevance评估回答是否与所提问题匹配、相关流畅度Fluency回答在语法上是否通顺。配套 Notebook 还演示了用Mean Average PrecisionMAP做检索相关性的量化评估为什么是感知机等 4 个测试问题分别准备相关/不相关的回答集合用sklearn.metrics.average_precision_score对每个查询计算平均精度再取平均得到 MAP 分数。RAG 与向量数据库的典型用例问答系统QA把公司数据接地到聊天机器人供员工提问推荐系统构建匹配最相似值的系统如电影、餐厅推荐等聊天机器人服务存储对话历史基于用户数据个性化对话基于向量嵌入的图像搜索在图像识别与异常检测场景中十分有用。小结与练习本部分覆盖了 RAG 的基本领域从把数据加入应用、用户查询到最终输出。要简化 RAG 的搭建可以使用 Semantic Kernel、LangChain、AutoGen 等框架。练习来自原文档 Assignment 一节使用你偏好的框架为应用构建前端界面使用 LangChain 或 Semantic Kernel 框架重建你的 RAG 应用。可继续深入的资料课程英文版 15-rag-and-vector-databases/README.md、可交互 Notebook 15-rag-and-vector-databases/notebook-rag-vector-databases.ipynb以及三份神经网络主题示例文档 data/perceptron.md、data/frameworks.md、data/own_framework.md——它们既是本课程的 RAG 语料也是理解切块粒度如何影响检索质量的一手素材。【免费下载链接】generative-ai-for-beginners21 Lessons, Get Started Building with Generative AI项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai-for-beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考