Assistants API 深入探究
试用版

创建和管理助手的深入指南。

Assistants 概述中所述,使用 Assistants API 构建应用程序涉及多个概念。source

本指南将更深入地介绍这些概念中的每一个。source

如果您想立即开始编码,请查看 Assistants API 快速入门source

创建助手

我们建议将 OpenAI 的最新模型与 Assistants API 结合使用 以获得最佳效果和与工具的最大兼容性。source

首先,创建 Assistant 只需要指定model使用。但您可以进一步自定义 Assistant 的行为:source

  1. 使用instructions参数来指导 Assistant 的个性并定义其目标。说明类似于 Chat Completions API 中的系统消息。
  2. 使用tools参数,以便 Assistant 访问最多 128 个工具。您可以授予它对 OpenAI 托管工具的访问权限,例如code_interpreterfile_search调用第三方工具,或通过function叫。
  3. 使用tool_resources参数为工具提供code_interpreterfile_search访问文件。文件使用File upload 端点,并且必须具有purpose设置为assistants与此 API 一起使用。

例如,要创建一个 Assistant,该 Assistant 可以基于.csv文件,请先上传一个文件。source

1
2
3
4
file = client.files.create(
  file=open("revenue-forecast.csv", "rb"),
  purpose='assistants'
)

然后,使用code_interpreter工具,并将文件作为资源提供给工具。source

1
2
3
4
5
6
7
8
9
10
11
assistant = client.beta.assistants.create(
  name="Data visualizer",
  description="You are great at creating beautiful data visualizations. You analyze data present in .csv files, understand trends, and come up with data visualizations relevant to those trends. You also share a brief text summary of the trends observed.",
  model="gpt-4o",
  tools=[{"type": "code_interpreter"}],
  tool_resources={
    "code_interpreter": {
      "file_ids": [file.id]
    }
  }
)

您最多可以将 20 个文件附加到code_interpreter和 10,000 个文件更改为file_search(使用vector_store 对象)。source

每个文件的大小最大为 512 MB,最多有 5,000,000 个令牌。默认情况下,项目中上传的所有文件的大小不能超过 100 GB,但您可以联系我们的支持团队来提高此限制。source

管理线程和消息

Threads (线程) 和 Messages (消息) 表示 Assistant 与用户之间的对话会话。每个线程的消息数限制为 100,000 条。一旦 Messages 的大小超过模型的上下文窗口,Thread 将尝试巧妙地截断消息,然后完全删除它认为最不重要的消息。source

您可以创建一个具有初始 Messages 列表的 Thread,如下所示:source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": "Create 3 data visualizations based on the trends in this file.",
      "attachments": [
        {
          "file_id": file.id,
          "tools": [{"type": "code_interpreter"}]
        }
      ]
    }
  ]
)

消息可以包含文本、图像或文件附件。消息attachments是将文件添加到线程的tool_resources.您还可以选择将文件添加到thread.tool_resources径直。source

创建图像输入内容

消息内容可以包含外部图像 URL 或通过文件 API 上传的文件 ID。只有支持 Vision 的型号才能接受图像输入。支持的图像内容类型包括 png、jpg、gif 和 webp。创建图像文件时,将purpose="vision",以便您以后下载并显示输入内容。目前,每个项目有 100GB 的限制。请联系我们以请求提高限制。source

除非指定,否则工具无法访问图像内容。要将图像文件传递给 Code Interpreter,请在消息中添加文件 IDattachmentslist 以允许工具读取和分析输入。目前无法在 Code Interpreter 中下载图像 URL。source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
file = client.files.create(
  file=open("myimage.png", "rb"),
  purpose="vision"
)
thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "What is the difference between these images?"
        },
        {
          "type": "image_url",
          "image_url": {"url": "https://example.com/image.png"}
        },
        {
          "type": "image_file",
          "image_file": {"file_id": file.id}
        },
      ],
    }
  ]
)

低保真或高保真图像理解

通过控制detail参数,该参数有三个选项,low,highauto中,您可以控制模型处理图像和生成其文本理解的方式。source

  • low将启用 “Low Res” 模式。该模型将收到 512 像素 x 512 像素的低分辨率图像版本,并以 85 个令牌的预算表示图像。这允许 API 返回更快的响应,并为不需要高细节的使用案例消耗更少的输入令牌。
  • high将启用“高分辨率”模式,该模式首先允许模型查看低分辨率图像,然后根据输入图像大小创建输入图像的详细裁剪。使用定价计算器查看各种图像大小的令牌计数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "What is this an image of?"
        },
        {
          "type": "image_url",
          "image_url": {
            "url": "https://example.com/image.png",
            "detail": "high"
          }
        },
      ],
    }
  ]
)

上下文窗口管理

Assistants API 会自动管理截断,以确保其保持在模型的最大上下文长度内。您可以通过指定希望运行使用的最大令牌数和/或希望包含在运行中的最近消息的最大数量来自定义此行为。source

Max Completion 和 Max Prompt Tokens

要控制单次 Run 中的令牌使用,请将max_prompt_tokensmax_completion_tokens在创建 Run.这些限制适用于整个运行生命周期中所有完成中使用的令牌总数。source

例如,使用max_prompt_tokens设置为 500 且max_completion_tokens设置为 1000 表示第一次完成会将线程截断为 500 个令牌,并将输出限制为 1000 个令牌。如果在第一次完成中仅使用 200 个提示令牌和 300 个完成令牌,则第二次完成将具有 300 个提示令牌和 700 个完成令牌的可用限制。source

如果完成达到max_completion_tokenslimit,则 Run 将终止,状态为incomplete,详细信息将在incomplete_details字段。source

使用文件搜索工具时,我们建议将 max_prompt_tokens 设置为不小于 超过 20,000 个。对于使用 File Search 进行更长时间的对话或多次交互, 请考虑将此限制增加到 50,000,或者理想情况下,删除 max_prompt_tokens 限制以获得最高质量的结果。source

截断策略

您还可以指定截断策略来控制如何将线程渲染到模型的上下文窗口中。 使用类型为auto将使用 OpenAI 的默认截断策略。使用类型为last_messages将允许您指定要包含在上下文窗口中的最新消息的数量。source

消息注释

由 Google 助理创建的消息可能包含annotationscontent对象的数组。注释提供有关应如何注释 Message 中的文本的信息。source

有两种类型的 Annotation:source

  1. file_citation:文件引文由file_search工具,并定义对 Assistant 上传和用于生成响应的特定文件的引用。
  2. file_path:文件路径注释由code_interpreter工具,并包含对该工具生成的文件的引用。

当 Message 对象中存在注释时,您将在文本中看到难以辨认的模型生成的子字符串,您应该将其替换为注释。这些字符串可能如下所示【13†source】sandbox:/mnt/data/file.csv.下面是一个示例 python 代码片段,它将这些字符串替换为注释中存在的信息。source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Retrieve the message object
message = client.beta.threads.messages.retrieve(
  thread_id="...",
  message_id="..."
)
# Extract the message content
message_content = message.content[0].text
annotations = message_content.annotations
citations = []
# Iterate over the annotations and add footnotes
for index, annotation in enumerate(annotations):
    # Replace the text with a footnote
    message_content.value = message_content.value.replace(annotation.text, f' [{index}]')
    # Gather citations based on annotation attributes
    if (file_citation := getattr(annotation, 'file_citation', None)):
        cited_file = client.files.retrieve(file_citation.file_id)
        citations.append(f'[{index}] {file_citation.quote} from {cited_file.filename}')
    elif (file_path := getattr(annotation, 'file_path', None)):
        cited_file = client.files.retrieve(file_path.file_id)
        citations.append(f'[{index}] Click <here> to download {cited_file.filename}')
        # Note: File download functionality not implemented above for brevity
# Add footnotes to the end of the message before displaying to user
message_content.value += '\n' + '\n'.join(citations)

运行和运行步骤

当您在 Thread 中拥有用户所需的所有上下文时,您可以使用您选择的 Assistant 运行 Thread。source

1
2
3
4
run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant.id
)

默认情况下,Run 将使用modeltools配置,但您可以在创建 Run 时覆盖其中的大部分配置,以增加灵活性:source

1
2
3
4
5
6
7
run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant.id,
  model="gpt-4o",
  instructions="New instructions that override the Assistant instructions",
  tools=[{"type": "code_interpreter"}, {"type": "file_search"}]
)

注意:tool_resources在创建运行期间,无法覆盖与 Assistant 关联的 Assistant。您必须使用 modify Assistant 终端节点来执行此作。source

运行生命周期

Run 对象可以具有多个状态。source

运行生命周期 - 显示可能的状态转换的图表source

地位定义
queued首次创建运行时或完成required_action,它们将移至 queued 状态。他们几乎应该立即迁移到in_progress.
in_progressin_progress时,Assistant 使用模型和工具执行步骤。您可以通过检查 Run Steps 来查看 Run 的进度。
completedRun 成功完成!您现在可以查看 Assistant 添加到 Thread 的所有消息,以及 Run 执行的所有步骤。您还可以通过向 Thread 添加更多用户 Messages 并创建另一个 Run 来继续对话。
requires_action使用函数调用工具时,Run 将移动到required_actionstate 之后,模型确定要调用的函数的名称和参数。然后,您必须运行这些函数并在运行继续之前提交输出。如果在expires_at时间戳通过(创建后大约 10 分钟),运行将变为 Expired 状态。
expired当调用输出的函数之前未提交时,会发生这种情况expires_at并且运行过期。此外,如果运行执行时间过长,并且超出了expires_at,我们的系统将使运行过期。
cancelling您可以尝试取消in_progress使用 Cancel Run 终端节点运行。尝试取消后,Run (运行) 的状态将变为cancelled.尝试取消,但不能保证取消。
cancelled已成功取消运行。
failed您可以通过查看last_error对象。失败的时间戳将记录在failed_at.
incomplete运行结束时间max_prompt_tokensmax_completion_tokens达到。您可以通过查看incomplete_details对象。

轮询更新

如果您未使用流式处理,为了使运行状态保持最新,您必须定期检索 Run 对象。每次检索对象时,您都可以检查运行状态,以确定应用程序下一步应执行的作。source

您可以选择使用我们的 NodePython SDK 中的 Polling Helpers 来帮助您完成此作。这些帮助程序将自动为你轮询 Run 对象,并在 Run 对象处于最终状态时返回该对象。source

线程锁

当 Run 为in_progress而不是处于终端状态,则 Thread 被锁定。这意味着:source

  • 无法将新消息添加到线程中。
  • 无法在 Thread 上创建新的 Run。

运行步骤

运行步骤生命周期 - 显示可能的状态转换的图表source

Run step statuss 与 Run statuss 具有相同的含义。source

Run Step 对象中的大部分有趣细节都位于step_details田。可以有两种类型的步骤详细信息:source

  1. message_creation:当 Assistant 在线程上创建消息时,将创建此运行步骤。
  2. tool_calls:此运行步骤是在 Assistant 调用工具时创建的。有关此内容的详细信息,请参阅工具指南的相关部分。

数据访问指南

目前,通过 API 创建的 Assistants、Threads、Messages 和 Vector Store 的范围限定为创建它们的 Project。因此,任何拥有该项目 API 密钥访问权限的人都可以在项目中读取或写入 Assistants、Threads、Messages 和 Runs。source

我们强烈建议使用以下数据访问控制:source

  • 实施授权。在对 Assistants、Threads、Messages 和 Vector Store 执行读取或写入作之前,请确保最终用户已获得授权。例如,将最终用户有权访问的对象 ID 存储在数据库中,并在使用 API 获取对象 ID 之前对其进行检查。
  • 限制 API 密钥访问。仔细考虑您的组织中哪些人应该拥有 API 密钥并成为项目的一部分。定期审核此列表。API 密钥支持各种作,包括读取和修改敏感信息,例如消息和文件。
  • 创建单独的帐户。请考虑为不同的应用程序创建单独的项目,以便跨多个应用程序隔离数据。