-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improving example text: function calling
- Loading branch information
Showing
2 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
%% Analyze Scientific Papers Using ChatGPT Function Calls | ||
% This example shows how to extract recent scientific papers from ArXiv, summarize | ||
% them using ChatGPT, and write the results to a CSV file using the |openAIFunction| | ||
% function. | ||
%% | ||
% * The example contains three steps: | ||
% * Define a custom function for ChatGPT to use to process its input and output. | ||
% * Extract papers from ArXiv. | ||
% * Use ChatGPT to assess whether a paper is relevant to your query, and to | ||
% add an entry to the results table if so. | ||
%% Initialize OpenAI API Function and Chat | ||
% Use |openAIFunction| to define functions that the model will be able to requests | ||
% calls. | ||
% | ||
% Set up the function to store paper details and initiate a chat with the OpenAI | ||
% API with a defined role as a scientific paper expert. | ||
% | ||
% Define the function that you want the model to have access to. In this example | ||
% the used function is |writePaperDetails|. | ||
|
||
f = openAIFunction("writePaperDetails", "Function to write paper details to a table."); | ||
f = addParameter(f, "name", type="string", description="Name of the paper."); | ||
f = addParameter(f, "url", type="string", description="URL containing the paper."); | ||
f = addParameter(f, "explanation", type="string", description="Explanation on why the paper is related to the given topic."); | ||
|
||
chat = openAIChat("You are an expert in filtering scientific papers. " + ... | ||
"Given a certain topic, you are able to decide if the paper" + ... | ||
" fits the given topic or not.", Tools=f); | ||
|
||
function writePaperDetails(name, url, desc) | ||
filename = "papers_to_read.csv"; | ||
T = table(name, url, desc, VariableNames=["Name", "URL", "Description"]); | ||
writetable(T, filename, WriteMode="append"); | ||
end | ||
%% Extract Papers From ArXiv | ||
% Specify the category of interest, the date range for the query, and the maximum | ||
% number of results to retrieve from the ArXiv API. | ||
|
||
category = "cs.CL"; | ||
endDate = datetime("today", "Format","uuuuMMdd"); | ||
startDate = datetime("today", "Format","uuuuMMdd") - 5; | ||
maxResults = 40; | ||
urlQuery = "https://export.arxiv.org/api/query?search_query=" + ... | ||
"cat:" + category + ... | ||
"&submittedDate=["+string(startDate)+"+TO+"+string(endDate)+"]"+... | ||
"&max_results=" + maxResults + ... | ||
"&sortBy=submittedDate&sortOrder=descending"; | ||
|
||
options = weboptions('Timeout',160); | ||
code = webread(urlQuery,options); | ||
%% | ||
% Extract individual paper entries from the API response and use ChatGPT to | ||
% determine whether each paper is related to the specified topic. | ||
% | ||
% ChatGPT will parse the XML file, so we only need to extract the relevant entries. | ||
|
||
entries = extractBetween(code, '<entry>', '</entry>'); | ||
%% Write Relevant Information to Table | ||
% Determine the topic of interest. | ||
|
||
topic = "Large Language Models"; | ||
%% | ||
% Loop over the entries and see if they are relevant to the topic of interest. | ||
|
||
for i = 1:length(entries) | ||
prompt = "Given the following paper:" + newline +... | ||
string(entries{i})+ newline +... | ||
"Is it related to the topic: "+ topic +"?" + ... | ||
" Answer 'yes' or 'no'."; | ||
[text, response] = generate(chat, prompt); | ||
|
||
%% | ||
% If the model classifies this entry as relevant, then it tries to request a | ||
% function call. | ||
|
||
if contains("yes", text, IgnoreCase=true) | ||
prompt = "Given the following paper:" + newline + string(entries{i})+ newline +... | ||
"Given the topic: "+ topic + newline + "Write the details to a table."; | ||
[text, response] = generate(chat, prompt); | ||
|
||
%% | ||
% If |function_call| if part of the response, it means the model is requesting | ||
% a function call. The function call request should contain the needed arguments | ||
% to call the function specified at the end of this example and defined with |openAIFunctions|. | ||
|
||
if isfield(response, "tool_calls") | ||
funCall = response.tool_calls; | ||
functionCallAttempt(funCall); | ||
end | ||
end | ||
end | ||
%% | ||
% Read the generated file. | ||
|
||
data = readtable("papers_to_read.csv", Delimiter=",") | ||
%% Helper Function | ||
% This function handles function call attempts from the model, checking the | ||
% function name and arguments before calling the appropriate function to store | ||
% the paper details. | ||
|
||
function functionCallAttempt(funCall) | ||
%% | ||
% The model can sometimes hallucinate function names, so you need to ensure | ||
% that it's suggesting the correct name. | ||
|
||
if funCall.function.name == "writePaperDetails" | ||
try | ||
%% | ||
% The model can sometimes return improperly formed JSON, which needs to be handled. | ||
|
||
funArgs = jsondecode(funCall.function.arguments); | ||
catch ME | ||
error("Model returned improperly formed JSON."); | ||
end | ||
%% | ||
% The model can hallucinate arguments. The code needs to ensure the arguments | ||
% have been defined before calling the function. | ||
|
||
if isfield(funArgs, "name") && isfield(funArgs, "url") && isfield(funArgs,"explanation") | ||
writePaperDetails(string(funArgs.name), string(funArgs.url), string(funArgs.explanation)); | ||
end | ||
end | ||
end | ||
%% | ||
% _Copyright 2023-2024 The MathWorks, Inc._ |
Binary file not shown.