OpenAI File Search 是 Responses API 的托管工具。应用先把文件加入 Vector Store,再让模型在指定 Vector Store 中执行语义和关键词检索。文件处理和工具执行由平台托管,适合快速验证文档问答。

本文按 OpenAI File Search 官方文档整理。API 和模型支持范围可能变化,实际开发时应再次核对官方文档。

三个对象先分清

对象 含义
File 通过 Files API 上传的原始文件
Vector Store 面向检索的知识库容器
Vector Store File 已关联到某个 Vector Store、正在处理或已完成索引的文件

流程不是把同一文件上传两次,而是:

1
2
3
4
5
本地文件
→ 上传到 Files API,得到 file_id
→ 创建 Vector Store,得到 vector_store_id
→ 把 file_id 关联到 Vector Store
→ 等待处理状态 completed

准备项目

安装官方 JavaScript SDK:

1
pnpm add openai

把 API Key 放在本机环境变量,不要写进代码、Markdown 或 Git:

1
2
export OPENAI_API_KEY="你的本机密钥"
export OPENAI_MODEL="支持 file_search 的模型 ID"

示例目录:

1
2
3
4
5
file-search-demo/
├── docs/
│ └── security-policy.md
├── index-docs.mjs
└── ask.mjs

上传文件并建立知识库

index-docs.mjs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI();

const file = await client.files.create({
file: fs.createReadStream("./docs/security-policy.md"),
purpose: "assistants"
});

const vectorStore = await client.vectorStores.create({
name: "company_policies"
});

const vectorStoreFile = await client.vectorStores.files.create(
vectorStore.id,
{ file_id: file.id }
);

console.log({
fileId: file.id,
vectorStoreId: vectorStore.id,
status: vectorStoreFile.status
});

运行:

1
node index-docs.mjs

保存输出的 vectorStoreId。文件加入后是异步处理的,必须等待状态为 completed 再查询;批量导入时可使用 SDK 提供的轮询辅助方法,具体名称以当前 SDK 文档为准。

让模型搜索文件

ask.mjs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import OpenAI from "openai";

const client = new OpenAI();
const vectorStoreId = process.env.OPENAI_VECTOR_STORE_ID;
const model = process.env.OPENAI_MODEL;

if (!vectorStoreId || !model) {
throw new Error("缺少 OPENAI_VECTOR_STORE_ID 或 OPENAI_MODEL");
}

const response = await client.responses.create({
model,
input: "根据制度,登录失败几次后会锁定账号?请说明文件来源。",
tools: [
{
type: "file_search",
vector_store_ids: [vectorStoreId],
max_num_results: 5
}
],
include: ["file_search_call.results"]
});

console.log(response.output_text);

执行:

1
OPENAI_VECTOR_STORE_ID="vs_..." node ask.mjs

响应中可以出现 file_search_call 和带 file_citation 的消息。include 用于同时返回搜索结果,便于调试召回质量;正式返回给前端前应只暴露用户有权查看的来源信息。

File Search 替你完成了什么

官方托管能力负责知识库文件的处理与检索执行,因此最小项目不需要单独安装向量数据库或手写相似度搜索。

应用仍要负责:

  • 哪些用户可以访问哪个 Vector Store。
  • 文件从哪里来,是否合法、是否包含敏感数据。
  • 文档版本、更新、删除和失效同步。
  • Prompt、答案格式、引用展示和拒答规则。
  • API 超时、错误、限流、费用和监控。
  • 用真实问题评测答案与引用是否正确。

托管工具减少了基础设施代码,不会自动解决业务权限和答案质量。

更新与删除

文件内容变化时,不要继续让旧版本和新版本同时参与检索。常见流程是:

1
2
3
4
5
上传新文件
→ 加入 Vector Store 并等待 completed
→ 验证新版本可检索
→ 从 Vector Store 移除旧文件
→ 按保留策略决定是否删除原始 File

“从 Vector Store 移除文件”和“删除 Files API 中的原始文件”是不同操作。应用应记录 document_id、file_id、vector_store_id 和业务版本之间的映射。

什么时候适合使用

适合:

  • 快速构建小型知识库原型。
  • 不想维护解析、Embedding 和向量索引基础设施。
  • 已使用 OpenAI Responses API。
  • 可以接受托管服务的数据、成本和能力边界。

需要谨慎评估:

  • 必须完全本地部署或有严格数据驻留要求。
  • 需要高度定制的解析、分块、召回或重排序策略。
  • 需要跨多家模型平台共享同一套检索后端。
  • 文档权限复杂且必须与内部系统实时一致。

如果希望其他支持 MCP 的 AI Host 复用这一知识库,可以再开发一个受控 MCP Server,由它调用内部服务或 OpenAI API;File Search 本身是 Responses API 的内置工具,不应直接当成通用 MCP Server 地址。

验收一个最小实验

至少验证三类问题:

  1. 文档中存在答案,返回正确内容和文件引用。
  2. 文档中不存在答案,系统明确说明证据不足。
  3. 文档更新并重新索引后,回答随有效版本变化。

再增加一组越权测试,确认用户不能通过提问检索到其他租户或无权限文件。

一句话记忆

1
2
File 保存原始文件,Vector Store 组织可检索知识,
file_search 在回答前找证据,应用仍负责权限、版本、质量与安全。

站内搜索

没有找到内容!