OpenAi Function Calls and Laravel
In the post I will show how to use OpenAl API functions to trigger Laravel helper functions.
This example will create Tasks based on the users question. (btw join my mailing list here to learn more)
First, I will create a function that the LLM (OpenAi’s Large Language Model) can call to make tasks in the system. I made it in the database but in the end it will look like this when we send the JSON to the API.
{
"model": "gpt-3.5-turbo-0613",
"messages": [
{
"role": "system",
"content": "Only use the functions you have been provided with if needed to help the user with this question. As a helpful assistant please assist the user in marketing and staying on track for this question\/idea"
},
{
"role": "user",
"content": "I need help marketing an idea about an LLM Assistant. To start I just need you to make a schedule of a few days in this next week to make sure I do some tasks to stay on top of it. Can you suggest some tasks like 'Post to LinkedIn to Market the idea', 'Code and Planning time', 'YouTube video due' so I end up with a plan that will help me market it and build it"
}
],
"temperature": 0,
"functions": [
{
"name": "llm_functions_scheduling",
"description": "If the user needs help scheduling this will help create tasks in their personal calendar.",
"parameters": {
"type": "object",
"properties": {
"tasks": {
"type": "array",
"description": "Each task to schedule can be placed in a list like the following tasks: [{date: string, description: string}] The format of date should be 0000-00-00",
"items": {
"date": "string",
"description": "string"
}
}
},
"required": [
"tasks"
]
}
}
]
}
Next, I will add a helper function for easy reference, as mentioned in their documentation.
This is in my “app/helpers.PHP” file:
if (! function_exists('llm_functions_scheduling')) {
function llm_functions_scheduling(
FunctionCallDto $functionCallDto
): void {
logger('Message coming in ', $functionCallDto->toArray());
TaskRepository::handle(TasksDto::from($functionCallDto->arguments),
$functionCallDto->message);
}
}
You can do this otherways and the “TaskRepository” is a Realtime Facade 🔥
Now, when I call the OpenAi Chat, I include the function name and details.
After receiving the results, I check if there is a “function_call”.
if (data_get($response, 'choices.0.finish_reason') === 'function_call') {
$name = data_get($response, 'choices.0.message.function_call.name');
$arguments = data_get($response, 'choices.0.message.function_call.arguments');
$dto = FunctionCallDto::from([
'arguments' => $arguments,
'message' => $this->messageModel,
]);
logger('Making function call then will reiterate', [
$arguments,
]);
FunctionCall::handle($name, $dto);
$messages[] = [
'role' => 'assistant',
'content' => sprintf('As an assistant I ran the function %s for you with these parameters %s',
$name,
json_encode($dto->arguments)
),
];
return ChatClientFacade::chat($messages);
} else {
return Response::from(
[
'content' => data_get($response, 'choices.0.message.content'),
'role' => data_get($response, 'choices.0.message.role'),
'token_count' => $response->usage->totalTokens,
'finish_reason' => data_get($response, 'choices.0.finish_reason'),
]
);
}
If it is there the “FuncationCall” facade will deal with it. That you can do anyway you want but then I run the Chat request again removing the function part so the next call will just give some results back to the user. The user will see Tasks created and some nice results like.
Basically if the “finish_reason” is “function_call” we stop to do the function then continue with the “chat”. (It can be a chat or completion api 🤔)
That’s it!
Links
Function calls Announced
This article helped me to find out how the Array Schema is formatted
https://community.openai.com/t/function-calling-parameter-types/268564/2
OpenAi Cookbook
Join my mailing list