English
主导航

旧版 API

Assistants 函数调用

在 Responses API 实现功能对等后,我们已弃用了 Assistants API。该 API 将于 2026 年 8 月 26 日关闭。请参阅 迁移指南 to update your integration. 了解更多.

概览

与 Chat Completions API 类似,Assistants API 支持函数调用。函数调用允许你向 Assistants API 描述函数,并让它智能地返回需要调用的函数及其参数。

快速入门

在这个例子中,我们将创建一个天气助手并定义两个函数, get_current_temperature and get_rain_probability,作为 Assistant 可以调用的工具。根据用户的查询,如果使用 2023 年 11 月 6 日及之后发布的最新模型,模型将调用并行函数。在我们使用并行函数调用的示例中,我们将询问 Assistant 旧金山今天的天气情况以及降雨的概率。我们还将展示如何通过流式输出生成 Assistant 的响应。

随着 Structured Outputs 的发布,你现在可以使用参数 strict: true 在使用 Assistants API 进行函数调用时。有关更多信息,请参阅 函数调用指南。请注意,在使用视觉功能时,Assistants API 不支持结构化输出。

第 1 步:定义函数

在创建助手时,你将首先在助手的 tools 参数下定义函数。

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from openai import OpenAI
client = OpenAI()

assistant = client.beta.assistants.create(
instructions="You are a weather bot. Use the provided functions to answer questions.",
model="gpt-4o",
tools=[
{
"type": "function",
"function": {
"name": "get_current_temperature",
"description": "Get the current temperature for a specific location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g., San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["Celsius", "Fahrenheit"],
"description": "The temperature unit to use. Infer this from the user's location."
}
},
"required": ["location", "unit"]
}
}
},
{
"type": "function",
"function": {
"name": "get_rain_probability",
"description": "Get the probability of rain for a specific location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g., San Francisco, CA"
}
},
"required": ["location"]
}
}
}
]
)

第 2 步:创建 Thread 并添加 Messages

当用户开始对话时创建一个 Thread,并在用户提问时将 Messages 添加到 Thread 中。

1
2
3
4
5
6
thread = client.beta.threads.create()
message = client.beta.threads.messages.create(
  thread_id=thread.id,
  role="user",
  content="What's the weather in San Francisco today and the likelihood it'll rain?",
)

第 3 步:发起 Run

当你在包含触发一个或多个函数的用户 Message 的 Thread 上发起 Run 时,Run 将进入 pending 状态。处理完毕后,Run 将进入 requires_action 状态,你可以通过检查 Run 的 status。这表示您需要运行工具并将它们的输出提交给 Assistant,以继续 Run 的执行。在我们的例子中,我们将看到两个 tool_calls,这表示用户查询导致了并行函数调用。

请注意,Run 会在创建十分钟后过期。请务必在 10 分钟标记之前提交你的工具输出。

你将看到两个 tool_calls 位于 required_action,这表示用户查询触发了并行函数调用。

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
26
27
28
29
{
  "id": "run_qJL1kI9xxWlfE0z1yfL0fGg9",
  ...
  "status": "requires_action",
  "required_action": {
    "submit_tool_outputs": {
      "tool_calls": [
        {
          "id": "call_FthC9qRpsL5kBpwwyw6c7j4k",
          "function": {
            "arguments": "{"location": "San Francisco, CA"}",
            "name": "get_rain_probability"
          },
          "type": "function"
        },
        {
          "id": "call_RpEDoB8O0FTL9JoKTuCVFOyR",
          "function": {
            "arguments": "{"location": "San Francisco, CA", "unit": "Fahrenheit"}",
            "name": "get_current_temperature"
          },
          "type": "function"
        }
      ]
    },
    ...
    "type": "submit_tool_outputs"
  }
}
为提高可读性,此处截断了 Run 对象

你发起 Run 并提交 tool_calls 的方式将取决于你是否使用流式传输,尽管在两种情况下,所有 tool_calls 都需要同时提交。然后,你可以通过提交所调用函数的工具输出来完成 Run。传递在 tool_call_id 对象中引用的每个 required_action 以便将输出与每个函数调用进行匹配。

对于流式传输的情况,我们创建了一个 EventHandler 类来处理响应流中的事件,并使用 Python 和 Node SDK 中的 “submit tool outputs stream” 辅助函数一次性提交所有工具输出。

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from typing_extensions import override
from openai import AssistantEventHandler
 
class EventHandler(AssistantEventHandler):
    @override
    def on_event(self, event):
      # Retrieve events that are denoted with 'requires_action'
      # since these will have our tool_calls
      if event.event == 'thread.run.requires_action':
        run_id = event.data.id  # Retrieve the run ID from the event data
        self.handle_requires_action(event.data, run_id)
 
    def handle_requires_action(self, data, run_id):
      tool_outputs = []
        
      for tool in data.required_action.submit_tool_outputs.tool_calls:
        if tool.function.name == "get_current_temperature":
          tool_outputs.append({"tool_call_id": tool.id, "output": "57"})
        elif tool.function.name == "get_rain_probability":
          tool_outputs.append({"tool_call_id": tool.id, "output": "0.06"})
        
      # Submit all tool_outputs at the same time
      self.submit_tool_outputs(tool_outputs, run_id)
 
    def submit_tool_outputs(self, tool_outputs, run_id):
      # Use the submit_tool_outputs_stream helper
      with client.beta.threads.runs.submit_tool_outputs_stream(
        thread_id=self.current_run.thread_id,
        run_id=self.current_run.id,
        tool_outputs=tool_outputs,
        event_handler=EventHandler(),
      ) as stream:
        for text in stream.text_deltas:
          print(text, end="", flush=True)
        print()
 
 
with client.beta.threads.runs.stream(
  thread_id=thread.id,
  assistant_id=assistant.id,
  event_handler=EventHandler()
) as stream:
  stream.until_done()

使用 Structured Outputs

当你通过提供启用 结构化输出strict: true,OpenAI API 将在您的首次请求时对提供的 schema 进行预处理,然后使用该产物来约束模型以符合您的 schema。

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from openai import OpenAI
client = OpenAI()

assistant = client.beta.assistants.create(
instructions="You are a weather bot. Use the provided functions to answer questions.",
model="gpt-4o-2024-08-06",
tools=[
{
"type": "function",
"function": {
"name": "get_current_temperature",
"description": "Get the current temperature for a specific location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g., San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["Celsius", "Fahrenheit"],
"description": "The temperature unit to use. Infer this from the user's location."
}
},
"required": ["location", "unit"],
"additionalProperties": False
},
"strict": True
}
},
{
"type": "function",
"function": {
"name": "get_rain_probability",
"description": "Get the probability of rain for a specific location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g., San Francisco, CA"
}
},
"required": ["location"],
"additionalProperties": False
},
"strict": True
}
}
]
)