Gemini与LlamaIndex结合Chroma和WebPageReader的问答系统教程

本教程面向有编程基础的开发者,深入讲解如何利用Gemini、LlamaIndex和Chroma构建基于RAG的问答系统。通过读取网页数据、生成嵌入、存储于Chroma向量库,并集成Gemini LLM,实现精准问答。教程涵盖环境配置、核心组件原理、代码逐段解析、常见错误排查及生产优化建议,帮助开发者掌握RAG架构的工程实践。

技术背景

大型语言模型(LLM)在训练时使用公开数据,无法直接回答私有或定制数据的问题。检索增强生成(RAG)通过检索相关文档片段作为上下文,增强LLM的应答能力。本教程使用Gemini作为LLM和嵌入模型,LlamaIndex作为数据框架,Chroma作为向量数据库,实现一个基于网页内容的问答系统。该方案适用于需要从大量文档中快速提取信息的场景,如企业知识库、产品文档问答等。主要限制包括依赖外部API的速率限制和成本,以及向量检索的准确性受嵌入模型质量影响。

核心原理

RAG架构包含两个核心阶段:检索器和生成器。检索器利用嵌入模型将文档转换为向量,存储在向量数据库中,查询时通过相似度检索返回相关片段。生成器将用户查询与检索到的上下文拼接成提示,交给LLM生成答案。本教程中,SimpleWebPageReader读取网页,BeautifulSoup解析HTML提取文本,Gemini嵌入模型生成向量,Chroma存储向量,VectorStoreIndex构建索引,查询引擎整合检索与生成。关键设计决策包括使用PersistentClient持久化数据,通过Settings统一配置LLM和嵌入模型,以及使用PromptTemplate定制提示模板。

架构分析

系统架构分为数据摄取、索引构建和查询推理三层。数据摄取层使用SimpleWebPageReader和BeautifulSoup从网页提取文本,转换为LlamaIndex的Document格式。索引构建层通过GoogleGenAIEmbedding生成嵌入,ChromaVectorStore存储向量,VectorStoreIndex创建索引。查询推理层使用VectorStoreIndex的as_query_engine方法,结合自定义PromptTemplate,将用户查询转换为LLM可理解的提示。组件间通过LlamaIndex的Settings和StorageContext进行配置和通信。设计上强调模块化,便于替换数据源、嵌入模型或向量数据库。

完整实战教程

##### 版权所有 2026 Google LLC。

# @title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

Gemini API:使用 LlamaIndex 和 Chroma 进行问答

注意: 此笔记本需要付费层级速率限制才能正常运行。(更多详情请参阅定价)。

概述

Gemini 是一系列生成式 AI 模型,让开发者能够生成内容并解决问题。这些模型经过设计和训练,可以处理文本和图像作为输入。

LlamaIndex 是一个简单、灵活的数据框架,可供大型语言模型(LLM)应用程序使用,将自定义数据源连接到 LLM。

Chroma 是一个开源的嵌入数据库,专注于简单性和开发人员生产力。Chroma 允许用户存储嵌入及其元数据,嵌入文档和查询,并快速搜索嵌入。

在本笔记本中,您将学习如何借助 Gemini、LlamaIndex 和 Chroma,创建一个使用网站数据回答问题的应用程序。

设置

首先,您必须安装软件包并设置必要的环境变量。

安装

安装 LlamaIndex 的 Python 库 llama-index。安装 LlamaIndex 的 Gemini 集成包 llama-index-llms-gemini 以及 Gemini 嵌入模型的集成包 llama-index-embeddings-gemini。接下来,安装 LlamaIndex 的网页读取器 llama-index-readers-web。最后,安装 ChromaDB 的 Python 客户端 SDK chromadb 和

%pip install -q -U llama-index
%pip install -q -U llama-index-llms-google-genai
%pip install -q -U llama-index-embeddings-google-genai
%pip install -q -U llama-index-readers-web
%pip install -q -U llama-index-vector-stores-chroma
%pip install -q -U chromadb
%pip install -q -U bs4

配置你的 API 密钥

要运行以下单元格,你的 API 密钥必须存储在名为 GEMINI_API_KEY 的 Colab Secret 中。如果你还没有 API 密钥,或者不确定如何创建 Colab Secret,请参阅 身份验证 示例。

import os
from google.colab import userdata
GEMINI_API_KEY=userdata.get('GEMINI_API_KEY')

os.environ["GEMINI_API_KEY"] = GEMINI_API_KEY

基本步骤

LLM是在大型公共数据语料库上离线训练的。因此,如果没有额外的上下文,它们无法基于自定义或私有数据准确回答问题。

如果你想利用LLM基于私有数据回答问题,你必须在提示中提供相关文档作为上下文。这种方法称为检索增强生成(RAG)。

你将使用这种方法,通过LlamaIndex集成的Gemini文本模型创建一个问答助手。该助手预期回答关于Google Gemini模型的问题。为了实现这一点,你将使用网站数据为助手添加更多上下文。

在本教程中,你将实现基于RAG架构的两个主要组件:

  1. 检索器

根据用户的查询,检索器从文档中检索相关的片段,为上下文增加内容。在本教程中,文档是网站数据。

相关的片段作为上下文传递给下一阶段——“生成器”。

  1. 生成器

来自网站数据的相关片段与用户查询一起传递给LLM,以生成准确的答案。

在接下来的章节中,你将在实现应用程序时进一步了解这些阶段。

导入所需的库

from bs4 import BeautifulSoup
from IPython.display import Markdown, display
from llama_index.core import Document
from llama_index.core import Settings
from llama_index.core import SimpleDirectoryReader
from llama_index.core import StorageContext
from llama_index.core import VectorStoreIndex
from llama_index.readers.web import SimpleWebPageReader
from llama_index.embeddings.google_genai import GoogleGenAIEmbedding
from llama_index.vector_stores.chroma import ChromaVectorStore

import chromadb
import re

1. 检索器

在此阶段,您将执行以下步骤:

  1. 使用 LlamaIndex 读取并解析网站数据。
  1. 创建网站数据的嵌入。

嵌入是文本的数值表示(向量)。因此,具有相似含义的文本将具有相似的嵌入向量。您将使用 Gemini 的嵌入模型来创建网站数据的嵌入向量。

  1. 将嵌入存储在 Chroma 的向量存储中。

Chroma 是一个向量数据库。Chroma 向量存储有助于高效检索相似的向量。因此,为了向 LLM 的提示添加上下文,可以使用 Chroma 轻松检索与用户问题匹配的文本的相关嵌入。

  1. 从 Chroma 向量存储创建检索器。

检索器将用于将相关的网站嵌入与用户查询一起传递给 LLM。

读取并解析网站数据

LlamaIndex 提供了多种多样的数据加载器。要读取网站数据作为文档,你将使用 LlamaIndex 中的 SimpleWebPageReader。

要了解更多关于如何使用 LlamaIndex 的数据加载器从不同来源读取和解析输入数据,请阅读 LlamaIndex 的加载数据指南。

web_documents = SimpleWebPageReader().load_data(
    ["https://blog.google/technology/google-deepmind/gemini-model-thinking-updates-march-2025/"]
)

# Extract the content from the website data document
html_content = web_documents[0].text

你可以使用各种 HTML 解析器从 HTML 内容中提取所需的文本。

在本例中,你将使用 Python 的 BeautifulSoup 库来解析网站数据。处理完成后,提取的文本应转换回 LlamaIndex 的 Document 格式。

# Parse the data.
soup = BeautifulSoup(html_content, 'html.parser')
p_tags = soup.find_all('p')
text_content = ""
for each in p_tags:
    text_content += each.text + "\n"

# Convert back to Document format
documents = [Document(text=text_content)]

初始化 Gemini 的嵌入模型

为了从网站数据创建嵌入,你将使用 Gemini 的嵌入模型 gemini-embedding-001,该模型支持创建文本嵌入。

要使用此嵌入模型,你需要从 LlamaIndex 导入 GeminiEmbedding。要了解更多关于嵌入模型的信息,请阅读 Google AI 的语言文档。

gemini_embedding_model = GoogleGenAIEmbedding(model_name="models/gemini-embedding-001")

初始化 Gemini

您必须从 LlamaIndex 导入 Gemini 来初始化您的模型。

在此示例中,您将使用 gemini-3.7-flash,因为它支持文本摘要。要了解更多关于文本模型的信息,请阅读 Google AI 的模型文档。

您可以在初始化 Gemini LLM 时,使用 *generation_config* 参数配置模型参数,如 *temperature* 或 *top_p*。要了解更多关于模型参数及其用途的信息,请阅读 Google AI 的概念指南。

from llama_index.llms.google_genai import GoogleGenAI

# To configure model parameters use the `generation_config` parameter.
# eg. generation_config = {"temperature": 0.7, "topP": 0.8, "topK": 40}
# If you only want to set a custom temperature for the model use the
# "temperature" parameter directly.

llm = GoogleGenAI(model_name="models/gemini-3.7-flash")

使用 Chroma 存储数据

接下来,你将使用 LlamaIndex 将网站数据的嵌入存储在 Chroma 的向量存储中。

首先,你必须在 chromadb 中启动一个 Python 客户端。由于计划将数据保存到磁盘,你将使用 PersistentClient。你可以在 客户端参考指南 中阅读更多关于 Chroma 中不同客户端的信息。

初始化客户端后,你必须创建一个 Chroma 集合。然后,你将使用上一步创建的集合在 LlamaIndex 中初始化 ChromaVectorStore 类。

接下来,你必须设置 Settings 并为向量存储创建存储上下文。

Settings 是在 LlamaIndex 管道的索引和查询阶段使用的一组常用资源。你可以在 Settings 中指定用于创建应用程序的 LLM、嵌入模型等。要了解更多关于 Settings 的信息,请阅读 Settings 模块指南。

StorageContext 是 LlamaIndex 对不同类型存储的抽象。要了解更多关于存储上下文的信息,请阅读 存储上下文 API 指南。

最后一步是加载文档并构建索引。LlamaIndex 提供了多种索引,有助于为用户查询检索相关上下文。在这里,你将使用 VectorStoreIndex,因为网站嵌入需要存储在向量存储中。

要创建索引,你必须将存储上下文和文档一起传递给 VectorStoreIndex 的 from_documents 函数。

VectorStoreIndex 使用 Settings 中指定的嵌入模型从文档创建嵌入向量,并将这些向量存储在存储上下文指定的向量存储中。要了解更多关于 VectorStoreIndex 的信息,你可以阅读 使用 VectorStoreIndex 指南。

# Create a client and a new collection
client = chromadb.PersistentClient(path="./chroma_db")
chroma_collection = client.get_or_create_collection("quickstart")

# Create a vector store
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

# Create a storage context
storage_context = StorageContext.from_defaults(vector_store=vector_store)

# Set Global settings
Settings.llm = llm
Settings.embed_model = gemini_embedding_model

# Create an index from the documents and save it to the disk.
index = VectorStoreIndex.from_documents(
    documents, storage_context=storage_context
)

使用 Chroma 创建检索器

现在,你将创建一个检索器,用于从新创建的 Chroma 向量存储中检索数据嵌入。

首先,使用与创建 Chroma 向量存储时相同的路径初始化 PersistentClient。然后,从 Chroma 中检索你之前创建的 "quickstart" 集合。你可以使用该集合初始化 ChromaVectorStore,在其中存储网站数据的嵌入。然后,你可以使用 VectorStoreIndex 的 from_vector_store 函数加载索引。

from IPython.display import Markdown

# Load from disk
load_client = chromadb.PersistentClient(path="./chroma_db")

# Fetch the collection
chroma_collection = load_client.get_collection("quickstart")

# Fetch the vector store
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

# Get the index from the vector store
index = VectorStoreIndex.from_vector_store(
    vector_store
)

# Check if the retriever is working by trying to fetch the relevant docs related
# to the phrase 'MMLU' (Multimodal Machine Learning Understanding).
# If the length is greater than zero, it means that the retriever is
# functioning well.
# You can ask questions about your data using a generic interface called
# a query engine. You have to use the `as_query_engine` function of the
# index to create a query engine and use the `query` function of query engine
# to inquire the index.
test_query_engine = index.as_query_engine()
response = test_query_engine.query("AIME")
Markdown(response.response)

2. 生成器

当用户提问时,生成器会提示LLM给出答案。你在上一阶段从Chroma向量存储中创建的检索器将用于将网站数据中的相关嵌入传递给LLM,从而为用户查询提供更多上下文。

在此阶段,你将执行以下步骤:

  1. 使用LlamaIndex创建一个用于回答任何问题的提示。
  1. 使用查询引擎提问并提示模型给出答案。

创建提示模板

你将使用 LlamaIndex 的 PromptTemplate 来生成向 LLM 提问的提示。

在 llm_prompt 中,变量 query_str 稍后会被输入的问题替换,变量 context_str 会被从 Chroma 向量存储中检索到的网站相关文本替换。

from llama_index.core import PromptTemplate

template = (
    """ You are an assistant for question-answering tasks.
Use the following context to answer the question.
If you don't know the answer, just say that you don't know.
Use five sentences maximum and keep the answer concise.\n
Question: {query_str} \nContext: {context_str} \nAnswer:"""
)
llm_prompt = PromptTemplate(template)

使用查询引擎提示模型

你将使用 VectorStoreIndex 的 as_query_engine 函数,通过将 llm_prompt 作为 text_qa_template 参数的值传入,从索引创建查询引擎。然后,你可以使用查询引擎的 query 函数来提示 LLM。要了解更多关于 LlamaIndex 中自定义提示的信息,请阅读 LlamaIndex 的 提示使用模式文档。

# Query data from the persisted index
query_engine = index.as_query_engine(text_qa_template=llm_prompt)
response = query_engine.query("What is Gemini?")
Markdown(response.response)

下一步?

本笔记本仅展示了 langchain 与 Gemini API 的一种可能用例。你可以在此处找到更多示例。

常见问题

常见错误包括:1) API密钥未正确设置,导致认证失败,需确保GEMINI_API_KEY环境变量已配置。2) 依赖包版本不兼容,建议使用pip安装最新版本。3) Chroma持久化路径不一致,导致无法加载集合,需确保使用相同路径。4) 网页解析失败,可能因HTML结构变化,需检查BeautifulSoup选择器。5) 查询结果为空,可能因嵌入模型未正确初始化或向量存储为空。排查方法包括检查日志、验证集合存在性、测试检索器。生产环境优化包括使用异步加载、批量嵌入、缓存查询结果、监控API调用量。

企业应用扩展

可扩展方向包括:1) 集成更多数据源,如PDF、数据库或API。2) 使用不同的嵌入模型或向量数据库(如Pinecone、Weaviate)。3) 实现流式响应以提升用户体验。4) 添加用户反馈机制以优化检索结果。5) 部署为REST API或微服务。6) 结合LangChain等其他框架实现更复杂的Agent行为。

总结

本教程面向有编程基础的开发者,深入讲解如何利用Gemini、LlamaIndex和Chroma构建基于RAG的问答系统。通过读取网页数据、生成嵌入、存储于Chroma向量库,并集成Gemini LLM,实现精准问答。教程涵盖环境配置、核心组件原理、代码逐段解析、常见错误排查及生产优化建议,帮助开发者掌握RAG架构的工程实践。

内容来源与验证

继续系统学习

站内还有更多完整实战教程

加入会员,解锁全部教程、完整代码与持续更新内容。

加入会员
查看全部RAG 与知识库教程