File → Vector Store → 摄取完成 → Responses file_search → 引用与评测。仅用 Files API 上传不会自动产生可搜索知识库;摄取是异步操作,必须确认状态完成。回答页面还应读取 file_citation,调试时显式包含搜索结果,避免模型给出没有来源的“知识库答案”。
官方资料(2026-10-31 核对):File Search guide · Retrieval and Vector Stores · Create Vector Store · File Batch reference · API pricing
File Search 与 Files API、直接文件输入有什么区别?
| 方式 | 对象 | 适合 | 关键边界 |
|---|---|---|---|
| Files API | File / file_id | 上传、到期、读取和删除原始文件 | 不会自动分块和建立检索索引 |
| Responses input_file | 单次请求文件 | 一次性总结或分析少量文件 | 内容直接进入模型上下文,受单次请求限制 |
| File Search | Vector Store / vector_store.file | 可复用知识库与相关片段检索 | 需要异步摄取、召回评测和存储管理 |
| Retrieval API | Vector Store search | 应用自己搜索并处理结果 | 需要自己决定如何把片段交给模型 |
File Search 是 Responses API 的托管工具:模型可以自动发起语义和关键词搜索,再基于检索片段作答。Retrieval API 则允许应用直接查询 Vector Store,适合需要自定义排序、预览、人工选择或把结果交给其他流程的场景。
第一步:创建 Vector Store 并设置到期
Vector Store 是可搜索文件的容器。测试库、临时项目和用户上传库应设置到期,避免孤儿索引持续占用存储。
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
const store = await openai.vectorStores.create({
name: "Support knowledge base",
expires_after: {
anchor: "last_active_at",
days: 30
}
});
console.log(store.id);
expires_after 当前以 last_active_at 为锚点,天数允许 1 到 365。Vector Store 过期后,关联的 vector_store.file 会删除并停止对应存储计费;不要把它误解为业务数据库、原始文件副本或审计记录也会自动清除。
第二步:加入文件并等待摄取完成
如果已经通过 Files API 得到 file_id,可以将其附加到 Vector Store。摄取会自动分块、生成向量并索引,是异步操作。
const indexed = await openai.vectorStores.files.createAndPoll(
store.id,
{
file_id: file.id,
attributes: {
category: "policy",
region: "CN",
published_at: 1793376000
},
chunking_strategy: {
type: "static",
static: {
max_chunk_size_tokens: 1200,
chunk_overlap_tokens: 200
}
}
}
);
if (indexed.status !== "completed") {
throw new Error(`Ingestion failed: ${indexed.status}`);
}
大量文件优先使用 File Batch。一个 Batch 当前最多包含 500 个文件;为同一个 Vector Store 添加文件的单文件和批量接口共享每分钟 300 次限制。完成后同时检查 Batch 的 status 和 file_counts.failed,不能只看请求返回 200。
默认分块与自定义分块怎么选?
| 策略 | 当前规则 | 适合 | 风险 |
|---|---|---|---|
| auto | 800 tokens / 400 overlap | 首次原型、普通文档 | 表格、短 FAQ 或长章节可能不理想 |
| static 小块 | 100–4096 范围内选择较小 chunk | 精确条款、FAQ、短答案 | 上下文不足、命中碎片化 |
| static 大块 | 选择较大 chunk | 需要连续上下文的章节 | 噪声、Token 和存储增加 |
重叠不能超过 chunk 大小的一半。没有对所有知识库都最佳的数字;应准备真实问题和期望来源,比较 Recall@K、正确引用率、无答案拒答率、延迟和成本,再决定是否改变默认值。
第三步:在 Responses 中启用 File Search
const response = await openai.responses.create({
model: "gpt-6-astra",
input: "退款政策允许哪些例外?请给出文件来源。",
tools: [{
type: "file_search",
vector_store_ids: [store.id],
max_num_results: 5,
filters: {
type: "and",
filters: [
{
type: "eq",
key: "category",
value: "policy"
},
{
type: "eq",
key: "region",
value: "CN"
}
]
}
}],
include: ["file_search_call.results"]
});
console.log(response.output_text);
max_num_results 当前允许 1 到 50。减少结果通常能降低延迟和进入上下文的检索内容,但也可能降低召回;不要只凭接口成功决定数值。metadata filter 支持 eq、ne、gt、gte、lt、lte、in、nin,并可用 and/or 组合。
为什么默认看不到完整搜索结果?
模型调用 File Search 后,Response 通常包含一个 file_search_call 输出项和一个 message。回答文字中的 annotations 会包含 file_citation、file_id 和 filename;但搜索调用的结果默认不展开。需要调试、评测或审计时,加入:
include: ["file_search_call.results"]
生产界面应把 citations 显示为用户可点击或可核查的来源,不要只在服务器日志里保存。需要进一步展示原文时,按权限读取 Vector Store File 的已解析内容或原始 File;任何跨租户请求都要校验文件和 Vector Store 所有权。
怎样设计 metadata 和过滤?
- 稳定维度:region、language、department、document_type、product。
- 版本维度:published_at、effective_from、effective_to、revision。
- 权限维度:tenant_id 或 access_group,但必须同时在应用鉴权层强制检查,不能只依赖模型工具参数。
- 状态维度:draft、active、archived,避免草稿和过期政策被召回。
属性不是全文内容的替代品。过滤太严会造成零结果,过滤太松会召回错误地区或旧版本。上线前为常用过滤组合建立自动化检索测试,并对零结果给出明确的“未找到来源”响应。
成本和容量怎么核算?
截至 2026-10-31,官方价格页列出:所有 Vector Store 合计前 1 GB 免费,超出部分为每 GB 每天 0.10 美元;Responses 的 File Search 工具调用为每 1,000 次 2.50 美元;检索内容进入模型后的输入与输出 Token 仍按所选模型计费。
Vector Store 存储按解析后的 chunks 与 embeddings 计算,不等于原文件字节。单个文件当前最高 512 MB,加入 Vector Store 时最多 5,000,000 tokens。应记录 usage_bytes、文件数量、失败数、查询量、工具调用次数与模型 Token,并定期清理过期版本。
更新和删除知识库时有哪些坑?
- 不可把同名上传当覆盖:新文件会有新 file_id;用版本属性或别名表切换有效版本。
- 先摄取新版本:确认 completed 和评测通过,再让查询过滤指向新版本。
- 再移除旧版本:从 Vector Store 移除是最终一致的,短时间仍可能出现在搜索结果。
- 区分三种删除:删除 vector_store.file 是移除关联;删除底层 File 会从所有 Vector Store 移除;删除 Vector Store 是删除整个检索容器。
- 保留审计:记录谁上传、谁发布、谁删除、版本何时生效,以及删除后何时验证不再命中。
上线前检查清单
- 从首页经 Help 可以到达本页,且 Files API 与 File Search 双向内链。
- Vector Store 设置名称、业务所有者、Project 和合理到期策略。
- 文件附加后等待摄取完成,并检查 failed、cancelled 和 last_error。
- 分块策略经过真实问答评测,不照搬默认或经验数字。
- attributes 能区分租户、地区、版本和状态,应用鉴权仍是强制边界。
- File Search 设置合理 max_num_results,并对零结果和低质量结果有处理。
- 调试环境包含 file_search_call.results;生产界面展示 file_citation。
- 记录 usage_bytes、工具调用、模型 Token、延迟、召回率和正确引用率。
- 文件更新采用“新版本摄取→评测→切流→旧版本移除”。
- 删除流程考虑最终一致、缓存、跨 Vector Store 引用和审计。
常见问题
OpenAI File Search 是什么?
File Search 是 Responses API 的托管工具。应用把文件加入 Vector Store 后,OpenAI 会自动分块、生成向量并建立索引;模型需要时会同时使用语义和关键词搜索,取得相关片段后生成回答。
File Search 和 Files API 有什么区别?
Files API 管理原始 File 对象及 file_id;File Search 依赖 Vector Store 和 vector_store.file,把原始文件处理成可检索索引。仅上传 File 不会自动建立知识库,必须把 file_id 加入 Vector Store 并等待摄取完成。
文件加入 Vector Store 后多久可以搜索?
摄取是异步操作,时间取决于文件数量和大小。不要使用固定 sleep 或看到请求返回就开始搜索;应使用 createAndPoll、uploadAndPoll、File Batch 轮询,或检查状态与 file_counts,只有完成且 failed 为 0 后才开放查询。
File Search 默认怎么分块?
当前 auto 策略默认每个 chunk 最多 800 tokens,相邻 chunk 重叠 400 tokens。自定义 static 策略允许 max_chunk_size_tokens 在 100 到 4096 之间,重叠不能超过 chunk 大小的一半;需要用自己的问答评测集验证召回和成本。
怎样查看 File Search 实际检索了哪些内容?
回答文本会通过 file_citation annotations 提供文件引用,但 file_search_call 默认不会返回完整搜索结果。调试和评测时在 Responses 请求中加入 include: ["file_search_call.results"],再记录命中片段、分数、属性和最终引用。
删除 Vector Store 中的文件会立即消失吗?
不一定。官方说明从 Vector Store 移除文件是最终一致的,搜索结果可能在短时间内仍包含该内容。删除 vector_store.file 只是移除索引关联;删除底层 File 会把它从所有 Vector Store 中移除,生产系统需要设计等待、缓存和审计。
OpenAI File Search 怎么收费?
截至 2026-10-31,官方价格页列出的 Vector Store 存储前 1 GB 免费,超出部分为每 GB 每天 0.10 美元;Responses 的 File Search 工具调用为每 1,000 次 2.50 美元,模型输入和输出 Token 另按所选模型计费。价格可能调整,上线前应再次核对官方价格页。
如果你要自己管理模型、维度、向量数据库、权限过滤和召回评测,参见 OpenAI Embeddings API 教程。
本文核对日期为 2026-10-31。File Search 的模型支持、分块默认值、限制、价格、字段和删除语义可能变化,上线前请再次读取官方 File Search、Retrieval、Vector Store API 与价格页。