生成式人工智能/大语言模型

使用 NVIDIA Nemotron 构建检索增强生成 (RAG) 智能体

与基于 LLM 的传统系统受限于其训练数据不同,检索增强生成 (RAG) 通过整合相关的外部信息来提升文本生成效果。 AGENT-RAG 进一步引入与 LLM 和检索机制集成的自主代理系统,使模型能够自主决策,适应动态变化的需求,并执行复杂的推理任务。

在本关于构建 RAG 智能体的自主培训指南中,您将获得:

  • 了解代理式 RAG 的核心原则,包括 NVIDIA Nemotron,这是一个具有开放数据和权重的开放模型系列。
  • 了解如何使用 LangGraph 构建代理式 RAG 系统。
  • 一站式可移植开发环境。
  • 您自己的定制代理式 RAG 系统,随时可作为 NVIDIA Launchable 进行分享。

视频演练

视频 1。使用 NVIDIA Nemotron 构建 RAG 智能体

研讨会开幕

将研讨会作为 NVIDIA 可启动内容 进行发布:

Button of the “Deploy Now” button for NVIDIA DevX  Workshop
图 1。单击“Deploy Now”(立即部署)按钮,即可在云端部署 NVIDIA DevX Workshop。

运行 Jupyter Lab 环境后,在 JupyterLab Launcher 的 NVIDIA DevX 学习路径 部分,选择 Agentic RAG(代理式 RAG)磁贴,以打开实验说明并开始操作。

A screenshot of the 2. Agentic RAG tile
图 2。单击“NVIDIA DevX Learning Path” ( NVIDIA DevX 学习路径) 中的“Agentic RAG”图块,打开实验室说明。

设置机密

参加本研讨会前,您需要收集并配置相关的项目密钥和令牌。具体操作步骤请参考所提供的蓝图。

  • NGC API 密钥: 此密钥支持访问 NVIDIA 软件、模型、容器等
  • (可选) LangSmith API 密钥: 此密钥可将研讨会连接到 LangChain 的平台,用于追踪和调试您的 AI 智能体

您可以使用 JupyterLab Launcher 中 NVIDIA DevX 学习路径下的 Secrets Manager 磁贴为您的 Workshop 开发环境配置这些 TOKEN。在“Logs”(日志)选项卡中验证 SECRET 是否已成功添加。

A screenshot of the Secrets Manager tile under NVIDIA DevX Learning Path.
图 3。在 NVIDIA DevX 学习路径部分,通过“Secrets Manager”图块配置项目密钥(API 密钥)。

RAG 架构简介

设置好研讨会环境后,下一步是了解您要构建的代理式 RAG 系统的架构蓝图。

RAG 通过在输出文本生成过程中整合相关外部信息来增强 LLM 的功能。传统语言模型仅依赖训练数据中所包含的知识生成响应,这在面对快速变化的信息、高度专业化的知识领域或企业机密数据时可能成为限制因素。相比之下,RAG 是一种功能强大的工具,能够基于从外部知识库检索到的相关非结构化数据生成响应。

A flow chart showing the path of a user prompt takes from the retrieval chain, to the LLM, to the final generated response.
图 4。传统上,RAG 使用用户提示来检索与上下文相关的文档,并将其作为上下文提供给 LLM,以便做出更明智的回应。

RAG 系统的典型流程是:

  1. 提示: 用户生成自然语言查询。
  2. 嵌入模型: 将提示转换为向量
  3. 向量数据库搜索: 将用户的提示词嵌入到向量中后,系统会搜索包含语义索引文档块的向量数据库,从而快速检索与上下文相关的数据块。”
  4. 重排序模型: 对检索到的数据块进行重排序,以优先处理最相关的数据。
  5. LLM: LLM 根据检索到的数据生成响应。

这种方法可确保语言模型能够访问训练数据之外的最新特定信息,从而提升其通用性和有效性。

了解 ReAct 智能体架构

与传统的基于 LLM 的应用不同,智能体能够动态选择工具,整合复杂的推理过程,并根据实际情况调整分析方法。

A flow chart showing the path a user prompt takes inside of a ReAct agent to iteratively utilize tool calling.
图 5 展示了ReAct智能体如何通过迭代推理并调用用户定义的工具,生成基于RAG的高质量响应。

ReAct 智能体是一种简洁的代理式架构,通过支持工具调用的大型语言模型(LLM)实现“推理与行动”。当 LLM 在接收提示后请求调用任何工具时,这些工具将被执行,并将结果添加到对话历史中,随后再次传回模型进行下一步处理。

RAG 效果不错,但由于大语言模型(LLM)无法确定数据的检索方式、控制数据质量或在不同数据源之间进行选择,因此存在较大的局限性。Agentic RAG 进一步拓展了 RAG 的概念,将 LLM 在语言理解、上下文推理和灵活生成方面的优势,与动态工具调用以及语义搜索、混合检索、重排序和数据源选择等高级检索机制相结合。通过为智能体提供检索链作为工具,即可构建适用于 RAG 的 ReAct 智能体,使其能够自主决定何时以及如何进行信息检索。

A flow chart showing the path a user prompt takes between the ReAct agent and the Retrieval Chain.
图 6。完整的代理式 RAG 工作流将涉及将 ReAct 代理添加到存储上下文文档的检索链中。

代理式 RAG 采用 ReAct Agent 架构,在该架构中,推理 LLM 系统决定是通过工具调用来检索信息,还是直接生成响应,仅在需要额外上下文以更好满足用户请求时才激活检索工作流。

学习并实施代码

了解了这些概念后,接下来我们将深入探讨技术实现。在构建基于代理的完整 RAG 系统之前,先从基础组件入手:

  1. 模型
  2. 工具
  3. 数据提取
  4. 文本分割
  5. 向量数据库提取
  6. 文档检索器和重排序器
  7. Retriever 工具创建
  8. 智能体配置

基础:模型

研讨会依赖于 NVIDIA NIM 端点,以提供核心模型为智能体赋能。NVIDIA NIM 提供高性能推理功能,包括:

  • 工具绑定: 对函数调用的原生支持。
  • 结构化输出: 内置对 Pydantic 模型的支持。
  • 异步操作: 完全支持并发处理的异步/ 等待。
  • 企业级可靠性: 生产级推理基础架构。

此示例展示了使用 NVIDIA NIM 的 ChatNVIDIA LangChain 连接器。

from langchain_nvidia_ai_endpoints import ChatNVIDIA
LLM_MODEL = "nvidia/nvidia-nemotron-nano-9b-v2"
llm = ChatNVIDIA(model=LLM_MODEL, temperature=0.6, top_p=0.95, max_tokens=8192)

为确保基于大语言模型(LLM)的应用质量,必须向智能体提供明确的指令,以澄清其决策过程、消除歧义,并说明其应如何处理检索到的文档,这一点至关重要。以下是 code/rag_agent.py 中的一个相关示例:

SYSTEM_PROMPT = (
    "You are an IT help desk support agent.\n"
    "- Use the 'company_llc_it_knowledge_base' tool for questions likely covered by the internal IT knowledge base.\n"
    "- Always write grounded answers. If unsure, say you don't know.\n"
    "- Cite sources inline using [KB] for knowledge base snippets.\n"
    "- If the knowledge base doesn't contain sufficient information, clearly state what information is missing.\n"
    "- Keep answers brief, to the point, and conversational."
)

此提示说明了基于 RAG 的应用中可靠 LLM 提示的一些关键原则:

  • 角色规范: 明确定义智能体的专业知识和职责。
  • 工具利用率: 指示智能体将哪些工具用于特定任务。
  • 基础知识: 强调根据可靠来源提供答案的重要性,以及承认不确定性的重要性。
  • 来源引文: 提供引用来源的指南,以确保透明度。
  • 通信风格: 指定所需的通信风格。

code/rag_agent.py 中,我们利用知识库定义了 IT 帮助台智能体回答用户查询所需的模型。

  • LLM 模型 Nemotron Nano 9b V2 是用于生成响应的主要推理模型。
  • NVIDIA NeMo Retriever 嵌入模型 Llama 3.2 EmbedQA 1b V2 用于将文档转换为用于存储和检索的向量嵌入表示。
  • NeMo Retriever 重排序模型 Llama 3.2 RerankQA 1b V2 用于对相关性最高的检索文档和数据进行重排序。

这些模型协同支持 IT 帮助台智能体,通过整合语言生成、文档检索与重排序功能,精准响应用户查询。

基础:工具

我们的 RAG 智能体将能够访问 ./data/it-knowledge-base 上提供的知识库,其中包含记录常见 IT 相关程序的 Markdown 文件。检索工具使智能体可以在内部 IT 知识库中搜索与用户查询相关的文档。

向量数据库能够存储、索引和查询以数值形式表示的向量化嵌入,支持对文本、图像和音频等非结构化数据进行高效的相似性搜索。出于我们的目的,我们将使用内存中的 FAISS 数据库,该数据库能够快速启动并适用于小型数据库的构建。在数据提取方面,我们将重点关注如何利用知识库中的文本信息。对于生产环境的应用,建议考虑支持多模态等更全面的功能。

基础知识:数据提取

使用的嵌入模型是 NeMo Retriever llama-3.2-nv-embedqa-1b-v2。该模型为文档和查询生成嵌入,通过衡量查询与文档之间的语义相似性,高效地从知识库中检索相关文档。

为提取文档,我们将对文档进行分块处理,将各分块嵌入为向量,然后将这些向量存入数据库。在此之前,需使用 LangChain DirectoryLoader 从 ./data/it-knowledge-base 目录加载数据。

from langchain_community.document_loaders import DirectoryLoader, TextLoader
# Read the data
_LOGGER.info(f"Reading knowledge base data from {DATA_DIR}")
data_loader = DirectoryLoader(
    DATA_DIR,
    glob="**/*",
    loader_cls=TextLoader,
    show_progress=True,
)
docs = data_loader.load()

基础:文本分割

文档拆分由两个方面控制:数据块大小和数据块重叠。

数据块大小定义了每个文本块的最大长度。这可以确保每个数据块的大小经过优化,适合语言模型和检索系统处理。如果数据块过大,可能会包含与特定查询相关性较低的信息;而如果数据块过小,则可能丢失重要的上下文。

数据块重叠定义了连续数据块之间重叠的TOKEN数量。其目标是确保数据块之间的连续性并保留上下文,从而维持检索到的信息的一致性。

为高效执行文本分割,我们采用 RecursiveCharacterTextSplitter。该工具会依据字符长度递归地将文档拆分为较小的块,确保每个块均符合预设的 token 大小和重叠参数。它在处理大型文档时尤为有效,有助于提升信息检索的整体准确性。

from langchain.text_splitter import RecursiveCharacterTextSplitter
CHUNK_SIZE = 800
CHUNK_OVERLAP = 120

_LOGGER.info(f"Ingesting {len(docs)} documents into FAISS vector database.")
splitter = RecursiveCharacterTextSplitter(
    chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP
)
chunks = splitter.split_documents(docs)

基础:向量数据库提取

为促进高效检索相关信息,我们需要将大量文档提取并存储到向量数据库中。目前,文档已被分解为可管理的块,我们利用嵌入模型为每个文档块生成向量嵌入。

这些嵌入是数据块语义内容的数值表示。高质量的嵌入支持高效的相似性搜索,使系统能够快速识别并检索与用户查询相关性最高的数据块。

下一步是将生成的嵌入存储在内存中的 FAISS 数据库中,以实现快速索引和实时信息检索的高效查询。在本示例中,我们利用 LangChain 提供的 FAISS `from_documents` 方法,该方法能够在一次函数调用中自动为文档块生成 EMBEDDING 并将其存入 FAISS 向量存储,从而简化了流程。

from langchain_community.vectorstores import FAISS
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings,

embeddings = NVIDIAEmbeddings(model=RETRIEVER_EMBEDDING_MODEL, truncate="END")
vectordb = FAISS.from_documents(chunks, embeddings)

通过遵循这些步骤并利用嵌入模型的强大功能,我们可确保 IT 帮助台智能体能够高效地从知识库中检索和处理相关信息。

基础:文档检索器和重排序器

填充向量数据库后,我们可以构建内容检索链。这需要创建一个无缝的工作流程,包含嵌入步骤和查找步骤。

A flow chart showing the path ingested document chunks take to get stored in a vector database.
图 7 展示了基本的检索链,由嵌入模型和用于存储转换后向量嵌入的数据库构成。

在嵌入步骤中,用户查询将使用与文档块相同的模型转换为 embedding。这确保了查询和文档块在相同的语义空间中进行表示,从而实现准确的相似性比较。

为了在此示例中初始化检索器,我们将采用语义相似性,并检索与查询相比最相关的前六个结果。

# imports already handled
kb_retriever = vectordb.as_retriever(search_type="similarity", search_kwargs={"k": 6})

在查找过程中,将用户查询的嵌入与向量数据库中存储的嵌入进行对比,系统会检索出与之最相近的文档块,并将其用于生成回复。

A flow chart showing the path ingested document chunks take to get stored in and retrieved from a vector database.
图 8。更复杂的检索链包括连接 Reranking 模型,以重新组织检索到的上下文,将相关性最高的数据块放在第一位。

对于嵌入和重排序模型,我们将使用 NVIDIA NeMo Retriever 的 NIM 微服务。通过 LangChain,可以从向量数据库对象轻松构建基础检索链,该检索链包含嵌入和查找步骤。

为了提高检索文档的相关性和排序准确性,我们可以使用基于 NVIDIA Rerank 类,构建于 NVIDIA NeMo Retriever Reranker 模型之上。Reranker 模型会评估检索到的文档块与用户查询的相关性,并据此重新排序,确保更相关的信息优先呈现给用户。在本示例中,我们将 Reranker 初始化如下:

from langchain_nvidia_ai_endpoints import NVIDIARerank
reranker = NVIDIARerank(model=RETRIEVER_RERANK_MODEL)

基础:检索器工具创建

通过结合文档检索器与文档重排序器,我们现在能够构建一个完整的文档检索系统,如下所示:

RETRIEVER = ContextualCompressionRetriever(
    base_retriever=kb_retriever,
    base_compressor=reranker,
)

LangChain ContextualCompressionRetriever 可以轻松地将检索器与其他处理步骤相结合,并将检索链附加到重新排序模型上。现在,我们可以创建检索器工具,以启用 ReAct Agent。

在本示例中,我们可以使用以下 LangChain 工具包初始化检索器工具,并传入初始化的检索器:

from langchain.tools.retriever import create_retriever_tool
RETRIEVER_TOOL = create_retriever_tool(
    retriever=RETRIEVER,
    name="company_llc_it_knowledge_base",
    description=(
        "Search the internal IT knowledge base for Company LLC IT related questions and policies."
    ),
)

基础:智能体配置

有了向量数据库和检索链,我们就可以构建智能体图。该智能体图充当一种流程图,描绘出模型为完成任务所能采取的步骤。在传统的分步式 LLM 应用中,这些流程被称为“链”;而当工作流涉及更动态的非线性决策时,我们则称之为“图”,智能体可根据当前任务的上下文和需求,选择不同的路径,并分支到相应的决策节点。

鉴于 ReAct 智能体架构被广泛应用,LangGraph 提供了用于构建 ReAct 智能体图的函数。本示例中,我们将按如下方式使用它:

from langgraph.prebuilt import create_react_agent
AGENT = create_react_agent(
    model=llm,
    tools=[RETRIEVER_TOOL],
    prompt=SYSTEM_PROMPT,
)

通过构建智能体图,我们打造了一个动态且灵活的工作流,使 IT 帮助台智能体能够高效处理复杂的决策流程。该方法确保智能体可以精准检索与处理信息,提供准确响应,并灵活适应多种场景。

运行代理

恭喜!您已成功创建智能体,现在让我们来测试一下。

要开始在终端运行代理,请使用 cd 命令进入包含代理代码的 Python 文件所在目录。完成后,使用 LangGraph CLI 启动您的 Agent API。当您对代码进行修改并保存时,代理将自动重新加载。

langraph dev

要与您的代理聊天,Simple Agents Client 中包含了一个简单的 Streamlit 应用。您还可以通过 Jupyter Launcher 页面访问 Streamlit Client。在侧边栏中,确保选中 RAG_AGENT 客户端,然后开始聊天!

A screenshot of the Simple Agents Client tile
图 9:单击“NVIDIA DevX 学习路径”中的“Simple Agents Client”图块,启动 Streamlit 聊天应用程序。

随着智能体变得日益复杂,管理其内部复杂性可能变得困难。追踪功能有助于可视化智能体的每一步操作,从而更轻松地调试和优化其行为。在研讨会中,您可以选择配置 LANGSMITH_API_KEY,并在 LangSmith 控制面板 上查看追踪信息。

迁移到本地 NIM 微服务

本研讨会采用 NVIDIA-NEMOTRON-NANO-9B-V2 LLM 从 NVIDIA API Catalog。这些 API 支持评估多种模型并进行快速实验,且免费入门。然而,若需在生产环境中实现无限性能与全面控制,建议使用 NVIDIA NIM 微服务容器在本地部署模型。

在典型的开发工作流程中,智能体和 NIM 容器都将在后台运行,从而让您能够快速执行多任务处理和迭代。在本练习中,我们可以将 NIM 在前台运行,以便轻松监控其输出并确保其正确启动。

首先,您需要登录 NGC 容器注册表,操作如下所示:

echo $NVIDIA_API_KEY | \
  docker login nvcr.io \
  --username '$oauthtoken' \
  --password-stdin

下一步是为 NIM 容器创建一个位置,用于保存其下载的模型文件。

docker volume create nim-cache

现在,我们需要使用 Docker run 命令来拉取 NIM 容器镜像和模型数据文件,然后将模型托管在符合 OpenAI 规范的本地 API 后端。

docker run -it --rm \
    --name nemotron \
    --network workbench \
    --gpus 1 \
    --shm-size=16GB \
    -e NGC_API_KEY=$NVIDIA_API_KEY \
    -v nim-cache:/opt/nim/.cache \
    -u $(id -u) \
    -p 8000:8000 \
    nvcr.io/nim/nvidia/nvidia-nemotron-nano-9b-v2:latest

让 NIM 运行几分钟后,当它显示应用程序启动完成时,您就会知道 NIM 已准备好进行推理。

INFO 2025-09-10 16:31:52.7 on.py:48] Waiting for application startup.
INFO 2025-09-10 16:31:52.239 on.py:62] Application startup complete.
INFO 2025-09-10 16:31:52.240 server.py:214] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
...
INFO 2025-09-10 16:32:05.957 metrics.py:386] Avg prompt throughput: 0.2 tokens/s, Avg generation throughput: 1.1 tokens/s, Running: 0 reqs, Swapped: 0 reqs, Pending: 0 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 0.0%.

现在您的 NIM 已在本地成功运行,接下来需要更新您在 rag_agent.py 中创建的代理,以使其指向本地实例。

llm = ChatNVIDIA(
    base_url="http://nemotron:8000/v1",
    model=LLM_MODEL,
    temperature=0.6,
    top_p=0.95,
    max_tokens=8192
)

由于您的语言模型服务器仍在运行,请返回 Simple Agents Client 并尝试再次向代理发出提示。如果一切正常,您将不会注意到任何变化!

恭喜!现在,您已成功将 LangGraph Agent 迁移到使用本地 NIM 微服务!

结论和后续步骤

该研讨会提供了从基础概念到复杂代理式系统的完整学习路径,强调通过使用生产级工具和技术进行实践学习。

完成此研讨会后,开发者将获得以下实践经验:

  • 基本概念:了解标准 RAG 与代理式 RAG 之间的区别。
  • 状态管理:实现复杂的状态转换和持久性。
  • 工具集成:创建和管理代理式工具调用功能。
  • 现代 AI 堆栈:使用 LangGraph、NVIDIA NIM 和相关工具。

了解详情

有关实战学习、提示和技巧,请于 Nemotron Labs 直播“Build a RAG Agent with NVIDIA Nemotron” 于 2025 年 9 月 23 日(星期二)太平洋时间上午 9 点。

通过订阅 NVIDIA 新闻加入社区,以及在 LinkedInInstagramXFacebook 上关注 NVIDIA AI,及时了解 Agentic AI、Nemotron 等前沿资讯。

此处探索自定进度的视频教程和直播。

 

标签