LLM
【问题】 大模型的结构化输出指的是什么?
【答案】 大模型的结构化输出是指通过特定的提示工程或约束解码技术,引导大语言模型生成符合预定义格式(如 JSON、XML、CSV、YAML、Markdown 表格等)的文本输出。这种输出具有明确的字段和数据类型,可以被程序直接解析和使用,从而实现从自然语言到机器可读数据的转换。
结构化输出的核心价值在于解决大模型输出不确定性和非结构化的问题,使得模型能够无缝集成到自动化工作流、API 调用、数据库写入等应用场景中。
实现结构化输出的常见方法包括:
- 提示工程:在提示中明确指定输出格式,并提供示例(少样本学习),引导模型遵循格式。
- 约束解码:在生成过程中,通过设定语法规则或上下文无关文法(CFG)限制模型输出的 token 序列,强制生成符合格式的文本。例如,使用 JSON 模式强制生成合法的 JSON。
- 函数调用(Function Calling):许多模型(如 GPT-4、Claude)支持函数调用功能,允许模型以结构化的参数形式输出结果,而不是自然语言。
- 后处理解析与校验:对模型输出进行解析和校验,若不符合格式则重试或修正。
【大白话解释】
大模型的结构化输出,就是让 AI 不只是回答人话,而是输出像填表格、写代码、给数据包那样整齐的格式。比如你问“北京明天的天气怎么样?”,普通回答是“北京明天晴,气温 15-25 度”。结构化输出可能是一个 JSON:{"city":"北京","date":"2024-03-16","weather":"晴","temp_low":15,"temp_high":25}。这样电脑程序可以直接读取,不需要再去理解句子。
【扩展知识点详解】
- 为什么需要结构化输出:企业级应用需要将 LLM 集成到自动化流程中,例如从文档中提取信息填充数据库、调用外部 API 等。结构化输出是衔接 LLM 与传统软件系统的关键。
- 约束解码技术:如 Guidance、LMQL、Outlines 等库允许在生成过程中施加格式约束,确保输出符合 JSON Schema 等。
- 函数调用(Function Calling):OpenAI 等模型提供的函数调用能力,本质上是让模型选择函数并填充参数,返回结构化参数对象,而不是文本。
- JSON 模式:OpenAI 支持在 API 中指定
response_format={ "type": "json_object" },强制模型输出合法 JSON。 - 少样本示例的重要性:即使有格式约束,提供示例也能显著提高模型的遵从性和准确性。
- 错误处理:结构化输出可能因格式错误而失败,需设计重试机制或降级策略(如转回自然语言解析)。
- 权衡:结构化输出可能牺牲一定灵活性,且对复杂嵌套格式的生成质量可能下降。
【问题】 在大模型应用中,通常如何实现长短期记忆机制?
【答案】 大模型本身是无状态的,每次对话都是独立的,无法自动记住历史信息。在应用中,为了实现记忆能力,通常通过外部存储和结构化处理来模拟长短期记忆。实现策略根据记忆的时间跨度和粒度分为短期记忆和长期记忆两部分。
一、短期记忆的实现 短期记忆对应于当前对话或会话过程中的上下文信息,通常存储在一个有限的、易失的缓存中。
- 对话历史缓存:将用户和助手的历史消息直接拼接在提示(Prompt)中,作为上下文输入给模型。这是最直接的短期记忆实现。由于模型有上下文窗口限制,需要管理历史长度,例如:
- 滑动窗口:只保留最近的 N 轮对话。
- 截断:当历史超出最大长度时,丢弃最早的消息。
- 会话状态存储:在应用服务器端,使用内存缓存(如 Redis、内存 Map)存储当前会话的状态变量,如用户偏好、临时选择等。每次请求时,从缓存中加载状态,并在处理后更新。
- 摘要记忆:当对话过长时,可以使用模型对历史进行总结,将摘要作为上下文,代替完整历史。这既压缩了信息,又保留了要点。
二、长期记忆的实现 长期记忆对应于跨会话的、需要持久化的用户信息或知识,通常存储在外部数据库中,并在需要时检索相关片段注入提示。
- 向量数据库存储:
- 存储:将用户信息、历史对话的关键片段或知识点通过嵌入模型转换为向量,存入向量数据库(如 Pinecone、Chroma、FAISS)。
- 检索:当新对话开始时,将当前查询嵌入,从向量库中检索最相关的 K 条记忆片段,作为上下文补充到提示中。
- 键值存储:对于结构化信息(如用户姓名、偏好设置),可以使用传统数据库(如 PostgreSQL、Redis)存储,并在需要时通过 API 查询并注入。
- 记忆分层架构:结合短期和长期记忆,形成分层缓存。例如,LangChain 的
Zep或Mem0等专用记忆服务,自动管理记忆的存储、检索和过期。
三、记忆的整合与更新
- 整合:在每次请求时,应用层将短期记忆(当前对话历史)和从长期记忆中检索到的相关片段合并,组成完整的提示。
- 更新:对话结束后,提取有价值的信息(如新的事实、用户确认的偏好)更新到长期存储中。可以定期对历史进行摘要,压缩后存储。
四、常见实现框架
- LangChain Memory:提供多种记忆类型,如
ConversationBufferMemory(缓存历史)、ConversationSummaryMemory(摘要历史)、VectorStoreRetrieverMemory(基于向量检索的记忆)。 - LlamaIndex Memory:通过
ChatMemoryBuffer管理对话历史,并支持将记忆持久化到向量索引。 - Mem0:专门的开源记忆层,为 AI 应用提供长期、个性化记忆管理,支持多会话和跨应用记忆共享。
- Zep:提供云服务或自托管,自动存储、总结、检索对话记忆,并支持事实提取和实体记忆。
【大白话解释】 大模型的短期记忆就像你手里的便签纸,临时记下刚才聊了什么,但便签纸很小,只能记最近几件事。如果聊太多,就撕掉最早的,腾出地方记新的。
长期记忆就像你的个人档案室。每次聊完天,你会把重要信息(比如对方的生日、喜好)整理成小卡片,放到档案室。下次再聊天,你会先去档案室翻出相关的卡片,放在手边参考。
整个系统就是档案管理员+便签纸的组合:每次对话前,先去档案室(向量数据库)找出相关的历史卡片,然后和当前便签纸上的内容(对话历史)一起,交给大模型,让它结合记忆来回答。
【扩展知识点详解】
- 记忆类型:
- 缓冲区记忆:直接存储原始对话文本,适用于短期。
- 摘要记忆:用模型生成对话摘要,节省 token。
- 实体记忆:提取特定实体(如人名、地点)及其属性,存储在键值对中。
- 向量检索记忆:将记忆片段嵌入向量,通过相似度检索获取相关片段。
- 实现挑战:
- 检索质量:向量检索可能召回不相关记忆,需要优化嵌入模型和分块策略。
- 存储成本:长期记忆积累会占用大量存储,需设计过期策略或压缩机制。
- 隐私与安全:记忆可能包含敏感信息,需加密存储,并提供用户删除权利。
- 延迟:每次检索增加请求时间,需优化数据库和缓存。
- 高级技术:
- MemGPT:一种扩展大模型上下文窗口的架构,通过虚拟内存管理,将长期记忆分页加载,模拟无限上下文。
- 记忆的反思与更新:让模型定期反思记忆的准确性,合并重复信息,删除过时内容。
- 多模态记忆:不仅存储文本,还可存储图像、音频等,通过多模态检索增强。
-
与 RAG 的关系:长期记忆本质上是一种个性化 RAG,其中知识库来自用户自身的历史交互。实现方式与 RAG 高度重叠,可共用向量库和检索技术。
- 评估指标:
- 记忆准确率:检索到的记忆是否正确且相关。
- 记忆利用率:模型在生成时是否有效利用了记忆。
- 用户满意度:个性化程度提升对用户体验的影响。
RAG
【问题】 什么是 RAG?RAG 的主要流程是什么?
【参考答案】 RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合信息检索与语言生成的人工智能技术,旨在通过引入外部知识库来增强大语言模型(LLM)的生成能力。它解决了传统LLM仅依赖训练数据导致的“知识截止日期”和“幻觉”问题,使模型能够基于实时、专业或私有知识生成更准确、更可信的回答。
主要流程 RAG通常包含两个核心阶段:索引构建(离线) 和查询与生成(在线)。
- 索引构建(离线阶段)
- 文档切分:将外部知识库(如文档、网页、数据库)切分成小的文本块(chunk),便于检索。
- 向量化:使用嵌入模型(如BERT、Sentence-BERT)将每个文本块转换为向量表示,存入向量数据库(如FAISS、Pinecone、Weaviate)。
- 建立索引:在向量数据库中为这些向量建立高效索引,以便快速检索。
- 查询与生成(在线阶段)
- 用户查询:用户输入一个问题或请求。
- 查询向量化:使用相同的嵌入模型将用户查询转换为向量。
- 检索相关文档:在向量数据库中执行相似性搜索(如余弦相似度),找到与查询最相关的K个文本块。
- 增强输入:将检索到的文本块与原始查询组合,形成增强的提示(prompt),通常格式为“根据以下资料:… 请回答:…”。
- 生成回答:将增强后的提示输入给大语言模型(如GPT、LLaMA),模型基于上下文生成最终答案。
- 返回结果:将生成的答案返回给用户。
可选步骤:对检索结果进行重排序、过滤,或对生成的答案进行验证、引用溯源。
【大白话解释】 RAG就像让一个学霸(LLM)在考试时允许翻书(外部知识库)。学霸本身知道很多基础知识(训练数据),但遇到不熟悉的问题,他可以去查参考书,找到相关段落,然后结合自己的理解给出答案。这样,答案既准确又有据可查。
具体流程:
- 先给参考书编个目录(索引构建),把书里的内容切成小块,并贴上标签(向量化)。
- 考试时,看到题目,先根据题目去目录里找最相关的几页(检索)。
- 把这几页的内容贴在卷子上(增强输入),然后学霸根据这些资料和自己的知识写出答案(生成)。
【扩展知识点】
- RAG与微调的区别:
- 微调(Fine-tuning)是让模型学习特定领域的知识,但知识固化在模型参数中,更新成本高。
- RAG不修改模型参数,通过外部知识库动态获取信息,易于更新和扩展,适合知识频繁变化的场景。
- RAG的优势:
- 实时性:可接入最新数据,不受训练数据截止时间限制。
- 可解释性:可追溯答案来源,提升可信度。
- 降低幻觉:通过检索事实减少模型凭空捏造。
- 领域适应:无需重新训练即可快速适配私有知识库。
- 常见工具与框架:
- LangChain:提供完整的RAG组件链,支持多种检索器和LLM。
- LlamaIndex:专注于构建和管理索引,简化RAG开发。
- 向量数据库:FAISS、Chroma、Weaviate、Pinecone、Qdrant等。
- 嵌入模型:OpenAI的text-embedding-ada-002、Cohere的embed、开源的BAAI/bge等。
- RAG的变种与优化:
- Self-RAG:让模型自我反思检索结果,决定是否需要额外检索。
- ReAct:结合推理和行动,交替进行检索和生成。
- HyDE:先生成假设性答案,再用该答案检索相关文档,提高召回率。
- 多跳检索:针对复杂问题,分步检索,逐步细化。
- 挑战与应对:
- 检索质量:检索到的文档可能不相关,需优化分块策略、嵌入模型和相似度算法。
- 上下文长度限制:LLM对输入长度有限制,需压缩或精选检索结果。
- 延迟:检索和生成串行,可能增加响应时间,可通过缓存、并行检索优化。
【问题】 什么是 RAG 中的 Rerank?具体需要怎么做?
【参考答案】 在 RAG(检索增强生成)系统中,Rerank(重排序)是指对检索阶段获取的候选文档列表进行二次排序的过程。其核心目的是通过更精确的模型评估查询与文档的相关性,将最相关的文档排在前面,从而提高大语言模型生成答案的质量和准确性。
一、为什么需要 Rerank? RAG 的典型流程中,首先通过向量检索(如嵌入相似度)快速从海量文档中召回 Top-K 个候选文档。向量检索速度快,但存在以下问题:
- 语义丢失:嵌入模型将文本压缩为固定长度向量,可能丢失细节信息,导致某些相关文档未被召回或排名靠后。
- 相关性误判:单纯依靠向量相似度可能将语义相近但实际不相关的文档排得较高。
- 噪声引入:召回结果中可能混杂一些低质量或不相关文档,影响 LLM 生成。
重排序阶段通过更强大的模型(如交叉编码器)对查询和每个候选文档进行深度交互计算,重新评估相关性,从而提升最终输入给 LLM 的文档质量。
二、Rerank 的具体流程 Rerank 通常作为 RAG 流程中的一个中间环节,位于检索(Retrieval)之后、生成(Generation)之前。具体步骤如下:
- 第一阶段检索
- 使用高效检索方法(如向量相似度、BM25)从知识库中快速获取 Top-N 个候选文档(N 通常较大,例如 100 或 200)。
- 此阶段目标是“广撒网”,确保召回尽可能多的相关文档,允许包含一些噪声。
- 准备输入对
- 对于每个候选文档,将其与用户查询拼接成一个输入对
(query, document)。 - 如果文档过长,可能需要截断或分段处理。
- 对于每个候选文档,将其与用户查询拼接成一个输入对
- 使用重排序模型计算相关性分数
- 将每个输入对送入重排序模型(如 cross-encoder),模型输出一个相关性分数(通常为 0 到 1 之间的值或 logits)。
- 交叉编码器(Cross-Encoder)与双编码器(Bi-Encoder)不同:双编码器将查询和文档分别编码为向量,然后计算相似度;交叉编码器则让查询和文档在模型内部进行深度交互(如通过注意力机制),从而更精准地捕捉语义匹配,但计算成本更高。
- 常用重排序模型包括:
- 基于 BERT 的 cross-encoder(如
cross-encoder/ms-marco-MiniLM-L-6-v2) - 专用重排序模型:Cohere Rerank、bge-reranker 等。
- 基于 BERT 的 cross-encoder(如
- 排序与筛选
- 根据相关性分数对所有候选文档进行降序排列,选择分数最高的 Top-M 个文档(M 通常较小,例如 5 或 10)作为最终上下文。
- 可以设置一个相关性阈值,过滤掉分数过低的文档。
- 输入给生成模型
- 将筛选后的高质量文档与原始查询一起构建增强提示,输入给大语言模型生成最终答案。
三、Rerank 的实现要点
- 性能权衡:重排序模型通常比向量检索慢,因此 N 不能太大,且需使用 GPU 加速或批处理。常见做法是将 N 控制在 100 左右。
- 模型选择:根据业务需求选择通用或领域特定的重排序模型。如果需要多语言支持,可选择多语言版本。
- 延迟优化:可将重排序与检索并行(如异步流水线),或使用更轻量级的模型(如蒸馏版)来降低延迟。
- 混合重排序:结合多种信号,如向量相似度、BM25 分数、文档权威性、时间新鲜度等,进行加权排序。
四、大白话解释 想象你要从一堆书里找最相关的一本回答一个问题。你先让助手快速扫一眼书架,挑出可能相关的几十本(第一阶段检索)。但这些书可能有些只是书名相关但内容不相关。现在你亲自坐下来,仔细阅读每本书的目录和简介(重排序),然后挑出最贴切的几本。最后你根据这几本书的内容回答提问。
重排序就是那个“仔细阅读”的过程,它虽然慢,但能保证你选的书是最准的。
五、扩展知识点
- 交叉编码器 vs 双编码器:
- 双编码器(如 Sentence-BERT):速度快,适合大规模检索,但精度较低。
- 交叉编码器:精度高,适合小规模重排序,但计算量大。
- 重排序的几种策略:
- 点式(pointwise):对每个文档独立打分,然后排序。
- 列表式(listwise):直接对文档列表整体优化排序,如 LambdaRank。
- Rerank 在 RAG 中的位置:
- 有些系统采用多级 Rerank:先用轻量级模型粗排,再用复杂模型精排。
- 也可以与检索迭代结合,如基于重排序结果进行二次检索(扩展查询)。
- 开源工具与框架:
- LangChain 提供
ContextualCompressionRetriever和CrossEncoderReranker组件。 - LlamaIndex 支持
CohereRerank、SentenceTransformerRerank等。
- LangChain 提供
- 评估指标:
- 重排序效果常用 NDCG、MAP、MRR 等排序指标评估。
- 最终对生成答案的影响需通过人工或自动评估(如 ROUGE、BLEU、GPT 评分)。
- 挑战与应对:
- 延迟:可使用缓存、异步、降级策略。
- 模型大小:模型蒸馏、量化、ONNX 优化。
- 长文档处理:将文档分段,分别评分后取最大值或平均值。
通过引入重排序,RAG 系统能够在保证检索效率的同时,大幅提升最终生成内容的相关性和可靠性,是构建高质量知识问答系统的关键一环。
【问题】 什么是混合检索?在基于大模型的应用开发中,混合检索主要解决什么问题?
【参考答案】 混合检索(Hybrid Search)是一种结合多种检索技术(通常包括基于关键词的稀疏检索和基于向量的密集检索)的搜索方法。其核心思想是利用不同检索方式的互补优势,提高检索结果的准确性、召回率和鲁棒性。在基于大模型的应用(如RAG)中,混合检索主要用于解决单一检索方法固有的局限性,确保检索到的上下文既能精准匹配关键词,又能理解语义相关性。
一、混合检索的主要类型 常见的混合检索组合包括:
- 稀疏检索 + 密集检索:例如BM25(词频-逆文档频率)与向量检索(如基于BERT的嵌入相似度)的结合。BM25擅长精确匹配关键词,对罕见词敏感;向量检索擅长语义匹配,能理解同义词和上下文。
- 多路召回 + 融合排序:不同检索方法独立召回文档,然后通过某种融合策略(如倒数排序融合RRF、加权求和)综合排序。
- 结构化和非结构化数据混合:结合数据库的结构化查询与文本的向量检索,适用于多模态知识库。
二、混合检索解决的主要问题 在基于大模型的应用开发中,混合检索主要解决以下问题:
- 语义与关键词的互补
- 向量检索擅长捕捉语义相似性,但可能忽略对精确词汇的匹配,导致包含关键术语的文档排名靠后。
- 关键词检索(如BM25)能精确匹配用户输入的专有名词、缩写或产品型号,但对同义词、概念性查询效果差。
- 混合检索通过结合两者,既能命中包含“苹果”的语义相关文档(如水果、公司),也能找到包含“AAPL”股票代码的精确匹配文档。
-
提升召回率(Recall)
单一检索方式可能遗漏某些相关文档。例如,用户查询“机器学习算法”,向量检索可能召回大量关于深度学习的文档,但BM25可以召回提到“KNN”等具体算法的文档。混合检索综合多种信号,提高了相关文档的召回数量,为后续大模型生成提供更全面的上下文。 -
处理词汇不匹配问题
用户查询往往使用与文档不同的词汇(例如,用户说“怎么修车”,文档写“汽车维修”)。向量检索通过语义理解可以跨越词汇鸿沟,而BM25则可能失效。混合检索可以确保当一种方法失败时,另一种方法仍能捕获相关文档。 -
提高检索鲁棒性
不同检索方法对噪声、数据分布变化的敏感度不同。例如,在垂直领域(如医疗、法律),专业术语的嵌入可能不够准确,但BM25基于精确词汇仍能工作。混合检索使系统在面对多样化的查询和文档时更加稳定。 -
应对查询多样性
用户查询可能兼具语义和精确两种需求。例如,“2023年诺贝尔物理学奖获得者”包含精确实体“2023”“诺贝尔物理学奖”,同时“获得者”可能需要语义理解。混合检索能同时满足这两种需求。 - 优化最终生成质量
在RAG中,检索质量直接决定生成答案的准确性。混合检索通过提供更相关、更全面的上下文,减少大模型产生幻觉的风险,提升答案的可信度。
三、大白话解释 混合检索就像请两个专家一起帮你找资料:
- 专家A(BM25) 擅长按字眼找,你说“苹果手机”,他就去翻所有包含“苹果”“手机”字眼的文档,但如果你说“智能手机”,他可能就不认识“智能手机”就是“手机”。
- 专家B(向量检索) 擅长理解意思,你说“智能手机”,他能联想到“手机”“移动设备”,但他对“iPhone 14 Pro”这种精确型号可能不太敏感。
- 混合检索就是让两位专家同时找,然后把他们的推荐名单综合起来,选出最靠谱的资料。这样既不会漏掉包含关键字的文档,也能找到语义相关的文档。
四、扩展知识点详解
- 融合策略
- 倒数排序融合(RRF):对多个结果集按排名位置进行加权,公式为
score = ∑ 1/(k + rank_i),其中k为常数(通常60)。无需归一化,简单有效。 - 加权和(Weighted Sum):对每种检索方法给出归一化的分数,然后按权重相加。
- 级联(Cascade):先用一种方法快速召回候选,再用另一种方法精排。
- 学习排序(LTR):利用机器学习模型学习不同特征的最佳组合。
- 倒数排序融合(RRF):对多个结果集按排名位置进行加权,公式为
- 常见实现框架
- Elasticsearch:支持布尔查询与向量检索的混合(
script_score查询)。 - Weaviate:内置混合检索功能,支持BM25与向量搜索的RRF融合。
- Pinecone:支持稀疏-密集检索(通过稀疏向量)。
- LangChain:提供
EnsembleRetriever,可组合多个检索器。
- Elasticsearch:支持布尔查询与向量检索的混合(
- 在RAG中的典型流程
- 用户查询 → 同时执行BM25检索和向量检索 → 分别得到Top-N文档 → 融合排序 → 取Top-K文档 → 输入LLM生成答案。
- 评估指标
- 召回率(Recall@K)、精确率(Precision@K)、NDCG、MRR。
- 最终任务指标:答案准确率、ROUGE、人工评分。
- 挑战与优化
- 延迟:多路检索增加耗时,可并行化或使用缓存。
- 参数调优:需要根据业务调整融合权重、各检索的召回数量。
- 相关性分数归一化:不同检索的分数分布不同,需归一化处理。
混合检索已成为构建高质量RAG系统的关键技术之一,能够显著提升检索效果,从而优化大模型生成内容的质量。
【问题】 在 RAG 应用中为了优化检索精度,其中的数据清洗和预处理怎么做?
【参考答案】 在 RAG 应用中,数据清洗与预处理是构建高质量知识库的基石,直接影响检索的准确性和生成内容的质量。其核心目标是将原始非结构化数据转化为干净、结构化、易于检索的文本块。以下是系统化的处理步骤和最佳实践。
一、数据清洗(Data Cleaning) 数据清洗的目的是去除噪声和无关信息,确保输入给嵌入模型和检索系统的数据纯净。
- 格式统一与内容提取
- 多格式支持:从 PDF、Word、HTML、Markdown 等不同来源提取纯文本。使用专门的解析库(如
pypdf、python-docx、BeautifulSoup)避免直接处理二进制流。 - 去除格式标记:移除 HTML 标签、Markdown 符号、PDF 中的页眉页脚和页码。
- 保留结构:对于标题、列表、表格等结构化内容,采用特殊标记或分段保留,以辅助检索理解。
- 多格式支持:从 PDF、Word、HTML、Markdown 等不同来源提取纯文本。使用专门的解析库(如
- 噪声过滤
- 停用词:根据语言和领域,去除无实际意义的常见词(如“的”、“是”、“the”),但需谨慎,避免影响检索(例如,“to be or not to be”中的停用词可能关键)。
- 特殊字符:清除乱码、控制字符、多余的空白符(将多个换行替换为单个,统一空格)。
- 非文本元素:移除脚本代码、CSS 样式、注释等内容。
- 敏感信息:根据合规要求,检测并脱敏或剔除身份证号、手机号等隐私数据。
- 语言检测与翻译(可选)
- 如果知识库是多语言的,进行语言识别,后续可针对不同语言选择对应的嵌入模型。
- 对于需要统一检索的场景,可将非主流语言内容翻译成目标语言(如英语),但需注意翻译质量可能引入误差。
- 纠错与规范化
- 拼写纠正:对于 OCR 识别错误或用户输入错误的数据,可应用拼写检查工具(如
pyspellchecker),但需权衡成本与收益。 - 术语统一:将同义词或缩写映射为标准术语(如“AI”统一为“人工智能”),提高检索一致性。
- 拼写纠正:对于 OCR 识别错误或用户输入错误的数据,可应用拼写检查工具(如
二、文本切分(Chunking) 将长文档切分为适合检索和嵌入的片段,是预处理中最关键的环节。
- 切分策略
- 固定大小切分:按字符数或词数切分,简单但可能打断语义。
- 递归切分:优先保持段落、句子边界,若超出最大长度再逐级切分(如 LangChain 的
RecursiveCharacterTextSplitter)。 - 语义切分:利用 NLP 技术(如基于 BERT 的句子分割)或文档结构(标题、列表)切分,保证每个片段语义完整。
- 滑动窗口:片段间保留重叠区域,防止切分边缘丢失上下文。
- 参数调优
- 块大小:取决于嵌入模型的最大输入长度(如 512 tokens)。经验值 500-1000 词,需根据内容类型调整(代码可稍小,文档可稍大)。
- 重叠量:10%-20% 的重叠有助于上下文连贯,避免关键信息恰好被切开。
- 结构化保留
- 对于列表、表格等,可考虑特殊处理(如转为 Markdown 表格)后嵌入,或单独检索。
三、元数据构建 为每个文本块附加元数据,增强检索时的过滤和排序能力。
- 基础元数据
- 文档来源(文件名、URL)、创建时间、作者、版本等。
- 文档层级结构(章节标题、父文档 ID),便于追溯。
- 派生元数据
- 摘要:为长文档生成摘要,可在检索时先匹配摘要,再定位到具体块。
- 关键词:提取 TF-IDF 关键词或实体(人名、地名、组织名)。
- 文档类型:如“技术手册”、“法律条款”、“常见问题”。
- 用于过滤的元数据
- 时间戳(便于按时间范围检索)、领域标签、权限级别等。
四、数据增强与扩展
- 生成假设性问题
- 对每个文本块,使用 LLM 生成若干可能被用户提出的问题,并将问题与原文块一起存入向量库。检索时,用户问题可能与生成的问题更匹配,从而提高召回率(HyDE 思想)。
- 示例:原文块讲“Redis 的持久化方式”,可生成问题“Redis 如何保证数据不丢失?”、“RDB 和 AOF 有什么区别?”。
- 多粒度索引
- 同时存储文档块和摘要/标题,检索时先匹配摘要,再定位到具体块,或采用层次检索。
五、质量评估与迭代
- 数据质量检查
- 抽样检查清洗后文本的完整性和准确性。
- 使用嵌入模型计算块间的相似度,识别重复或过于相似的块(可能需去重)。
- 检索效果评估
- 构建测试查询集,人工标注相关文档块。
- 运行检索,计算召回率、精确率,根据结果调整切分策略、清洗规则。
六、实践建议
- 工具链:使用
unstructured库处理多种文档格式;langchain或llama-index提供标准切分器;pandas处理元数据。 - 增量更新:知识库需要持续更新,设计增量处理流程,只处理新增或修改的文档。
- 领域适配:针对垂直领域(如医疗、法律),清洗规则需加入专业术语词典和特殊格式处理。
七、大白话解释 可以把数据清洗和预处理比作 “整理图书馆的藏书”:
- 数据清洗:把旧书上的灰尘擦掉(去噪),撕掉破损的页(去除乱码),把不同出版社的书统一包上书皮(格式统一)。
- 文本切分:把每本书按章节拆成小册子(分块),并在每本小册子之间留一页空白(重叠),防止内容断档。
- 元数据构建:在小册子封面写上书名、章节名、关键词(元数据),方便以后快速查找。
- 数据增强:在小册子背面贴几个常见问题(假设性问题),即使读者不记得原文也能通过问题找到。
经过这样整理,当用户来问问题时,管理员就能快速找到最相关的那本小册子,而不是整本书。
八、扩展知识点
- Embedding 模型的选择:不同模型对文本长度和语言的支持不同,切分时需考虑模型限制。
- 检索与重排序的结合:预处理的质量直接决定后续检索的上限,但结合重排序可进一步修正。
- 避免过度清洗:某些场景下,保留少量“噪声”(如语气词)可能有助于语义理解,需根据业务判断。
- 长文本处理:对于超长文档(如整本书),可采用分层索引:文档摘要→章节块→段落块,逐层检索。
通过系统化的数据清洗与预处理,RAG 系统能够获得高质量的知识基础,显著提升检索精度和最终生成效果。
【问题】 什么是查询扩展?为什么在 RAG 应用中需要查询扩展?
【参考答案】 查询扩展(Query Expansion) 是一种信息检索技术,旨在通过向原始用户查询中添加相关词汇、同义词、短语或改写查询,来增强查询的表达能力,从而提高检索系统的召回率和准确性。在 RAG(检索增强生成)应用中,查询扩展被用于优化检索阶段,使系统能够从知识库中获取更全面、更相关的上下文,最终提升生成答案的质量。
一、查询扩展的常见方法
-
基于同义词或知识库的扩展
利用预定义的同义词词典、WordNet 或领域本体,将查询中的关键词替换或添加其同义词。例如,“智能手机”可扩展为“手机”、“移动电话”。 -
基于伪相关反馈(Pseudo-Relevance Feedback, PRF)
先执行原始查询,从初次检索结果中提取 top-K 篇文档,分析其中的高频词或关键短语,将它们作为扩展词加入原查询,然后进行二次检索。 -
基于嵌入的语义扩展
使用词向量或句子嵌入模型,计算与查询词向量最相似的词作为扩展。例如,用 Word2Vec 找出与“汽车”最相似的词“轿车”、“车辆”。 -
基于大语言模型(LLM)的查询生成
利用 LLM 对原始查询进行改写、生成多个相关问法,或生成假设性答案(HyDE),再将生成的文本作为检索查询。 -
基于用户历史或上下文
结合对话历史或用户画像,对当前查询进行个性化扩展。
二、为什么在 RAG 应用中需要查询扩展? 在 RAG 系统中,检索的准确性直接决定了生成内容的质量。查询扩展主要解决以下几个关键问题:
-
词汇不匹配问题(Vocabulary Mismatch)
用户查询与知识库中的文档可能使用不同的词汇表达同一概念(例如用户问“如何修理手机”,文档中写的是“智能手机维修指南”)。查询扩展通过引入同义词或相关词,弥补这种表达差异,确保相关文档能被召回。 -
查询信息不完整或过于简短
用户常输入简短模糊的查询(如“苹果价格”),导致检索结果泛泛。扩展可以补充隐含信息(如“苹果公司股价”或“水果苹果市场价格”),使查询更具体,提高命中率。 -
处理一词多义和歧义
查询可能有多种含义(如“Java”可能指编程语言或岛屿)。通过扩展并利用上下文(如对话历史或领域知识),可以明确意图,避免检索到不相关的文档。 -
提升召回率(Recall)
单一查询可能遗漏相关文档,尤其当文档分布稀疏时。生成多个查询变体或添加扩展词,可以覆盖更多潜在相关文档,提高召回的全面性。 -
优化生成质量
更丰富、更精准的检索上下文使 LLM 能基于更全面的信息生成答案,减少幻觉(hallucination),增强答案的可信度和完整性。
三、大白话解释 查询扩展就像你向朋友咨询问题时,先把问题润色一下:
- 你原本想问“怎么学编程?”,但朋友可能理解成“怎么学写代码?”或“学编程需要什么步骤?”。为了让他更准确地帮你找资料,你补充说“我想学 Python,有没有入门教程?”——这就相当于对原查询进行了扩展。
- 在 RAG 里,系统会自动做这个“润色”工作:把用户的简短问题变成多个可能的问法,或者加上同义词,然后去知识库里找最匹配的答案。这样即使原文用的是不同的词,也能被找出来。
四、扩展知识点详解
- 查询扩展与 HyDE 的区别
- HyDE(Hypothetical Document Embeddings)先生成一个假设性答案,再用该答案的嵌入去检索。而查询扩展直接修改查询词本身。HyDE 本质上也是一种查询扩展,但更侧重于生成答案风格的文本。
- 扩展的权衡
- 扩展词过多可能导致查询漂移(topic drift),引入噪声,降低精确率。需要合理控制扩展词的数量和质量。
- 实现技巧
- 可结合多种扩展方法,如先用 LLM 生成相关词,再用同义词库过滤。
- 在 RAG 流程中,查询扩展通常作为检索前的一步,与重排序(rerank)配合使用,先扩展召回,再精排。
- 评估指标
- 通过对比扩展前后的召回率(Recall@K)、精确率(Precision@K)以及最终生成答案的 ROUGE、人工评分等来衡量效果。
- 实际应用场景
- 搜索引擎、问答系统、对话机器人等广泛使用查询扩展。
- 注意事项
- 领域特定术语可能需要构建专用扩展词典。
- 在线场景需考虑扩展的延迟开销,可采用缓存或轻量级模型。
查询扩展是提升 RAG 系统检索效果的重要技术,通过合理设计,能显著改善用户体验和系统智能度。
【问题】 什么自查询?为什么在 RAG 中需要自查询?
【参考答案】 自查询(Self-Query) 是指在 RAG(检索增强生成)系统中,利用大语言模型(LLM)本身将用户的自然语言查询转化为结构化查询(如包含过滤条件、关键词、时间范围等)的技术。它通过解析用户意图,从查询中提取关键实体和约束条件,然后针对向量数据库或知识库执行更精准的检索,而不仅仅是依赖语义相似度。
一、自查询的工作原理 自查询通常分为两个步骤:
- 解析与结构化:将用户的原始自然语言输入(如“去年苹果发布的手机有哪些?”)交给一个 LLM,让它输出一个结构化的查询对象,例如:
{
"query": "手机",
"filter": {
"company": "苹果",
"year": 2023
}
}
- 执行检索:根据结构化查询,在知识库中进行两阶段检索:
- 先应用过滤条件(如时间、类别)缩小搜索范围;
- 再对过滤后的内容进行向量相似度检索(如使用
query字段)。
二、为什么在 RAG 中需要自查询? 在 RAG 应用中,传统的检索方式通常只进行向量相似度搜索,但面对复杂、多约束的查询时存在明显不足。自查询主要解决以下问题:
-
处理结构化约束
用户查询往往包含时间、地点、类别等显式条件(如“2023年之前的论文”、“价格低于500元的商品”)。纯向量检索无法准确应用这些条件,而自查询能提取并转换为元数据过滤,确保检索结果符合约束。 -
提高检索精确性
通过将自然语言中的实体和关系拆解为结构化过滤器,可以避免因语义相似而引入的无关文档。例如,“苹果”可能指水果或公司,结合“手机”上下文,自查询能明确意图为“苹果公司”,从而精准筛选。 -
降低检索噪声
当知识库中混合了多种类型数据时,过滤条件能提前剔除不相关领域,减少后续相似度计算的干扰,提升召回的准确性。 -
支持复杂查询
对于多条件组合查询(如“找到最近三个月关于气候变化的评论,并且是正面评价”),自查询能分解出时间、主题、情感等多个维度,协同检索。 -
增强可解释性
结构化查询的中间输出可以展示给用户或开发者,帮助理解系统如何理解查询,便于调试和优化。
三、大白话解释 自查询就像让一个聪明的助手帮你找东西:
- 你随口说:“帮我找下去年买的红色外套。”
- 助手不会直接去翻遍所有衣服,而是先记下关键信息:时间=去年,物品=外套,颜色=红色。然后他才去衣柜里找,只翻去年的外套,并且只挑红色的。这样又快又准。
- 在 RAG 里,这个助手就是 LLM,它把你说的话翻译成机器能懂的过滤条件,然后向量数据库根据这些条件快速定位,最后找出最匹配的文档。
四、扩展知识点详解
- 实现方式
- 通常使用 LLM 结合提示工程,要求模型以 JSON 格式输出解析结果。例如,在 LangChain 中,可以通过
SelfQueryRetriever配合LLMChain实现。 - 需要定义知识库支持的元数据字段(如日期、类别)和操作符(如等于、大于、包含)。
- 通常使用 LLM 结合提示工程,要求模型以 JSON 格式输出解析结果。例如,在 LangChain 中,可以通过
- 与元数据过滤的区别
- 元数据过滤通常是手动或基于规则提取,而自查询是模型动态从自然语言中推断,更具通用性。
- 挑战与优化
- 解析准确性:需要设计清晰的提示,确保 LLM 能正确理解意图并输出标准格式。
- 多意图处理:用户查询可能包含多个条件或隐含逻辑,需训练模型处理。
- 性能开销:自查询增加了一次 LLM 调用,需平衡延迟与收益。
- 应用场景
- 电商推荐(按价格、品牌过滤)
- 企业知识库问答(按部门、时间、文档类型查询)
- 科研文献检索(按年份、作者、期刊筛选)
通过自查询,RAG 系统能够更智能地理解用户需求,实现更精准的检索,从而提升生成答案的质量和相关性。
【问题】 什么是提示压缩?为什么在 RAG 中需要提示压缩?
【参考答案】 提示压缩(Prompt Compression) 是指在将检索到的文档与原始用户查询一起输入给大语言模型(LLM)生成最终答案之前,对文档内容进行精简、提炼或过滤,以减少输入长度、保留核心信息的过程。其本质是一种上下文优化技术,旨在解决长上下文带来的效率和质量问题。
一、提示压缩的主要方法
-
抽取式压缩
通过算法(如基于 BM25 或嵌入相似度)从文档中抽取与查询最相关的句子或段落,丢弃无关内容。常用工具如 LangChain 的LLMChainExtractor。 -
摘要式压缩
利用 LLM 本身对文档生成简洁的摘要,保留关键事实和逻辑,去除冗余表达。 -
选择式压缩
直接选取文档中与查询最匹配的 Top-K 个块,丢弃其余部分,类似于重排序后截断。 -
混合压缩
结合抽取与摘要,例如先抽取关键句,再对这些句子进行摘要。
二、为什么在 RAG 中需要提示压缩? 在 RAG 系统中,提示压缩主要解决以下核心问题:
-
应对 LLM 的上下文窗口限制
主流 LLM(如 GPT-4、Claude)都有固定的最大输入长度(例如 4K、8K、32K tokens)。当检索到的文档总长度超过窗口限制时,必须进行压缩,否则无法输入。即使模型支持长上下文(如 128K),过长的输入也会显著增加推理延迟和成本。 -
降低计算成本与延迟
LLM 的推理时间与输入 token 数成正比。压缩可以显著减少 token 数量,从而降低响应时间和 API 调用费用,提升用户体验。 -
去除噪声,聚焦核心信息
检索阶段可能返回一些与查询相关性较低或包含冗余信息的文档。压缩过程可以过滤掉这些噪声,使模型能够集中处理最关键的内容,减少“注意力分散”,提高生成答案的准确性和连贯性。 -
提升生成质量
过长的输入可能导致模型在长距离依赖中丢失关键信息,或受无关内容干扰产生幻觉。压缩后的提示更精炼,有助于模型准确理解需求,生成更高质量的答案。 -
支持更丰富的检索策略
由于压缩后能容纳更多文档块,检索阶段可以召回更多候选文档(Top-N 可以更大),然后通过压缩精选出最相关的部分,实现“广召回、精筛选”的优化。
三、大白话解释 提示压缩就像你向朋友请教问题前,先把自己准备的一大堆资料整理一下:
- 你找到了 10 篇相关文章,但每篇都很长。如果直接把所有文章甩给朋友,他可能会看花眼,而且没时间看完。
- 于是你先把每篇文章里的重点句子划出来,甚至把几篇文章的核心观点提炼成一段话,然后再拿给朋友看。这样朋友就能快速抓住要点,给你精准的建议。
在 RAG 中,LLM 就是那位朋友,提示压缩就是帮他筛选和提炼资料的过程,让他不用浪费时间看无关内容,专注于解决你的问题。
四、扩展知识点详解
-
压缩与检索的关系
检索是“找到相关文档”,压缩是“精炼文档内容”。两者结合实现高效 RAG:检索广覆盖,压缩保核心。 - 常见的压缩工具与框架
- LangChain 提供了
ContextualCompressionRetriever,可搭配LLMChainExtractor(抽取)或LLMChainFilter(过滤)使用。 - LlamaIndex 支持通过
NodeParser和SummaryIndex等实现摘要式压缩。 - 专用压缩模型如
LongLLaMA、Recomp等可用于高效压缩。
- LangChain 提供了
- 压缩质量评估
- 压缩率 = 压缩后 token 数 / 原始 token 数。
- 信息保留度:通过问答评估压缩后的内容是否能覆盖原始文档中的关键信息。
- 对最终生成答案质量的影响(如 ROUGE、人工评分)。
- 权衡与挑战
- 压缩损失:过度压缩可能丢失重要细节,需根据业务场景调整压缩强度。
- 延迟增加:压缩过程本身需要额外计算(尤其是使用 LLM 进行摘要时),需权衡总延迟。
- 动态适应性:对于不同类型查询,压缩策略可能需要动态调整(如简单查询只需抽取,复杂查询需摘要)。
- 进阶技术
- 分层压缩:先对每个文档块独立压缩,再对多个文档进行聚合压缩。
- 查询感知压缩:根据查询动态决定压缩方式,例如对与查询高度相关的部分保留完整,其余部分摘要。
- 端到端学习压缩:训练专门的压缩模型,以最大化下游任务(如问答)的性能为目标。
通过提示压缩,RAG 系统能够在有限上下文内高效利用检索结果,实现更快、更准、更省的目标,是大规模知识库问答系统的关键技术之一。
【问题】 如何进行 RAG 调优后的效果评估?请给出真实应用场景中采用的效果评估标准与方法。
【参考答案】 RAG(检索增强生成)系统的效果评估是确保系统在实际应用中可靠、准确的关键环节。由于RAG涉及检索和生成两个阶段,评估需要覆盖检索质量、生成质量以及端到端整体表现。以下从评估维度、核心指标、真实场景的评估方法以及常用工具四个方面展开。
一、评估维度与核心指标
- 检索质量评估
检索阶段的目标是从知识库中召回与用户查询最相关的文档片段。主要指标包括:
- 精确率(Precision@K):检索返回的前K个结果中相关文档的比例。
- 召回率(Recall@K):前K个结果中相关文档数占总相关文档数的比例。
- NDCG@K(归一化折损累计增益):考虑排序位置,对排在前面的相关文档给予更高权重。
- MRR(平均倒数排名):第一个相关文档出现的位置的倒数平均值。
- 平均精度(MAP):对每个查询的精度-召回曲线下的面积求平均。
- 生成质量评估
生成阶段评估LLM基于检索结果产生的答案质量,分为自动指标和人工指标:
- 自动指标:
- ROUGE(Recall-Oriented Understudy for Gisting Evaluation):基于n-gram重叠,衡量生成答案与参考答案的相似度(常用于摘要)。
- BLEU(Bilingual Evaluation Understudy):基于精确率的n-gram匹配(常用于机器翻译)。
- METEOR:考虑词干和同义词匹配,比BLEU更灵活。
- BERTScore:利用BERT嵌入计算生成答案与参考答案的语义相似度。
- Perplexity:衡量生成文本的流畅度(越低越好)。
- 事实一致性指标:如QAGS、QuestEval,评估生成内容是否与检索到的证据相符。
- 人工指标:
- 准确性:答案是否真实正确。
- 忠实度:答案是否基于提供的上下文,而非模型幻觉。
- 连贯性与流畅性:语言是否自然易读。
- 完整性:是否覆盖了问题所需的所有要点。
- 自动指标:
- 端到端整体评估
将检索与生成结合,评价最终答案的整体效果:
- 答案正确率:通过人工或与标准答案比对,判断回答是否正确。
- 无幻觉率:答案中未出现与检索上下文矛盾的信息的比例。
- 用户满意度:通过用户反馈(如点赞、点踩)或任务完成率衡量。
- 响应时间与成本:端到端延迟和API token消耗。
二、真实应用场景中的评估方法 在实际业务中,RAG系统的评估通常是多阶段、多方法的组合。
- 离线评估(Offline Evaluation)
- 构建测试集:从真实用户日志中抽样查询,并为每个查询标注:
- 相关的文档片段(用于检索评估)。
- 理想的答案(用于生成评估)。
- 自动计算指标:在测试集上运行RAG系统,计算上述检索和生成指标。例如,使用ROUGE和BERTScore评估答案相似度。
- 优势:快速、可重复,便于调优对比。
- 构建测试集:从真实用户日志中抽样查询,并为每个查询标注:
- 在线评估(Online Evaluation)
- A/B测试:将用户流量随机分配到不同版本的RAG系统(如基线 vs 优化后),对比业务指标:
- 用户停留时间、点击率、任务完成率。
- 用户反馈(赞/踩、满意度评分)。
- 真实用户反馈:在对话界面嵌入“有用/无用”按钮,收集用户评价,并结合日志分析错误案例。
- 优势:直接反映真实体验,但需控制变量且周期较长。
- A/B测试:将用户流量随机分配到不同版本的RAG系统(如基线 vs 优化后),对比业务指标:
- 人工评估(Human Evaluation)
- 专家评审:邀请领域专家对系统输出进行评分(1-5分),维度包括准确性、完整性、可读性等。
- 众包评估:通过Amazon Mechanical Turk等平台收集大规模人工评分。
- 对抗性测试:故意输入模糊、有歧义或复杂问题,评估系统的鲁棒性。
- 组件级评估
- 检索单独评估:在冻结生成模型的情况下,替换检索算法,观察检索指标变化。
- 生成单独评估:固定检索结果,替换LLM或提示模板,对比生成质量。
三、实际案例:智能客服知识库问答系统 假设我们要优化一个针对某产品的智能客服RAG系统。评估流程如下:
- 构建测试集:收集最近一个月用户咨询记录,筛选500条常见问题,由产品专家为每条问题标注:
- 应召回的文档片段(来自产品手册、FAQ)。
- 标准答案。
- 离线评估:
- 计算检索模块的Recall@5和NDCG@5,确保90%以上问题能在前5个结果中找到相关片段。
- 使用ROUGE-L和BERTScore对比生成答案与标准答案,要求平均分>0.6。
- 在线A/B测试:
- 对10%用户使用优化后版本,90%用户使用旧版本,持续一周。
- 监控指标:
- 用户满意度:点击“有帮助”的比例提升5%。
- 客服转接率:降低10%。
- 平均会话时长:缩短20秒。
- 人工抽样复核:每天随机抽取100条对话,由客服主管评分,检查有无错误信息或遗漏。
- 迭代优化:根据错误案例(如检索遗漏、幻觉)调整检索参数或提示模板,重复上述流程。
四、常用评估框架与工具
- RAGAS:专为RAG设计的评估框架,提供检索相关性、答案忠实度、上下文召回率等指标。
- TruLens:支持多模态评估,可定义自定义反馈函数。
- LlamaIndex 内置评估模块,可计算检索指标和生成指标。
- DeepEval:提供单元测试式的评估,支持LLM-based评分。
- Phoenix:Arize开源的LLM可观测性平台,支持RAG链路追踪和评估。
五、总结 RAG系统的效果评估需要结合离线指标和在线反馈,从检索、生成到端到端全方位衡量。关键是根据业务场景选择合适指标,并持续通过用户反馈和数据驱动迭代。没有单一指标能完全反映系统性能,多维度综合评估才是可靠之道。
【问题】 什么是 RAG 中的分块?为什么需要分块?常见的分块策略有哪些?分别有什么区别?
【参考答案】 一、什么是分块? 在 RAG(检索增强生成)系统中,分块(Chunking) 是指将长文档或知识库中的文本按照一定的规则切分成多个较小的、语义相对完整的片段(chunks)。这些片段随后会被向量化并存储到向量数据库中,用于后续的检索和生成。
二、为什么需要分块?
- 嵌入模型输入长度限制:大多数嵌入模型(如 OpenAI 的 text-embedding-ada-002、Sentence-BERT)都有最大输入长度限制(通常为 512 token)。长文档必须切分才能嵌入。
- 提升检索精度:短片段与用户查询的相关性更容易计算,避免长文档中无关内容干扰相似度匹配。例如,一篇万字文档可能只有一段与查询相关,切分后能精准召回该段落。
- 降低计算与存储成本:嵌入长文本消耗更多资源,且向量维度固定,长文本的向量表示可能丢失细节。分块后整体计算更高效。
- 改善生成质量:LLM 的上下文窗口有限,提供多个相关片段比提供整篇文档更灵活,便于模型聚焦关键信息。
- 支持精细化过滤:分块后可为每个片段附加元数据(如章节、时间),实现更精确的过滤检索。
三、常见的分块策略及其区别
- 固定大小分块
- 方法:按固定字符数、词数或 token 数切分,可以设置重叠(overlap)避免切分点丢失上下文。
- 优点:实现简单,速度快,适用于任何文本。
- 缺点:可能打断句子或段落,导致语义不完整,检索效果受影响。
- 适用场景:日志、代码、无结构文本的快速处理。
- 递归分块
- 方法:按文本的自然结构(如段落、句子、词)递归切分,优先保持段落完整,若超出长度则继续切分句子。例如 LangChain 的
RecursiveCharacterTextSplitter按["\n\n", "\n", " ", ""]分隔。 - 优点:尽可能保持语义边界,比固定分块更合理。
- 缺点:仍可能打断句子(若句子过长),但已尽量优化。
- 适用场景:大多数通用文档。
- 方法:按文本的自然结构(如段落、句子、词)递归切分,优先保持段落完整,若超出长度则继续切分句子。例如 LangChain 的
- 语义分块
- 方法:利用 NLP 技术(如 BERT 的句子分割、文档结构识别)确定语义边界,如标题、章节、主题切换处。
- 优点:语义完整性最好,块内连贯性强。
- 缺点:实现复杂,依赖文档结构和语言模型,速度较慢。
- 适用场景:书籍、学术论文、技术文档等有清晰结构的文本。
- 基于文档结构的分块
- 方法:直接利用文档的原始结构(如 Markdown 的标题、列表,HTML 的标签)进行切分,将每个标题下的内容作为一个块。
- 优点:保留原文逻辑,便于后续按结构检索(如只查某章节)。
- 缺点:结构不统一的文档难以处理。
- 适用场景:Markdown、HTML、PDF 等结构化文档。
- 基于模型的分块
- 方法:训练专门的模型预测切分点,或使用大语言模型动态决定块边界。
- 优点:高度自适应,能处理复杂语义。
- 缺点:计算成本高,需额外资源。
- 适用场景:对检索精度要求极高且有充足算力的场景。
四、各种策略的区别总结
| 策略 | 切分依据 | 语义完整性 | 实现复杂度 | 速度 | 适用场景 |
|---|---|---|---|---|---|
| 固定大小 | 字符/词数 | 低 | 低 | 快 | 简单文本,快速原型 |
| 递归 | 自然分隔符(换行等) | 中 | 中 | 中 | 通用文档 |
| 语义 | 语义边界(标题、主题) | 高 | 高 | 慢 | 高质量文档 |
| 文档结构 | 原始格式标记 | 高 | 中 | 中 | 结构化文档(HTML等) |
| 基于模型 | 机器学习模型预测 | 很高 | 很高 | 很慢 | 极致精度,领域定制 |
【大白话解释】 分块就像把一本厚书拆成一个个小册子:
- 如果不管内容,按固定页数撕开(固定分块),可能把一句话撕成两半,不好读。
- 如果按章节拆(递归/文档结构),每本小册子内容完整,读起来舒服。
- 如果按主题拆(语义分块),把讲同一个话题的几段话放一起,即使跨章节也很合理。
- 如果请专家来拆(基于模型),拆得最精准,但费时费力。
在 RAG 里,这些小册子就是检索的基本单元,拆得好,找答案才准。
【扩展知识点详解】
- 块大小的选择:取决于嵌入模型的最大输入长度和任务需求。经验值 200-500 词(约 300-800 token)。太小则丢失上下文,太大则引入噪声且可能超限。
- 重叠(Overlap)的作用:在固定分块中,块间保留一定重叠(如 10%-20%)可以避免关键信息被切分点切断,提高检索召回率。
- 分块与元数据的结合:每个块可携带原文档的元数据(如标题、章节路径),便于在检索时按条件过滤。
- 分块对检索效果的影响:实验表明,语义完整的块比随机切分能显著提升检索准确率(如 Recall@K 提高 10-20%)。
- 动态分块:有些系统根据查询动态调整块大小(如先检索粗粒度块,再细粒度检索相关内容),但实现复杂。
- 与嵌入模型的关系:如果嵌入模型支持长文本(如 8K token),可考虑更大块,但需权衡精度和成本。
- 工具支持:LangChain、LlamaIndex 等框架提供了丰富的文本分割器,支持多种策略和参数配置。
通过合理选择分块策略,RAG 系统能够在检索效率和准确性之间取得平衡,为生成高质量答案奠定基础。
【问题】 在 RAG 中的 Embedding 嵌入是什么?你知道有哪些 Embedding Model 嵌入模型?如何选择 Embedding Model 嵌入模型,需要考虑哪些因素?
【参考答案】 一、什么是 Embedding 嵌入? 在 RAG(检索增强生成)系统中,Embedding(嵌入) 是将文本(如词、句子、段落或文档)映射到高维向量空间的技术。这个向量空间通常被称为语义空间,其中每个文本对应一个由浮点数组成的向量(例如 384 维、768 维或 1024 维)。语义相近的文本在该空间中会彼此靠近,语义不同的文本则相互远离。
嵌入由嵌入模型生成。早期方法如 Word2Vec 和 GloVe 只能为每个词生成固定的向量,无法处理一词多义。现代的嵌入模型(如 Sentence Transformers)基于 Transformer 架构,能够生成上下文相关的向量。例如,句子“我去公园遛狗”和“我把车停在车库”中的“park”,会被编码成不同的向量,因为模型能理解其在不同语境下的含义。
在 RAG 流程中,嵌入扮演着语义转换器的角色:
- 文档嵌入:在离线阶段,将知识库中的所有文档切分成块(chunks),通过嵌入模型转换为向量,并存入向量数据库。
- 查询嵌入:在线阶段,将用户的自然语言查询用相同的嵌入模型转换为向量。
- 向量检索:在向量数据库中执行相似性搜索(如余弦相似度、欧氏距离),找到与查询向量最相似的文档块。
- 生成答案:将检索到的文档块作为上下文,连同原始查询一起交给大语言模型(LLM)生成最终答案。
嵌入的质量直接决定了检索的准确性。如果嵌入模型无法捕捉语义差异,即使数据库中有正确答案,也可能因检索不到而导致模型给出错误回答。
二、常见的 Embedding Model 嵌入模型 嵌入模型可分为通用型、多语言型、领域专用型和轻量高效型。以下是一些主流模型(截至 2026 年初):
- 通用高性能模型
- Qwen3-Embedding 系列(阿里巴巴):基于 Qwen3 大模型构建,提供 8B、4B、0.6B 三种规模。8B 版本在 MTEB 多语言和英文榜单上表现卓越,尤其擅长长文本理解。许可证:Apache-2.0(可商用)。
- bge-m3(BAAI):2024 年发布的多功能模型,支持 100+ 语言、8192 上下文长度,并能同时生成稠密向量、稀疏向量和多向量,适配多种检索方式。许可证:MIT。
- gte-modernbert-base(阿里巴巴):基于 ModernBERT 架构,在保持高精度的同时,对量化(INT8)和二值化(binary)非常友好,可在大幅降低存储和计算开销的同时,保留 98% 的原始质量。
- 轻量高效模型(适合资源受限环境)
- embeddinggemma-300m(谷歌):仅 3 亿参数,支持 100+ 语言,可在 CPU 甚至手机上运行。许可证:Apache-2.0。
- stella_en_1.5B_v5:约 15 亿参数,支持Matryoshka Representation Learning(MRL),即可以按需截断向量维度(如从 1024 维截取 512 维),在存储和精度间灵活权衡。许可证:MIT。
- all-MiniLM-L6-v2:Sentence Transformers 家族经典模型,384 维输出,速度快,适合原型验证。
- 多语言模型
- multilingual-e5-base:微软出品,支持 100+ 语言,但在纯英文任务上精度可能略低于英文专用模型。
- distiluse-base-multilingual-cased-v1:Sentence Transformers 的多语言版本,支持 50+ 语言,512 维输出。
- 领域专用模型
- 医学:PubMedBERT(在生物医学文献上微调)、BioLORD。
- 金融:Finance Embeddings(Investopedia)、Voyage Finance。
- 法律:Legal-BERT(在法律文书上预训练)。
- 代码:CodeBERT、GraphCodeBERT。
- 数学:Math Similarity Model(捕捉 LaTeX 公式的结构)。
三、如何选择 Embedding Model:关键考量因素 选择嵌入模型时,不能只看 MTEB 排行榜的总体分数。需要综合以下六个维度进行权衡:
- 任务类型(Task Relevance)
不同的下游任务对嵌入的要求不同:
- 检索(Retrieval) 和 语义文本相似度(STS):需要模型能精细区分语义差异,是 RAG 的核心。重点关注 MTEB 中“Retrieval”和“STS”子项得分。
- 分类(Classification):需要稳定的类别边界。
- 聚类(Clustering):需要良好的全局结构捕捉能力。
- 重排序(Reranking):需要模型对候选顺序高度敏感。
原则:按需聚焦,不要被总分迷惑。
-
领域匹配(Domain Relevance) 如果数据来自特定领域(医疗、法律、金融、代码),领域专用模型几乎总是优于通用模型。因为它们对领域术语、行文风格和概念关系有更深入的理解。例如,用 PubMedBERT 检索医学文献,效果远超通用 BERT。
- 性能与成本权衡
这是生产环境最现实的问题,需考虑:
- 模型量化(Quantization):将模型权重从 FP32 转为 INT8,在 CPU 上推理速度可提升 2.7-3.4 倍,同时保持 94-98% 的质量。但在 GPU 上,INT8 反而可能更慢(应使用 FP16)。
- 向量精度(Vector Precision):存储向量时,可以使用 FP32、FP16、INT8 甚至二值化(binary)。二值化可将存储空间降低 32 倍,但部分模型(如 E5 家族)质量损失明显,而现代模型(如 GTE ModernBERT)能保留 98% 质量。
- 向量维度(Dimensionality):支持 MRL 的模型(如
stella_en_1.5B_v5)允许在索引时截断维度,用较小内存换取可接受的质量。 - 推理硬件:在 CPU 上,选择轻量模型(如
embeddinggemma-300m)并启用 INT8;在 GPU 上,可考虑 7B 模型并使用 FP16。
- 数据特性
- 语言:单语(如仅英文)选英文专用模型;多语选
bge-m3或multilingual-e5。 - 文本长度:如果文档很长(如论文、报告),需选择上下文窗口大的模型(如
bge-m3支持 8192 token)。传统 BERT 模型仅 512 token,超长文本需切块,可能导致上下文断裂。
- 语言:单语(如仅英文)选英文专用模型;多语选
- 成本与部署约束
- API 模型:如 OpenAI 的
text-embedding-3-small,上手快,但长期使用成本可能较高。 - 开源模型:自托管需要 GPU 或优化后的 CPU 环境,但无 API 调用费,且数据可控。
- 许可证:务必检查是否可商用。例如,NVIDIA 的
llama-embed-nemotron-8b仅限研究使用(CC-BY-NC)。
- API 模型:如 OpenAI 的
- 在自己的数据上测试 MTEB 是起点,不是终点。最终应在自有数据集上进行小规模评估,使用 NDCG@K、MRR 等指标衡量真实效果。因为通用基准无法完全反映特定领域的术语分布和查询习惯。
四、总结
| 考量维度 | 关键问题 | 推荐做法 |
|---|---|---|
| 任务类型 | 检索、分类、聚类? | 聚焦 MTEB 对应子项,而非总分 |
| 领域 | 数据是通用还是专业(医疗/法律/代码)? | 优先选择领域专用模型 |
| 性能/成本 | 实时性要求多高?硬件资源如何? | CPU 选轻量+INT8,GPU 可选大模型+FP16;利用量化与 MRL 平衡 |
| 数据长度 | 文档多长? | 长文需 8192+ 上下文窗口模型 |
| 多语言 | 是否需支持多种语言? | 选 bge-m3 或 multilingual-e5 |
| 商业许可 | 能否商用? | 检查许可证(如 Apache 2.0、MIT 可商用;CC-BY-NC 不可) |
最佳路径:先用 MTEB 筛选出符合任务类型的候选模型,再结合硬件条件量化优化,最后用自有数据实测。
【问题】 在 RAG 应用的过程中,关于提示工程的设计有什么心得和技巧吗?
【参考答案】 在 RAG(检索增强生成)应用中,提示工程的设计至关重要,因为它直接决定了生成模型如何理解和利用检索到的上下文信息,从而影响最终答案的质量、准确性和可靠性。以下是一些核心心得和实用技巧,涵盖从基础构建到高级优化的各个层面。
一、理解提示工程在 RAG 中的角色 RAG 的提示工程不同于传统 LLM 对话,它需要巧妙地将用户查询与检索到的文档片段融合,并引导模型生成基于事实的答案。好的提示能够:
- 帮助模型区分指令、上下文和用户问题。
- 指导模型在信息不足时如何回应(避免幻觉)。
- 格式化输出以便于应用解析。
- 在多轮对话中维持一致性和上下文。
二、核心设计与技巧
- 明确角色与任务
- 设置系统角色:在提示开头明确 LLM 的身份,例如“你是一个专业的客服助手,请根据提供的资料回答问题”。这有助于模型进入正确的行为模式。
- 清晰的任务描述:直接说明任务,如“请基于以下文档片段回答用户的问题。如果文档中找不到答案,请说明‘根据现有信息无法回答’,不要编造。”
- 结构化上下文与查询
- 使用清晰的分隔符:用特殊标记(如
###、---、<context>)将检索到的文档与用户查询分开,避免模型混淆。例如:
- 使用清晰的分隔符:用特殊标记(如
<context>
{检索到的文本块}
</context>
问题:{用户输入}
- 标注来源:如果检索到多个文档,可以为每个片段添加编号或元数据(如
[来源1]),并指导模型在回答中引用,增强可信度。
- 指导模型如何利用检索结果
- 强制基于上下文:明确要求“仅根据上述资料回答”,减少模型依赖内部知识产生幻觉。
- 处理信息缺失:设定兜底策略,如“如果资料中未提及,请直接说‘抱歉,我没有找到相关信息’”。
- 处理多片段:当检索到多个相关片段时,可要求“综合多个资料中的信息给出完整回答”,或“如果不同资料有冲突,请指出并分析”。
- 格式约束与输出规范
- 指定输出格式:对于需要结构化输出的场景(如 API 响应),可要求“以 JSON 格式返回:
{"answer": "...", "sources": [...]}”。 - 列表或步骤:若答案适合分点,可提示“请用 Markdown 列表分点说明”。
- 限制长度:如“请用不超过 100 字简要回答”。
- 指定输出格式:对于需要结构化输出的场景(如 API 响应),可要求“以 JSON 格式返回:
- 处理多轮对话
- 融入历史:将对话历史作为上下文的一部分,但要注意 token 限制。可以只保留最近的几轮交互。
- 重置指令:在多轮中,可能需要在每轮提示中重申核心规则,避免模型偏离。
- 少样本学习(Few-shot Examples)
- 提供几个示例,展示理想的输入输出模式。示例应覆盖正常回答、信息不足、多片段综合等场景。
示例:
资料:张三出生于北京。
问题:张三在哪里出生?
回答:北京。
---
资料:略。
问题:李四的生日?
回答:资料中未提及李四的生日,无法回答。
- 少样本能显著提升模型遵循格式的稳定性。
- 处理噪声与低质量检索
- 容忍不相关:检索结果可能包含噪声。可在提示中加入“忽略与问题无关的信息”。
- 提示验证:要求模型先判断检索内容是否与问题相关,再决定是否使用。例如“请先判断以下资料是否与问题相关,若相关则回答,否则说明无法回答”。
- 迭代优化提示
- 测试与反馈:构建验证集(包含典型问题、困难情况),测试提示效果,根据失败案例调整措辞。
- 版本控制:记录不同提示版本的效果,逐步优化。
- A/B 测试:在真实场景中对比不同提示的业务指标(如用户满意度)。
三、高级技巧
- 动态提示调整
- 根据检索结果的置信度或数量调整提示。例如,当检索到高相似度的文档时,可允许更直接的引用;当文档质量低时,要求模型更谨慎。
- 如果检索结果为空,可切换到备选提示(如“未找到相关资料,请基于自身知识回答,但需声明”)。
- 提示链(Prompt Chaining)
将复杂任务拆解为多个步骤,每一步都有专门的提示:
- 步骤1:用“请总结以下资料的关键点”提取核心信息。
- 步骤2:将总结与用户问题结合,生成最终答案。 这有助于减少上下文长度,提高处理复杂信息的质量。
- 对抗幻觉提示
- 要求模型“引用原文片段”或“提供依据”。例如“请从资料中摘录支持你回答的句子”。
- 如果答案需要计算或推理,可要求“一步步思考”并展示过程,便于追踪。
- 多语言与本地化
- 如果涉及多语言,明确指定输出语言,例如“请用中文回答,即使用户问题是英文”。
四、实践心得
- 简洁清晰胜于复杂:冗长的提示可能让模型丢失重点,关键指令应放在显眼位置(如开头)。
- 反复迭代是常态:没有一劳永逸的提示,随着应用场景和数据变化,提示需要持续优化。
- 注意 token 开销:提示本身会消耗 token,需平衡效果与成本。精简提示、删除冗余历史。
- 利用系统消息:在支持角色设定的平台(如 OpenAI 的 Chat Completions API),将固定指令放入 system 消息,用户问题放入 user 消息,对话历史保持独立。
- 监控与日志:记录每次使用的提示和输出,便于后续分析和改进。
五、示例对比 不好的提示:
根据资料回答问题:{资料} 问题:{问题}
- 缺乏角色设定,无格式约束,未处理信息不足情况。
好的提示:
你是一位严谨的问答助手。请严格根据以下资料回答用户问题。
资料用 <context> 包裹。
<context>
{检索到的文本块}
</context>
如果资料中无法找到答案,请回答“根据现有资料无法回答”。请用简洁的语句回答,不要添加额外信息。
问题:{用户问题}
回答:
通过精心设计提示,RAG 系统能够更稳定地输出高质量、可信任的答案,显著提升用户体验。
【问题】 什么是 Advanced RAG?什么是 Modular RAG?
【答案】 Advanced RAG(高级检索增强生成)和 Modular RAG(模块化检索增强生成)代表了 RAG 技术演进中的两个关键阶段,它们在设计理念、复杂度和解决的问题上存在本质区别。
一、Advanced RAG Advanced RAG 是在 Naive RAG(朴素 RAG)基础之上,通过在检索前、检索中、检索后三个核心环节引入精细化优化策略,对原有线性流程进行纵向深化和环节优化的增强版本。其核心目标是在不改变基础流程的前提下,系统性地提升检索精度和生成质量。
主要优化环节:
- 检索前优化:
- 查询改写:将模糊或不完整的用户问题改写为更利于检索的语义形式。
- 索引优化:改进文档切分策略(如滑动窗口、元数据标注),或使用假设性问题生成(HyDE)来增强索引。
- 检索中优化:
- 多路召回:同时使用向量检索、关键词检索(如 BM25)或知识图谱检索,融合多种结果提升召回率。
- 检索后优化:
- 重排序:用交叉编码器(Cross-Encoder)对召回文档进行二次排序,过滤噪声。
- 提示压缩:精简合并文档内容,缩短上下文长度,让大模型聚焦关键信息。
二、Modular RAG Modular RAG 是 RAG 技术演进的更高级阶段,其核心理念是横向重构和范式突破。它将 RAG 系统拆解为一系列独立、可替换的模块(如索引模块、检索模块、记忆模块、路由模块、融合模块、生成模块等),并引入灵活的编排机制,使得系统不再局限于线性的“检索-生成”流水线。
核心特点:
- 组件解耦:模块像乐高积木一样,可以被自由插入、替换和复用,降低系统耦合度。
- 灵活编排:支持复杂的执行流程,包括:
- 线性编排:即传统流水线。
- 条件编排:根据查询类型动态选择处理路径。
- 循环/递归编排:支持多轮检索、复杂问题分解再聚合,为 Agentic RAG 奠定基础。
三、核心区别对比
| 维度 | Advanced RAG | Modular RAG |
|---|---|---|
| 核心思想 | 在固定流程上优化各个环节 | 将系统拆分为独立模块,并动态编排 |
| 架构形态 | 增强的流水线 | 灵活的流程图(支持条件、循环、递归) |
| 模块关系 | 紧耦合,优化可能影响整体 | 松耦合,模块独立可插拔 |
| 关注焦点 | 如何更好地完成“检索-生成” | 如何更灵活地组合能力解决问题 |
【大白话解释】
- Naive RAG:就像最基础的快餐店,流程固定(点餐-后厨-取餐),动作快,但只能提供简单套餐。
- Advanced RAG:还是那家快餐店,但流程得到深度优化:门口有智能点餐机(检索前优化),后厨用更新鲜的食材(检索中优化),出餐前服务员帮你挑掉多余的薯条(检索后优化)。效率和质量都提升了。
- Modular RAG:快餐店彻底变了,变成高度灵活的厨房。它把做菜拆成煮面机、炸薯条机、做汉堡台、饮料机等独立模块。没有固定菜单,而是根据顾客需求灵活组合:想吃辣的,先启动“辣椒筛选模块”,再决定做汉堡还是面条(条件编排)。点了一份复杂大餐,它可能需要煮面和炸薯条同时进行(并行编排)。
【扩展知识点详解】
- 演进关系:Advanced RAG 是在原有线性架构上的“加法”,而 Modular RAG 是架构层面的“重构”。后者可以包含前者的所有优化模块,但以更灵活的方式编排。
- 与 Agentic RAG 的关系:Modular RAG 的灵活编排能力(如条件、循环)为构建能够自主决策的 Agentic RAG 系统提供了架构基础。当模块中加入“推理”、“规划”、“工具使用”等能力时,系统便向智能体化演进。
- 选型建议:
- 如果业务场景相对固定,需求是提升现有流水线的精度,Advanced RAG 是更直接、成本更低的选择。
- 如果面临复杂多变的查询类型,需要系统具备动态适应能力和流程控制,或计划构建智能体系统,Modular RAG 提供了必要的架构灵活性。
A2A协议
【问题】 什么是A2A协议?A2A协议有哪五大设计原则?A2A协议的工作原理是怎样的?
【参考答案】 一、什么是A2A协议? A2A(Agent2Agent)协议是谷歌于2025年4月提出并开源的一项智能体互操作协议。它旨在为不同框架、不同供应商构建的AI智能体提供一种“通用语言”,使它们能够无缝地发现彼此、进行通信与协作,共同完成复杂任务。A2A协议专注于智能体之间的应用层协作,与专注于智能体与工具/数据连接的MCP(模型上下文协议)形成互补关系。
二、A2A协议的五大设计原则 谷歌在设计A2A协议时,遵循了以下五个关键原则:
-
拥抱智能体能力(Embrace agentic capabilities)
协议允许智能体以自然、非结构化的方式进行协作,即使它们不共享内存、工具或上下文信息。这保证了智能体的自主性,使它们能够在分布式环境中作为对等主体独立运行与交互,而非仅仅作为工具。 -
基于现有标准构建(Build on existing standards)
A2A建立在HTTP、SSE(服务器发送事件)和JSON-RPC 2.0等广泛使用的Web标准之上。这使得该协议易于与企业现有的IT堆栈集成,降低了开发和部署的复杂度。 -
默认安全(Secure by default)
协议在设计之初就内置了企业级的身份验证和授权机制,其安全性与OpenAPI规范对等。它支持OAuth 2.0、API密钥等多种认证方式,确保跨智能体的通信和数据交换在安全可控的环境下进行。 -
支持长时间运行的任务(Support for long-running tasks)
A2A不仅能处理快速响应的任务,还能灵活支持需要数小时甚至数天才能完成的复杂工作流。在执行过程中,协议支持通过SSE或Webhook等方式向客户端提供实时的反馈、通知和状态更新。 -
模态无关(Modality agnostic)
协议的核心通信单元——消息(Message)和部件(Part),支持多种内容类型,包括文本、结构化JSON数据、图像、音频和视频流等。这使得智能体能够根据业务需要协商并交换任何格式的信息。
三、A2A协议的工作原理 A2A协议采用客户端-服务器(Client-Server) 的架构模型,通过定义几个核心组件来实现智能体间的互操作。
- 核心组件
- 智能体卡(Agent Card):一个托管在
/.well-known/agent-card.json路径下的JSON文件,用于描述智能体的“身份和能力”。它包含了智能体的名称、功能描述、服务端点URL、支持的技能以及身份验证要求等信息。 - 任务(Task):表示完成一次客户端请求所需的工作单元。每个任务拥有唯一的ID,并经历一个完整的生命周期,包含
submitted(已提交)、working(工作中)、input-required(需要输入)、completed(完成)和failed(失败)等状态。 - 消息(Message):智能体间交流的基本单位,代表一次交互中的单次“对话回合”。消息包含一个或多个部件(Part),用于传递上下文、指令或回复。
- 工件(Artifact):远程智能体在完成任务过程中生成的有形产出物,例如一份文档、一张图片、一个JSON数据包等。
- 智能体卡(Agent Card):一个托管在
- 交互流程 A2A协议的工作流程主要分为三个步骤:
- 第一步:能力发现:当客户端智能体接收到用户或其他智能体的请求后,会启动发现过程。它通过HTTP获取其他智能体的Agent Card,解析其中的元数据,以确定哪个远程智能体最适合执行当前的任务。
- 第二步:身份验证:客户端智能体根据选中的远程智能体在Agent Card中声明的安全方案(如OAuth 2.0),完成身份验证。验证成功后,方可建立安全的通信链路。
- 第三步:通信与协作:客户端智能体向已验证的远程智能体发送一个任务(Task)。双方通过基于JSON-RPC 2.0格式的消息(Message)进行交互。对于简单的快速任务,可以使用同步请求;对于复杂的、需长时间运行的任务,则可通过
tasks/sendSubscribe方法建立流式连接,利用SSE接收任务的实时状态更新。当任务完成时,远程智能体会将生成的工件(Artifact)返回给客户端。
【大白话解释】 可以把A2A协议想象成外交官的通用礼仪手册。来自不同国家(不同厂商或框架)的外交官(AI智能体)虽然语言和办事风格不同,但只要他们遵循同一本手册(A2A协议),就能交换名片(智能体卡)、确认身份(身份验证),然后通过翻译(JSON-RPC消息)就具体议题(任务)展开谈判和协作,最终共同发布一份联合声明(工件)。整个沟通过程无需透露各自国家内部的机密信息(不共享内部状态),高效且安全。
【扩展知识点详解】
- 与MCP的关系:MCP(模型上下文协议)解决了智能体“如何连接和使用工具”的问题,而A2A解决了“智能体之间如何对话”的问题。两者是互补而非竞争的关系,常被用于构建一个完整的智能体系统。
- 核心价值:A2A通过标准化通信,打破了AI生态的“孤岛效应”,使得企业可以通过部署专业的、跨平台的多智能体团队来处理复杂的工作流,而不必担心底层实现差异。
- 开源与社区:该协议由谷歌发起,并于2025年6月捐赠给Linux基金会托管,旨在通过开放协作推动其成为智能体交互领域的通用标准。
LangChain
【问题】 什么是 LangChain?LangChain 的核心组件有哪些?LangChain核心架构是什么样的?什么是 LangChain model?什么是 LangChain Agent?
【答案】 一、什么是 LangChain? LangChain 是一个开源的框架,旨在简化基于大型语言模型(LLM)的应用程序开发。它充当着 LLM 与外部数据源、API 及各类工具之间的“桥梁”或“基础设施”,使开发者能够构建出不仅限于单一对话,而是具备上下文感知、实时数据交互和复杂任务处理能力的 AI 应用。
二、LangChain 的核心组件 LangChain 围绕多个模块化概念构建,其核心组件主要包括:
- 模型 I/O:标准化 LLM 的交互接口,包括与各类 LLM、聊天模型和嵌入模型的集成,以及提示模板和输出解析器。
- 数据增强(索引):用于处理自有数据,包括文档加载器、文本分割器、向量存储和检索器,是实现 RAG 的基础。
- 链(Chains):将多个步骤(如模型调用、数据处理)组合成一个可复用的工作流,是构建复杂应用的核心。
- 记忆(Memory):为无状态的 LLM 提供持久化状态的能力,使对话或应用能够记住历史交互。
- 代理(Agents):利用 LLM 作为推理引擎,动态决策要采取的一系列行动,并调用相应的工具来达成目标。
- 回调处理器:提供全链路的监控、日志记录和调试能力。
三、LangChain 核心架构
LangChain 的核心架构是一种松耦合、可组合的设计。各组件通过标准接口相互协作。现代 LangChain 推荐使用 LCEL(LangChain Expression Language,表达式语言) 来构建应用,它使用 | 管道符将不同的组件(如提示模板、模型、输出解析器)连接成一个端到端的流水线,前一步的输出自动成为下一步的输入,使代码简洁且易于扩展。架构的核心是围绕“链”来组织工作流,而 Agent 则作为一种特殊的、能够动态决策的链,可以调用其他所有模块的功能。
四、什么是 LangChain Model? 在 LangChain 中,Model 指的是与各种语言模型交互的标准接口和集成模块。LangChain 本身不提供模型,而是为两种主要类型的模型提供了统一的抽象:
- LLMs(大型语言模型):接收一个文本字符串作为输入,并返回一个文本字符串作为输出(如 GPT-3)。
- 聊天模型(Chat Models):由 LLM 支持,但专门针对对话调优。它们接收一个聊天消息列表(通常带有“系统”、“AI”、“人类”等标签)作为输入,并返回一个 AI 聊天消息作为输出(如 GPT-4、Claude)。 通过这个统一的模型接口,开发者可以在应用中轻松切换不同的模型提供商(如 OpenAI、Anthropic、Google 等)或模型类型,而无需大幅改动核心业务逻辑。
五、什么是 LangChain Agent? LangChain Agent(代理)是一个使用 LLM 作为“大脑”或“推理引擎”的决策组件。它不遵循固定的执行序列,而是能够动态地根据用户输入和当前状态,决定需要执行哪些操作(例如调用搜索引擎、运行代码、查询数据库),并按照什么顺序执行,直到完成任务。
Agent 的核心工作流程通常遵循 ReAct(Reasoning + Acting,推理与行动) 模式:
- 推理(Reason):LLM 分析用户问题,思考为了解决问题需要做什么。
- 行动(Act):调用一个或多个选择的工具(Tools)并获取观察结果。
- 循环:将观察结果反馈给 LLM,让它进行下一步推理,直到能生成最终答案。
因此,Agent 赋予了 LLM 与外部世界交互和解决复杂、多步骤问题的能力。
【大白话解释】
- LangChain:就像一个乐高积木箱,里面装着各种标准化的积木块(组件)。它让你可以轻松地把大模型这颗“智慧大脑”和网络搜索、数据库这些“手和脚”拼接起来,搭建出复杂的机器人应用。
- 核心组件:就是不同类型的积木块。
- Model:就是框架里预留的“接口槽”,你可以把 OpenAI 的 GPT、Google 的 Gemini 等不同品牌的大脑插进去用,接口都一样,拔下来换个新的也能马上工作。
- Agent:就像一个外包项目经理。你给他一个任务(“组织一场聚会”),他先思考(推理)需要做什么:先找场地、再定菜单。然后他去执行这些行动(调用工具),看看结果(“场地A没档期”),再重新思考下一步(“那试试场地B”),直到任务完成为止。
【扩展知识点详解】
- LCEL(LangChain Expression Language):LangChain 表达式语言是现代 LangChain 的核心,它通过
|操作符将各种“可运行”组件(Runnable)串联起来,构建出清晰的数据处理流水线,取代了早期复杂的LLMChain类。 - Tool(工具):Agent 可以调用的外部功能模块,如搜索引擎、计算器、API 接口或自定义函数。工具需要有清晰的名称、描述和输入参数定义,以便 LLM 理解何时以及如何使用它。
- Memory 的类型:除了简单的缓存(
ConversationBufferMemory),还有ConversationSummaryMemory(总结历史)、EntityMemory(存储特定实体信息)等,以满足不同场景的上下文需求。 - Chain vs Agent:
- Chain:适合执行确定性的、步骤固定的工作流,比如“先总结文本,再把总结翻译成英文”。
- Agent:适合执行不确定的、需要动态决策的任务,比如“帮我研究一下这个领域的最新论文,并写一份报告”,具体要搜几次、搜什么,需要 Agent 自己决定。
- Agent 的局限性:依赖 LLM 的推理能力,可能产生错误决策(如陷入循环、调用错误工具)。因此,在设计 Agent 时需要仔细定义提示词和工具描述,并可能需要引入人工确认(Human-in-the-loop)机制。
【问题】 LlamaIndex 如何与 LangChain 结合?
【答案】 LlamaIndex 和 LangChain 是两个功能强大但侧重点不同的 LLM 应用框架。LlamaIndex 专注于以数据为中心,提供高质量的索引、检索和查询引擎;LangChain 专注于以编排为中心,提供灵活的链、代理和工具调用能力。两者并非互斥,而是可以深度结合,发挥各自优势。
LlamaIndex 官方提供了与 LangChain 的集成方案,主要通过两种方式实现结合:
一、将 LlamaIndex 作为 LangChain 的工具
LlamaIndex 可以将自身的查询引擎(Query Engine)包装成 LangChain 可以调用的 Tool(工具),供 LangChain 的 Agent 或 Chain 使用。这样,LangChain 负责复杂的决策和流程编排,LlamaIndex 负责精准的文档检索。
实现方式:
from llama_index.langchain_helpers.agents import IndexToolConfig, LlamaIndexTool
# 创建 LlamaIndex 查询引擎
query_engine = index.as_query_engine()
# 配置工具
tool_config = IndexToolConfig(
query_engine=query_engine,
name="文档检索工具",
description="当用户询问关于技术文档的问题时使用",
tool_kwargs={"return_direct": True}
)
# 创建 LangChain 工具
tool = LlamaIndexTool.from_tool_config(tool_config)
创建后的工具可以直接集成到 LangChain 的 Agent 中。
二、使用 LangChain 编排 LlamaIndex 的检索能力
LlamaIndex 提供了 LlamaToolkit 和内置的代理创建函数,可以直接创建基于 LangChain 的聊天代理,将 LlamaIndex 的检索能力无缝嵌入 LangChain 的工作流中。
实现方式:
from llama_index.langchain_helpers.agents import LlamaToolkit, create_llama_chat_agent
# 创建工具包
toolkit = LlamaToolkit(index_configs=[tool_config])
# 创建基于 LangChain 的聊天代理
agent_chain = create_llama_chat_agent(
toolkit=toolkit,
llm=llm,
memory=memory,
verbose=True
)
# 执行查询
agent_chain.run(input="请帮我查找去年的财报")
这种方式让开发者既能享受 LlamaIndex 强大的检索能力,又能利用 LangChain 的记忆、工具调用和多轮对话管理功能。
三、混合架构的最佳实践
在实际生产环境中,许多团队采用混合架构:用 LlamaIndex 处理数据摄取、分块、索引和检索,将检索结果作为上下文,交给 LangChain 的代理进行后续的工具调用、多步推理和答案生成。这种架构实现了“检索优先”与“编排优先”的有机结合。
概念示例:
# LlamaIndex 负责检索
from llama_index import VectorStoreIndex
index = VectorStoreIndex.from_documents(docs)
query_engine = index.as_query_engine(similarity_top_k=5)
# 包装为 LangChain 工具
from langchain.tools import Tool
llama_tool = Tool(
name="知识库检索",
func=lambda q: query_engine.query(q).response,
description="当需要查询内部知识库时使用"
)
# LangChain 代理负责决策和编排
from langchain.agents import initialize_agent
agent = initialize_agent(
tools=[llama_tool, other_tools],
llm=llm,
agent="zero-shot-react-description"
)
【大白话解释】 LlamaIndex 和 LangChain 就像一支“超级团队”里的两个专家:
- LlamaIndex 是档案管理员,他精通如何把海量文档整理得井井有条(索引),并且能快速找出最相关的那几页(检索)。
- LangChain 是项目经理,他擅长规划流程、调用各种工具(比如搜索、计算器、API),还能记住对话历史。
让这两位专家合作的方法有两种:
- 档案管理员给项目经理当助手:项目经理遇到需要查资料的任务,就派档案管理员去查,查完把结果交回来。项目经理继续做其他决策。
- 让项目经理直接指挥档案管理员:用一个“指挥中心”(
create_llama_chat_agent)把两位专家的工作流打通,档案管理员查资料,项目经理安排对话流程,配合得天衣无缝。
【扩展知识点详解】
- 设计哲学差异:LlamaIndex 是以数据为中心,LangChain 是以编排为中心。LlamaIndex 提供开箱即用的高质量检索默认设置,而 LangChain 提供高度可定制的链和代理。
- 集成层级:集成不仅限于工具层,还包括内存模块——LlamaIndex 可以作为 LangChain 的内存组件,存储和检索对话历史。
- 适用场景判断:
- 检索质量是核心 KPI、需要处理复杂文档结构 → 以 LlamaIndex 为主
- 需要多工具调用、复杂代理决策、跨系统集成 → 以 LangChain 为主
- 两者兼有 → 采用混合架构
- 官方教程资源:LlamaIndex 官方提供了完整的 notebook 教程,演示如何结合两者的 Tool 和 Memory 模块构建聊天代理。
- 性能与成本:LlamaIndex 通过精准检索减少不相关上下文的 token 消耗;LangChain 通过模块化设计控制工具调用次数,两者结合可实现成本与效果的平衡。
- 注意事项:混合使用时需清晰划分职责,避免“意大利面式”的混乱流程,建议将 LlamaIndex 限定在检索层,将 LangChain 限定在编排层。
ReAct
【问题】 ReAct 是什么?它的原理是什么?
【答案】 一、什么是 ReAct? ReAct 是一种用于构建智能代理(Agent)的提示工程框架,由 Shunyu Yao 等人在 2022 年的论文《ReAct: Synergizing Reasoning and Acting in Language Models》中提出。其名称来源于 Reasoning(推理)和 Acting(行动)的组合。ReAct 的核心思想是让大语言模型在解决问题的过程中,交替生成推理轨迹(Thought)和行动指令(Action),并从外部环境(如工具、知识库)获取观察结果(Observation),形成 Thought → Action → Observation 的循环,直到得出最终答案。
二、ReAct 的原理是什么? ReAct 的原理基于对人类解决问题方式的模拟:人在解决复杂问题时,通常会先思考当前情况(推理),然后采取行动(如查阅资料、计算),观察行动结果,再根据新信息继续思考,如此反复。在 ReAct 框架中,语言模型被赋予一个循环,其核心流程如下:
- 思考(Thought):模型分析当前状态,推理接下来需要做什么,并解释为什么。这一步是内部推理,不涉及外部调用。
- 行动(Action):基于思考,模型生成一个具体的指令,通常是要调用的工具名称和参数。例如,调用搜索引擎、执行代码、查询数据库等。行动需要与环境交互。
- 观察(Observation):执行行动后,外部环境返回结果,作为新的输入反馈给模型。
- 重复循环:模型将观察结果作为新信息,继续生成思考,再次行动,如此反复,直到推理认为任务完成,生成最终答案(通常是“最终答案:…”)。
这个循环在提示词中被显式地规定,通常通过少样本示例(few-shot examples)来引导模型学习这种交互模式。提示中会给出几个完整的“思考-行动-观察”示例,然后让模型按照相同格式对新问题生成推理和行动。
三、ReAct 的优势
- 增强解决问题的能力:通过结合推理和行动,模型可以动态调整计划,应对复杂、多步骤的任务。
- 可解释性:推理轨迹(Thought)提供了模型决策的中间步骤,使人类能够理解其思考过程,便于调试和验证。
- 鲁棒性:模型可以通过观察结果纠正错误推理,例如,如果第一次行动结果不理想,可以在后续思考中调整策略。
- 减少幻觉:通过与外部真实数据交互,模型的回答可以基于事实,而不是单纯依赖内部参数知识。
【大白话解释】 ReAct 就像一个侦探破案的过程:
- 思考:侦探根据已有线索(当前状态)推理:“凶手可能使用了凶器,我需要去查一下凶器上的指纹。”(推理下一步)
- 行动:侦探发出指令:“小李,去把凶器送到实验室检测指纹。”(调用工具)
- 观察:实验室返回结果:“凶器上发现了张三的指纹。”(观察结果)
- 再思考:侦探继续推理:“张三有指纹,但他有不在场证明,也许指纹是之前留下的?我需要查一下张三的通话记录。”…… 这个循环一直持续,直到侦探收集足够证据,得出最终结论(最终答案)。
【扩展知识点详解】
- ReAct 与 Chain-of-Thought(CoT)的区别:
- CoT 只关注推理路径,模型通过一系列中间推理步骤得出结论,但不与外部环境交互。它适用于需要逻辑推导但无需外部信息的任务。
- ReAct 不仅包含推理,还包含行动和观察,使模型能够获取外部信息、执行工具,适用于需要与环境交互的复杂任务。ReAct 可以看作是 CoT 的扩展,增加了行动能力。
- ReAct 在 LangChain 中的实现:
- LangChain 提供了
create_react_agent函数,用于快速构建基于 ReAct 模式的代理。开发者只需定义工具列表,框架会自动生成相应的 ReAct 提示,并管理 Thought-Action-Observation 循环。 - 在 LangGraph 中,ReAct 可以被实现为一个包含循环的图,节点分别代表思考、行动和观察,通过条件边控制循环继续或终止。
- LangChain 提供了
- 提示设计的关键点:
- 格式约束:必须明确指定输出格式,例如用
Thought:、Action:、Observation:、Final Answer:等标签分隔不同部分。 - 少样本示例:提供 2-3 个完整的示例,涵盖不同类型的问题,帮助模型理解模式。
- 工具描述:每个工具需要提供清晰的名称、描述和参数说明,以便模型在行动时正确选择。
- 格式约束:必须明确指定输出格式,例如用
- 变体和改进:
- ReAct + 记忆:在循环中加入短期记忆,保存历史交互,使模型能参考之前的步骤。
- Self-Ask:另一种代理模式,通过“我需要问什么?”来递归分解问题,与 ReAct 互补。
- Plan-and-Execute:先规划多个步骤,再逐步执行,与 ReAct 的动态决策不同。
- 局限性:
- 推理开销:每次循环都调用 LLM,可能增加延迟和成本。
- 错误累积:如果模型在某次推理或行动中出错,可能导致后续步骤全部偏离,需要设计回退机制。
- 工具依赖:ReAct 的效果高度依赖工具的质量和模型对工具的理解能力。
ReAct 已成为现代代理系统的基础模式,被广泛应用于需要多步推理和工具调用的场景,如个人助理、数据分析、自动化工作流等。
LangGraph
【问题】 什么是 LangGraph ?LangGraph 编排的原理是什么?LangChain 和 LangGraph 有什么区别?
【答案】 一、什么是 LangGraph? LangGraph 是一个构建在 LangChain 之上的低级编排框架,专门用于创建有状态、循环、多分支的复杂代理工作流。它将代理系统建模为图结构,其中节点(Nodes)表示执行单元(如 LLM 调用、工具使用、函数),边(Edges)表示控制流逻辑,而一个共享的状态(State)对象贯穿整个执行过程。
LangGraph 的核心价值在于为开发者提供了对代理行为的细粒度控制,支持持久执行、人机协作、检查点恢复等生产级特性,特别适合构建需要长期运行、复杂决策和可靠性的应用。
二、LangGraph 编排的原理是什么? LangGraph 的编排基于图运行时(Graph Runtime)和状态机(State Machine)模型,其核心机制可以概括为三个关键组件和一种执行模式:
- 三大核心组件:
- State(状态):一个在图中共享的数据结构(通常是
TypedDict或 Pydantic 模型),代表了应用程序的“当前快照”。图执行的每一步都会读取并更新这个状态。每个状态字段都可以配置归约器(Reducer),以定义当多个节点更新同一字段时如何合并(例如,是覆盖还是累加)。 - Nodes(节点):编码实际业务逻辑的 Python 函数。它们接收当前的
State作为输入,执行计算或调用外部工具,然后返回一个更新后的State或部分更新。 - Edges(边):决定控制流逻辑的 Python 函数。它们根据当前的
State来决定下一步该执行哪个节点。边可以是固定的(总是从 A 到 B),也可以是条件边,即根据状态内容动态选择后续路径。
- State(状态):一个在图中共享的数据结构(通常是
- 执行模式:超步(Super-step):
LangGraph 的执行受 Google Pregel 系统的启发,以离散的“超步”为单位进行。
- 超步:一个超步可以理解为图的一次迭代。在同一个超步中,所有可以并行执行的节点(即它们的输入都已就绪)会被同时触发。
- 消息传递:当一个节点完成执行后,它会通过边将更新后的状态作为“消息”传递给下游节点,激活下一个超步的执行。这个过程循环往复,直到没有节点需要执行且没有消息在传递时,整个图执行才终止。
简而言之:开发者通过状态、节点、边定义好一个有向图,LangGraph 的运行时负责在超步中驱动这个图,自动管理状态流转和并发执行,从而实现复杂、可控的代理工作流。
三、LangChain 和 LangGraph 有什么区别? LangChain 和 LangGraph 并非替代关系,而是面向不同复杂度的互补工具。LangChain 提供构建模块和线性编排,LangGraph 则在它之上提供了强大的图式控制能力。两者的核心区别对比如下:
| 对比维度 | LangChain | LangGraph |
|---|---|---|
| 核心抽象 | 链(Chain)和 LCEL 管道,通常用于构建线性的、步骤固定的工作流。 | 有状态图(StateGraph),用于构建有循环、分支和复杂依赖的非线性工作流。 |
| 状态管理 | 通过 Memory 组件传递上下文,适用于简单的会话历史记录。 | 一等公民的类型化状态。状态在整个图中显式定义、传递和持久化,并通过归约器进行细粒度更新。 |
| 控制流 | 以线性管道为主,条件分支通过 RunnableBranch 等方式实现,循环支持有限。 |
原生支持循环、分支、分叉、合并、递归等任意复杂度的控制流,通过节点和边显式定义。 |
| 设计目标 | 速度和易用性。提供大量集成和预制组件,适合快速构建原型和标准模式(如 RAG、简单对话)。 | 控制和可靠性。提供细粒度、确定性的流程控制,适合构建复杂的、长期运行的生产级代理系统。 |
| 持久化/容错 | 无内置持久化,需要开发者自行实现。 | 内置检查点(Checkpoint) 机制,支持在故障后从最近的状态恢复执行,实现持久运行。 |
| 学习曲线 | 相对平缓,有丰富的文档和社区示例,上手快。 | 相对陡峭,需要理解图、状态、节点、边等抽象概念,以及如何进行状态建模。 |
| 最新演进 | 从 LangChain 1.0 开始,其 create_agent 等高层抽象在底层已运行在 LangGraph 运行时之上。 |
作为 LangChain 生态的执行引擎,提供底层控制能力,并已发布稳定版 v1.0。 |
【大白话解释】
- LangChain:就像一个预制菜料理包。你按照说明书把各种食材(组件)丢进去,它很快就能帮你做出一盘菜。特别适合你急着吃饭(快速原型)或者做家常菜(标准 RAG 流程)的场景。
- LangGraph:则像一个专业厨房的烹饪流程图。厨师长(开发者)先画好流程图:切菜→备料→看情况(如果客人不吃辣,则跳过加辣步骤)→起锅烧油→装盘。每一步(节点)做什么、做完下一步去哪(边),都写得清清楚楚。整个厨房都盯着一个订单小票(状态) 做菜,确保不会出错。这适合做需要精心烹制的米其林大餐(复杂的生产级 Agent)。
【扩展知识点详解】
- 关系演进:两者并非二选一。LangGraph v1 发布后,LangChain 的许多高层 Agent 抽象(如
create_react_agent)已经默认运行在 LangGraph 运行时之上,形成了 LangChain 提供组件,LangGraph 负责编排的技术栈分层。 - 状态归约器:LangGraph 的
reducer是一个关键设计。例如,如果多个节点都要往“对话历史”这个状态里追加消息,你可以指定operator.add作为归约器,它会自动将所有消息合并成一个列表,而不是后一个覆盖前一个。 - 人机交互(Human-in-the-loop):LangGraph 原生支持在工作流中设置断点或“中断节点”,当执行到该节点时,可以暂停下来,等待人工审核和输入后再继续,这对于需要审批的流程(如金融交易、内容审核)至关重要。
- 适用场景速判:
- 你的任务是线性的,比如“查文档 -> 生成摘要”?选 LangChain。
- 你的代理需要思考、行动、观察、再思考(ReAct 循环),可能需要根据情况调用不同工具,甚至需要人工介入?选 LangGraph。
向量数据库
【问题】 什么是向量数据库?向量数据库主要解决什么问题?向量数据库原理是什么?常用的向量数据库有哪几个?如何选型?他们默认的向量搜索算法分别是什么?有什么优势?
【答案】 一、什么是向量数据库? 向量数据库是一种专门用于存储、管理和检索高维向量数据的数据库系统。它将文本、图像、音频等非结构化数据通过嵌入模型(Embedding Model)转换为向量形式(即一系列浮点数),并基于向量之间的空间距离实现语义相似性搜索,而非传统数据库的关键词精确匹配。
二、向量数据库主要解决什么问题?
- 语义检索问题:传统数据库依赖关键词匹配,无法理解“意思”。向量数据库通过相似度计算,能检索出语义相关而非仅关键词匹配的内容。
- 非结构化数据利用:企业超过80%的数据是非结构化的(文本、图片、视频等),向量数据库使其能被AI系统有效处理。
- 大模型外部记忆:作为RAG架构的核心组件,为大模型提供最新、专业的知识,减少“幻觉”。
- 多模态搜索:支持文本搜图、以图搜图等跨模态检索场景。
三、向量数据库原理是什么? 其核心机制围绕三个关键环节:
- 向量化(Embedding):通过嵌入模型将原始数据转换为高维向量,语义相近的对象在向量空间中也相互靠近。
- 索引构建:采用近似最近邻(ANN) 算法建立索引,避免暴力扫描。常用算法包括:
- HNSW(分层可导航小世界):构建多层图结构,上层快速跳转,下层精准定位,时间复杂度O(log N)。
- IVF(倒排文件):通过K-Means聚类划分空间,搜索仅在最近簇中进行。
- PQ(乘积量化):压缩向量以减少内存占用。
- 相似性搜索:将查询向量化后,通过余弦相似度、欧氏距离等度量,检索最相似的Top-K个向量。
四、常用的向量数据库及默认搜索算法 | 数据库 | 默认/核心搜索算法 | 优势 | 适用场景 | |——–|——————-|——|———-| | Milvus | HNSW、IVF-PQ等可配置,支持GPU加速 | 云原生架构,可扩展性强,支持十亿级向量 | 大规模生产环境、多模态搜索 | | Qdrant | 可定制的HNSW实现,支持混合搜索 | Rust编写,高性能,支持高级过滤和ACID事务 | 实时应用、边缘计算(Qdrant Edge) | | Weaviate | HNSW | GraphQL API,与知识图谱结合,开源 | 混合搜索、多模态用例 | | Pinecone | 托管服务,内部优化算法 | 全托管Serverless,免运维,生态集成完善 | 快速原型、轻量级生产部署 | | Chroma | HNSW、IVF等 | 轻量级开源,易于上手 | 原型设计、本地开发 | | FAISS | HNSW、IVF、PQ等(库而非数据库) | 高性能索引库,非完整数据库系统 | 静态数据的高效索引 |
五、如何选型? 选型需综合评估功能、性能、生态三个维度,并结合具体场景:
- 功能匹配:
- 多模态需求:需要同时检索文本、图像→选择支持多模态的Milvus、Weaviate。
- 混合搜索:需结合关键词和语义检索→选择支持稀疏-稠密混合的Qdrant、Pinecone。
- 高级过滤:需要复杂标量过滤→优先Qdrant、Milvus。
- 性能与规模:
- 十亿级向量、高并发:选Milvus(云原生+GPU加速)。
- 千万级以下、轻量快速:Chroma或FAISS足够。
- 边缘/嵌入式设备:Qdrant Edge专为资源受限环境设计。
- 生态与运维:
- 全托管免运维:Pinecone或云服务(如阿里云Milvus)。
- 开源、自托管、多云中立:Milvus、Qdrant、Weaviate。
- 与LangChain/LlamaIndex集成:几乎所有主流数据库均支持。
- 数据规模拐点:低于100万向量,pgvector等扩展可能更简单;超过1000万向量,专用向量数据库优势明显。
六、不同算法的优势
- HNSW:召回率和性能的最佳平衡,大多数现代数据库的首选。
- IVF:内存占用可控,适合超大集群的粗粒度分区。
- PQ:极致压缩向量,适合内存有限但需处理海量数据的场景。
- GPU索引:Milvus支持,满足极低延迟的在线推理需求。
【大白话解释】
- 向量数据库是什么:传统数据库像Excel表格,存的是“姓名:张三,年龄:25”这样的确定信息。向量数据库像语义地图,把“苹果”变成地图上的一个点,旁边是“水果”、“iPhone”,远离“拖拉机”。你要找“好吃的水果”,它就把离“水果”最近的点都捞出来。
- 解决什么问题:传统数据库管“是什么”(WHERE 姓名=‘张三’),向量数据库管“像什么”(找长得像这张图的图片、意思相近的文档)。
- 原理:三步走:嵌入(把东西变成向量)→索引(给向量建个快查目录)→搜索(把问题也变向量,然后在目录里找最近的)。
- 选型:就想明白三件事:多少数据(百万级随便选,亿级看Milvus)、多快响应(毫秒级要上GPU)、要人伺候不(想省心用Pinecone,想自己折腾选开源)。
【扩展知识点详解】
- 混合搜索趋势:Pinecone等引入级联搜索,先并行召回再重排序,提升结果质量。
- 边缘计算:Qdrant Edge实现设备端向量搜索,适应物联网、机器人场景。
- 与传统数据库融合:PostgreSQL(pgvector)、MongoDB(Atlas Vector Search)开始原生支持向量,适合轻量级场景。
- 性能测试工具:可用VDBBench在生产环境对比不同数据库的QPS、延迟、召回率。
- 政企需求:强调私有化部署、数据加密、审计日志,百度VectorDB等提供相应方案。
【问题】 向量数据库中的 HNSW、LSH、PQ 分别是什么意思?
【答案】 HNSW、LSH 和 PQ 是向量数据库中用于加速近似最近邻(ANN)搜索的三种核心算法或索引技术。它们各有不同的原理和适用场景,旨在解决高维向量空间下暴力搜索效率低下的问题。
一、HNSW(Hierarchical Navigable Small World,分层可导航小世界)
- 全称:Hierarchical Navigable Small World
- 原理:基于图结构的多层索引。它构建了一个多层图,上层图稀疏,连接距离较远的节点(用于快速跳转),下层图稠密,连接相近的节点(用于精细搜索)。搜索时从顶层开始,沿最接近目标的路径向下层移动,最终在底层找到最近邻。
- 特点:
- 优点:搜索精度高、速度快(时间复杂度接近对数级),是目前最流行的 ANN 算法之一。
- 缺点:内存占用较大,构建索引时间较长。
- 应用:广泛应用于 Milvus、Weaviate、Qdrant 等向量数据库,作为默认或核心算法。
二、LSH(Locality-Sensitive Hashing,局部敏感哈希)
- 全称:Locality-Sensitive Hashing
- 原理:通过一组哈希函数将高维向量映射到低维哈希桶中,使得相近的向量以高概率落入同一个桶(或相近的桶)。查询时,只需在查询向量所在桶及相邻桶内进行暴力搜索。
- 特点:
- 优点:理论保证好,适用于海量数据的高维空间,支持分布式。
- 缺点:需要多张哈希表来保证召回率,导致存储和计算开销较大;对数据分布敏感。
- 应用:常用于文本去重、图像检索等场景,但在现代向量数据库中已较少作为核心索引,更多用于特定领域。
三、PQ(Product Quantization,乘积量化)
- 全称:Product Quantization
- 原理:将原始高维向量分割成多个低维子向量,对每个子空间分别进行聚类,用聚类中心索引(即码本)表示原向量。这样,向量被压缩成短码(如8字节),大幅降低内存占用。搜索时,通过计算查询向量与各子码本的距离,并查表快速估算向量间距离。
- 特点:
- 优点:极低的内存占用,适合大规模数据(十亿级以上)的存储和检索。
- 缺点:精度损失较大,需要配合倒排索引(如 IVF-PQ)使用以提升性能。
- 应用:常用于工业级大规模检索系统,如 Faiss 中的 IVF-PQ 组合。
【大白话解释】
- HNSW:想象你要在陌生的城市找一家特定餐厅。你有一张多层地图:顶层只标出主要地标,你通过顶层快速定位到餐厅所在的大致区域,然后切换到更详细的地图一层层接近,最后在街区地图上找到精确位置。HNSW 就是这种“层层递进”的导航方式,又快又准。
- LSH:好比你要从一堆书里找到内容相似的书。你先把每本书按主题(哈希)扔到不同的书架上(哈希桶)。找书时,你只查同一个书架上的书,因为相近的书大概率在同一书架。但如果书架分得不够细,你可能需要多查几个相邻书架来保证不遗漏。LSH 就是这种“分桶归类”的思想。
- PQ:想象你要给一座城市里的每一栋房子存储精确坐标,但内存有限。你决定用“坐标码本”:将城市划分成网格,每个网格有一个代表坐标。每栋房子的坐标用其所在网格的编号代替。虽然位置不那么精确了,但存储量大大减少。PQ 就是用“码本压缩”向量,牺牲精度换取内存。
【扩展知识点详解】
-
算法对比:
特性 HNSW LSH PQ 搜索速度 快(对数级) 较快(取决于哈希表) 快(需配合倒排) 内存占用 高 中等 低 召回率 高 中等 中低 构建时间 慢 快 中等 适用规模 千万级 亿级 十亿级以上 -
混合使用:实际系统中常将多种算法组合使用。例如 IVF-PQ(倒排文件+乘积量化)先用 IVF 做粗聚类,再对每个簇内的向量用 PQ 压缩,兼顾速度和内存。
- 参数调优:
- HNSW 的关键参数:
M(每个节点的最大连接数)和efConstruction(建图时的搜索范围),影响精度和内存。 - PQ 的关键参数:
m(子向量数量)和nbits(每个子码本的比特数),决定压缩率和精度。 - LSH 的关键参数:哈希表数量、每表哈希函数个数。
- HNSW 的关键参数:
- 工程实现:
- Faiss(Facebook 开源的相似性搜索库)实现了多种算法,包括 HNSW、IVF、PQ 等。
- Milvus 等向量数据库内部集成了这些算法,并提供可配置的参数。
- 选择建议:
- 对精度要求极高、数据量适中(千万级):选 HNSW。
- 数据量极大(十亿级以上)、内存有限:选 IVF-PQ。
- 需要理论保证且数据分布简单:可选 LSH,但需注意现代方案中较少单独使用。
理解这些算法有助于在向量数据库选型和调优时做出合理决策,平衡精度、速度和资源消耗。
【问题】 向量数据库中的 ANN 是什么?为什么需要用它?
【答案】 一、什么是 ANN? ANN 是 Approximate Nearest Neighbor(近似最近邻) 的缩写。它是一类用于在高维向量空间中快速查找与查询向量最相似的 K 个向量的算法和技术。与精确最近邻(KNN,K-Nearest Neighbor)不同,ANN 允许在结果中包含少量的近似误差(即返回的不一定是绝对最近的向量),以换取数量级的性能提升。
在向量数据库中,ANN 以索引的形式实现,通过对向量空间进行预处理(如构建图、聚类、量化等),将搜索时间复杂度从暴力扫描的 O(n) 降低到 O(log n) 或 O(1) 级别,从而支撑海量数据的实时检索。
二、为什么需要 ANN?
- 维度灾难与规模瓶颈:当数据量达到百万、十亿级别,且向量维度较高(如 768 维、1024 维)时,精确计算所有向量与查询的距离(暴力扫描)需要巨大的计算资源和时间,无法满足在线服务的毫秒级响应要求。
- 性能与精度的权衡:在许多实际应用(如推荐系统、语义搜索)中,用户更关注“最相关的前几条结果”,而非理论上的绝对最近邻。ANN 算法通过牺牲可接受的少量精度,将检索速度提升几个数量级,使大规模向量检索变得切实可行。
- 成本控制:ANN 索引通常对内存和计算进行了优化,允许在有限硬件资源上处理超大规模数据,降低部署成本。
- 实时性要求:现代应用需要秒级甚至毫秒级响应,ANN 索引的快速查询能力使其成为向量数据库的核心技术。
【大白话解释】
- 精确最近邻(KNN):好比你在 10 亿本书里找一本内容最像的书,你必须一本本翻开比对,虽然结果绝对准确,但等你找到时可能已经过了几天——这在现实中根本不可行。
- 近似最近邻(ANN):就像你在图书馆里有一套智能索引系统:先把书按主题分成不同区域(聚类),再在每个区域里按关键词建个小目录(索引)。你想找书时,先定位到相关区域,再在区域里快速翻找。虽然可能漏掉一两本藏在角落的书,但 99% 的情况下你能在几秒内找到最相关的几本。这种“牺牲一点准确率,换取海量速度”的做法,就是 ANN 的核心思想。
【扩展知识点详解】
-
ANN 与 KNN 的区别:
对比维度 精确最近邻 (KNN) 近似最近邻 (ANN) 结果精度 100% 准确 可容忍误差,通常召回率 >90% 时间复杂度 O(n) O(log n) 或更低 适用规模 小数据集(万级以下) 大数据集(百万至十亿级) 实现方式 暴力扫描 索引结构(图、树、哈希、量化) - 常见 ANN 算法分类:
- 基于图:如 HNSW,通过构建多层图结构实现高效导航,精度高但内存占用较大。
- 基于聚类/倒排:如 IVF,将向量聚类到多个簇,搜索时只查询最相关的几个簇。
- 基于量化:如 PQ,通过压缩向量降低内存,常与 IVF 结合(如 IVF-PQ)。
- 基于哈希:如 LSH,通过哈希函数将相似向量映射到同一桶中。
- ANN 的核心评价指标:
- 召回率(Recall):返回结果中真正最近邻所占的比例。
- 查询速度(QPS):每秒能处理的查询数量。
- 构建时间:建立索引所需的时间。
- 内存占用:索引占用的内存大小。
- 平衡点:通常需要在召回率和查询速度之间权衡。
- 在向量数据库中的应用:
- 几乎所有主流的向量数据库(如 Milvus、Qdrant、Weaviate)都在底层集成了 ANN 索引,并提供参数供用户根据业务调整(如调整 HNSW 的 efConstruction、M 值等)。
- 用户通常可以在“追求极致召回”和“追求极致速度”之间选择索引类型和参数。
- 为什么不能抛弃 ANN?:如果没有 ANN,向量数据库就无法在规模上扩展,只能局限于小数据集演示,无法支撑生产级的推荐、搜索、RAG 等核心场景。因此,ANN 是向量数据库的基石。
【问题】 向量数据库中,常见的向量搜索方法:余弦相似度、欧几里得距离和曼哈顿距离分别是什么?有什么区别?
【答案】 一、三种常见向量搜索方法
- 余弦相似度(Cosine Similarity)
- 定义:测量两个向量在方向上的相似程度,通过计算它们夹角的余弦值得到。公式为 ( \text{cosine}(A,B) = \frac{A \cdot B}{|A| |B|} )。值域为 ([-1, 1]),1 表示方向完全相同,0 表示正交,-1 表示方向相反。
- 特点:只关注方向,忽略向量长度(模长)。即使两个向量长度差异很大,只要方向一致,余弦相似度也高。
- 欧几里得距离(Euclidean Distance)
- 定义:计算两个向量在欧氏空间中的直线距离。公式为 ( |A - B| = \sqrt{\sum_{i=1}^{n}(A_i - B_i)^2} )。值域为 ([0, +\infty)),0 表示完全相同,距离越大表示越不相似。
- 特点:同时考虑向量的大小和方向,对长度敏感。常用于空间位置、物理距离等场景。
- 曼哈顿距离(Manhattan Distance)
-
定义:计算两个向量在各维度上绝对差值的和。公式为 ( \sum_{i=1}^{n} A_i - B_i )。值域同样为 ([0, +\infty))。 - 特点:相当于在网格状路径上行走的距离,对离群点相对不敏感,计算比欧氏距离简单(无需平方和开方)。
-
二、主要区别 | 对比维度 | 余弦相似度 | 欧几里得距离 | 曼哈顿距离 | |———|————|————–|————| | 几何意义 | 向量夹角 | 直线距离 | 轴对齐的折线距离 | | 对向量大小的敏感性 | 不敏感(忽略模长) | 敏感 | 敏感 | | 值域 | [-1, 1] | [0, +∞) | [0, +∞) | | 计算复杂度 | 需计算点积和模长 | 需计算平方差和开方 | 只需绝对值求和 | | 适用场景 | 文本相似度、语义匹配(如词向量) | 图像特征、物理位置、聚类 | 稀疏向量、高维数据(如某些推荐系统) | | 对异常值的鲁棒性 | 较高 | 较低(平方放大差异) | 较高 |
三、选择建议
- 当数据经过归一化(单位长度)后,余弦相似度与欧氏距离等价(因为 ( |A-B|^2 = 2(1 - \cos\theta) ))。此时二者可互相转换。
- 若向量模长包含重要信息(如词频),用欧氏距离更合适。
- 若数据稀疏或维度极高,曼哈顿距离可能更稳定。
【大白话解释】
- 余弦相似度:好比判断两个人“志向”是否相同,不管他们身高体重(向量长度)差多少,只要方向一致,就认为相似。例如,“苹果”和“香蕉”在语义空间中方向接近,即使“苹果”的向量长度(如出现频率)比“香蕉”大,余弦相似度仍能捕捉到它们是水果。
- 欧几里得距离:好比测量两个点在地图上的直线距离。如果你关心的是“绝对位置”(如用户兴趣点坐标),用这个很直观。例如,推荐系统里,用户A和B的偏好向量如果直线距离近,说明他们品味相近。
- 曼哈顿距离:好比在城市网格中从一个路口到另一个路口,不能穿楼,只能横平竖直地走。它更强调各维度上的差异累计,适合某些高维稀疏数据,比如计算两个用户对不同物品的评分差异总和。
【扩展知识点详解】
- 其他常见距离/相似度:
- 点积(Dot Product):( A \cdot B ),相当于未归一化的余弦相似度,常用于神经网络计算。
- 皮尔逊相关系数:去中心化的余弦相似度,衡量线性相关性。
- 杰卡德相似度:适用于集合,计算交集与并集之比。
-
归一化的重要性:在使用欧氏距离或点积前,常对向量进行 L2 归一化(即除以模长),使其单位长度,此时余弦相似度等价于点积,且与欧氏距离平方成反比。
-
距离与相似度的转换:通常将距离转换为相似度(如 ( \text{similarity} = 1 / (1 + \text{distance}) ))以便统一比较。
- 向量数据库中的支持:
- 大多数向量数据库(如 Milvus、Qdrant、Weaviate)支持多种度量类型,用户可在创建索引时指定。
- 某些数据库(如 Pinecone)默认使用余弦相似度,但可通过设置元数据实现其他度量。
- 选择原则:
- 对于文本嵌入(如 Sentence-BERT),通常使用余弦相似度,因为模型训练时往往优化的是余弦距离。
- 对于图像嵌入,欧氏距离和余弦相似度都有使用,取决于模型。
- 在高维空间,欧氏距离可能受“维度灾难”影响,曼哈顿距离有时表现更稳定。
- 混合使用:某些高级检索策略会融合多种距离得分,如先通过余弦召回,再用欧氏精排。
springAI
什么是Spring AI ?
Spring AI是Spring框架的扩展,旨在简化人工智能大模型在Java应用中的集成与使用,提供与Spring生态无缝衔接的工具和抽象,降低AI技术接入门槛。它为开发者提供了一套简洁的API和注解,使得在Spring应用中调用AI服务变得像使用普通服务一样简单。通过Spring AI,开发者无需深入了解AI模型的底层实现细节,只需关注如何将AI能力融入业务逻辑中,大大提高了开发效率和应用的可维护性
与传统AI框架相比,Spring AI更注重与Spring生态的融合以及应用层的开发体验。传统AI框架通常专注于AI模型的构建、训练和优化,需要开发者具备深厚的数学和算法背景,且在将模型集成到实际应用时往往面临复杂的工程问题。而Spring AI则屏蔽了这些底层复杂性,以Spring开发者熟悉的方式提供AI能力,如通过注解驱动的配置、模板类的封装等,使得即使没有AI专业背景的开发者也能快速上手
Spring AI支持哪些AI服务提供商?
目前Spring AI已经支持了OpenAI、智谱、阿里百炼,文心一言等多家主流的AI服务提供商。这意味着开发者可以根据项目需求和预算,灵活选择不同的AI服务。例如,使用OpenAI的GPT系列模型可以实现强大的自然语言理解和生成能力,而智谱的AI服务则在某些特定领域有着出色的表现。Spring AI通过统一的抽象层,将不同提供商的API细节封装起来,使得开发者在切换提供商时无需修改大量代码,提高了应用的可扩展性和灵活性
Spring AI核心组件有哪些?
OpenAiChatClient是Spring AI提供的一个核心客户端类,专门用于与OpenAI的ChatCompletion API进行交互。它封装了与ChatCompletion API通信的底层细节,如HTTP请求的构建、发送和响应的处理等,使得开发者能够以一种简洁、声明式的方式调用AI聊天服务。通过OpenAiChatClient,开发者可以轻松实现各种聊天机器人的功能,如单轮对话、多轮对话等,并且可以灵活设置对话的参数,如模型名称、温度值(控制生成回答的随机性)、最大令牌数等,以满足不同场景下的需求
PromptTemplate在Spring AI中用于定义提示词模板,是实现灵活、可复用的AI提示工程的关键组件。在实际应用中,往往需要根据不同的输入动态生成提示词,以引导AI模型生成符合预期的回答。PromptTemplate允许开发者预先定义好提示词的结构和占位符,然后在运行时通过传入实际参数来填充这些占位符,从而生成完整的提示内容。这种方式不仅提高了代码的可维护性和可读性,还能够方便地对提示词进行版本管理和优化,确保AI服务的稳定性和高质量输出
OpenAiImageModel是Spring AI中用于调用OpenAI图像生成API的核心组件,它为开发者提供了将文本描述转换为图像的能力。通过OpenAiImageModel,开发者可以实现各种基于文本的图像生成功能,如根据用户输入的描述生成相应的插画、照片等。它支持设置图像的尺寸、质量、生成数量等多个参数,以满足不同应用场景对图像的多样化需求。此外,OpenAiImageModel还处理了与图像生成API交互的复杂细节,如异步请求、错误处理等,使得开发者能够更加专注于业务逻辑的实现
EmbeddingModel在Spring AI中主要用于将文本数据转换为高维向量表示,这些向量能够捕捉文本的语义信息,因而在多个场景中有着广泛的应用。例如,在文本相似度计算中,通过将两段文本转换为向量后,可以利用余弦相似度等方法快速计算它们的语义相似度,用于实现智能推荐、文档检索等功能。在语义搜索场景中,EmbeddingModel可以将用户查询和文档库中的文本都转化为向量,然后进行向量检索,找到与查询语义最匹配的文档,提高搜索的准确性和相关性。此外,EmbeddingModel还常用于聚类分析、文本分类等机器学习任务中,为模型提供语义丰富的特征表示
RedisVectorStore是Spring AI提供的一种向量存储实现,它利用Redis数据库来存储和管理文本向量数据。在需要对大量文本进行向量化并进行高效检索的应用中,RedisVectorStore发挥着至关重要的作用。它将文本向量以高效的方式存储在Redis中,并且支持基于向量相似度的快速检索,如K近邻检索等。通过RedisVectorStore,开发者可以轻松构建大规模的向量检索系统,例如在智能文档检索系统中,可以将海量文档的向量存储其中,用户提出查询时,迅速从向量库中检索出最相关的文档,极大地提升了应用的性能和用户体验
如何构建一个RAG应用问答系统?
1:数据准备和文档分块
Spring AI DocumentReader:内置分块工具,支持按固定长度或语义分块
LangChain TextSplitter:支持重叠分块(保留上下文)
滑动窗口分块:固定长度分块,可能丢失上下文
语义分块:基于句子边界或 NLP 模型(如 spaCy)分割
分块大小调优:调整每个文本块的长度(如 256/512 tokens)
重叠区调优:相邻块之间的重叠 tokens 数(如 128 tokens)
测试不同分块大小对检索效果的影响(大块可能保留上下文,小块更精准)
使用滑动窗口重叠避免上下文割裂(例如 LangChain 的 RecursiveCharacterTextSplitter)
大块可能导致检索噪声,小块可能丢失关键上下文
2:文本嵌入Embedding
OpenAI text-embedding-ada-002:高精度,需 API 调用,适合云端场景
HuggingFace 模型(如 BGE、MiniLM):本地部署,开源免费
Cohere Embed:多语言支持,商用友好
嵌入维度:OpenAI 为 1536 维,MiniLM 为 384 维
性能:本地模型延迟低,但需 GPU 加速
Transformer 编码器:如 BERT 变种,生成上下文感知向量
3:向量存储和检索
Redis:内存数据库,支持 ANN 检索,低延迟
PGVector:PostgreSQL 扩展,支持精确检索(余弦/Euclidean)
Chroma:轻量级,适合本地开发
Milvus/Pinecone:分布式架构,适合大规模数据
精确检索:暴力计算相似度(余弦/Euclidean),精度高但速度慢
近似最近邻(ANN):HNSW(Hierarchical Navigable Small World):高召回率,内存友好;IVF(Inverted File Index):快速分区检索,适合大规模数据
距离度量方式:余弦相似度(默认)、欧氏距离、内积
根据嵌入是否归一化选择算法(归一化后余弦=内积)
Top-K 值:检索返回的候选文档数量(如 K=5 或 K=10)
阈值过滤:仅返回相似度高于阈值(如 0.7)的结果
混合检索:结合关键词搜索(BM25)与向量检索
ANN 索引参数:efConstruction:索引构建时的邻居数(值越大精度越高,越慢);efSearch:搜索时的扩展列表大小(值越大召回率越高);M:层间连接数(通常 16-64,内存与精度平衡)
4:检索增强生成
OpenAI GPT-4/GPT-3.5:生成质量高,但需 API 调用
Anthropic Claude:长上下文支持(100K tokens)
本地模型(如 Llama 2、Falcon):数据隐私可控,需本地 GPU
Transformer Decoder:自回归生成(如 GPT 系列)
temperature:控制生成随机性(0 为确定性输出,1 为创造性)
max_tokens:生成答案的最大长度
top_p(核采样):控制候选词集合(如 0.9)