我为 Gemini 的文件搜索(managed RAG)API 构建了缺失的 UI

发布: (2026年1月18日 GMT+8 09:30)
8 min read
原文: Dev.to

Source: Dev.to

检索增强生成(RAG)已成为构建了解特定数据的 AI 应用的标准架构。

通常,构建 RAG 流水线涉及许多环节:启动向量数据库(如 Pinecone 或 Weaviate)、编写 Python 脚本对 PDF 进行分块、生成嵌入向量以及管理检索逻辑。

Google 最近推出了一项名为 Gemini File Search 的功能,极大地简化了这一过程。
它是直接内置于 Gemini API 的全托管 RAG 流水线,负责分块、嵌入和存储。更重要的是,其定价模式可以说是最具吸引力的特性。

  • 与传统向量数据库通常按每小时节点使用或存储容量付费不同,Gemini File Search 在查询时提供 免费存储和免费嵌入生成
  • 仅在首次索引文档时收取一次性费用(目前为 每 100 万 token $0.15),以及模型响应的标准输入/输出 token 成本。

这使得它对侧项目和大规模应用都极具成本效益,因为你不必为闲置的向量存储付出额外费用。

但是有个问题

Gemini File Search 完全是 “无头” 的。没有控制台来查看你的文件,没有拖拽上传器,也没有在不编写脚本的情况下测试知识库的方式。如果你想删除文件或检查你的分块策略是否有效,必须编写代码。

我厌倦了仅仅为了管理我的知识库而编写一次性脚本,于是我构建了 Gemini File Search Manager

Gemini File Search Manager Dashboard

什么是 Gemini 文件搜索管理器?

一个开源、本地优先的网页界面,充当 Gemini File Search API 的控制平面。使用 Next.js 构建,它让您可以可视化地管理 RAG 流程。

您可以在此查看代码并在本地运行:

👉

为什么我会构建它以及它解决了哪些问题

可视化“黑盒”

当你以编程方式使用文件搜索 API 时,往往是盲目操作。你创建一个 Store,上传文件,然后希望它能正确处理。

仪表盘显示:

  • 所有活跃的 Store
  • 每个 Store 的文档数量
  • 索引状态(活跃、待处理、失败)

拖拽式导入(不再需要脚本)

通过 API 上传文件是一个多步骤的过程:上传字节、等待操作完成,然后将其关联到 Store。

管理器提供了一个拖拽式界面,负责整个编排。它支持 PDF、TXT、MD、CSV、JSON 以及 Gemini 支持的 100 多种其他格式。

Upload Interface

Gemini API 最强大的功能之一是 自定义分块和元数据。通常你需要在代码中构造复杂的 JSON 对象;现在 UI 让你可以:

  • 调整 maxTokensPerChunkmaxOverlapTokens
  • 添加元数据标签(例如作者、年份),以便后续过滤

RAG 试玩场

上传数据后,你需要验证模型是否真的能检索到它。每个 Store 的 Playground 视图让你可以:

  • 与特定文档聊天(会话历史会被保留)
  • 选择不同模型(Gemini 3 Pro Preview、Gemini 3 Flash、Gemini 2.5 Pro 等)
  • 使用 AIP‑160 语法 按元数据过滤(例如 author = "Smith" AND year > 2020
  • 查看引用——UI 会解析 API 响应中的 groundingMetadata,并准确显示生成答案时使用了哪些文档块。

RAG Playground

深入内部:技术栈

组件技术
框架Next.js 16 (App Router with React 19)
样式Tailwind CSS 4 + shadcn/ui
状态管理TanStack Query
SDK@google/genai

解决异步轮询挑战

当你向 Gemini 上传文件时,文件不会立即变为活跃状态。API 会返回一个 Operation 对象,文件会进入 PROCESSING 状态。

为了避免浏览器卡死,管理器实现了轮询机制:

// Pseudo‑code
const pollOperation = async (operationId) => {
  while (true) {
    const status = await fetchOperationStatus(operationId);
    if (status === 'DONE') break;
    await new Promise(r => setTimeout(r, 3000)); // poll every 3 seconds
  }
};

在初始上传完成后,应用每 3 秒 轮询一次 operations 端点,直到文件的状态变为 ACTIVE(或出现错误)。这使得 UI 保持响应,同时提供对摄取进度的实时反馈。

背景处理

当文档上传后,服务器会立即在后台开始生成嵌入。嵌入生成完成后,系统会自动使缓存失效并更新 UI——文档状态会从加载动画变为绿色对勾。

对于文档列表本身,TanStack Query 每 5 秒进行一次后台重新获取,以捕获任何状态变化。

流式聊天响应

聊天游乐场使用 Server‑Sent Events (SSE) 实时流式传输响应。当模型生成文本时,它会在 UI 中逐字符显示。当流结束时,基础元数据(引用)会被提取并显示在响应下方。

Source:

安全

由于这是面向开发者的工具,我不想处理用户账户或数据库。应用程序本地运行,使用你的环境变量。

  1. 创建一个包含 GEMINI_API_KEY.env.local 文件。
  2. 应用仅在服务器端读取该密钥。

你的密钥永远不会离开你的机器,也不会暴露给客户端浏览器。

快速开始

您可以在大约 2 分钟内让项目运行起来。

1. 克隆仓库

git clone https://github.com/prashantrohilla-max/gemini-file-search-manager
cd gemini-file-search-manager
npm install

2. 添加您的 API 密钥

创建一个 .env.local 文件:

GEMINI_API_KEY=your_key_here

3. 运行应用

npm run dev

打开 http://localhost:3000,即可开始使用。

接下来是什么?

  • 结构化输出 – 用于测试数据提取工作流。
  • URL 导入 – 一项直接从网页导入内容的功能。
  • 持久化聊天会话 – 当前在离开页面或停止服务器时会丢失;持久化功能已在路线图上。

该项目是开源且采用 MIT 许可证。如果你觉得有用,请 ⭐ 仓库或提交 PR!

Repo:

Back to Blog

相关文章

阅读更多 »

Rapg:基于 TUI 的密钥管理器

我们都有这种经历。你加入一个新项目,首先听到的就是:“在 Slack 的置顶消息里查找 .env 文件”。或者你有多个 .env …

技术是赋能者,而非救世主

为什么思考的清晰度比你使用的工具更重要。Technology 常被视为一种魔法开关——只要打开,它就能让一切改善。新的 software,...

踏入 agentic coding

使用 Copilot Agent 的经验 我主要使用 GitHub Copilot 进行 inline edits 和 PR reviews,让我的大脑完成大部分思考。最近我决定 t...