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的助手进行交互。下面是代码的功能分析:

  1. 读取系统变量:从环境中加载变量。
  2. 初始化OpenAI客户端。
  3. 创建一个新的线程(Thread)。
  4. 添加用户的消息到线程中。
  5. 运行Assistant处理线程。
  6. 轮询Run以检查其状态直到状态不再是'requires_action'或完成。
  7. 获取Function的元数据信息。
  8. 再次检查Run的状态。
  9. 定义鼓励函数,根据心情返回鼓励消息。
  10. 解析参数并动态调用函数。
  11. 向Run提交结果。
  12. 再次轮询Run直至完成。
  13. 获取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)

  

 

posted @ 2024-05-22 17:43  bonelee  阅读(129)  评论(0编辑  收藏  举报