TodayAI

GuidesRAG

用 Responses API File Search 检索 PDF 知识库

上传一个 PDF 到 OpenAI Vector Store,再用 Responses API 的 file_search 基于这份文件回答问题。

基于 OpenAI Cookbook 整理 · 官方资料 ↗

很多 RAG 教程一上来就让你自己处理整条链路:解析 PDF、切 chunk、做 embedding、建向量库,再自己写 retrieval。这条路适合你要深度定制检索策略的时候,但对很多真实需求来说过重了。

如果你现在只是想做到一件事——让模型根据一批 PDF 回答问题——OpenAI File Search 已经把其中大部分检索基础设施托管掉了。你不用自己维护向量库,也不用先手写检索再拼 prompt。

这篇就完成一个具体任务:上传一个 PDF,然后让 Responses API 基于这个 PDF 回答问题,并确认答案真的引用了你的文件。

File Search 到底替你做了什么

可以把整条链路理解成:PDF → File → Vector Store → file_search → Responses API。

你把本地 PDF 上传成 OpenAI 的 File,再把它放进 Vector Store。OpenAI 会负责后续的索引与检索。提问时,你不是先自己搜一段文字塞进 prompt,而是在 Responses API 的 tools 里声明 file_search,并告诉它去哪个 Vector Store 里找。

模型决定需要查资料时,会调用这个工具;命中的内容再进入回答过程。对你来说,最重要的工作变成两件:把正确的文件放进去,以及在响应里确认它真的用了这些文件。

准备一个 PDF

先准备最小环境。你需要 Python、可用的 OPENAI_API_KEY,以及至少一个本地 PDF。Cookbook 还会用到 PyPDF2、pandas、tqdm;这篇先走最小可运行路径,依赖按官方示例安装即可。

  • Python 3.10+ 与虚拟环境
  • 环境变量 OPENAI_API_KEY
  • 至少一个本地 PDF(例如放到 openai_blog_pdfs/)
  • 网络可访问 OpenAI API

安装依赖(与官方 Cookbook 一致)

bash
pip install openai PyPDF2 pandas tqdm

创建客户端,并指定 PDF 目录

python
from openai import OpenAI
import os

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
dir_pdfs = "openai_blog_pdfs"  # 放入你的 PDF

创建 Vector Store

Vector Store 是这批文件的检索容器。先创建一个,后面上传和提问都会用到它的 id。

python
vector_store = client.vector_stores.create(name="openai_blog_store")
print(vector_store.id)

把 PDF 放进去

上传分两步:先用 files.create 把本地文件交上去,再用 vector_stores.files.create 把它关联到刚才的 Vector Store。Cookbook 里可以并行上传多个 PDF;这里先用一个文件把链路跑通。

python
file_path = "openai_blog_pdfs/sample.pdf"
file_response = client.files.create(
    file=open(file_path, "rb"),
    purpose="assistants",
)
client.vector_stores.files.create(
    vector_store_id=vector_store.id,
    file_id=file_response.id,
)
print("uploaded", file_response.id)

注意 purpose 要用 "assistants"。文件刚关联进去时,索引可能还需要一点时间;如果立刻提问却完全不引用内容,先确认文件已经处理完成。

怎么确认答案真的来自你的文件

不要只看自然语言是否“像那么回事”。打印 annotations,检查里面有没有命中的 filename。这是这条链路最直接的验证信号。

  • vector_stores.create 返回了带 id 的对象
  • 上传后能在 Vector Store 文件列表中看到 PDF
  • responses.create 返回与 PDF 相关的答案
  • annotations 中能看到命中的 filename

如果 response.output 的下标和示例不一致,先把整个 output 打印出来。Cookbook 的下标假设了特定返回顺序;真实响应里 message 和 file_search_call 的位置可能不同。

什么情况下适合用 File Search

File Search 适合你想尽快验证“基于这些 PDF 能不能答得起来”的场景。它把切块、嵌入和向量存储托管在 OpenAI 一侧,你主要负责上传与提问。

如果你需要精细控制切块策略、本地向量库、复杂权限隔离,或者检索必须完全跑在自己的基础设施里,那就要回到自建 RAG。先用 File Search 证明问题成立,再决定要不要上更重的方案,通常更省时间。

最容易踩的几个坑

上传失败或 purpose 报错

确认文件可读,并使用 purpose="assistants";同时检查 API Key 权限与配额。

问答完全不引用 PDF

确认 vector_store_ids 正确,且文件已经处理完成;换一个 PDF 内明确出现过的问题再试。

response.output 下标与示例不一致

先打印 response.output,按实际 message / file_search_call 项取值,不要死记 Cookbook 里的固定下标。

官方资料

OpenAI Cookbook

Doing RAG on PDFs using File Search in the Responses API