构建AI智能体:十八、解密LangChain中的RAG架构:让AI模型突破局限学会“翻书”答题

简介: 本文深入探讨了如何利用LangChain框架实现RAG(检索增强生成)架构,构建智能问答系统。文章首先介绍了RAG技术解决大模型知识更新和准确性问题的原理,以及LangChain作为开发框架提供的模块化组件。详细解析了LangChain的核心模块(模型、提示、索引、链等)和四种ChainType(stuff、map_reduce、refine、map_rerank)的特点与适用场景。通过一个完整的代码示例,展示了如何结合DeepSeek模型和FAISS向量数据库处理PDF文档,实现本地知识库问答功能

一、相得益彰

       在人工智能领域,我们常常遇到两个核心挑战:如何让模型获取最新知识,以及如何让模型基于特定信息生成准确答案。RAG(Retrieval-Augmented Generation:检索增强生成) 提供了一种解决这些挑战的范式,而 LangChain 则提供了实现这一范式的完整工具箱。二者的结合,就像RAG给了建筑师既有了设计蓝图,而LangChain又有了全套现代化工具,让构建智能应用变得前所未有的高效和可靠。

       本文将深入探讨如何利用 LangChain 框架实现 RAG 架构,通过具体代码示例展示如何构建一个能够理解特定领域知识的智能问答系统。

二、什么是LangChain

       LangChain 是一个用于构建大模型应用的开发框架。它本身不是 RAG,但它提供了实现 RAG 所需的所有组件。

       LangChain 将构建LLM应用时常见的功能都模块化了,比如连接各种数据源、文本处理、调用模型、管理对话历史等。开发者可以像搭积木一样,将这些模块组合起来,快速构建应用。

       结合《构建AI智能体:十七、大模型的幻觉难题:RAG 解决AI才华横溢却胡言乱语的弊病》中介绍的“开卷”的比喻,要实现“开卷考试”(RAG)这个流程,你需要很多工具:找书(文档加载)、翻书和找重点(文本分割与检索)、把找到的重点段落和问题写在草稿纸上(提示模板)、最后让学生答题(调用模型)。

       LangChain 就是提供了所有这些工具的超强工具箱:它给你提供了各种“找书”的方法(Document Loaders)、“翻书”的技巧(Text Splitters 和 Vectorstores)、“写草稿纸”的模板(Prompt Templates)以及“组织考试流程”的说明书(Chains)。

三、为什么需要LangChain

       想象一下我们使用过程中的一个痛点,大语言模型是一个超级聪明但生活不能自理的大脑。它知识渊博,但它不知道你的文件、公司的数据库;它一次只能回答一个问题,记不住之前的对话;它不会用工具,比如上网查资料或者按计算器;你想让它帮你分析公司财报、当个24小时客服、或者帮你订机票,直接告诉它去做是行不通的。你需要为它打理好一切。

       当我们一个帮助手册或职工手册的PDF文档,一般我们需要什么信息都需要自己去逐页逐行的定位到精准的段落才能找到答案,而现在有了LangChain,它能够自动的按照自己的方式和逻辑快速精准的分析和答复问题:  

  1. 检索:去你之前上传的员工手册PDF里搜索“年假”关键词。
  2. 组装:把找到的相关段落和你的问题组合成一个新的、更详细的提示。
  3. 提问:把这个组装好的提示发给AI“大脑”。
  4. 回复:把AI的回答清晰地返回给你。

四、LangChain是怎么去做的

       LangChain 可以理解为是一个用于开发由语言模型驱动的应用程序的框架。其核心价值在于提供了模块化可组合性。可以将 LangChain 想象成一副“乐高积木”,它提供了各种标准化组件(如模型交互、数据检索、记忆管理、工作流编排),让你可以通过组合这些组件,像搭积木一样快速、灵活地构建起复杂的LLM应用,而无需从零开始处理各种底层细节。就像大模型的私人助理。它会把各种工具组合起来,搭建一个完整的流水线,让大模型能真正干活;

  • 数据连接:喂资料,把你的PPT、PDF、网站文章等各种文件,拆解、整理、打包好,等大模型需要时立刻递上去。
  • 记忆管理:记笔记,把和用户的聊天记录记下来,下次聊天时提醒大模型:“这位用户上次说他叫小明,喜欢咖啡。”
  • 工具调用:递工具,当大模型说“我需要算个数”或者“我需要查一下今天的新闻”时,助理立刻把计算器或者搜索引擎递过去。
  • 工作流编排:安排工作,把一个复杂任务拆成几步,比如先让“A模型”总结文章,再让“B模型”把总结翻译成法语。

       LangChain 是一个工具箱和脚手架,它能把强大的AI大脑(LLM)和你自己的数据、工具、业务流程连接起来,拼装成一个真正能用的、智能的应用程序。

五、LangChain 的核心模块

要深入了解LangChain,首先需要了解它的核心模块:

  • Models(模型):这是与各种LLM交互的抽象。LangChain 支持多种模型提供商(OpenAI, Hugging Face等),可以用统一的接口调用它们。
    ChatModels:用于聊天模式,输入输出是消息列表。
    LLMs:用于补全模式,输入输出是字符串。
  • Prompts(提示):管理、优化和模板化提示词的组件。PromptTemplate 允许你创建带有变量的模板,动态注入内容。如"请将以下文本翻译成{language}:{text}"
  • Indexes(索引):让模型能够与外部数据连接和交互,这是克服模型知识截止问题的关键。主要包括:
    Document Loaders:从各种源(PDF, 网页, Notion)加载文档。
    Text Splitters:将长文档分割成模型上下文窗口能处理的小块。
    VectorStores:将文本块转换为向量(Embeddings)并存储,以便快速进行相似性搜索。
    Retrievers:从 VectorStores 中检索与问题相关的文档片段。
  • Chains(链):将多个组件“链”在一起,形成一个序列化的工作流。这是 LangChain 的核心。一个链可以包含一个提示模板、一个模型和一个输出解析器。
    LLMChain 是最基本的链。  RetrievalQA 是一个高级链,它集成了检索器和问答链。
  • Agents(代理):链是预先定义好的固定流程,而代理则让模型自己决定使用哪些工具、以什么顺序使用,来完成用户指令。代理相当于模型的“大脑”,工具则是它的“手脚”。

      工具:可以是搜索引擎、计算器、数据库查询等任何函数。

  • Memory(记忆):用于在链或代理的多次调用之间持久化状态,如对话历史。这对于聊天应用至关重要。

六、LangChain中的Chain Type

       通俗的讲,LangChain如果是一个功能强大的自动化汽车制造工厂,chain_type 就像是工厂里的特定车辆组装蓝图或流水线,是特定 Chain 的配置参数,参考以下代码中的load_qa_chain方法中配置的chain_type;

from langchain.prompts import PromptTemplate
custom_prompt = PromptTemplate(
    template="""请严格根据以下上下文来回答问题。如果上下文没有提供足够信息,请直接说"根据已知信息无法回答该问题",不要编造答案。
上下文:
{context}
问题:{question}
答案:""",
    input_variables=["context", "question"]
)
chain = load_qa_chain(llm, chain_type="stuff", prompt=custom_prompt)

image.gif

       在 load_qa_chain 中, chain_type 参数决定了 RAG 流程中“增强”这一步的具体工作方式。即:如何将检索到的多个相关文档块(context)与用户的问题(question)组合起来,发送给大语言模型(LLM)以生成最终答案。不同的 chain_type 在效果、成本和速度上有着显著的权衡。

四种主要的 Chain Type 详解:

       假设我们针对问题 “LangChain 有哪些核心组件?” 检索到了 4 个相关的文档块(chunks)。

1. stuff(堆叠)

  • 工作方式:这是最简单的方法。它将所有检索到的文档块简单地“堆叠”在一起,组合成一个巨大的提示(prompt),然后一次性发送给 LLM。Prompt 结构: 请根据以下信息回答问题:{context_chunk_1} ... {context_chunk_4} 问题:{question}
  • 优点:

   单次调用:只调用 LLM 一次,速度快。

   最大上下文:LLM 可以同时看到所有信息,理论上能做出最综合、最连贯的回答。

  • 缺点:

   上下文长度限制:如果检索到的文档块很多或很长,很容易超过 LLM 的上下文窗口(context window)限制,导致报错或信息被截断。


  • 适用场景:当检索到的文档总篇幅较短,并且确信不会超出所用 LLM 的上下文窗口时。这是最常用且默认的选项。

2. map_reduce(映射归纳)

  • 工作方式:该方法分为两个阶段:

   1. Map(映射):将每个文档块分别与问题组合,发送给 LLM,要求 LLM 针对该块本身提取答案。这会进行 N 次(文档块的数量)LLM 调用。Prompt 结构(每次): 根据以下片段回答问题:{context_chunk_i} 问题:{question}

   2. Reduce(归纳):将所有来自 Map 阶段的答案(可能还有原始问题)再次组合,发送给 LLM,要求它将这些分散的答案归纳成一个最终、连贯的答案。这是第 N+1 次 LLM 调用。

  • 优点:

   突破上下文限制:可以处理任意数量的文档,因为每个文档都是独立处理的。

  • 缺点:

   高成本/高延迟:需要进行多次 LLM 调用(N+1 次),成本更高,速度更慢。

   可能丢失全局视角:在 Map 阶段,LLM 无法看到不同文档块之间的关联,可能导致归纳阶段融合困难。

  • 适用场景:当需要处理大量文档,并且 stuff 方法不适用时。

3. refine(迭代细化)

  • 工作方式:这是一个迭代、序列化的过程。

   首先,将第一个文档块和问题发送给 LLM,得到一个初始答案。

   然后,将下一个文档块、当前已有的答案和问题再次发送给 LLM,要求它根据新信息修正或完善(refine) 当前的答案。

   重复步骤 2,直到所有文档块都处理完毕。最终的答案就是最后一次迭代的结果。

  • 优点:

   答案质量高:答案在迭代中不断细化,可以产生非常精确和细致的回答。

   能处理长文档:同样不受上下文窗口限制。

  • 缺点:

   速度最慢:串行处理意味着调用次数多(N 次),且后续调用必须等待前一次完成,延迟很高。

   答案依赖性:文档块的处理顺序可能会影响最终答案。早期的错误可能被后续迭代放大或修正。

  • 适用场景:当答案需要高度精确,并且愿意以速度和成本为代价来换取质量时。

4. map_rerank(映射重排序)

  • 工作方式:

   Map(映射):与 map_reduce 的 Map 阶段类似,为每个文档块单独调用 LLM。但不同的是,它要求 LLM 不仅给出答案,还要为该答案基于当前块的可信度输出一个分数(score)。

   Rerank(重排序):不再进行 Reduce 步骤。而是直接选择分数最高的那个答案作为最终输出。

  • 优点:

   单文档答案:对于事实型、答案可能存在于单个文档块中的问题(例如,“某某人的生日是哪天?”)非常有效。

  • 缺点:

   不适用于综合型问题:如果答案需要从多个文档中综合信息,此方法会失败,因为它只选一个。

  • 适用场景:主要用于问答(Answer Question) 而不是总结(Summarization),并且你确信答案完整地存在于某个单一的文档块中。

Chain Type的差异:

特性

stuff

map_reduce

refine

map_rerank

LLM调用次数

1

N + 1

N

N

速度

最快

中等

最慢

Token 消耗

处理长文档能力

答案质量

高 (上下文完整)

中等 (可能丢失关联)

最高 (迭代细化)

取决于最佳块

适用场景

默认选择,文档短

文档多,需平衡

文档多,要求高精度

事实型问题,答案在单块中

为了更直观地理解和选择,可以参考下面的决策流程:

image.gif

选择建议:

  1. 优先尝试 stuff:在大多数情况下,这是最佳选择。只需确保你的块大小(chunk_size)和检索数量( k)的乘积不会超出 LLM 的上下文窗口(记得为问题和答案留出空间)。
  2. 如果文档太多太长 → 选择 map_reduce 或 refine。
  • 答案质量且不计较延迟 → 选 refine。
  • 想要一种平衡的方案 → 选 map_reduce。
  1. 如果是事实型、答案明确的问题 → 可以尝试 map_rerank。

七、LangChain与RAG的关系

       通俗的讲,RAG(检索增强生成)是一种技术理念或架构模式,是一个具体的“技术方案”或“模式”,就像“做一份番茄炒蛋的菜谱”;而LangChain 是一个实现这种模式(以及其他模式)的强大工具包和框架,就像“一整套厨房用具和智能灶台”。

你可以这样理解:

  • RAG 是“菜谱”:它告诉你做一道菜(构建一个能回答问题的AI)需要哪些步骤(检索、增强、生成)。
  • LangChain 是“厨房和全套厨具”:它为你提供了实现这个菜谱所需要的所有工具(锅、碗、瓢、盆、灶具),让你能更高效、更标准地做出这道菜。

八、LangChain与RAG的协调工作原理    

       当我们用 LangChain 构建一个文档问答应用时,实际上就是在实现一个标准的 RAG 流程。下图直观地展示了LangChain是如何实现RAG全流程的,它通过其丰富的组件和链,将RAG从一个理论架构变成了一个可以快速落地实现的具体方案。

image.gif

       综合可知,在 LangChain 中实现 RAG,本质上是将检索器(Retriever)和生成器(Generator)通过链(Chain)组合起来的工作流程。这个流程通常包含四个关键阶段:

  1. 文档加载与处理:从各种来源(PDF、网页、数据库等)加载文档
  2. 文档索引与存储:将文档分割并转换为向量表示,存入向量数据库
  3. 相关检索:根据用户查询找到最相关的文档片段
  4. 增强生成:将检索到的上下文与用户查询组合,生成最终答案

       LangChain 为每个阶段都提供了丰富的组件和简化接口,让开发者可以专注于业务逻辑而不是底层实现细节。

九、综合示例:DeepSeek+ Faiss构建本地知识库检索

       接下来我们实现了一个基于 RAG 架构的 PDF 文档问答系统,使用LangChain、DashScope中的deepseek-v3模型和 FAISS。读取本地的文档进行检索;

from PyPDF2 import PdfReader
from langchain.chains.question_answering import load_qa_chain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.vectorstores import FAISS
from typing import List, Tuple
import os
import pickle
DASHSCOPE_API_KEY = os.getenv('DASHSCOPE_API_KEY')
if not DASHSCOPE_API_KEY:
    raise ValueError("请设置环境变量 DASHSCOPE_API_KEY")
def extract_text_with_page_numbers(pdf) -> Tuple[str, List[Tuple[str, int]]]:
    """
    从PDF中提取文本并记录每个字符对应的页码
    参数:
        pdf: PDF文件对象
    返回:
        text: 提取的文本内容
        char_page_mapping: 每个字符对应的页码列表
    """
    text = ""
    char_page_mapping = []
    for page_number, page in enumerate(pdf.pages, start=1):
        extracted_text = page.extract_text()
        if extracted_text:
            text += extracted_text
            # 为当前页面的每个字符记录页码
            char_page_mapping.extend([page_number] * len(extracted_text))
        else:
            print(f"No text found on page {page_number}.")
    return text, char_page_mapping
def process_text_with_splitter(text: str, char_page_mapping: List[int], save_path: str = None) -> FAISS:
    """
    处理文本并创建向量存储
    参数:
        text: 提取的文本内容
        char_page_mapping: 每个字符对应的页码列表
        save_path: 可选,保存向量数据库的路径
    返回:
        knowledgeBase: 基于FAISS的向量存储对象
    """
    # 创建文本分割器,用于将长文本分割成小块
    text_splitter = RecursiveCharacterTextSplitter(
        separators=["\n\n", "\n", ".", " ", ""],
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len,
    )
    # 分割文本
    chunks = text_splitter.split_text(text)
    print(f"文本被分割成 {len(chunks)} 个块。")
    # 创建嵌入模型
    embeddings = DashScopeEmbeddings(
        model="text-embedding-v1",
        dashscope_api_key=DASHSCOPE_API_KEY,
    )
    # 从文本块创建知识库
    knowledgeBase = FAISS.from_texts(chunks, embeddings)
    print("已从文本块创建知识库。")
    # 为每个文本块找到对应的页码信息
    page_info = {}
    current_pos = 0
    for chunk in chunks:
        chunk_start = current_pos
        chunk_end = current_pos + len(chunk)
        # 找到这个文本块中字符对应的页码
        chunk_pages = char_page_mapping[chunk_start:chunk_end]
        # 取页码的众数(出现最多的页码)作为该块的页码
        if chunk_pages:
            # 统计每个页码出现的次数
            page_counts = {}
            for page in chunk_pages:
                page_counts[page] = page_counts.get(page, 0) + 1
            # 找到出现次数最多的页码
            most_common_page = max(page_counts, key=page_counts.get)
            page_info[chunk] = most_common_page
        else:
            page_info[chunk] = 1  # 默认页码
        current_pos = chunk_end
    knowledgeBase.page_info = page_info
    print(f'页码映射完成,共 {len(page_info)} 个文本块')
    # 如果提供了保存路径,则保存向量数据库和页码信息
    if save_path:
        # 确保目录存在
        os.makedirs(save_path, exist_ok=True)
        # 保存FAISS向量数据库
        knowledgeBase.save_local(save_path)
        print(f"向量数据库已保存到: {save_path}")
        # 保存页码信息到同一目录
        with open(os.path.join(save_path, "page_info.pkl"), "wb") as f:
            pickle.dump(page_info, f)
        print(f"页码信息已保存到: {os.path.join(save_path, 'page_info.pkl')}")
    return knowledgeBase
def load_knowledge_base(load_path: str, embeddings = None) -> FAISS:
    """
    从磁盘加载向量数据库和页码信息
    参数:
        load_path: 向量数据库的保存路径
        embeddings: 可选,嵌入模型。如果为None,将创建一个新的DashScopeEmbeddings实例
    返回:
        knowledgeBase: 加载的FAISS向量数据库对象
    """
    # 如果没有提供嵌入模型,则创建一个新的
    if embeddings is None:
        embeddings = DashScopeEmbeddings(
            model="text-embedding-v1",
            dashscope_api_key=DASHSCOPE_API_KEY,
        )
    # 加载FAISS向量数据库,添加allow_dangerous_deserialization=True参数以允许反序列化
    knowledgeBase = FAISS.load_local(load_path, embeddings, allow_dangerous_deserialization=True)
    print(f"向量数据库已从 {load_path} 加载。")
    # 加载页码信息
    page_info_path = os.path.join(load_path, "page_info.pkl")
    if os.path.exists(page_info_path):
        with open(page_info_path, "rb") as f:
            page_info = pickle.load(f)
        knowledgeBase.page_info = page_info
        print("页码信息已加载。")
    else:
        print("警告: 未找到页码信息文件。")
    return knowledgeBase
# 读取PDF文件
pdf_reader = PdfReader('./电脑的日常维护.pdf')
# 提取文本和页码信息
text, char_page_mapping = extract_text_with_page_numbers(pdf_reader)
#print('page_numbers=',page_numbers)
print(f"提取的文本长度: {len(text)} 个字符。")
# 处理文本并创建知识库,同时保存到磁盘
save_dir = "./vector_db"
knowledgeBase = process_text_with_splitter(text, char_page_mapping, save_path=save_dir)
# 示例:如何加载已保存的向量数据库
# 注释掉以下代码以避免在当前运行中重复加载
"""
# 创建嵌入模型
embeddings = DashScopeEmbeddings(
    model="text-embedding-v1",
    dashscope_api_key=DASHSCOPE_API_KEY,
)
# 从磁盘加载向量数据库
loaded_knowledgeBase = load_knowledge_base("./vector_db", embeddings)
# 使用加载的知识库进行查询
docs = loaded_knowledgeBase.similarity_search("客户经理每年评聘申报时间是怎样的?")
# 直接使用FAISS.load_local方法加载(替代方法)
# loaded_knowledgeBase = FAISS.load_local("./vector_db", embeddings, allow_dangerous_deserialization=True)
# 注意:使用这种方法加载时,需要手动加载页码信息
"""
from langchain_community.llms import Tongyi
llm = Tongyi(model_name="deepseek-v3", dashscope_api_key=DASHSCOPE_API_KEY) # qwen-turbo
# 设置查询问题
query = "如何进行系统性能优化"
if query:
    # 执行相似度搜索,找到与查询相关的文档
    docs = knowledgeBase.similarity_search(query,k=10)
    # 加载问答链
    chain = load_qa_chain(llm, chain_type="stuff")
    # 准备输入数据
    input_data = {"input_documents": docs, "question": query}
    # 执行问答链
    response = chain.invoke(input=input_data)
    print(response["output_text"])
    print("来源:")
    # 记录唯一的页码
    unique_pages = set()
    # 显示每个文档块的来源页码
    for doc in docs:
        #print('doc=',doc)
        text_content = getattr(doc, "page_content", "")
        source_page = knowledgeBase.page_info.get(
            text_content.strip(), "未知"
        )
        if source_page not in unique_pages:
            unique_pages.add(source_page)
            print(f"文本块页码: {source_page}")

image.gif

输出结果:

提取的文本长度: 7494 个字符。
文本被分割成 10 个块。
已从文本块创建知识库。
页码映射完成,共 10 个文本块
向量数据库已保存到: ./vector_db
页码信息已保存到: ./vector_db\page_info.pkl
系统性能优化可以通过多种方式进行,以下是具体的方法和步骤:
### 1. **磁盘缓存优化**
   - 调整系统对磁盘数据的缓存策略,以提高读写效率。
### 2. **桌面菜单优化**
   - 减少桌面图标和菜单项的加载时间,提高桌面响应速度。
### 3. **文件系统优化**
   - 定期进行磁盘碎片整理,确保文件存储连续,减少磁盘寻道时间。
### 4. **网络系统优化**
   - 调整网络协议和设置,优化网络连接速度和稳定性。
### 5. **开机速度优化**
   - **设置开机信息停留时间**:通过拖动滑块调整开机信息显示的时间。
   - **采用快速启动方式**:选中“采用Windows XP快速启动方式”复选框。
   - **关闭不必要的开机自启动程序**:在“请选择开机不自动运行的项目”列表中取消选中不需要的程序。
### 6. **系统安全优化**
   - 关闭不必要的后台服务和防火墙规则,减少系统资源占用。
### 7. **系统个性优化**
   - 根据用户需求调整系统界面和功能设置。
### 8. **后台服务优化**
   - 停用或调整不常用的后台服务,以释放系统资源。
### 9. **使用系统工具**
   - 利用**Windows优化大师**等工具,对系统进行全面优化,包括垃圾文件清理、冗余DLL分析等。
### 操作步骤示例:
1. **单击“系统性能优化”选项**,选择“开机速度优化”。
2. **调整启动信息停留时间**:拖动滑块设置开机信息停留时间。
3. **设置启动方式**:勾选“采用Windows XP快速启动方式”和“异常时启动磁盘错误检查等待时间”。
4. **选择不开机自启动的项目**:在列表框中取消选中不需要开机自启动的程序。
5. **单击“优化”按钮**完成设置。
通过这些方法,可以显著提高系统的运行效率和响应速度。
来源:
文本块页码: 13
文本块页码: 10
文本块页码: 9
文本块页码: 7
文本块页码: 1
文本块页码: 18
文本块页码: 4
文本块页码: 16
文本块页码: 2

image.gif

       示例的文档是一份《电脑的日常维护.pdf》手册,我们提问的是“如何进行系统性能优化?”,以下截取文档的部分图片:

image.gif

image.gif

思路分析:


  1. 知识库构建(Indexing Pipeline):
  • 从 PDF 提取文本和精确的页码信息。
  • 对文本进行分块(chunking)。
  • 使用 DashScope 的嵌入模型将文本块转换为向量。
  • 将向量存入 FAISS 向量数据库。
  • 将向量库和关键的页码映射信息保存到本地。
  1. 问答推理(Retrieval & Generation Pipeline):
  • 从本地加载预先构建好的知识库(FAISS 索引和页码信息)。
  • 接收用户查询。
  • 在向量库中检索与查询最相关的文本块。
  • 将相关文本块和查询组合,发送给 LLM(Tongyi 的 Deepseek-v3 模型)生成答案。
  • 输出答案并标注答案来源的页码

十、总结

       LangChain 与 RAG 的结合为构建高效、准确的智能问答系统提供了强大基础。通过 LangChain 提供的模块化组件,我们可以轻松实现RAG架构的各个阶段,从文档处理到最终答案生成。

这种组合的优势在于:

  • 知识实时性:可以随时更新知识库,而不需要重新训练模型
  • 答案可追溯:可以显示答案来源,提高可信度和可解释性
  • 定制化能力强:可以针对特定领域或企业需求定制知识库
  • 开发效率高:LangChain抽象了复杂流程,大幅减少开发时间

       无论是想构建企业知识库、智能客服系统还是专业问答助手,LangChain与RAG的组合都能提供强大的技术基础和灵活的定制能力,协助将AI技术转化为实际业务价值。

相关文章
|
15天前
|
存储 人工智能 自然语言处理
构建AI智能体:十七、大模型的幻觉难题:RAG 解决AI才华横溢却胡言乱语的弊病
RAG(检索增强生成)是一种结合信息检索与大型语言模型的技术,旨在解决LLM的幻觉问题。其核心流程包括:离线处理阶段(知识库构建)和在线处理阶段(用户查询应答)。通过将外部知识源转换为向量存入数据库,当用户提问时,系统会检索相关内容并增强提示,再由LLM生成准确答案。RAG技术显著提升了AI在专业领域的可靠性,适用于智能客服、企业知识管理、内容创作等场景。尽管面临检索精度、多模态处理等挑战,RAG仍是AI实用化的重要突破方向。
183 2
|
9天前
|
存储 人工智能 自然语言处理
构建AI智能体:二十三、RAG超越语义搜索:如何用Rerank模型实现检索精度的大幅提升
本文介绍了重排序(Rerank)技术在检索增强生成(RAG)系统中的应用。Rerank作为初始检索和最终生成之间的关键环节,通过交叉编码器对初步检索结果进行精细化排序,筛选出最相关的少量文档提供给大语言模型。相比Embedding模型,Rerank能更精准理解查询-文档的语义关系,显著提高答案质量,降低Token消耗。文章详细比较了BGE-Rerank和CohereRerank等主流模型,并通过代码示例展示了Rerank在解决歧义查询(如区分苹果公司和水果)上的优势。
207 5
|
19天前
|
机器学习/深度学习 人工智能 自然语言处理
构建AI智能体:十三、大数据下的“搭积木”:N-Gram 如何实现更智能的语义搜索
N-gram是一种基于上下文的统计语言模型,通过前N-1个词预测当前词的概率,广泛应用于文本生成、输入法预测、语音识别等领域,具有简单高效、可解释性强的优点,是自然语言处理的基础技术之一。
221 10
|
17天前
|
SQL 数据采集 人工智能
评估工程正成为下一轮 Agent 演进的重点
面向 RL 和在数据层(SQL 或 SPL 环境)中直接调用大模型的自动化评估实践。
821 213
|
13天前
|
存储 人工智能 JSON
构建AI智能体:十九、优化 RAG 检索精度:深入解析 RAG 中的五种高级切片策略
本文详细介绍了RAG(检索增强生成)系统中的文本切片策略。RAG切片是将长文档分割为语义完整的小块,以便AI模型高效检索和使用知识。文章分析了五种切片方法:改进固定长度切片(平衡效率与语义)、语义切片(基于嵌入相似度)、LLM语义切片(利用大模型智能分割)、层次切片(多粒度结构)和滑动窗口切片(高重叠上下文)。作者建议根据文档类型和需求选择策略,如通用文档用固定切片,长文档用层次切片,高精度场景用语义切片。切片质量直接影响RAG系统的检索效果和生成答案的准确性。
201 11
|
1月前
|
SQL 人工智能 关系型数据库
AI Agent的未来之争:任务规划,该由人主导还是AI自主?——阿里云RDS AI助手的最佳实践
AI Agent的规划能力需权衡自主与人工。阿里云RDS AI助手实践表明:开放场景可由大模型自主规划,高频垂直场景则宜采用人工SOP驱动,结合案例库与混合架构,实现稳定、可解释的企业级应用,推动AI从“能聊”走向“能用”。
776 39
AI Agent的未来之争:任务规划,该由人主导还是AI自主?——阿里云RDS AI助手的最佳实践
|
1月前
|
人工智能 测试技术 API
构建AI智能体:二、DeepSeek的Ollama部署FastAPI封装调用
本文介绍如何通过Ollama本地部署DeepSeek大模型,结合FastAPI实现API接口调用。涵盖Ollama安装、路径迁移、模型下载运行及REST API封装全过程,助力快速构建可扩展的AI应用服务。
524 6
|
23天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:十、开箱即见 Gradio:大模型的“魔法画布”,让每一个想法清晰可见
Gradio是一个快速构建机器学习演示界面的Python库,能够将需要数天开发工作的模型展示缩短为几分钟的脚本编写。它通过简单的Python代码即可生成完整的Web应用界面,支持文本、图像、音频等多种交互组件,适用于模型展示、教学演示和原型测试等场景。文章详细介绍了Gradio的核心功能、基础语法和组件使用方法,并通过情感分析和聊天机器人两个实际案例展示了如何快速部署AI模型交互界面。Gradio大幅降低了将模型转化为可交互应用的门槛,使开发者能更专注于模型本身而非界面开发。
351 7
|
17天前
|
存储 人工智能 算法
构建AI智能体:十五、超越关键词搜索:向量数据库如何解锁语义理解新纪元
向量数据库是专为存储和检索高维向量设计的新型数据库,通过Embedding技术将文本、图像等非结构化数据转化为向量,利用近似最近邻(ANN)算法实现语义级相似性搜索,广泛应用于AI推荐、语义搜索与智能问答,是大模型时代的关键基础设施。
252 12