Assistant Thread 和 Message的关系
本文章是以代码形式实现的assistang api,还可以通过网页形式直接创建assistant。
对象 | 含义 |
---|---|
assistant | 为了利用OpenAl的模型并调用工具而设计的AI |
thread | 助手和用户之间的交流会话。线程存储消息并自动处理截断以适应模型的上下文。 |
messages | 助手或用户创建的消息。消息可以包括文本图片和其他文件。消息以列表形式存储在线程上。 |
run | 一个对线程上的助手的调用。助手使用它的配置和线程的消息来通过调用模型和工具执行任务。作为运行的一部分,助手将消息附加到线程中。 |
run step | 一个详细的步骤列表,助手在运行过程中所采取的步骤。助手可以在运行过程中调用工具或创建消息。检查运行步骤可以帮助您分析助手(5Laure达到最终结果的方式。 |
Threads 里保存的是对话历史,即 messages
一个 assistant 可以有多个 thread
一个 thread 可以有无限条 message
一个用户与 assistant 的多轮对话历史可以维护在一个 thread 里
Assistant的主要能力:
已有能力:
创建和管理 assistant,每个 assistant 有独立的配置
支持无限长的多轮对话,对话历史保存在 OpenAI 的服务器上
支持 Code Interpreter
在沙箱里编写并运行 Python 代码
自我修正代码
可传文件给 Code Interpreter
支持文件 RAG
支持 Function Calling
收费:
按 token 收费。无论多轮对话,还是 RAG,所有都按实际消耗的 token 收费
如果对话历史过多超过大模型上下文窗口,会自动放弃最老的对话消息
文件按大小和存放时长收费。1 GB 文件一天收费 0.20 美元
Code interpreter 跑一次 $0.03
创建 Assistant和Thread
用python创建一个assistant,首先创建env文件
#在python项目中先创建.env文件,录入自己的api_key和base_url,其中api_key需要申请,OPENAI_BASE_URL是openAI请求地址(请自行更换,本地址是一个代理地址)
OPENAI_API_KEY="sk-aggybFjhorevlj4IZXgS3Nhk1FzeJyokvg5XNO1qGEyhLm5z"
OPENAI_BASE_URL="https://api.fe8.cn/v1"
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
import os
_ = load_dotenv(find_dotenv())
# 初始化 OpenAI 服务
client = OpenAI()
# 创建助手
assistant = client.beta.assistants.create(
name="zgg 的GPT",
description="你是我的秘书,听我指挥。",
model="gpt-4-turbo-preview",
)
assistant_id = assistant.id
#json打印
import json
def show_json(obj):
"""把任意对象用排版美观的 JSON 格式打印出来"""
print(json.dumps(
json.loads(obj.model_dump_json()),
indent=4,
ensure_ascii=False
))
# 创建 thread,添加metadata树形
thread = client.beta.threads.create(
metadata={"fullname" : "zgg", "username": "如梦初醒"}
)
show_json(thread)
thread的唯一主键可以存储下来,可以通过retrieve函数获取以前创建的thread对象
thread = client.beta.threads.retrieve(thread.id)
show_json(thread)
此外,还有:
threads.update() 修改 thread 的 metadata
threads.delete() 删除 threads
创建 Messages
不仅有文本,还可以有图片和文件
文本还可以带参考引用
也有 metadata
message = client.beta.threads.messages.create(
thread_id=thread.id, # message 必须归属于一个 thread
role="user", # 取值是 user 或者 assistant。但 assistant 消息会被自动加入,我们一般不需要自己构造
content="你都能做什么?",
)
show_json(message)
还有如下函数:
threads.messages.retrieve() 获取 message
threads.messages.update() 更新 message 的 metadata
threads.messages.list() 列出给定 thread 下的所有 messages
执行run
用 run 把 assistant 和 thread 关联,进行对话
一个 prompt 就是一次 run
run = client.beta.threads.runs.create(
assistant_id=assistant_id,
thread_id=thread.id,
)
show_json(run)
run的状态一览
wait_on_run方法展现了run的各个状态
import time
def wait_on_run(run, thread):
"""等待 run 结束,返回 run 对象,和成功的结果"""
while run.status == "queued" or run.status == "in_progress":
"""还未中止"""
run = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id=run.id)
print("status: " + run.status)
# 打印调用工具的 step 详情
if (run.status == "completed"):
run_steps = client.beta.threads.runs.steps.list(
thread_id=thread.id, run_id=run.id, order="asc"
)
for step in run_steps.data:
if step.step_details.type == "tool_calls":
show_json(step.step_details)
# 等待 1 秒
time.sleep(1)
if run.status == "requires_action":
"""需要调用函数"""
# 可能有多个函数需要调用,所以用循环
tool_outputs = []
for tool_call in run.required_action.submit_tool_outputs.tool_calls:
# 调用函数
name = tool_call.function.name
print("调用函数:" + name + "()")
print("参数:")
print(tool_call.function.arguments)
function_to_call = available_functions[name]
arguments = json.loads(tool_call.function.arguments)
result = function_to_call(arguments)
print("结果:" + str(result))
tool_outputs.append({
"tool_call_id": tool_call.id,
"output": json.dumps(result),
})
# 提交函数调用的结果
run = client.beta.threads.runs.submit_tool_outputs(
thread_id=thread.id,
run_id=run.id,
tool_outputs=tool_outputs,
)
# 递归调用,直到 run 结束
return wait_on_run(run, thread)
if run.status == "completed":
"""成功"""
# 获取全部消息
messages = client.beta.threads.messages.list(thread_id=thread.id)
# 最后一条消息排在第一位
result = messages.data[0].content[0].text.value
return run, result
# 执行失败
return run, None
执行以下结果
run, result = wait_on_run(run, thread)
print(result)
打印输出
status: in_progress
status: in_progress
status: in_progress
status: in_progress
status: in_progress
status: in_progress
status: in_progress
status: completed
我能做很多事情,这里有一些示例:
1. **提供信息**:关于科学、历史、文化、技术等方面的详细信息。
2. **回答问题**:回答各种类型的问题,包括但不限于学术问题、普遍知识问题、解释概念等。
3. **学习帮助**:提供学习建议,包括数学问题的解决方法、语言学习技巧等。
4. **日常生活建议**:比如健康饮食建议、锻炼技巧、时间管理技巧等。
5. **技术支持**:解释软件、硬件的使用方法,提供基本的故障排除方法。
6. **语言工具**:提供词汇翻译、语法讲解、文本纠正等服务。
7. **编程帮助**:提供编程语言的基础知识,代码问题的解答等。
8. **趣味事实和数据**:提供关于电影、音乐、体育等领域的趣味信息和统计数据。
请注意,我提供的信息是基于我的训练数据,可能会有限制或者不包括最新的数据和信息。需要具体的帮助时,请给出详细的询问。