I am creating a chatbot which can query all 'Views' in my database based on user query. I tried many other methods but didn't succeed so now I thought I should try OpenAI's function calling.
What I did: I created a function for one of the view. In that, I am calling GPT3 to create a SQL query based on the user question that I provide in the parameter. I have given instructions and schema to the model so it can create correct query. Below is the function.
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'])
I am thinking to create such functions for each view. After this I got the code from OpenAI Function Calling documentation and modified it as per my need. Below is the 'function calling' function:
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
This is the first time I am trying Function Calling so I am not hundred percent sure if this will work.
When I run this code, I am getting this error: openai.error.InvalidRequestError: <exception str() failed>
for response = openai.ChatCompletion.create()
in run_conversation(user_query)
function.
Can anyone please guide me where I am making mistakes?
I am providing whole code below:
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)