[译][AI OpenAI-doc] 文件搜索 Beta

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 文件搜索通过从其模型外部获取的知识增强了助手的功能,例如专有产品信息或用户提供的文档。通过向量存储库,您可以管理文件的解析、分块、嵌入和存储,以进行关键字和语义搜索。确保向量存储库准备就绪,以确保所有数据可搜索,并利用到期策略管理成本。

文件搜索通过从其模型外部获取的知识增强了助手的功能,例如专有产品信息或用户提供的文档。OpenAI 自动解析和分块您的文档,创建并存储嵌入,并使用向量和关键字搜索来检索相关内容,以回答用户的查询。

快速入门

在这个示例中,我们将创建一个助手,可以帮助回答关于公司财务报表的问题。

步骤 1:创建启用了文件搜索的新助手

在助手的 tools 参数中启用 file_search,创建一个新的助手。

from openai import OpenAI

client = OpenAI()

assistant = client.beta.assistants.create(
  name="Financial Analyst Assistant",
  instructions="您是一位专业的财务分析师。请使用您的知识库来回答关于审计财务报表的问题。",
  model="gpt-4-turbo",
  tools=[{
   "type": "file_search"}],
)

启用了 file_search 工具后,模型会根据用户消息决定何时检索内容。

步骤 2:上传文件并将它们添加到向量存储库

要访问您的文件,文件搜索工具使用 Vector Store 对象。上传您的文件并创建一个 Vector Store 来容纳它们。一旦创建了 Vector Store,您应该轮询其状态,直到所有文件都不再处于“in_progress”状态,以确保所有内容都已完成处理。SDK 提供了一次性上传和轮询的帮助程序。

# Create a vector store caled "Financial Statements"
vector_store = client.beta.vector_stores.create(name="Financial Statements")

# Ready the files for upload to OpenAI
file_paths = ["edgar/goog-10k.pdf", "edgar/brka-10k.txt"]
file_streams = [open(path, "rb") for path in file_paths]

# Use the upload and poll SDK helper to upload the files, add them to the vector store,
# and poll the status of the file batch for completion.
file_batch = client.beta.vector_stores.file_batches.upload_and_poll(
  vector_store_id=vector_store.id, files=file_streams
)

# You can print the status and the file counts of the batch to see the result of this operation.
print(file_batch.status)
print(file_batch.file_counts)

步骤 3:更新助手以使用新的向量存储库

为了使文件对您的助手可访问,请使用新的 vector_store id 更新助手的 tool_resources。

assistant = client.beta.assistants.update(
  assistant_id=assistant.id,
  tool_resources={
   "file_search": {
   "vector_store_ids": [vector_store.id]}},
)

步骤 4:创建一个线程

您也可以将文件作为消息附件附加到您的线程上。这样做将创建另一个与线程关联的向量存储库,或者,如果已经有一个向量存储库附加到此线程上,则将新文件附加到现有线程向量存储库上。当您在此线程上创建一个运行时,文件搜索工具将查询助手的向量存储库和线程上的向量存储库。

在这个例子中,用户附加了一份苹果公司最新的 10-K 报告。

# 将用户提供的文件上传到 OpenAI
message_file = client.files.create(
  file=open("edgar/aapl-10k.pdf", "rb"), purpose="assistants"
)

# 创建一个线程并将文件附加到消息中
thread = client.beta.threads.create(
  messages=[
    {
   
      "role": "user",
      "content": "截止到 2023 年 10 月底,AAPL 的股份有多少?",
      # 将新文件附加到消息中。
      "attachments": [
        {
    "file_id": message_file.id, "tools": [{
   "type": "file_search"}] }
      ],
    }
  ]
)

# 线程现在在其工具资源中具有一个包含该文件的向量存储库。
print(thread.tool_resources.file_search)

使用消息附件创建的向量存储库具有默认的过期策略,在它们最后活跃的 7 天后过期(定义为向量存储库最后成为运行的一部分的时间)。这个默认值有助于您管理向量存储成本。您可以随时覆盖这些过期策略。在这里了解更多信息。

步骤 5:创建一个运行并检查输出

使用流式传输

from typing_extensions import override
from openai import AssistantEventHandler, OpenAI

client = OpenAI()

class EventHandler(AssistantEventHandler):
    @override
    def on_text_created(self, text) -> None:
        print(f"\nassistant > ", end="", flush=True)

    @override
    def on_tool_call_created(self, tool_call):
        print(f"\nassistant > {tool_call.type}\n", flush=True)

    @override
    def on_message_done(self, message) -> None:
        # print a citation to the file searched
        message_content = message.content[0].text
        annotations = message_content.annotations
        citations = []
        for index, annotation in enumerate(annotations):
            message_content.value = message_content.value.replace(
                annotation.text, f"[{index}]"
            )
            if file_citation := getattr(annotation, "file_citation", None):
                cited_file = client.files.retrieve(file_citation.file_id)
                citations.append(f"[{index}] {cited_file.filename}")

        print(message_content.value)
        print("\n".join(citations))

# 然后,我们使用流 SDK 辅助程序
# 用 EventHandler 类创建 Run
# 并流式传输响应。

with client.beta.threads.runs.stream(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="请把用户称为简•多。",
    event_handler=EventHandler(),
) as stream:
    stream.until_done()

不使用流式传输

# Use the create and poll SDK helper to create a run and poll the status of
# the run until it's in a terminal state.

run = client.beta.threads.runs.create_and_poll(
    thread_id=thread.id, assistant_id=assistant.id
)

messages = list(client.beta.threads.messages.list(thread_id=thread.id, run_id=run.id))

message_content = messages[0].content[0].text
annotations = message_content.annotations
citations = []
for index, annotation in enumerate(annotations):
    message_content.value = message_content.value.replace(annotation.text, f"[{index}]")
    if file_citation := getattr(annotation, "file_citation", None):
        cited_file = client.files.retrieve(file_citation.file_id)
        citations.append(f"[{index}] {cited_file.filename}")

print(message_content.value)
print("\n".join(citations))

您的新助手将查询两个附加的向量存储库(一个包含 goog-10k.pdf 和 brka-10k.txt,另一个包含 aapl-10k.pdf),并从 aapl-10k.pdf 返回此结果。

它的工作原理

文件搜索工具实现了几种检索最佳实践,帮助您从文件中提取正确的数据并增强模型的响应。文件搜索工具:

  1. 重写用户查询以优化其用于搜索。
  2. 将复杂的用户查询分解为多个可以并行运行的搜索。
  3. 在助手和线程向量存储库上同时运行关键字搜索和语义搜索。
  4. 在生成最终响应之前,重新排列搜索结果以选择最相关的结果。

默认情况下,文件搜索工具使用以下设置:

  • 块大小:800 个标记
  • 块重叠:400 个标记
  • 嵌入模型:256 维的 text-embedding-3-large
  • 添加到上下文中的最大块数:20(可能更少)

已知限制

我们目前正在努力添加支持的一些已知限制:

  1. 支持修改分块、嵌入和其他检索配置。
  2. 支持使用自定义元数据进行确定性预搜索过滤。
  3. 支持解析文档内的图像(包括图表、图形、表格等)。
  4. 支持对结构化文件格式(如 csv 或 jsonl)进行检索。
  5. 更好地支持摘要生成 —— 目前该工具主要针对搜索查询进行了优化。

向量存储库

向量存储库对象赋予文件搜索工具搜索您的文件的能力。将文件添加到向量存储库会自动解析、分块、嵌入和存储文件在一个向量数据库中,该数据库能够进行关键字和语义搜索。每个向量存储库最多可以容纳 10,000 个文件。向量存储库可以附加到助手和线程上。目前,您最多可以将一个向量存储库附加到一个助手上,最多可以将一个向量存储库附加到一个线程上。

创建向量存储库并添加文件

您可以在单个 API 调用中创建向量存储库并向其添加文件:

vector_store = client.beta.vector_stores.create(
  name="产品文档",
  file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5']
)

向向量存储库添加文件是一个异步操作。为了确保操作完成,我们建议您使用我们官方 SDK 中的“创建和轮询”辅助程序。如果您不使用 SDK,您可以检索向量存储库对象并监视其 file_counts 属性,以查看文件摄取操作的结果。

文件还可以在创建后添加到向量存储库中,方法是创建向量存储库文件。

file = client.beta.vector_stores.files.create_and_poll(
  vector_store_id="vs_abc123",
  file_id="file-abc123"
)

或者,您可以通过创建最多包含 500 个文件的批次,将多个文件添加到向量存储库中。

batch = client.beta.vector_stores.file_batches.create_and_poll(
  vector_store_id="vs_abc123",
  file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5']
)

同样,这些文件可以通过以下方式从向量存储库中移除:

  • 删除向量存储库文件对象,或者
  • 通过删除底层文件对象(从您组织中的所有助手和线程中的所有向量存储库和代码解释器配置中移除文件)

最大文件大小为 512 MB。每个文件应包含不超过 5,000,000 个标记(当您附加文件时会自动计算)。

文件搜索支持各种文件格式,包括 .pdf、.md 和 .docx。有关支持的文件扩展名(及其对应的 MIME 类型)的更多详细信息,请参见下面的支持文件部分。

附加向量存储库

您可以使用 tool_resources 参数将向量存储库附加到您的助手或线程上。

assistant = client.beta.assistants.create(
  instructions="您是一个乐于助人的产品支持助手,您会根据提供给您的文件来回答问题。",
  model="gpt-4-turbo",
  tools=[{
   "type": "file_search"}],
  tool_resources={
   
    "file_search": {
   
      "vector_store_ids": ["vs_1"]
    }
  }
)

thread = client.beta.threads.create(
  messages=[ {
    "role": "user", "content": "我怎样取消订阅?"} ],
  tool_resources={
   
    "file_search": {
   
      "vector_store_ids": ["vs_2"]
    }
  }
)

您还可以在创建后通过使用正确的 tool_resources 更新助手或线程来将向量存储库附加到线程或助手上。

在创建运行之前确保向量存储库准备就绪

我们强烈建议在创建运行之前确保向量存储库中的所有文件都已完全处理。这将确保向量存储库中的所有数据都可以进行搜索。您可以使用我们 SDK 中的轮询辅助程序来检查向量存储库的准备就绪状态,或者通过手动轮询向量存储库对象来确保状态已完成。

作为备用方案,当线程的向量存储库包含仍在处理中的文件时,我们在运行对象中设置了最长等待时间为 60 秒。这是为了确保在运行继续之前线程中的用户上传的任何文件都可以完全进行搜索。此备用等待时间不适用于助手的向量存储库。

利用到期策略管理成本

文件搜索工具使用向量存储库对象作为其资源,您将根据创建的向量存储库对象的大小进行计费。向量存储库对象的大小是您的文件中所有解析块及其相应的嵌入之和。

您的第一个 GB 是免费的,超出部分的使用将按照每 GB/每天的向量存储费用 $0.10 计费。向量存储库操作没有其他费用。

为了帮助您管理与这些向量存储库对象相关的成本,我们在向量存储库对象中添加了对到期策略的支持。您可以在创建或更新向量存储库对象时设置这些策略。

vector_store = client.beta.vector_stores.create_and_poll(
  name="Product Documentation",
  file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5'],
  expires_after={
   
      "anchor": "last_active_at",
      "days": 7
  }
)

线程向量存储库具有默认的到期策略

使用线程辅助程序(如 Threads 中的 tool_resources.file_search.vector_stores 或 Messages 中的 message.attachments)创建的向量存储库具有默认的到期策略,在其最后活跃的 7 天后过期(最后活跃指的是向量存储库最后成为运行的一部分的时间)。

当一个向量存储库到期时,该线程上的运行将失败。要解决此问题,您可以简单地使用相同的文件重新创建一个新的向量存储库,并将其重新附加到线程上。

all_files = list(client.beta.vector_stores.files.list("vs_expired"))

vector_store = client.beta.vector_stores.create(name="rag-store")
client.beta.threads.update(
    "thread_abc123",
    tool_resources={
   "file_search": {
   "vector_store_ids": [vector_store.id]}},
)

for file_batch in chunked(all_files, 100):
    client.beta.vector_stores.file_batches.create_and_poll(
        vector_store_id=vector_store.id, file_ids=[file.id for file in file_batch]
    )

支持的文件

对于文本/ MIME 类型,编码必须是 utf-8、utf-16 或 ascii 之一。

文件格式 MIME 类型
.c text/x-c
.cs text/x-csharp
.cpp text/x-c++
.doc application/msword
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
.html text/html
.java text/x-java
.json application/json
.md text/markdown
.pdf application/pdf
.php text/x-php
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
.py text/x-python
.py text/x-script.python
.rb text/x-ruby
.tex text/x-tex
.txt text/plain
.css text/css
.js text/javascript
.sh application/x-sh
.ts application/typescript

相关文章
|
7天前
|
机器学习/深度学习 人工智能 安全
GLM-Zero:智谱AI推出与 OpenAI-o1-Preview 旗鼓相当的深度推理模型,开放在线免费使用和API调用
GLM-Zero 是智谱AI推出的深度推理模型,专注于提升数理逻辑、代码编写和复杂问题解决能力,支持多模态输入与完整推理过程输出。
112 24
GLM-Zero:智谱AI推出与 OpenAI-o1-Preview 旗鼓相当的深度推理模型,开放在线免费使用和API调用
|
9天前
|
存储 人工智能 自然语言处理
|
20天前
|
人工智能 前端开发 Unix
使用tree命令把自己的代码归类文件目录的方法-优雅草央千澈以优雅草AI智能功能为例给大家展示tree命令实际用法
使用tree命令把自己的代码归类文件目录的方法-优雅草央千澈以优雅草AI智能功能为例给大家展示tree命令实际用法
使用tree命令把自己的代码归类文件目录的方法-优雅草央千澈以优雅草AI智能功能为例给大家展示tree命令实际用法
|
19天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
89 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
19天前
|
数据采集 人工智能 运维
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
本文介绍了阿里云 Elasticsearch 推出的创新型 AI 搜索方案
135 3
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
|
5天前
|
人工智能 自然语言处理 搜索推荐
云端问道12期实操教学-构建基于Elasticsearch的企业级AI搜索应用
本文介绍了构建基于Elasticsearch的企业级AI搜索应用,涵盖了从传统关键词匹配到对话式问答的搜索形态演变。阿里云的AI搜索产品依托自研和开源(如Elasticsearch)引擎,提供高性能检索服务,支持千亿级数据毫秒响应。文章重点描述了AI搜索的三个核心关键点:精准结果、语义理解、高性能引擎,并展示了架构升级和典型应用场景,包括智能问答、电商导购、多模态图书及商品搜索等。通过实验部分,详细演示了如何使用阿里云ES搭建AI语义搜索Demo,涵盖模型创建、Pipeline配置、数据写入与检索测试等步骤,同时介绍了相关的计费模式。
|
24天前
|
人工智能 自然语言处理 并行计算
ASAL:Sakana AI 联合 OpenAI 推出自动探索人工生命的系统,通过计算机模拟生命进化的过程
ASAL 是由 Sakana AI 联合 OpenAI 等机构推出的自动化搜索人工生命系统,基于基础模型实现多种搜索机制,扩展了人工生命研究的边界。
98 1
ASAL:Sakana AI 联合 OpenAI 推出自动探索人工生命的系统,通过计算机模拟生命进化的过程
|
5天前
|
人工智能 算法 API
构建基于 Elasticsearch 的企业级 AI 搜索应用
本文介绍了基于Elasticsearch构建企业级AI搜索应用的方案,重点讲解了RAG(检索增强生成)架构的实现。通过阿里云上的Elasticsearch AI搜索平台,简化了知识库文档抽取、文本切片等复杂流程,并结合稠密和稀疏向量的混合搜索技术,提升了召回和排序的准确性。此外,还探讨了Elastic的向量数据库优化措施及推理API的应用,展示了如何在云端高效实现精准的搜索与推理服务。未来将拓展至多模态数据和知识图谱,进一步提升RAG效果。
|
13天前
|
人工智能 测试技术 决策智能
玩转智能体魔方!清华推出AgentSquare模块化搜索框架,开启AI智能体高速进化时代
清华大学研究团队提出模块化LLM智能体搜索(MoLAS)框架AgentSquare,将LLM智能体设计抽象为规划、推理、工具使用和记忆四大模块,实现模块间的轻松组合与替换。通过模块进化和重组机制,AgentSquare显著提升了智能体的适应性和灵活性,并在多个基准测试中表现出色,平均性能提高17.2%。此外,该框架还具备可解释性,有助于深入理解智能体架构对任务性能的影响。论文地址:https://arxiv.org/abs/2410.06153
55 10
|
17天前
|
人工智能 关系型数据库 分布式数据库
PolarDB-PG AI最佳实践3 :PolarDB AI多模态相似性搜索最佳实践
本文介绍了如何利用PolarDB结合多模态大模型(如CLIP)实现数据库内的多模态数据分析和查询。通过POLAR_AI插件,可以直接在数据库中调用AI模型服务,无需移动数据或额外的工具,简化了多模态数据的处理流程。具体应用场景包括图像识别与分类、图像到文本检索和基于文本的图像检索。文章详细说明了技术实现、配置建议、实战步骤及多模态检索示例,展示了如何在PolarDB中创建模型、生成embedding并进行相似性检索