OpenAI Vector Store 文件卡在 in_progress:failed、格式与批次排查
直接答案
OpenAI Vector Store 文件卡在 inprogress:failed、格式与批次排查
症状、差异与判断依据
先区分三个对象
排障时分别记录 File、Vector Store 和 Vector Store File 的 ID。File 是已上传的原始文件;Vector Store 是处理后文件集合;Vector Store File 是某个 File 附加到某个 Vector Store 后的摄取记录。批量附加时还会产生 File Batch 对象。 同一个 fileid 可以参与不同流程,单看 Files API 返回对象无法证明目标向量库已经摄取。日志必须同时保存 fileid、vectorstoreid、可选 batchid、创建时间和请求 ID。
哪个 status 才算可用
OpenAI API Reference 定义 Vector Store File 状态为 inprogress、completed、cancelled 或 failed;只有 completed 表示文件可以使用。Vector Store 自身也有 inprogress、completed 或 expired 状态,并提供各类 filecounts。 客户端不能在创建附加记录后立即假定搜索可用。应轮询单文件或批次,设置合理总时限与退避,并把终态持久化。业务请求到来时若文件未完成,应返回“知识库处理中”,而不是悄悄产生无依据回答。
读取 last_error 而不是只看 failed
Vector Store File 对象提供 lasterror;无错误时为 null。官方 Schema 中的错误代码包括 servererror、unsupportedfile 和 invalidfile,同时带有人类可读 message。内部诊断应保存代码和脱敏 message。 unsupportedfile 通常需要检查文件类型是否被摄取能力支持;invalidfile 要检查内容是否损坏、空文件、编码或实际格式与扩展名不一致;servererror 则适合有限退避后重试。不要对所有错误无差别重传,否则永久格式错误会形成成本和请求风暴。
上传成功不等于内容有效
Files API 接受文件并返回对象,说明上传请求完成,不代表后续使用该文件的每个产品都能解析。官方上传接口说明,不同用途有不同格式和限制;用于 Retrieval 或 filesearch 时,需先上传,再附加到 Vector Store。 在上传前检查真实 MIME、扩展名、文件头、字节数、是否加密或损坏。把网页错误内容保存成 .pdf、把空响应保存为文档、只有扫描图片没有可提取文本,都会使后续效果或解析失败与预期不同。
检查 purpose 与生命周期
Files API 的 purpose 表达预期用途。官方当前列出的值包括 assistants、batch、fine-tune、vision、userdata 和 evals 等;不同功能应使用其支持的用途和格式。不要复用本为 Batch 或 Fine-tuning 构造的 JSONL 文件来假定 File Search 一定能解析。 还要检查 expiresafter 与 expiresat。默认情况下,purpose=batch 文件会在规定时间后过期,其他文件通常保留到手工删除;应用自定义过期策略也可能让延迟摄取引用已失效文件。
文件大小与 token 限制
官方 Files API 当前说明单文件上传上限为 512 MB,项目文件存储有独立容量限制;具体产品还可能施加更严格约束,例如用于相关检索能力的 token 和文件类型限制。上传层上限不是 Vector Store 摄取保证。 记录原始 bytes、可提取文本量和估算 token。异常大的单页、重复文本、压缩炸弹或含大量嵌入对象的 Office/PDF 文件可能增加处理时间。不要通过反复上传同一巨大文件判断系统是否恢复。
批次状态要看 file_counts
File Batch 有 inprogress、completed、cancelled 和 failed 状态,并提供 filecounts.completed、failed、cancelled、inprogress 与 total。批次是聚合操作,排障必须进一步列出其中失败文件,不能只记录一个 batch 状态。 一个批次里多数成功、少数失败时,应用应保留成功结果并只处理失败项。用分页和状态过滤获取全部文件,避免默认一页只返回部分对象而误报“全部完成”。
不要混淆 Files status
Files API 返回对象中的旧 status / statusdetails 字段已标为 deprecated。Vector Store 摄取问题应读取 Vector Store File 的 status 和 lasterror,而不是继续依赖原始 File 的旧处理状态。 SDK 升级时检查类型定义和字段路径。如果监控仍观察 file.status=processed,它无法准确代表某个特定 Vector Store 的附加与索引结果。
in_progress 多久算异常
官方状态模型没有承诺所有文件固定在某个秒数内完成,因此应根据文件大小、类型、批量规模和历史分位数定义内部告警,而不是编造统一 SLA。短暂 inprogress 是正常异步过程。 监控创建时间到终态的延迟,按类型和大小分桶。只有明显超过自己的正常分位、批次不再推进或相关服务事件表明异常时,才标记 stuck。告警中保留 ID,便于重新查询权威状态。
排障步骤与验证
轮询与退避
轮询应使用指数或分阶段退避并带抖动,设置总超时,但超时只表示客户端停止等待,不等于服务端任务失败。超时后保存 checkpoint,后台继续查询同一对象,不能重新创建相同附加请求导致重复记录。 网络超时或 5xx 后先 retrieve 原对象;若创建请求结果未知,使用本地幂等记录和文件/向量库映射核对。不要因为没收到 HTTP 响应就直接再次上传和附加。
chunking_strategy 参数
Vector Store 支持 auto 与静态分块。官方当前自动策略使用最大 800 token、重叠 400 token;静态策略的最大 chunk 大小允许 100 到 4096,overlap 不能超过最大 chunk 的一半。 非法组合通常会在请求校验阶段失败,不应被描述为“摄取卡住”。对于已进入处理的文件,保存实际返回的 chunkingstrategy。调整分块主要影响检索质量和使用量,不是所有 failed 状态的通用修复。
failed 后怎样安全重试
先依据 lasterror.code 分类并修复根因。格式或内容无效时生成新文件并保留原错误证据;瞬时服务错误可有限重试。重试前检查同一 SHA-256、文件名和业务版本是否已经有 completed 记录,避免重复摄取。 对新上传或新附加操作生成内部 attempt ID,记录旧/新 File ID 和 Vector Store File ID。只有新记录到达 completed 且抽样搜索通过后,才切换业务引用;旧记录的删除应是独立、可审计步骤。
cancelled 与删除不是同一件事
File Batch 的 cancel 是尽快尝试取消仍在进行的处理,返回时某些文件可能已经完成或仍在 progress。取消后读取最终 filecounts,不要假设所有文件被回滚。 删除 Vector Store File 会把文件从该 Vector Store 移除,但不会删除原始 File;若要删除底层文件,需要调用相应 Files 删除接口。生产清理程序必须区分这两个作用域,避免误删仍被其他功能使用的文件。
completed 以后还要验收检索
completed 证明摄取完成,不证明文档内容符合业务预期。用 Vector Store Search 对具有明确答案的测试查询验收,检查结果的 fileid、filename、score、attributes 和 content。还可调用文件内容检索接口查看解析后的内容,确认不是空白或乱码。 测试覆盖标题、正文、表格和边界词,并验证属性过滤。若 completed 但搜不到,问题可能在文本提取、分块、查询表达、过滤条件或业务引用了错误 Vector Store,而不是异步状态。
过期的 Vector Store
Vector Store 可配置 expiresafter,当前支持以 lastactiveat 为 anchor;对象会提供 expiresat,状态可能变为 expired。如果应用保存了过期 Vector Store ID,新上传或搜索流程可能与预期不一致。 在恢复任务中先 retrieve Vector Store,确认未 expired、ID 属于正确项目、filecounts 与本地记录一致。不要仅依赖数据库里很久以前保存的 ID。
推荐排查顺序
记录 File、Vector Store、Vector Store File 和 Batch 的全部 ID。 retrieve Vector Store File,读取 status 与 lasterror。 retrieve Vector Store 和 Batch,核对聚合 filecounts。 验证 purpose、实际文件格式、字节数、内容与过期时间。 列出批次全部文件,找出 failed/cancelled 项。 检查轮询总时限、退避、分页和断点恢复逻辑。 按错误码决定修复文件还是有限重试。 completed 后执行解析内容与搜索验收。
建议的状态机
本地状态至少区分 UPLOADED、ATTACHING、INPROGRESS、COMPLETED、FAILED、CANCELLED 和 EXPIRED。每次转移保存远端 ID、时间、错误码和 attempt。重启后从最后状态 retrieve 远端对象,而不是从上传步骤重新开始。 只有 COMPLETED + SEARCHVALIDATED 才能进入业务可用状态。失败记录不应被无期限自动清理,因为它们用于诊断重复文件、格式问题和服务异常。
总结
OpenAI Vector Store 摄取是独立的异步状态机。把原始 File、Vector Store File、Batch 和 Vector Store 分开观察,以单文件 status、lasterror、批次 filecounts 和检索验收组成闭环。对永久文件错误先修复内容,对瞬时错误有限重试,对 inprogress 采用断点轮询,才能避免重复上传、错误计数和知识库静默缺失。
常见问题
Files API 返回成功,为什么 File Search 仍找不到?
上传只是第一步。文件还需附加到正确 Vector Store,并等待 Vector Store File 状态变成 completed,随后再验证搜索结果。
status 为 in_progress 可以立即重传吗?
不应。短暂处理是正常的;先按退避查询同一对象。客户端超时不代表服务端失败,盲目重传会制造重复文件。
批次 completed 是否代表每个文件都成功?
应同时核对 `file_counts` 并列出文件状态。聚合信息和单文件错误是排障依据,不能只保存 batch 顶层字段。
删除 Vector Store File 会删除原文件吗?
不会。它只把文件从该 Vector Store 移除;删除底层 File 是另一个操作,影响范围更大。
completed 后搜不到内容应该重新上传吗?
先查看解析内容、查询、属性过滤、分块和实际使用的 Vector Store ID。只有确认原文件或解析内容错误后再生成新版本。
官方与规范资料
OpenAI API 错误处理OpenAI 官方文档
OpenAI File Search 指南OpenAI 官方文档