3
3
4
4
% Copyright 2023-2024 The MathWorks, Inc.
5
5
6
- methods (TestClassSetup )
7
- function saveEnvVar(testCase )
8
- % Ensures key is not in environment variable for tests
9
- openAIEnvVar = " OPENAI_API_KEY" ;
10
- if isenv(openAIEnvVar )
11
- key = getenv(openAIEnvVar );
12
- unsetenv(openAIEnvVar );
13
- testCase .addTeardown(@(x ) setenv(openAIEnvVar , x ), key );
14
- end
15
- end
16
- end
17
-
18
6
properties (TestParameter )
19
7
ValidConstructorInput = iGetValidConstructorInput();
20
8
InvalidConstructorInput = iGetInvalidConstructorInput();
@@ -39,10 +27,6 @@ function generateAcceptsMessagesAsInput(testCase)
39
27
testCase .verifyWarningFree(@()generate(chat ,messages ));
40
28
end
41
29
42
- function keyNotFound(testCase )
43
- testCase .verifyError(@()openAIChat , " llms:keyMustBeSpecified" );
44
- end
45
-
46
30
function constructChatWithAllNVP(testCase )
47
31
functions = openAIFunction(" funName" );
48
32
modelName = " gpt-3.5-turbo" ;
@@ -104,6 +88,80 @@ function invalidInputsConstructor(testCase, InvalidConstructorInput)
104
88
testCase .verifyError(@()openAIChat(InvalidConstructorInput.Input{: }), InvalidConstructorInput .Error );
105
89
end
106
90
91
+ function generateWithTools(testCase )
92
+ import matlab .unittest .constraints .HasField
93
+
94
+ f = openAIFunction(" writePaperDetails" , " Function to write paper details to a table." );
95
+ f = addParameter(f , " name" , type= " string" , description= " Name of the paper." );
96
+ f = addParameter(f , " url" , type= " string" , description= " URL containing the paper." );
97
+ f = addParameter(f , " explanation" , type= " string" , description= " Explanation on why the paper is related to the given topic." );
98
+
99
+ paperExtractor = openAIChat(" You are an expert in extracting information from a paper." , Tools= f );
100
+
101
+ input = join([
102
+ " <id>http://arxiv.org/abs/2406.04344v1</id>"
103
+ " <updated>2024-06-06T17:59:56Z</updated>"
104
+ " <published>2024-06-06T17:59:56Z</published>"
105
+ " <title>Verbalized Machine Learning: Revisiting Machine Learning with Language"
106
+ " Models</title>"
107
+ " <summary> Motivated by the large progress made by large language models (LLMs), we"
108
+ " introduce the framework of verbalized machine learning (VML). In contrast to"
109
+ " conventional machine learning models that are typically optimized over a"
110
+ " continuous parameter space, VML constrains the parameter space to be"
111
+ " human-interpretable natural language. Such a constraint leads to a new"
112
+ " perspective of function approximation, where an LLM with a text prompt can be"
113
+ " viewed as a function parameterized by the text prompt. Guided by this"
114
+ " perspective, we revisit classical machine learning problems, such as regression"
115
+ " and classification, and find that these problems can be solved by an"
116
+ " LLM-parameterized learner and optimizer. The major advantages of VML include"
117
+ " (1) easy encoding of inductive bias: prior knowledge about the problem and"
118
+ " hypothesis class can be encoded in natural language and fed into the"
119
+ " LLM-parameterized learner; (2) automatic model class selection: the optimizer"
120
+ " can automatically select a concrete model class based on data and verbalized"
121
+ " prior knowledge, and it can update the model class during training; and (3)"
122
+ " interpretable learner updates: the LLM-parameterized optimizer can provide"
123
+ " explanations for why each learner update is performed. We conduct several"
124
+ " studies to empirically evaluate the effectiveness of VML, and hope that VML can"
125
+ " serve as a stepping stone to stronger interpretability and trustworthiness in"
126
+ " ML."
127
+ " </summary>"
128
+ " <author>"
129
+ " <name>Tim Z. Xiao</name>"
130
+ " </author>"
131
+ " <author>"
132
+ " <name>Robert Bamler</name>"
133
+ " </author>"
134
+ " <author>"
135
+ " <name>Bernhard Schölkopf</name>"
136
+ " </author>"
137
+ " <author>"
138
+ " <name>Weiyang Liu</name>"
139
+ " </author>"
140
+ " <arxiv:comment xmlns:arxiv='http://arxiv.org/schemas/atom'>Technical Report v1 (92 pages, 15 figures)</arxiv:comment>"
141
+ " <link href='http://arxiv.org/abs/2406.04344v1' rel='alternate' type='text/html'/>"
142
+ " <link title='pdf' href='http://arxiv.org/pdf/2406.04344v1' rel='related' type='application/pdf'/>"
143
+ " <arxiv:primary_category xmlns:arxiv='http://arxiv.org/schemas/atom' term='cs.LG' scheme='http://arxiv.org/schemas/atom'/>"
144
+ " <category term='cs.LG' scheme='http://arxiv.org/schemas/atom'/>"
145
+ " <category term='cs.CL' scheme='http://arxiv.org/schemas/atom'/>"
146
+ " <category term='cs.CV' scheme='http://arxiv.org/schemas/atom'/>"
147
+ ], newline );
148
+
149
+ topic = " Large Language Models" ;
150
+
151
+ prompt = " Given the following paper:" + newline + string(input )+ newline + ...
152
+ " Given the topic: " + topic + newline + " Write the details to a table." ;
153
+ [~ , response ] = generate(paperExtractor , prompt );
154
+
155
+ testCase .assertThat(response , HasField(" tool_calls" ));
156
+ testCase .verifyEqual(response .tool_calls .type ,' function' );
157
+ testCase .verifyEqual(response .tool_calls .function .name ,' writePaperDetails' );
158
+ data = testCase .verifyWarningFree( ...
159
+ @() jsondecode(response .tool_calls .function .arguments ));
160
+ testCase .verifyThat(data ,HasField(" name" ));
161
+ testCase .verifyThat(data ,HasField(" url" ));
162
+ testCase .verifyThat(data ,HasField(" explanation" ));
163
+ end
164
+
107
165
function invalidInputsGenerate(testCase , InvalidGenerateInput )
108
166
f = openAIFunction(" validfunction" );
109
167
chat = openAIChat(Tools = f , APIKey= " this-is-not-a-real-key" );
@@ -177,6 +235,15 @@ function createOpenAIChatWithOpenAIKeyLatestModel(testCase)
177
235
testCase .verifyWarningFree(@()generate(chat , " Hello world." ));
178
236
end
179
237
238
+ function keyNotFound(testCase )
239
+ % to verify the error, we need to unset the environment variable
240
+ % OPENAI_API_KEY, if given. Use a fixture to restore the
241
+ % value on leaving the test point:
242
+ import matlab .unittest .fixtures .EnvironmentVariableFixture
243
+ testCase .applyFixture(EnvironmentVariableFixture(" OPENAI_API_KEY" ," dummy" ));
244
+ unsetenv(" OPENAI_API_KEY" );
245
+ testCase .verifyError(@()openAIChat , " llms:keyMustBeSpecified" );
246
+ end
180
247
end
181
248
end
182
249
0 commit comments