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
创建成功后,可以拿到Thread
id。
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 代表对话
thread
ID - run_123 代表Run对象的ID
- tool_call_id 代表某个函数调用ID,通过前面的tool_calls参数获得。
在成功提交了所有函数输出后,Run对象的状态会再次更新,助手将继续处理,并返回最终的响应给用户。