openAI assistants的自定义函数调用——类似HiAgent
openAI assistants的自定义函数调用功能
先添加函数:


和字节的hiagent非常相似。
定义好函数以后。然后就是在客户端通过如下代码调用:
# 读取系统变量
from dotenv import load_dotenv
load_dotenv()
from openai import OpenAI
# 初始化客户端
client = OpenAI()
# 检索您之前创建的Assistant
assistant_id = "asst_pF2pMtIHOL4CpXpyUdHkoKG3" # 你自己的助手ID
# thread_id = 'thread_ZBhfduW0rklxu120EnIH0QZT'
# 创建一个新的Thread
thread = client.beta.threads.create()
print(thread)
thread_id = thread.id
# 向Thread添加用户的消息
message = client.beta.threads.messages.create(
thread_id=thread_id,
# thread_id='thread_xSyXlruUzMIW1zD8rQUP3aFp',
role="user",
content="快安慰一下伤心的小雪!"
)
print(message)
# 运行Assistant来处理Thread
run = client.beta.threads.runs.create(
thread_id=thread_id,
assistant_id=assistant_id
)
print(run)
# 轮询Run,从'queue'等到'requires_action'
import time
# 定义一个轮询的函数
def poll_run_status(client, thread_id, run_id, interval=2):
""" 轮询Run的状态,直到它不再是'requires_action'或直到完成 """
while True:
run = client.beta.threads.runs.retrieve(thread_id=thread_id,
run_id=run_id)
print(run)
if run.status in ['requires_action', 'completed']:
return run
time.sleep(interval) # 等待后再次检查
# 轮询以检查Run的状态
print('这时,Run应该是进入了requires_action状态')
run = poll_run_status(client, thread_id, run.id)
print(run)
# 定义一个从Run中读取Function信息的函数
def get_function_details(run):
function_name = run.required_action.submit_tool_outputs.tool_calls[0].function.name
arguments = run.required_action.submit_tool_outputs.tool_calls[0].function.arguments
function_id = run.required_action.submit_tool_outputs.tool_calls[0].id
return function_name, arguments, function_id
# 拿到Function的元数据信息
function_name, arguments, function_id = get_function_details(run)
print("function_name:", function_name)
print("arguments:", arguments)
print("function_id:", function_id)
# 再次检查Run的状态 - 不需要轮询 -- 一直是Queue
print('这时,Run已经从requires_action出来了')
run = client.beta.threads.runs.retrieve(thread_id=thread_id,
run_id=run.id)
print(run)
# 定义鼓励函数
def get_encouragement(name, mood):
# 基础鼓励消息
messages = {
"happy": "继续保持积极的心态,做得好!",
"sad": "记住,即使在最黑暗的日子里,也会有阳光等待着你。",
"tired": "你做得足够好了,现在是时候休息一下了。",
"stressed": "深呼吸,一切都会好起来的。"
}
# 获取对应心情的鼓励消息
message = messages.get(mood.lower(), "你今天感觉如何?我总是在这里支持你!")
# 返回定制化的鼓励消息
return f"亲爱的{name},{message}"
# ---- 这里,我可要动态调用程序了!!!
import json
# 定义可用的函数字典
available_functions = {
"get_encouragement": get_encouragement
}
# 解析参数
function_args = json.loads(arguments)
# 动态调用函数
function_to_call = available_functions[function_name]
encouragement_message = function_to_call(
name=function_args.get("name"),
mood=function_args.get("mood")
)
# 打印结果以进行验证
print(encouragement_message)
# 向Run提交结果
def submit_tool_outputs(run,thread,function_id,function_response):
run = client.beta.threads.runs.submit_tool_outputs(
thread_id=thread.id,
run_id=run.id,
tool_outputs=[
{
"tool_call_id": function_id,
"output": str(function_response),
}
]
)
return run
run = submit_tool_outputs(run,thread,function_id,encouragement_message)
print('这时,Run收到了结果')
print(run)
print('这时,Run继续执行直至完成')
# 再次轮询Run直至完成
run = poll_run_status(client, thread_id, run.id)
print(run)
# 获取Assistant在Thread中的回应
messages = client.beta.threads.messages.list(
thread_id=thread_id
)
# 输出Assistant的回应
print('下面打印最终的Message')
for message in messages.data:
if message.role == "assistant":
print(message.content)
代码使用OpenAI API来创建一个客户端,并与OpenAI的助手进行交互。下面是代码的功能分析:
- 读取系统变量:从环境中加载变量。
- 初始化OpenAI客户端。
- 创建一个新的线程(Thread)。
- 添加用户的消息到线程中。
- 运行Assistant处理线程。
- 轮询Run以检查其状态直到状态不再是'requires_action'或完成。
- 获取Function的元数据信息。
- 再次检查Run的状态。
- 定义鼓励函数,根据心情返回鼓励消息。
- 解析参数并动态调用函数。
- 向Run提交结果。
- 再次轮询Run直至完成。
- 获取Assistant在线程中的回应并输出。
总体而言,该代码用于与OpenAI的助手进行交互,实现了用户与助手之间的消息传递和交流,并通过动态调用函数来生成鼓励性消息。
另外,还可以直接使用API方式去创建函数并作为工具调用:
import os
os.environ['OpenAI_API_KEY'] = 'xxx换成你的'
os.environ['SERPAPI_API_KEY'] = 'xxx换成你的'
# 读取系统变量
from dotenv import load_dotenv
load_dotenv()
# 初始化客户端
from openai import OpenAI
client = OpenAI()
# 定义检索鲜花库存的函数
import json
def get_flower_inventory(city):
"""获取指定城市的鲜花库存"""
if "北京" in city:
return json.dumps({"city": "北京", "inventory": "玫瑰: 100, 郁金香: 150"})
elif "上海" in city:
return json.dumps({"city": "上海", "inventory": "百合: 80, 康乃馨: 120"})
elif "深圳" in city:
return json.dumps({"city": "深圳", "inventory": "向日葵: 200, 玉兰: 90"})
else:
return json.dumps({"city": city, "inventory": "未知"})
# 工具(也就是函数)的元数据
tools = [
{
"type": "function",
"function": {
"name": "get_flower_inventory",
"description": "获取指定城市的鲜花库存",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,例如:北京、上海或深圳"
}
},
"required": ["city"]
}
}
}
]
# 第一次对话的Message
messages = [{"role": "user", "content": "北京、上海和深圳的鲜花库存是多少?"}]
print("message:", messages)
# 第一次对话的返回结果
first_response = client.chat.completions.create(
model="gpt-3.5-turbo-0125",
messages=messages,
tools=tools,
tool_choice="auto"
)
print("first_response:", first_response)
response_message = first_response.choices[0].message
tool_calls = response_message.tool_calls
# 如果返回结果要求用Function Call,就调用函数,并把函数的查询结果附加到消息中
if tool_calls:
messages.append(response_message)
for tool_call in tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
function_response = get_flower_inventory(
city=function_args.get("city")
)
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)
print("message:", messages)
# 用有了库存查询结果的Message再来一次对话
second_response = client.chat.completions.create(
model="gpt-3.5-turbo-0125",
messages=messages
)
print("second_response:", second_response)

浙公网安备 33010602011771号