文章目录
一、Assistant API 核心概念
1、相关核心概念简介
OpenAI 的 Assistants API 是 为 开发者 提供的 高级工具 , 用于 构建基于对话的 AI 应用 ;
在 Assistants 开发过程中 涉及到 助手 ( Assistant ) 、 对话线程 ( Thread ) 、 执行过程 ( Run ) 等核心概念 ;
- 助手 ( Assistant ) 是 静态配置 的 AI 代理 ;
- 对话线程 ( Thread ) 是 动态的 对话上下文 , 与 Assistant 关联 ;
- 执行过程 ( Run ) 是 Assistant 在 Thread 上的一次任务执行 , 将 用户输入 转化为 响应 ;
Assistant 工作流程 :
- 创建 Assistant ( 配置模型、指令、工具 ) ;
- 为 每个 用户 / 任务 创建 Thread ;
- 用户 发送 消息 到 Thread ;
- 在 Thread 上 启动 Run , 触发助手处理消息 ;
- 轮询 Run 状态直至完成 , 获取助手回复 ;
- 回复 自动添加到 Thread , 保持对话历史 ;
2、Assistant 助手
Assistant 助手 是 由 开发者 配置的 静态 AI 代理 , 基于 OpenAI 的模型 ( 如 GPT-4 ) 运行 , 可 自定义其 行为、知识库 和 工具 ;
每个 Assistant 助手 对应一个 独立的任务场景 ( 如客服、数据分析 ) , 通过配置实现特定功能 ;
Assistant 助手 核心功能如下 :
- 设置模型 : 设置需要使用的模型 , 如 : gpt-4-turbo ;
- 设置指令 : 通过 自然语言 设定 助手的 角色和目标 , 如 : 你是一名客服负责 …
- 扩展工具 : 集成 代码解释器、文件检索、函数调用 等扩展工具 ;
- 文件管理 : 支持 文档上传 , 供 助手在回答时参考 ;
3、Thread 对话线程
Thread 对话线程 是 用户 与 Assistant 之间的 对话上下文容器 , 用于管理 多轮对话的完整历史 ;
通过 Thread 可以 实现 连续对话 , 保持上下文连贯性 , 如用户追问时 , 助手能理解历史信息 ;
Thread 对话线程 核心功能如下 :
- 持久化存储 : 保存 用户 和 助手的交互记录 ( 消息列表 ) , 无需开发者自行管理会话状态 ;
- 独立性 : 每个 Thread 独立运行 , 可同时处理多个用户或任务 ( 例如不同客户的咨询 ) ;
- 消息管理 : 支持 在 Thread 中添加用户消息 ( user message ) 或 助手消息 ( assistant message ) ;
4、Run 执行过程
Run 执行过程 是 Assistant 在特定 Thread 上的一次任务执行 , 负责处理用户输入并生成响应 , 控制单次交互的完整流程 , 支持异步处理和复杂操作 , 如 : 运行代码、检索知识库 ;
Run 执行过程 执行流程如下 :
- 触发 : 当用户向 Thread 发送消息后 , 需 显式创建 Run 来启动助手的处理 ;
- 执行步骤 :
- 模型推理 : 根据 Thread 中的 历史消息 生成回复 ;
- 工具调用 ( 可选 ) : 若助手配置了工具 ( 如代码解释器 ) , Run 会自动执行相关操作 ;
- 状态管理 : Run 有 生命周期状态 ( 如 queued、in_progress、completed、failed ) , 需 轮询 或 通过回调 跟踪进度 ;
- 结果返回 : 完成后 , 助手的 回复 会被添加到 Thread 中 ;
二、Assistant API 开发流程
0、开发流程概述
OpenAI 的 Assistant API 是一个允许开发者 构建具备长期记忆 、 多步骤推理 和 工具调用能力 的 AI 应用的工具 , 开发流程如下 :
- 创建 Assistant : 定义 AI 的角色 ( 如模型类型、指令、工具等 ) , 并 上传所需文件 ( 如知识库文档 ) ;
client.beta.assistants.create(
name="助手名称",
instructions="行为指令",
model="模型名称",
tools=[{"type": "工具类型"}],
file_ids=["文件ID"]
)
- 创建 Thread : 每个 用户会话 对应一个 Thread , 用于存储对话历史 ; Assistant 只有一个 , 每个用户访问时会创建一个 Thread ;
client.beta.threads.create(messages=[...])
- 添加用户消息 : 将 用户输入 添加 到 Thread 中 ;
message = client.beta.threads.messages.create(
thread_id=thread.id,
role="user",
content="请分析销售数据中的趋势 ; ",
file_ids=[file.id]
)
- 运行 Assistant : 触发 Assistant 处理 Thread 中的消息 , 生成响应 ;
client.beta.threads.runs.create(
thread_id="线程ID",
assistant_id="助手ID",
instructions="覆盖指令",
tools=[{"type": "工具类型"}]
)
- 获取响应 : 从 Assistant 的 运行结果 中 提取回复内容 ;
1、创建 Assistant
client.beta.assistants.create 函数 作用是 创建一个具备特定能力的 AI 助手 , 定义其 角色 、 模型 、 工具 和 关联文件 , 函数原型如下 :
assistant = client.beta.assistants.create(
model="模型名称", # 必填参数
instructions="角色指令", # 核心参数
tools=[{"type": "工具类型1"}, {"type": "工具类型2"}], # 功能扩展参数
name="助手名称", # 可选标识
file_ids=["文件ID"], # 知识库关联参数
metadata={"自定义元数据"}, # 扩展参数
tool_resources={...} # 高级资源配置
)
- model 参数 : 指定使用的 模型版本 , 如 : gpt-4-turbo 、 gpt-4o , 注意 : 必须 从 OpenAI 支持的模型列表中选择 ;
- instructions 参数 : 定义 助手的 角色能力 与 响应规则 , 需明确任务边界 ( 如 : " 仅回答 XX 问题 " ) , 可包含格式要求 ( 如 : " 用 Markdown 表格 展示结果 " ) ;
- tools 参数 : 启用 功能扩展 工具 , 支持 如下三种 扩展工具类型 :
- code_interpreter : 代码解释器工具 , 执行 Python 代码 , 需配合文件使用 ;
- retrieval : 文件检索工具 , 基于知识库文件检索 , 需预上传文件 ;
- function : 自定义 函数调用 , 需定义参数结构 ;
- file_ids 参数 : 关联 知识库文档 ( 需通过 client.files.create 预先上传 ) , 单个文件最大 512MB , 支持 PDF/TXT/CSV 等格式 ;
- tool_resources 参数 : 配置 扩展工具 运行环境 , 高级参数 ;
代码示例 :
assistant = client.beta.assistants.create(
name="数据分析专家",
instructions="""1. 解析用户上传的 CSV/Excel 文件
2. 生成可视化图表
3. 输出结构化分析报告""",
model="gpt-4-turbo",
tools=[{"type": "code_interpreter"}, {"type": "retrieval"}],
file_ids=["file_123"]
)
2、创建 Thread
client.beta.threads.create 函数 作用是 创建一个 会话线程 Thread , 用于存储 用户与助手 的对话历史 , 每个线程独立存储消息内容 , 支持跨会话持续追踪上下文 , 函数原型如下 :
thread = client.beta.threads.create(
metadata={"key": "value"} # 可选参数 , 自定义元数据
)
- metadata 参数 ( 可选 ) : 存储线程的 扩展信息 ( 如 : 用户ID 、 会话标签 等 ) , 用于后续检索或分类管理 , 数据类型是 字典 键值对 ;
代码示例 :
# 创建带业务标签的线程
thread = client.beta.threads.create(
metadata={
"project": "customer_service",
"priority": "high"
}
)
# 输出线程唯一标识
print(thread.id) # 例如 thread_abc123
3、添加用户消息
client.beta.threads.messages.create 函数 作用是 将 用户输入 / 助手响应 按顺序存入 Thread 线程 , 实现 多轮对话 连贯性 , 同时支持 附加文件 供后续处理 , 通过消息级 file_ids 实现临时文件分析 , 函数原型如下 :
message = client.beta.threads.messages.create(
thread_id="线程ID", # 必填参数
role="user", # 必填参数 ( "user"或"assistant" )
content="消息内容", # 必填参数
file_ids=["文件ID"], # 可选参数 ( 临时分析文件 )
metadata={"自定义元数据"} # 可选参数
)
- thread_id 参数 : 指定 消息所属的 线程 ID , 该 ID 需通过 client.beta.threads.create 预先创建 , 字符串类型 ;
- role 参数 : 标识 消息发送者 身份 , 可设置如下值 :
- user : 用户发送的提问或指令 ;
- assistant : AI生成的响应 ( 通常由系统自动添加 ) ;
- content 参数 : 消息的文本内容 , 支持 Markdown格式 , 可 结合文件功能 包含 多模态内容 , 长度需要控制在模型上下文限制内 , 如 : GPT-4 Turbo 模型支持 128k tokens ;
- file_ids 参数 : 关联 临时分析文件 , 该 文件 需通过 client.files.create 预先上传 ;
- metadata 参数 : 存储 用户自定义 的 消息的扩展信息 , 如 : 消息来源、会话标签等 ;
代码示例 :
# 创建消息并关联文件
message = client.beta.threads.messages.create(
thread_id=thread.id,
role="user",
content="分析附件中的销售数据 , 生成趋势图",
file_ids=[file.id],
metadata={"request_type": "data_analysis"}
)
4、运行 Assistant
client.beta.threads.runs.create 函数 的 作用是 触发 Assistant 处理 Thread 中的消息 , 生成响应 , 该操作是 异步操作 ;
run = client.beta.threads.runs.create(
thread_id="线程ID", # 必填参数
assistant_id="助手ID", # 必填参数
instructions="覆盖指令", # 可选参数 ( 动态调整助手行为 )
tools=[{"type": "工具类型"}], # 可选参数 ( 临时启用/禁用工具 )
metadata={"自定义元数据"}, # 可选参数 ( 业务追踪标识 )
stream=True # 可选参数 ( 启用流式响应 )
)
- thread_id 参数 : 指定 要执行的 消息线程 , 在之前通过 client.beta.threads.create 函数 预先创建 ;
- assistant_id 参数 : 关联 已创建的 助手实例 , 在之前通过 client.beta.assistants.create 函数 生成 , 同一线程可切换不同助手实现多角色交互 ;
- instructions 参数 : 用于 动态控制 提示词 , 覆盖 助手 原有指令 , 实现 单次会话 的临时行为调整 ;
- tools 参数 : 动态工具管理 , 临时 启用 / 禁用 工具 , 可选择设置 代码解释器工具 / 文件检索工具 / 函数调用工具 ;
- stream 参数 : 设置 流式响应控制 , 设置为 True 时启用实时数据流传输 , 需配合 AssistantEventHandler 类实现分阶段响应 ;
代码示例 :
# 创建带流式处理与动态指令的运行
with client.beta.threads.runs.create(
thread_id=thread.id,
assistant_id=assistant.id,
instructions="优先调用内部API验证数据合法性",
tools=[{"type": "retrieval"}, {"type": "function"}],
stream=True
) as stream:
# 实时处理流式响应
for event in stream:
if event.event == 'text_delta':
print(event.data.value, end="")
5、获取响应
client.beta.threads.messages.list 函数 的 作用是 从 Thread 中获取 所有消息列表 , 提取 Assistant 的最新回复 ;
messages = client.beta.threads.messages.list(
thread_id="thread_xxx", # 必填参数 , 指定线程ID
limit=20, # 可选 , 返回消息数量 ( 默认20 , 最大值100 )
order="desc", # 可选 , 排序方式 ( 'asc'按时间升序 , 'desc'按时间降序 )
after="msg_xxx", # 可选 , 仅返回指定消息ID之后的消息
before="msg_yyy" # 可选 , 仅返回指定消息ID之前的消息
)
- thread_id 参数 : 必填参数 , 指定要查询的 线程 ID , 格式类似 thread_fH5pZQrMs8xTvWkYdNlAeBc9 ;
- limit 参数 : 控制 返回消息数量 , 默认返回最新20条 , 最大支持100条 ;
- order 参数 : 可选参数值如下 :
- desc ( 默认 ) : 按 消息创建时间 降序排列 ( 最新消息在前 ) ;
- asc : 按 创建时间 升序排列 ( 最早消息在前 ) ;
- after 与 before 参数 : 用于 分页查询 , 当消息量较大时 , 建议 通过 after 或 before 分批次拉取 , 避免单次请求超时 ;
- after=“msg_xxx” : 仅返回该消息 ID 之后的消息 ;
- before=“msg_yyy” : 仅返回该消息 ID 之前的消息 ;
- 返回值 : 返回的 messages 对象 包含 data 属性 ( 消息列表 ) , 每条消息的结构为 ;
{
"id": "msg_xxx", # 消息ID
"role": "user", # 角色 ( user/assistant )
"content": [{"type": "text", "text": {"value": "消息内容"}}], # 消息内容 ( 支持多模态 )
"created_at": 1677060000 # 时间戳
}
代码示例 : 当消息量较大时 , 建议通过 after 或 before 分批次拉取 , 避免单次请求超时 ;
# 获取线程 thread_123 的最新10条消息(按时间降序)
messages = client.beta.threads.messages.list(
thread_id="thread_123",
limit=10,
order="desc"
)
三、Assistants API 完整代码示例
1、完整代码示例
import os
import time
from openai import OpenAI # 导入OpenAI库
# 初始化 OpenAI 客户端 (替换成自己的 API 信息)
client = OpenAI(
api_key="sk-i3d7aF6", # 替换为你的 OpenAI API Key , 这里我把自己的 API-KEY 隐藏了
base_url="https://api.openai.com" # 也可替换为你的 API 服务端点
)
# 阶段1:创建智能助手
print("步骤1/5 正在创建助手...")
assistant = client.beta.assistants.create(
name="问答助手", # 助手名称
instructions="你是一个专业的知识问答助手", # 行为指令
model="gpt-4-turbo", # 指定模型
tools=[{"type": "code_interpreter"}] # 启用代码解释器
)
print(f"助手创建完成 ID:{assistant.id}")
# 阶段2:创建对话线程
print("\n步骤2/5 正在创建对话线程...")
thread = client.beta.threads.create() # 创建空对话线程
print(f"线程创建完成 ID:{thread.id}")
# 阶段3:添加用户消息
print("\n步骤3/5 正在添加问题...")
message = client.beta.threads.messages.create(
thread_id=thread.id, # 绑定线程
role="user", # 消息角色
content="2024巴黎奥运会的举办时间是哪天?" # 问题内容
)
print(f"问题添加完成 消息ID:{message.id}")
# 阶段4:启动任务运行
print("\n步骤4/5 启动任务处理...")
run = client.beta.threads.runs.create(
thread_id=thread.id, # 指定线程
assistant_id=assistant.id # 指定助手
)
# 实时监控处理进度
print("\n正在获取处理状态:")
while True:
current_run = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id=run.id
)
print(f"当前状态:{current_run.status}")
if current_run.status == "completed":
break
time.sleep(1) # 每秒检查一次状态
# 阶段5:获取最终响应
print("\n步骤5/5 获取处理结果...")
messages = client.beta.threads.messages.list(thread.id)
latest_response = messages.data[0].content[0].text.value # 提取最新回答
print("最终答案:", latest_response)
2、执行结果
执行上述代码 , 命令行输出如下结果 :
步骤1/5 正在创建助手...
助手创建完成 ID:asst_7YkBNqRwXmVzLtGJhUoPcD2E
步骤2/5 正在创建对话线程...
线程创建完成 ID:thread_fH5pZQrMs8xTvWkYdNlAeBc9
步骤3/5 正在添加问题...
问题添加完成 消息ID:msg_K2jLmOnVpR7sTqWxYbCdFgH4
步骤4/5 启动任务处理...
正在获取处理状态:
当前状态:queued
当前状态:in_progress
当前状态:completed
步骤5/5 获取处理结果...
最终答案: 2024年巴黎奥运会将于2024年7月26日开幕,8月11日闭幕。