149
149
border : 1px solid # ddd ;
150
150
padding : 8px ;
151
151
text-align : left;
152
+ vertical-align : middle;
152
153
}
153
154
154
155
th {
218
219
.copyright a : hover {
219
220
text-decoration : underline;
220
221
}
221
-
222
+ .verify-btn-group {
223
+ display : line-block;
224
+ }
222
225
.verify-btn {
223
- padding : 5 px 10 px ;
224
- margin-left : 10 px ;
226
+ padding : 3 px 8 px ;
227
+ margin-left : 8 px ;
225
228
cursor : pointer;
226
229
border : none;
227
230
border-radius : 3px ;
228
231
color : white;
232
+ display : inline-block;
233
+ font-size : 14px ;
234
+ line-height : 1.5 ;
229
235
}
230
-
231
236
.verify-btn .blue {
232
237
background-color : # 3498db ;
233
238
color : white;
249
254
.verify-btn .yellow : hover {
250
255
background-color : # e0a800 ;
251
256
}
257
+ .verify-btn .cyan {
258
+ background-color : # 1abc9c ;
259
+ color : white;
260
+ }
261
+ .verify-btn .cyan : hover {
262
+ background-color : # 16a085 ;
263
+ }
264
+ .verify-btn .pink {
265
+ background-color : # e91e63 ;
266
+ color : white;
267
+ }
268
+ .verify-btn .pink : hover {
269
+ background-color : # c2185b ;
270
+ }
252
271
.verify-btn ::after {
253
272
content : attr (data-tooltip); /* 获取 data-tooltip 属性的值作为提示文本 */
254
273
visibility : hidden;
@@ -455,6 +474,8 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
455
474
<div>🎉 等待结果并查看详细报告</div>
456
475
<div>🕵️ 使用“官转验证”功能确认API的真实性</div>
457
476
<div>🕵️♀️ 使用“温度验证”功能确认API的真实性</div>
477
+ <div>📊 使用“函数验证”功能确认API的真实性</div>
478
+ <div>🔒 <strong>beta 功能:增加本地缓存API信息功能,数据仅本地保留</strong> </div>
458
479
</ul>
459
480
<br>
460
481
<p><strong>版本历史:</strong></p>
@@ -839,7 +860,7 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
839
860
840
861
results . valid . forEach ( function ( r ) {
841
862
content += '<tr>' +
842
- '<td class="td1 td1-ok">模型一致可用</td>' +
863
+ '<td class="td1 td1-ok">模型一致可用</ td>' +
843
864
'<td class="td2"><span class="copy-btn2"" onclick="copyText(\'' + r . model + '\')">' + r . model + '</span></td>' +
844
865
'<td class="td3">' + r . responseTime . toFixed ( 2 ) + '</td>'
845
866
@@ -855,9 +876,13 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
855
876
officialButtonClass +
856
877
'" data-tooltip="相同种子参数下校验回复相似性和系统指纹,将发起4次请求" onclick="verifyOfficial(\'' +
857
878
r . model +
858
- "')\">官转验证</button>" : '' ) ;
879
+ "')\">官转验证</button>" : '' ) +
880
+ ( r . model . startsWith ( 'gpt-' ) ?
881
+ '<button class="verify-btn cyan" data-tooltip="校验函数功能是否可用,将发起1次请求" onclick="verifyFunctionCalling(\'' +
882
+ r . model +
883
+ "')\">函数验证</button>" : '' ) ;
859
884
}
860
- content += '<td class="td4">' + verifyButtons + '</td>'
885
+ content += '<td class="td4"><div class="verify-btn-group"> ' + verifyButtons + '</div> </td>'
861
886
} ) ;
862
887
863
888
results . inconsistent . forEach ( function ( r ) {
@@ -971,45 +996,45 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
971
996
}
972
997
}
973
998
974
- async function sendTemperatureVerificationRequest ( model ) {
999
+ async function sendTemperatureVerificationRequest ( model ) {
975
1000
const apiUrl = document
976
- . getElementById ( "api_url" )
977
- . value . replace ( / \/ + $ / , "" ) ;
1001
+ . getElementById ( "api_url" )
1002
+ . value . replace ( / \/ + $ / , "" ) ;
978
1003
const apiKey = document . getElementById ( "api_key" ) . value ;
979
1004
try {
980
- const response = await fetch ( `${ apiUrl } /v1/chat/completions` , {
1005
+ const response = await fetch ( `${ apiUrl } /v1/chat/completions` , {
981
1006
method : "POST" ,
982
1007
headers : {
983
- Authorization : `Bearer ${ apiKey } ` ,
984
- "Content-Type" : "application/json" ,
1008
+ Authorization : `Bearer ${ apiKey } ` ,
1009
+ "Content-Type" : "application/json" ,
985
1010
} ,
986
1011
body : JSON . stringify ( {
987
- messages : [
1012
+ messages : [
988
1013
{
989
- role : "system" ,
990
- content :
1014
+ role : "system" ,
1015
+ content :
991
1016
"You're an associative thinker. The user gives you a sequence of 6 numbers. Your task is to figure out and provide the 7th number directly, without explaining how you got there." ,
992
1017
} ,
993
1018
{
994
- role : "user" ,
995
- content : "5, 15, 77, 19, 53, 54," ,
1019
+ role : "user" ,
1020
+ content : "5, 15, 77, 19, 53, 54," ,
996
1021
} ,
997
- ] ,
998
- temperature : 0.01 ,
999
- model : model ,
1022
+ ] ,
1023
+ temperature : 0.01 ,
1024
+ model : model ,
1000
1025
} ) ,
1001
- } ) ;
1026
+ } ) ;
1002
1027
1003
- if ( ! response . ok ) {
1028
+ if ( ! response . ok ) {
1004
1029
throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
1005
- }
1030
+ }
1006
1031
1007
- return await response . json ( ) ;
1032
+ return await response . json ( ) ;
1008
1033
} catch ( error ) {
1009
- console . error ( "Error in sendTemperatureVerificationRequest:" , error ) ;
1010
- return { error : error . message } ;
1034
+ console . error ( "Error in sendTemperatureVerificationRequest:" , error ) ;
1035
+ return { error : error . message } ;
1011
1036
}
1012
- }
1037
+ }
1013
1038
1014
1039
async function performOfficialVerification ( model , seed ) {
1015
1040
layui . use ( 'layer' , function ( ) {
@@ -1135,6 +1160,168 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
1135
1160
}
1136
1161
}
1137
1162
1163
+ async function verifyFunctionCalling ( model ) {
1164
+ console . log ( "开始验证函数调用" ) ;
1165
+ layui . use ( 'layer' , function ( ) {
1166
+ const layer = layui . layer ;
1167
+
1168
+ layer . open ( {
1169
+ title : '请输入两个整数 a 和 b' ,
1170
+ area : [ '400px' , '250px' ] ,
1171
+ content : `
1172
+ <div style="padding: 10px;">
1173
+ <div style="margin-bottom: 10px;">
1174
+ <label style="display: inline-block; width: 100px;">请输入整数 a:</label>
1175
+ <input type="number" id="inputA" class="layui-input" style="width: 60px; display: inline-block;" value="3" placeholder="a">
1176
+ </div>
1177
+ <div style="margin-bottom: 10px;">
1178
+ <label style="display: inline-block; width: 100px;">请输入整数 b:</label>
1179
+ <input type="number" id="inputB" class="layui-input" style="width: 60px; display: inline-block;" value="5" placeholder="b">
1180
+ </div>
1181
+ </div>
1182
+ ` ,
1183
+ btn : [ '确定' , '取消' ] ,
1184
+ yes : function ( index , layero ) {
1185
+ const a = parseInt ( document . getElementById ( 'inputA' ) . value ) ;
1186
+ const b = parseInt ( document . getElementById ( 'inputB' ) . value ) ;
1187
+
1188
+ if ( isNaN ( a ) || isNaN ( b ) ) {
1189
+ layer . msg ( '请输入有效的整数 a 和 b' ) ;
1190
+ return ;
1191
+ }
1192
+
1193
+ layer . close ( index ) ;
1194
+ performFunctionCallingVerification ( model , a , b ) ;
1195
+ }
1196
+ } ) ;
1197
+ } ) ;
1198
+ }
1199
+ async function sendFunctionCallingRequest ( model , a , b ) {
1200
+ const apiUrl = document . getElementById ( 'api_url' ) . value . replace ( / \/ + $ / , '' ) ;
1201
+ const apiKey = document . getElementById ( 'api_key' ) . value ;
1202
+ try {
1203
+ const response = await fetch ( `${ apiUrl } /v1/chat/completions` , {
1204
+ method : 'POST' ,
1205
+ headers : {
1206
+ 'Authorization' : `Bearer ${ apiKey } ` ,
1207
+ 'Content-Type' : 'application/json'
1208
+ } ,
1209
+ body : JSON . stringify ( {
1210
+ messages : [
1211
+ { "role" : "system" , "content" : "You are a helpful assistant." } ,
1212
+ { "role" : "user" , "content" : `Please add ${ a } and ${ b } .` }
1213
+ ] ,
1214
+ functions : [
1215
+ {
1216
+ "name" : "add_numbers" ,
1217
+ "description" : "Adds two numbers together" ,
1218
+ "parameters" : {
1219
+ "type" : "object" ,
1220
+ "properties" : {
1221
+ "a" : {
1222
+ "type" : "number" ,
1223
+ "description" : "The first number"
1224
+ } ,
1225
+ "b" : {
1226
+ "type" : "number" ,
1227
+ "description" : "The second number"
1228
+ }
1229
+ } ,
1230
+ "required" : [ "a" , "b" ]
1231
+ }
1232
+ }
1233
+ ] ,
1234
+ function_call : "auto" ,
1235
+ temperature : 0.5 ,
1236
+ model : model
1237
+ } )
1238
+ } ) ;
1239
+
1240
+ if ( ! response . ok ) {
1241
+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
1242
+ }
1243
+
1244
+ return await response . json ( ) ;
1245
+ } catch ( error ) {
1246
+ console . error ( 'Error in sendFunctionCallingRequest:' , error ) ;
1247
+ return { error : error . message } ;
1248
+ }
1249
+ }
1250
+ async function performFunctionCallingVerification ( model , a , b ) {
1251
+ layui . use ( 'layer' , function ( ) {
1252
+ const layer = layui . layer ;
1253
+ layer . load ( ) ;
1254
+ } ) ;
1255
+
1256
+ try {
1257
+ const result = await sendFunctionCallingRequest ( model , a , b ) ;
1258
+
1259
+ if ( result . error ) {
1260
+ console . error ( `Error in request:` , result . error ) ;
1261
+ layui . use ( 'layer' , function ( ) {
1262
+ const layer = layui . layer ;
1263
+ layer . closeAll ( 'loading' ) ;
1264
+ layer . alert ( `请求失败: ${ result . error } ` , { title : '错误' } ) ;
1265
+ } ) ;
1266
+ return ;
1267
+ }
1268
+
1269
+ layui . use ( 'layer' , function ( ) {
1270
+ const layer = layui . layer ;
1271
+ layer . closeAll ( 'loading' ) ;
1272
+ const title = '<b><span style="color: black;">模型函数调用响应对比</span></b>' ;
1273
+ let text ;
1274
+ if ( result . choices ?. [ 0 ] ?. finish_reason !== 'function_call' ) {
1275
+ text = '<b><span style="color: red;">模型无函数调用响应返回,测试模型为:' + model + '</span></b>' ;
1276
+ }
1277
+ else {
1278
+ text = '<b><span style="color: green;">模型返回了函数调用响应,测试模型为:' + model + '</span></b>' ;
1279
+ }
1280
+ const referenceFunctionCall = JSON . stringify ( {
1281
+ "index" : 0 ,
1282
+ "message" : {
1283
+ "role" : "assistant" ,
1284
+ "content" : null ,
1285
+ "function_call" : {
1286
+ "name" : "add_numbers" ,
1287
+ "arguments" : `{"a":${ a } ,"b":${ b } }`
1288
+ } ,
1289
+ } ,
1290
+ "logprobs" : null ,
1291
+ "finish_reason" : "function_call" ,
1292
+ } , null , 4 ) ;
1293
+ const modelFunctionCall = JSON . stringify ( result . choices ?. [ 0 ] , null , 4 ) ;
1294
+ const message = text + `
1295
+ <table border="1" style="width: 100%; border-collapse: collapse; text-align: left;">
1296
+ <thead>
1297
+ <tr>
1298
+ <th style="padding: 8px; background-color: #f2f2f2;">标准输出参考</th>
1299
+ <th style="padding: 8px; background-color: #f2f2f2;">测试模型输出</th>
1300
+ </tr>
1301
+ </thead>
1302
+ <tbody>
1303
+ <tr>
1304
+ <td style="padding: 8px;">
1305
+ <pre style="white-space: pre-wrap; word-wrap: break-word;">${ referenceFunctionCall } </pre>
1306
+ </td>
1307
+ <td style="padding: 8px;">
1308
+ <pre style="white-space: pre-wrap; word-wrap: break-word;">${ modelFunctionCall } </pre>
1309
+ </td>
1310
+ </tr>
1311
+ </tbody>
1312
+ </table>
1313
+ ` ;
1314
+ layer . alert ( message , { title : title , area : [ '800px' , '600px' ] } ) ;
1315
+ } ) ;
1316
+ } catch ( error ) {
1317
+ console . error ( 'Error in performOfficialVerification:' , error ) ;
1318
+ layui . use ( 'layer' , function ( ) {
1319
+ const layer = layui . layer ;
1320
+ layer . closeAll ( 'loading' ) ;
1321
+ layer . alert ( '验证过程中发生错误: ' + error . message , { title : '错误' } ) ;
1322
+ } ) ;
1323
+ }
1324
+ }
1138
1325
1139
1326
function compareTextSimilarity ( text1 , text2 , text3 , text4 ) {
1140
1327
function calculateSimilarity ( str1 , str2 ) {
0 commit comments