一架梯子,一头程序猿,仰望星空!
OpenAI开发教程 > 内容正文

OpenAI Assistants API开发教程


1. 介绍OpenAI的Assistants API

1.1 Assistants API 的定义与作用

Assistants API允许开发者在自己的应用程序中构建人工智能助手。通过定义自定义的指令与选择模型,助手可以利用模型、工具和知识来回应用户的查询。当前,Assistants API支持三种类型的工具:代码解析器(Code Interpreter)、检索(Retrieval)和函数调用(Function calling)。

1.2 Assistants API 的应用场景

Assistants API适用于各种需要交互式AI支持的场景。例如:

  • 客户支持: 自动回答常见问题,减少人工客服的工作量。
  • 在线教学: 解答学生提出的问题,提供定制化的学习支持。
  • 数据分析: 分析用户上传的数据文件,生成报告和可视化图表。
  • 个性化推荐: 根据用户的历史交互,提供个性化的建议和服务。

1.3. Assistants的核心概念

Assistants API核心对象包括Assistant、Thread和Message。以下是这些对象的详细介绍及其作用:

Assistant

Assistant对象是构建在OpenAI模型之上,能够调用工具的AI助手。您可以自定义Assistant的指令,定制其个性和功能。例如,您可以创建一个名为”数据分析师”的Assistant,它通过“code_interpreter”工具分析数据并生成图表。

Thread

Thread对象表示用户和Assistant之间的对话会话。您可以为每个用户创建一个Thread,并在用户与Assistant交互时将消息添加到其中。Thread对象有效地存储消息历史,并在需要时截断消息以符合模型的上下文长度限制。

Message

Message对象可以是由用户或Assistant创建的消息。消息可能包含文本、图像和其他文件。消息作为列表存储在Thread上。在API的实际使用中,开发者可以向Thread添加用户消息,并根据需要触发Assistant的响应。

Run

Run对象代表执行一次助手请求,在Thread消息内容的基础上调用助手。助手使用它的配置和线程的消息通过调用模型和工具来执行任务。作为运行的一部分,助手将消息附加到线程中。

2. Assistants API开发流程

2.1 创建你的Assistant

要创建一个Assistant,您需要通过API发送包含指令、模型名和工具配置的请求。这里是一个简单的创建个人数学导师助手的例子:

curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "你是一个个人数学导师。编写并运行代码来回答数学问题。",
    "name": "Math Tutor",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4"
  }'

API参数说明:

  • instructions - 系统指令,告诉助手需要干什么。
  • name - 助手名字
  • tools - 定义助手可以使用那些工具。每个助手最多可以有128个工具。目前工具的类型可以是code_interpreter、retrieval或function。
  • model - 助手使用那个模型?

创建Assistant成功之后可以得到Assistant ID。

2.2 创建会话Thread

一个Thread代表一个对话,当用户开启对话时,我们推荐为每个用户创建一个会话Thread。您可以通过以下方式创建Thread:

curl https://api.openai.com/v1/threads \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d ''

Thread创建成功后,可以拿到Threadid。

2.3 向Thread添加消息

你可以向特定的Thread中添加消息,这些消息包含文本,并且可以选择性地包含用户允许上传的文件。例如:

curl https://api.openai.com/v1/threads/{thread_id}/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
      "role": "user",
      "content": "我需要解这个方程 `3x + 11 = 14`。你能帮我吗?"
    }'

API参数说明:

  • thread_id - 代表对话线程ID,创建Thread的时候可以拿到对话线程ID。
  • API请求体是一条用户消息,通常代表用户的问题,跟对话模型的消息结构类似。

2.4 运行Assistant以产生响应

要让助手响应用户消息,您需要创建一个Run。这使得助手读取Thread并决定是否调用工具(如果启用了)或简单地使用模型以最佳方式回答查询。

提示:到目前为止,助手并没有响应用户的问题,只有调用Run api,AI助手才会响应用户的问题。

curl https://api.openai.com/v1/threads/{thread_id}/runs \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "assistant_id": "assistant_id",
    "instructions": "请以Jane Doe称呼用户。该用户为高级账户。"
  }'

API参数说明:

  • thread_id - 代表对话线程ID,创建Thread的时候可以拿到对话线程ID。
  • assistant_id - 代表助手ID,创建Assistant的时候可以拿到助手ID。
  • instructions - 助手指令,可以覆盖创建Assistant的时候设置的指令。

API请求成功会得到一个Run ID

2.5 检查Assistant运行状态

在Assistant启动一个任务(Run)后,任务的执行是异步的。这意味着我们需要定期检查Run的状态,以确定它是否已经完成。为了检查Run的状态,可以通过CURL发出HTTP请求。下面是对这一过程的具体介绍。

CURL请求示例:

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123 \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

API参数详解:

  • https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123:这是API的请求URL,其中thread_abc123是线程(Thread)的唯一标识符,而run_abc123是Run的唯一标识符。

响应体示例:

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "completed",
  "created_at": 1699073585,
  ...
}

API响应参数详解:

  • id:Run的唯一标识符。
  • object:表明了返回对象的类型,这里是thread.run
  • status:Run的状态,可能的值包括queued(排队中)、in_progress(处理中)、completed(完成)、requires_action(需要进一步操作)、failed(失败)等。
  • created_at:Run创建的时间戳。

2.6 获取Assistant响应结果

当Assistant Run运行完成后,我们可以通过检查线程(Thread)中添加的消息来读取Assistant的响应结果。下面通过CURL请求展示如何发起请求,以及对API的参数进行详细讲解。

提示:跟Assistant助手的对话过程,类似两个人聊天的过程,当Assistant助手处理完用户的问题,会把Assistant助手消息追加到对话线程Thread中,因此我们只要查询对话线程Thread中的最新消息就可以获取助手的响应。

CURL请求示例:

curl https://api.openai.com/v1/threads/thread_abc123/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

API参数详解:

  • https://api.openai.com/v1/threads/thread_abc123/messages:API的请求URL,thread_abc123是线程(Thread)的唯一标识符。
  • 与之前检查Run状态时的请求头部相同,包含认证信息和API版本信息。

Assistant响应结果示例:

在此示例中,用户向助手提了一个数学问题,助手在处理结束后在Thread中添加了响应的Message。

用户:我需要解决方程`3x + 11 = 14`。你能帮我吗?
助手:当然可以,Jane Doe。为了解方程`(3x + 11 = 14)`,您需要将`(x)`隔离在方程的一侧。让我为您计算`(x)`的值。
助手:方程`(3x + 11 = 14)`的解是`(x = 1)`。

在从助手获取响应结果后,可以将其展示给用户,辅助用户更好地了解和利用助手为他们提供的服务。

3. Tools:OpenAI提供的内置工具

3.1 Code Interpreter工具

Code Interpreter工具允许Assistants API编写并在沙盒执行环境中运行Python代码。这个工具可以处理各种数据和格式的文件,并生成带有数据和图像的图形的文件。Code Interpreter使您的Assistant能够迭代地运行代码来解决复杂的代码和数学问题。当Assistant写的代码运行失败时,它可以通过尝试不同的代码来迭代这个代码,直到代码执行成功。

启用Code Interpreter

要启用Code Interpreter,请在创建Assistant对象时在tools参数中传递code_interpreter

curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "你是一个个人数学导师。当被问到数学问题时,写代码并运行代码来回答问题。",
    "tools": [
      { "type": "code_interpreter" }
    ],
    "model": "gpt-4-turbo-preview"
  }'

然后,模型会根据用户请求的性质决定在Run时何时调用Code Interpreter。您可以通过Assistant的instructions来促进此行为(例如,“写代码来解决这个问题”)。

使用Code Interpreter处理文件

Code Interpreter可以从文件中解析数据。这在您想为Assistant提供大量数据或允许您的用户上传自己的文件进行分析时很有用。请注意,为Code Interpreter上传的文件不会被索引以用于检索。有关如何为检索索引文件的详细信息,请参阅下面的Retrieval工具部分。

在Assistant级别传递的文件可以被所有与此Assistant关联的Runs访问:

# 上传目的为"assistants"的文件
curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/mydata.csv"

# 使用文件ID创建Assistant
curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "你是一个个人数学导师。当被问到数学问题时,写代码并运行代码来回答问题。",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4-turbo-preview",
    "file_ids": ["file_123abc456"]
  }'

读取Code Interpreter生成的图像和文件

Code Interpreter也可以在API中输出文件,例如生成图像图表、CSV和PDF等。有两种类型的文件被生成:图片和数据文件(例如,Assistant生成的带有数据的CSV文件)。

当Code Interpreter产生一个图像时,您可以在Assistant Message响应的file_id字段中查找和下载这个文件:

{
    "id": "msg_abc123",
    "object": "thread.message",
    "created_at": 1698964262,
    "thread_id": "thread_abc123",
    "role": "assistant",
    "content": [
    {
      "type": "image_file",
      "image_file": {
        "file_id": "file-abc123"
      }
    }
  ]
  // ...
}

3.2 Retrieval工具

Retrieval工具通过向Assistant增加从模型之外的知识(比如专有产品信息或用户提供的文档)来增强其能力。一旦文件上传并传递给Assistant,OpenAI将自动对您的文档进行切片、索引并存储嵌入,并实现向量搜索以检索相关内容以回答用户查询。

启用Retrieval

在Assistant的tools参数中传递retrieval来启用Retrieval:

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "你是一个客户支持聊天机器人。使用你的知识库来最佳地响应客户查询。",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview"
  }'

使用Retrieval上传文件

与Code Interpreter类似,文件可以在Assistant级别或个别Message级别上传。

# 上传目的为"assistants"的文件
curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/knowledge.pdf"

# 将文件添加到Assistant
curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "你是一个客户支持聊天机器人。使用你的知识库来最佳地响应客户查询。",
    "name": "Math Tutor",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview"
    "file_ids": ["file_123abc456"]
  }'

3.3 Function calling工具

与Chat Completions API类似,Assistants API支持调用函数。Function calling允许您向Assistants描述函数,并使其智能返回需要调用的函数以及其参数。在Run调用函数时,Assistants API会暂停执行,并且您可以提供函数调用的结果以继续Run执行。

定义函数

在创建Assistants助手时,你可以定义一组函数供助手调用。这些函数需要在创建助手对象时明确指定。每个函数都应该有一个唯一的名字、描述以及参数规范。

下面的代码展示了如何用curl命令在创建助手时定义两个函数:

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "你是一个天气预报机器人。使用提供的函数来回答问题。",
    "tools": [{
      "type": "function",
      "function": {
        "name": "getCurrentWeather",
        "description": "获取某个地点的天气情况",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "城市和省份,例如:旧金山,加州"},
            "unit": {"type": "string", "enum": ["c", "f"]}
          },
          "required": ["location"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "getNickname",
        "description": "获取城市的昵称",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "城市和省份,例如:旧金山,加州"}
          },
          "required": ["location"]
        }
      }
    }],
    "model": "gpt-4-turbo-preview"
  }'

读取Assistant调用的函数

当用户向助手提交一条消息,并且消息内容触发了一次函数调用时,你需要读取这次函数调用的信息。这一过程中,助手会产生一个requires_action状态的运行(Run),此时你可以通过检索Run对象来获取函数调用的详细信息。

以下是一个检索Run对象的示例,展示了如何获取需要调用的函数信息:

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "requires_action",
  "required_action": {
    "type": "submit_tool_outputs",
    "submit_tool_outputs": {
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "getCurrentWeather",
            "arguments": "{\"location\":\"旧金山\"}"
          }
        },
        {
          "id": "call_abc456",
          "type": "function",
          "function": {
            "name": "getNickname",
            "arguments": "{\"location\":\"洛杉矶\"}"
          }
        }
      ]
    }
  },
  ...
}

tool_calls参数包含了函数调用信息,你只要在本地程序调用对应的函数即可。

提交函数输出

在本地执行了函数调用并获得结果后,你需要将这些结果提交给Assistants助手,以便助手可以继续处理用户的请求。提交函数输出时,需要确保输出与原始函数调用相关联。

以下是如何提交函数输出结果的示例代码:

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_123/submit_tool_outputs \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "tool_outputs": [
      {
        "tool_call_id": "call_abc123",
        "output": "{\"temperature\": \"22\", \"unit\": \"celsius\"}"
      }, 
      {
        "tool_call_id": "call_abc456",
        "output": "{\"nickname\": \"LA\"}"
      }
    ]
  }'

参数说明:

  • thread_abc123 代表对话threadID
  • run_123 代表Run对象的ID
  • tool_call_id 代表某个函数调用ID,通过前面的tool_calls参数获得。

在成功提交了所有函数输出后,Run对象的状态会再次更新,助手将继续处理,并返回最终的响应给用户。


关联主题