在构建大语言模型应用时,尤其是需要处理大量专业文档的场景,将资料转化为模型可检索的上下文是实现精准回答的关键。Gemini API 提供的 File Search 功能,为开发者提供了一套完整的检索增强生成(RAG)方案,允许我们将数据持久化存储,并基于索引进行查询。
与临时上传文件不同,File Search 通过专用的存储区(Store)管理数据,不仅支持长期保存,还能通过元数据进行过滤,并利用引用(Citation)功能辅助进行事实核查与验证。本文将深入解析如何搭建这一流程。
一、 核心概念:File Search 与存储区
在使用 Gemini 的文件搜索功能前,必须明确其与普通 File API 的区别。普通 File API 上传的文件主要用于短期处理,原始文件会在 48 小时后自动删除。而 File Search 存储区(File Search Store)是专门为文档嵌入(Embeddings)设计的容器。
导入到存储区的数据会无限期存储,直到你手动将其删除。这意味着你可以构建多个存储区来对不同类别的文档进行归档。在 API 层级,可以通过 FileSearchStore API 对这些存储区进行管理,包括创建、列出、获取和删除。
二、 搭建与索引步骤
实现 File Search 的第一步是创建一个存储区,并将文档导入其中。此过程包含嵌入模型的配置,目前支持 gemini-embedding-2 等模型。
1. 创建存储区
使用 client.file_search_stores.create 方法来初始化存储区。你需要为其指定一个显示名称(display_name)和嵌入模型:
from google import genai
from google.genai import types
import time
client = genai.Client()
# 创建存储区
file_search_store = client.file_search_stores.create(
config={
'display_name': 'your-fileSearchStore-name',
'embedding_model': 'models/gemini-embedding-2'
}
)
2. 上传与索引文档
创建存储区后,使用 upload_to_file_search_store 方法上传文件。该过程是一个异步操作,你需要轮询操作状态,直到 operation.done 为 True,表示索引已构建完成。
operation = client.file_search_stores.upload_to_file_search_store(
file='sample.txt', # 待上传的文件路径
file_search_store_name=file_search_store.name,
config={'display_name': 'display-file-name'}
)
# 等待索引完成
while not operation.done:
time.sleep(5)
operation = client.operations.get(operation)
注意:目前 File Search 不支持音频和视频格式,请确保上传的文件格式符合当前接口规范。
三、 在 Interactions 中执行检索
当索引完成后,你可以在 client.interactions.create 中调用 file_search 工具。通过将存储区名称传入 file_search_store_names 列表,模型便能基于已索引的文档执行检索。
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Can you tell me about the project specifications?",
tools=[{
"type": "file_search",
"file_search_store_names": [file_search_store.name]
}]
)
通过这种方式,模型在生成回答时,会首先在指定的存储区中查找相关信息,将其作为上下文,从而辅助模型提供更相关的回答。
四、 引用核对与页码追踪
RAG 应用最核心的价值之一是“可溯源”。Gemini 的 File Search 支持返回引用信息,帮助用户核实模型回答的依据。
1. 访问引用信息
模型生成的回答中可能包含引用信息,这些信息包含在响应的 annotations 属性中。你可以通过遍历 interaction.steps 来提取这些数据。
for step in interaction.steps:
if step.type == 'model_output':
for content in step.content:
if content.type == 'text' and content.annotations:
print(content.annotations)
2. 获取 PDF 页码
如果上传的文档是 PDF 等包含页码格式的文件,模型在检索并生成引用时,可以定位到具体的页码。你可以通过 file_citation 注解中的 page_number 属性来获取此信息:
for step in interaction.steps:
if step.type == "model_output":
for content in step.content:
if content.type == "text" and content.annotations:
for annotation in content.annotations:
if annotation.type == "file_citation" and annotation.page_number:
print(f"Cited Page: {annotation.page_number}")
这对于需要对长篇文档进行事实核查的场景非常有用。
五、 进阶管理:元数据与费用说明
1. 元数据过滤
如果你的存储区内包含大量文档,可以通过向文件添加自定义元数据(Key-Value 对)来缩小搜索范围。在进行大规模检索时,这有助于提高检索的相关性和准确度,避免无关文档的干扰。
2. 费用与生命周期
关于成本,Gemini 官方说明如下:查询时的文件存储和嵌入生成是免费的。你主要需要承担的是首次为文件编制索引时支付的嵌入创建费用,以及正常的 Gemini 模型输入/输出 Token 费用。请务必根据业务规模预估这些成本。
管理方面,请记住 File Search 存储区的内容是持久化的。如果不使用,需通过 API 手动删除存储区,否则数据将一直保留。
更多关于 Gemini API 的开发实践与最新进展,可参考本站 Gemini 文章专栏。具体 API 接入与计费规则以本文引用的 Google 官方文档为准,若在开发过程中遇到复杂问题,也可访问 帮助中心 或使用 相关辅助工具。
六、 常见问题 FAQ
Q: 普通 File API 上传和 File Search 存储区有什么区别? A: 普通 File API 上传的文件会在 48 小时后自动删除,仅适用于短期任务;File Search 存储区的数据则会无限期保存,直到你手动删除,适合需要长期检索的 RAG 系统。
Q: File Search 是否支持所有文件格式? A: 目前 File Search 功能不支持音频和视频格式,建议优先使用文本或 PDF 文档进行索引。
Q: 如何在多个文档中精确查找? A: 你可以为文件添加自定义元数据(键值对),并在检索时利用这些元数据来过滤搜索范围,从而锁定特定的文档集。
Q: 如何确认模型的回答是基于哪份文件?
A: 当模型生成包含引用的回答时,响应中会包含 annotations 属性。你可以遍历其中的 file_citation 来查看引用来源,该属性可辅助指明用于生成回答的文档部分。
Q: 针对 PDF 文档,能定位到具体页码吗?
A: 如果模型回答中包含引用且文档支持页码解析,你可以在 file_citation 注解中通过 page_number 属性访问该信息。
Q: 使用 File Search 会产生哪些费用? A: 根据官方说明,查询时的文件存储和嵌入生成本身是免费的。费用主要包括首次创建嵌入时的费用,以及日常的 Gemini 模型输入和输出 Token 费用。