For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主导航

检索

利用语义相似性搜索您的数据。

检索 API 让您能够对数据执行语义搜索。这项技术可以找出语义相似的结果,即使这些结果仅匹配少量关键词,甚至完全不匹配。检索本身就很实用,与我们的模型结合使用来综合生成回答时,更能发挥强大作用。

检索示意图

检索 API 由向量存储提供支持,向量存储为您的数据建立索引。本指南将介绍如何执行语义搜索,并详细说明向量存储。

快速入门

  • 创建向量存储 并上传文件。

  • 创建包含文件的向量存储
    from openai import OpenAI
    
    client = OpenAI()
    
    vector_store = client.vector_stores.create(        # Create vector store
        name="Support FAQ",
    )
    
    client.vector_stores.files.upload_and_poll(        # Upload file
        vector_store_id=vector_store.id,
        file=open("customer_policies.txt", "rb")
    )
  • 发送搜索查询 以获取相关结果。

  • 搜索查询
    user_query = "What is the return policy?"
    
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query=user_query,
    )

    要了解如何将这些结果与我们的模型结合使用,请参阅综合生成 回答部分。

    语义搜索 是一种利用嵌入向量查找语义相关结果的技术。关键在于,它还能找到与查询只有少量相同关键词,甚至没有相同关键词的结果,而传统搜索技术可能会遗漏这些结果。

    例如,我们来看看 "When did we go to the moon?" 可能返回的结果:

    文本关键词相似度语义相似度
    首次登月发生在 1969 年 7 月。0%65%
    第一个登上月球的人是尼尔·阿姆斯特朗。27%43%
    我吃月饼时,觉得它很美味。40%28%

    (关键词相似度使用交并比计算;语义相似度则使用 text-embedding-3-small余弦相似度计算。)

    请注意,最相关的结果并不包含搜索查询中的任何词。这种灵活性使语义搜索成为查询任意规模知识库的强大技术。

    语义搜索由向量存储提供支持,我们将在本指南后文详细介绍向量存储。本节将重点介绍语义搜索的工作机制。

    您可以使用 search 函数并以自然语言指定 query,来查询向量存储。这会返回一个结果列表,其中每项结果都包含相关文本块、相似度分数和来源文件。

    搜索查询
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query="How many woodchucks are allowed per passenger?",
    )
    结果
    {
      "object": "vector_store.search_results.page",
      "search_query": "How many woodchucks are allowed per passenger?",
      "data": [
        {
          "file_id": "file-12345",
          "filename": "woodchuck_policy.txt",
          "score": 0.85,
          "attributes": {
            "region": "North America",
            "author": "Wildlife Department"
          },
          "content": [
            {
              "type": "text",
              "text": "According to the latest regulations, each passenger is allowed to carry up to two woodchucks."
            },
            {
              "type": "text",
              "text": "Ensure that the woodchucks are properly contained during transport."
            }
          ]
        },
        {
          "file_id": "file-67890",
          "filename": "transport_guidelines.txt",
          "score": 0.75,
          "attributes": {
            "region": "North America",
            "author": "Transport Authority"
          },
          "content": [
            {
              "type": "text",
              "text": "Passengers must adhere to the guidelines set forth by the Transport Authority regarding the transport of woodchucks."
            }
          ]
        }
      ],
      "has_more": false,
      "next_page": null
    }

    默认情况下,响应最多包含 10 条结果,但您可以通过 max_num_results 参数将上限设为最多 50 条。

    查询改写

    某些查询表达方式能带来更好的结果,因此我们提供了一项设置,可自动改写您的查询以获得最佳效果。执行 search 时,设置 rewrite_query=true 即可启用此功能。

    改写后的查询会出现在结果的 search_query 字段中。

    原始查询改写后的查询
    我想知道主办公楼的高度。主办公楼高度
    运输危险品有哪些安全规定?危险品安全规定
    如何就服务问题提出投诉?服务投诉提交流程

    属性筛选

    属性筛选通过应用条件来缩小结果范围,例如将搜索限定在特定日期范围内。您可以在 attribute_filter 中定义和组合条件,在执行语义搜索之前根据文件属性筛选目标文件。

    使用 比较筛选器 ,将文件 attributes 中的特定 key 与给定的 value 进行比较;使用 复合筛选器 ,通过 andor 组合多个筛选器。

    比较筛选器
    {
      "type": "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "in" | "nin",  // comparison operators
      "key": "attributes_key",                           // attributes key
      "value": "target_value"                             // value to compare against
    }
    复合筛选器
    {
      "type": "and" | "or",                                // logical operators
      "filters": [...]
    }

    以下是一些筛选器示例。

    按地区筛选
    {
      "type": "eq",
      "key": "region",
      "value": "us"
    }

    排序

    如果您发现文件搜索结果的相关性不足,可以调整 ranking_options 来提高响应质量。具体包括指定 ranker(例如 autodefault-2024-08-21),以及将 score_threshold 设置为 0.0 到 1.0 之间的值。较高的 score_threshold 会将结果限制为相关性更高的分块,但也可能排除一些潜在有用的分块。提供 ranking_options.hybrid_search 时,您还可以调整 hybrid_search.embedding_weightrrf_embedding_weight)和 hybrid_search.text_weightrrf_text_weight),以控制倒数排名融合如何平衡语义嵌入匹配与稀疏关键词匹配。增大前者可侧重语义相似性,增大后者可侧重文本重合度,并确保至少有一个权重大于零。

    向量存储

    向量存储是为 Retrieval API 和文件搜索工具的语义搜索提供支持的容器。将文件添加到向量存储后,系统会自动对其分块、生成嵌入向量并建立索引。

    向量存储包含 vector_store_file 对象,每个对象都以一个 file 对象为基础。

    对象类型
    说明
    file表示通过 Files API 上传的内容。通常与向量存储配合使用,也用于微调等其他使用场景。
    vector_store用于存放可搜索文件的容器。
    vector_store.file一种封装类型,专门表示已完成分块和嵌入向量生成、并已关联到 vector_storefile
    包含用于筛选的 attributes 映射。

    定价

    费用按您所有向量存储占用的总存储空间计算,具体取决于解析后的分块及其对应嵌入向量的大小。

    存储用量费用
    不超过 1 GB(所有存储合计)免费
    超过 1 GB 的部分$0.10/GB/天

    请参阅过期策略,了解如何尽量降低费用。

    向量存储操作

    创建向量存储
    client.vector_stores.create(
        name="Support FAQ",
        file_ids=["file_123"]
    )

    向量存储文件操作

    某些操作是异步的,可能需要一段时间才能完成,例如对 vector_store.file 执行 create。您可以使用 create_and_poll 等辅助函数阻塞等待,直到操作完成,也可以自行检查状态。从向量存储中移除文件采用最终一致性机制,因此在移除后的一小段时间内,搜索结果仍可能包含该文件的内容。

    添加文件的速率限制按向量存储 ID 分别计算。对 /vector_stores/{vector_store_id}/files/vector_stores/{vector_store_id}/file_batches 的请求共享每个向量存储每分钟 300 次请求的限额。

    创建向量存储文件
    client.vector_stores.files.create_and_poll(
        vector_store_id="vs_123",
        file_id="file_123"
    )

    批处理操作

    创建批处理操作
    client.vector_stores.file_batches.create_and_poll(
        vector_store_id="vs_123",
        files=[
            {
                "file_id": "file_123",
                "attributes": {"department": "finance"}
            },
            {
                "file_id": "file_456",
                "chunking_strategy": {
                    "type": "static",
                    "max_chunk_size_tokens": 1200,
                    "chunk_overlap_tokens": 200
                }
            }
        ]
    )

    创建批次时,您可以提供 file_ids,并按需指定 attributes 和/或 chunking_strategy;也可以使用 files 数组,为每个文件传入包含 file_id 以及可选的 attributeschunking_strategy 的对象。这两种方式互斥,便于您明确控制是让所有文件共用相同设置,还是按文件覆盖设置。

    为提高向单个向量存储摄取数据的吞吐量,我们建议尽可能使用批量创建。每个批次可在一次请求中包含最多 500 个文件,与发送大量单文件创建请求相比,这通常能减少资源争用并降低端到端延迟。

    属性

    每个 vector_store.file 都可以关联 attributes,这是一个值字典,在使用属性筛选进行语义搜索时可以引用其中的值。该字典最多可以包含 16 个键,每个键最多包含 256 个字符。

    创建带有属性的向量存储文件
    client.vector_stores.files.create(
        vector_store_id="<vector_store_id>",
        file_id="file_123",
        attributes={
            "region": "US",
            "category": "Marketing",
            "date": 1672531200      # Jan 1, 2023
        }
    )

    过期策略

    您可以通过 expires_aftervector_store 对象设置过期策略。向量存储过期后,所有关联的 vector_store.file 对象都会被删除,您也无需再为这些对象付费。

    为向量存储设置过期策略
    client.vector_stores.update(
        vector_store_id="vs_123",
        expires_after={
            "anchor": "last_active_at",
            "days": 7
        }
    )

    限制

    文件大小上限为 512 MB。每个文件包含的 Token 数不应超过 5,000,000(在您附加文件时自动计算)。

    分块

    默认情况下,max_chunk_size_tokens 设置为 800chunk_overlap_tokens 设置为 400,这意味着每个文件在建立索引时会被拆分为每块 800 个 Token 的块,相邻块之间有 400 个 Token 重叠。

    您可以在向向量存储添加文件时,通过设置 chunking_strategy 来调整分块方式。此策略有以下限制:

    • max_chunk_size_tokens 必须介于 100 和 4096 之间(包含两端值)。
    • chunk_overlap_tokens 必须为非负数,且不应超过 max_chunk_size_tokens / 2

    综合生成回答

    执行查询后,您可能希望根据结果综合生成回答。您可以向我们的模型提供查询结果和原始查询,让模型生成有据可依的回答。

    执行搜索查询以获取结果
    from openai import OpenAI
    
    client = OpenAI()
    
    user_query = "What is the return policy?"
    
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query=user_query,
    )
    根据结果综合生成回答
    # Use results and user_query from the preceding search step.
    formatted_results = format_results(results.data)
    
    "\n".join("\n".join(c.text for c in result.content) for result in results.data)
    
    completion = client.chat.completions.create(
        model="gpt-6-astra",
        messages=[
            {
                "role": "developer",
                "content": "Produce a concise answer to the query based on the provided sources.",
            },
            {
                "role": "user",
                "content": f"Sources: {formatted_results}\n\nQuery: '{user_query}'",
            },
        ],
    )
    
    print(completion.choices[0].message.content)
    "Our return policy allows returns within 30 days of purchase."

    这里使用了一个示例 format_results 函数,其实现方式可以 如下:

    结果格式化函数示例
    def format_results(results):
        formatted_results = ""
        for result in results.data:
            formatted_result = (
                f"<result file_id='{result.file_id}' file_name='{result.file_name}'>"
            )
            for part in result.content:
                formatted_result += f"<content>{part.text}</content>"
            formatted_results += formatted_result + "</result>"
        return f"<sources>{formatted_results}</sources>"