登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

OpenAI File Search 元数据过滤怎样缩小检索范围

来源:17golang原创

时间:2026-09-14 11:18:08 426浏览 收藏

我第一次把产品文档接入 File Search 时,最容易犯的错是把“只查中文、只查某个租户”写进提示词。这样只能请求模型自行理解,不能真正缩小候选文件范围。更稳的做法是:文件挂入 vector store 时写入 attributes,调用 Responses API 时把条件放进 file_search.filters。过滤负责先排除不符合条件的文件,语义检索再在剩余内容中找答案。

官方地址:https://developers.openai.com/api/reference/overview

要点速览
  • 元数据挂在 vector_store.file 上,不是只写在原始文件名里。
  • 同一字段要保持类型稳定;租户、语言适合字符串,年份适合数字。
  • 先用 and 收窄范围,再按业务需要增加 orin 或范围条件。

先把可筛选信息写进 vector store file

File Search 过滤的对象是已经附加到 vector store 的文件。创建附加关系时传入一个扁平的键值对象,例如把租户和语言设为字符串,把年份设为数字。官方接口限制这组属性最多 16 个键;键最长 64 个字符,字符串值最长 512 个字符,值可以是字符串、数字或布尔值。

from openai import OpenAI

client = OpenAI()

# 这些属性挂在 vector_store.file 上,后续过滤时按同名 key 比较。
client.vector_stores.files.create(
    vector_store_id="vs_123",
    file_id="file_policy_zh",
    attributes={
        "tenant": "acme",
        "language": "zh",
        "year": 2026,
        "is_public": True,
    },
)

# 生产代码应等待文件状态变为 completed,再把它交给检索。
print("attributes attached")
OpenAI File Search 元数据过滤示意:文件挂入 vector store file 后绑定 tenant、language、year 属性
图1:把文件属性绑定到 vector store file 的操作示意图;属性是后续筛选使用的字段,不是文件正文。

这里还有一个容易混淆的边界:attributes 描述文件,正文切块和向量召回仍然针对文件内容。不要把整段业务标签塞进属性,也不要把同一含义一会儿写成数字、一会儿写成字符串,否则条件看起来正确,结果仍可能为空。

用 AND 同时限定租户和语言

在 Responses API 中,File Search 工具接收 vector_store_ids 和可选的 filters。单个比较条件包含 typekeyvalue;多个条件用复合过滤器组合。下面的条件表示“tenant 等于 acme,并且 language 等于 zh”。

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-6-astra",
    tools=[{
        "type": "file_search",
        "vector_store_ids": ["vs_123"],
        "filters": {
            "type": "and",
            "filters": [
                # 先按租户隔离资料,再限制语言范围。
                {"type": "eq", "key": "tenant", "value": "acme"},
                {"type": "eq", "key": "language", "value": "zh"},
            ],
        },
    }],
    input="退款申请需要哪些材料?请只依据命中的资料回答。",
)

# 这里只打印模型回答;调试时可按官方 include 选项取回检索结果。
print(response.output_text)

过滤条件越像数据库的前置条件,越容易解释。用户问“退款材料”时,提示词负责表达问题,filters 负责表达资料边界。两者不要互相替代。若需要审计回答依据,可以在请求中按官方接口支持的方式包含 File Search 结果,再记录命中的文件 ID 和 attributes。

OR、in 和年份范围怎么选

当一个问题允许多个值时,不必拼接一长串自然语言。or 适合“中文或英文”;in 适合一个字段从一组离散值中选择;数字字段则可以使用 gtelt 等范围运算。

需求推荐条件注意
只要中文资料eq language zh写入时保持语言值一致
中文或英文or 包含两个 eq只放真正互斥或可替代的条件
2025、2026 两个版本in year [2025, 2026]年份应作为数字保存
2025 年及以后gte year 2025确认旧文件也有 year 属性
# 只保留 2025 年及以后、且属于两个产品线之一的资料。
filters = {
    "type": "and",
    "filters": [
        {"type": "gte", "key": "year", "value": 2025},
        {"type": "in", "key": "product", "value": ["billing", "support"]},
    ],
}

# 将 filters 放入 file_search 工具;不要把它写成 input 文本中的软约束。
tool = {
    "type": "file_search",
    "vector_store_ids": ["vs_123"],
    "filters": filters,
}
OpenAI File Search 复合过滤结果示意:and 条件先筛掉其他租户文件,再返回匹配的产品资料片段
图2:复合过滤后的结果示意图;先按属性排除文件,再在命中集合中返回相关片段。

过滤后为空,按四个边界排查

结果为空时,先别急着降低相似度阈值。按下面顺序查,通常能很快分清是元数据问题还是查询本身过严。

  1. 查附加对象:确认属性写在 vector_store.file,而不是只写在上传 File 的自定义记录里。
  2. 查类型:year 若写入时是字符串,查询就不要假设它是数字;更好的修复是统一写入规范并重新附加文件。
  3. 查状态:文件仍处于 in_progress 时,不要把它当作已经可检索的资料。
  4. 拆条件:先只保留一个 eq,再逐个加回条件。第一个让结果消失的条件,就是优先检查的字段。

另外,max_num_results 控制最多返回多少条结果,官方接口范围是 1 到 50。它解决的是返回数量,不是元数据隔离;把数量调大不能修复错误的属性值。

相关问题

元数据过滤会改变文件的切块方式吗?

不会。过滤用于按文件属性限制候选范围,切块策略是附加文件时的另一组设置。两者应分别设计和排查。

能用文件名代替 attributes 吗?

不建议。文件名适合展示和人工识别,稳定的租户、语言、版本和权限边界应写成结构化属性。

什么时候用 OR 而不是 IN?

同一个字段的多个离散值通常优先考虑 in;需要组合不同字段或嵌套条件时,用 or 表达逻辑关系更清楚。

过滤为空是不是说明模型没找到答案?

不一定。先区分“没有符合属性的文件”和“有符合文件但内容相关性不足”,分别检查属性、状态和查询文本。

实际落地时,我会把属性字典当成检索接口的一部分维护:字段名固定、类型固定、缺省值有约定,新增过滤条件先用单条件验证,再合并到 and。这样 File Search 缩小的是可解释的资料集合,而不是让提示词承担本该由数据边界完成的工作。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>