ChatGPT-3 OpenAI函数调用错误- openai.error.InvalidRequestError:< exception str()failed>

kpbwa7wx  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(554)

我正在创建一个聊天机器人,它可以根据用户查询查询我数据库中的所有“视图”。我尝试了许多其他方法,但没有成功,所以现在我想我应该尝试OpenAI的函数调用。
我所做的:我为其中一个视图创建了一个函数。在这个函数中,我调用GPT3根据我在参数中提供的用户问题创建一个SQL查询。我已经给模型提供了指令和架构,以便它可以创建正确的查询。下面是函数。

def get_rent_details(user_query):
    """Get the current weather in a given location"""
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        prompt="""User will ask you the question regarding their properties, assets and finance. 

        Follow below steps to get correct answer:

        1. Understand the user question and prepare a syntactically correct SQL query to retrieve the correct data.
        2. If you don't find the data in the table, just type "No answer found".
        3. Do not make up any answer by your own.
        4. Instead of '=', always use 'LIKE' statement with 'WHERE' statement.
        5. The user will mention either property name or tenant name. So to make sure the query is correct, use both columns 'TenantName' and 'PropertyName' with 'WHERE' statement. For example: SELECT PropertyCode FROM viewRentRoll WHERE PropertyName LIKE 'Younger, 3003' OR TenantName LIKE 'Younger, 3003'.
        6. DO NOT create any DML query like UPDATE, INSERT, DELETE, ADD.
        7. Below is the table schema to run query on:

        CREATE TABLE [dbo].[viewRentRoll] (            
       [PropertyPKId] [bigint]
      ,[PropertyCode] [nvarchar]
      ,[PropertyName] [nvarchar]
      ,[PropertyList] [nvarchar]
      ,[LeaseCode] [nvarchar]
      ,[TenantName] [nvarchar]
      ,[SnP Rating] [nvarchar]
      ,[Unit Number] [nvarchar]
      ,[Lease Status] [nvarchar]
      ,[Lease Start Date] [datetime]
      ,[Lease Expiration Date] [datetime]
      ,[Unit Square Feet] [bigint]
      ,[Remaining Lease Term] [bigint]
      ,[Currently Monthly Base Rent] [bigint]
      ,[Rent PSF] [bigint]
      ,[ABR] [bigint]
      ,[local tenant] [nvarchar]
      ,[Current Annualized Base Rent PSF] [bigint]
      ,[CreatedLeaseExpirationDate] [datetime]
      ,[TenantCategory] [nvarchar]
  )
    """ + user_query,
        max_tokens=200,
        temperature=0,
    )
    return (response['choices'][0]['text'])

我正在考虑为每个视图创建这样的函数。之后,我从OpenAI Function Calling文档中获得了代码,并根据我的需要修改了它。下面是'函数调用'函数:

def run_conversation(user_query):
    # Step 1: send the conversation and available functions to GPT

    print("Running run_conversion............\n\n")

    messages = [{"role": "user", "content": user_query}]
    functions = [
        {
            "name": "get_rent_details",
            "description": "Get the details of rent of tenants or properties",
            "parameters": {
                "type": "object",
                "user_query" : {
                    "type" : "string",
                    "description" : "User's question regarding the rent of Tenant or properties"
                }
            }
        }
    ]
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
        functions=functions,
        function_call="auto",  # auto is default, but we'll be explicit
    )
    response_message = response["choices"][0]["message"]

    # Step 2: check if GPT wanted to call a function
    if response_message.get("function_call"):
        # Step 3: call the function
        # Note: the JSON response may not always be valid; be sure to handle errors
        available_functions = {
            "get_rent_details": get_rent_details,
        }  # only one function in this example, but you can have multiple
        function_name = response_message["function_call"]["name"]
        fuction_to_call = available_functions[function_name]
        function_args = json.loads(response_message["function_call"]["arguments"])
        function_response = fuction_to_call(
            user_query=function_args.get("user_query"),
        )

        # Step 4: send the info on the function call and function response to GPT
        messages.append(response_message)  # extend conversation with assistant's reply
        messages.append(
            {
                "role": "function",
                "name": function_name,
                "content": function_response,
            }
        )  # extend conversation with function response
        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=messages,
        )  # get a new response from GPT where it can see the function response
        return second_response

这是我第一次尝试函数调用,所以我不能百分百确定这是否有效。当我运行这段代码时,我得到了这个错误:openai.error.InvalidRequestError: <exception str() failed> for response = openai.ChatCompletion.create() in run_conversation(user_query) function。
有没有人能告诉我,我在哪里犯了错误?
我在下面提供了完整的代码:

import openai
import json
import os

user_query = "What is the monthly rent of Good Neighbor Homes, Inc."

openai.api_key=os.environ['OPENAI_API_KEY']

def run_conversation(user_query):
    # Step 1: send the conversation and available functions to GPT

    print("Running run_conversion............\n\n")

    messages = [{"role": "user", "content": user_query}]
    functions = [
        {
            "name": "get_rent_details",
            "description": "Get the details of rent of tenants or properties",
            "parameters": {
                "type": "object",
                "user_query" : {
                    "type" : "string",
                    "description" : "User's question regarding the rent of Tenant or properties"
                }
            }
        }
    ]
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
        functions=functions,
        function_call="auto",  # auto is default, but we'll be explicit
    )
    response_message = response["choices"][0]["message"]

    # Step 2: check if GPT wanted to call a function
    if response_message.get("function_call"):
        # Step 3: call the function
        # Note: the JSON response may not always be valid; be sure to handle errors
        available_functions = {
            "get_rent_details": get_rent_details,
        }
        function_name = response_message["function_call"]["name"]
        fuction_to_call = available_functions[function_name]
        function_args = json.loads(response_message["function_call"]["arguments"])
        function_response = fuction_to_call(
            user_query=function_args.get("user_query"),
        )

        # Step 4: send the info on the function call and function response to GPT
        messages.append(response_message)  # extend conversation with assistant's reply
        messages.append(
            {
                "role": "function",
                "name": function_name,
                "content": function_response,
            }
        )  # extend conversation with function response
        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=messages,
        )  # get a new response from GPT where it can see the function response
        return second_response

def get_rent_details(user_query):
    """Get the current weather in a given location"""
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        prompt="""User will ask you the question regarding their properties, assets and finance. 

        Follow below steps to get correct answer:

        1. Understand the user question and prepare a syntactically correct SQL query to retrieve the correct data.
        2. If you don't find the data in the table, just type "No answer found".
        3. Do not make up any answer by your own.
        4. Instead of '=', always use 'LIKE' statement with 'WHERE' statement.
        5. The user will mention either property name or tenant name. So to make sure the query is correct, use both columns 'TenantName' and 'PropertyName' with 'WHERE' statement. For example: SELECT PropertyCode FROM viewRentRoll WHERE PropertyName LIKE 'Younger, 3003' OR TenantName LIKE 'Younger, 3003'.
        6. DO NOT create any DML query like UPDATE, INSERT, DELETE, ADD.
        7. Below is the table schema to run query on:

        CREATE TABLE [dbo].[viewRentRoll] (            
       [PropertyPKId] [bigint]
      ,[PropertyCode] [nvarchar]
      ,[PropertyName] [nvarchar]
      ,[PropertyList] [nvarchar]
      ,[LeaseCode] [nvarchar]
      ,[TenantName] [nvarchar]
      ,[SnP Rating] [nvarchar]
      ,[Unit Number] [nvarchar]
      ,[Lease Status] [nvarchar]
      ,[Lease Start Date] [datetime]
      ,[Lease Expiration Date] [datetime]
      ,[Unit Square Feet] [bigint]
      ,[Remaining Lease Term] [bigint]
      ,[Currently Monthly Base Rent] [bigint]
      ,[Rent PSF] [bigint]
      ,[ABR] [bigint]
      ,[local tenant] [nvarchar]
      ,[Current Annualized Base Rent PSF] [bigint]
      ,[CreatedLeaseExpirationDate] [datetime]
      ,[TenantCategory] [nvarchar]
  )

"""+user_query+"?",
        max_tokens=200,
        temperature=0,
    )
    print(response['choices'][0]['text'])
    return (response['choices'][0]['text'])

run_conversation(user_query)
aamkag61

aamkag611#

尝试将函数修改为如下内容:

{
    "name": "get_rent_details",
    "description": "Get the details of rent of tenants or properties",
    "parameters": {
        "type": "object",
        "properties": {
            "user_query": {
                "type": "string",
                "description": "User's question regarding the rent of Tenant or properties"
            }
        },
        "required": ["user_query"]
    }
}

即添加propertiesrequired
我也遇到过类似的问题,我的做法是从一个官方的Open AI函数开始,我验证了它可以工作,然后我逐行修改它,以验证没有任何更改会破坏它。
我还为自己构建了一个验证函数,以检查将来是否只向Open AI传递有效函数。它并不完美,但已经帮助我抓住了一些bug。

def validate_function(function):
    # example func
    """
    function = {
        "name": "get_current_weather",
        "description": "Get the current weather in a given location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA",
                },
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
            },
            "required": ["location"],
        },
    }
    """

    # Check the presence of required keys and their types
    assert "name" in function and isinstance(
        function["name"], str
    ), "'name' must be a string."
    assert "description" in function and isinstance(
        function["description"], str
    ), "'description' must be a string."
    assert "parameters" in function and isinstance(
        function["parameters"], dict
    ), "'parameters' must be a dictionary."

    # Check the structure of 'parameters' key
    params = function["parameters"]

    assert (
        "type" in params and params["type"] == "object"
    ), "'type' must be 'object' in parameters."
    assert "properties" in params and isinstance(
        params["properties"], dict
    ), "'properties' must be a dictionary."
    assert "required" in params and isinstance(
        params["required"], list
    ), "'required' must be a list."

    # Check the structure of 'properties' in 'parameters'
    for key, prop in params["properties"].items():
        assert "type" in prop and isinstance(
            prop["type"], str
        ), f"'type' must be a string in properties of {key}."

        if prop["type"] == "array":
            assert (
                "items" in prop
            ), f"'items' must be present in properties of {key} when type is 'array'."

        # Enum check only if it exists
        if "enum" in prop:
            assert isinstance(
                prop["enum"], list
            ), f"'enum' must be a list in properties of {key}."

    # Check 'required' properties are in 'properties'
    for key in params["required"]:
        assert (
            key in params["properties"]
        ), f"'{key}' mentioned in 'required' must exist in 'properties'."

相关问题