Skip to content

Commit 6c9c5c6

Browse files
committed
增加函数调用功能验证
1 parent 33fa343 commit 6c9c5c6

File tree

1 file changed

+215
-28
lines changed

1 file changed

+215
-28
lines changed

index.html

Lines changed: 215 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
border: 1px solid #ddd;
150150
padding: 8px;
151151
text-align: left;
152+
vertical-align: middle;
152153
}
153154

154155
th {
@@ -218,16 +219,20 @@
218219
.copyright a:hover {
219220
text-decoration: underline;
220221
}
221-
222+
.verify-btn-group {
223+
display: line-block;
224+
}
222225
.verify-btn {
223-
padding: 5px 10px;
224-
margin-left: 10px;
226+
padding: 3px 8px;
227+
margin-left: 8px;
225228
cursor: pointer;
226229
border: none;
227230
border-radius: 3px;
228231
color: white;
232+
display: inline-block;
233+
font-size: 14px;
234+
line-height: 1.5;
229235
}
230-
231236
.verify-btn.blue {
232237
background-color: #3498db;
233238
color: white;
@@ -249,6 +254,20 @@
249254
.verify-btn.yellow:hover {
250255
background-color: #e0a800;
251256
}
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+
}
252271
.verify-btn::after {
253272
content: attr(data-tooltip); /* 获取 data-tooltip 属性的值作为提示文本 */
254273
visibility: hidden;
@@ -455,6 +474,8 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
455474
<div>🎉 等待结果并查看详细报告</div>
456475
<div>🕵️ 使用“官转验证”功能确认API的真实性</div>
457476
<div>🕵️‍♀️ 使用“温度验证”功能确认API的真实性</div>
477+
<div>📊 使用“函数验证”功能确认API的真实性</div>
478+
<div>🔒 <strong>beta 功能:增加本地缓存API信息功能,数据仅本地保留</strong> </div>
458479
</ul>
459480
<br>
460481
<p><strong>版本历史:</strong></p>
@@ -839,7 +860,7 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
839860

840861
results.valid.forEach(function (r) {
841862
content += '<tr>' +
842-
'<td class="td1 td1-ok">模型一致可用</td>' +
863+
'<td class="td1 td1-ok">模型一致可用</ td>' +
843864
'<td class="td2"><span class="copy-btn2"" onclick="copyText(\'' + r.model + '\')">' + r.model + '</span></td>' +
844865
'<td class="td3">' + r.responseTime.toFixed(2) + '</td>'
845866

@@ -855,9 +876,13 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
855876
officialButtonClass +
856877
'" data-tooltip="相同种子参数下校验回复相似性和系统指纹,将发起4次请求" onclick="verifyOfficial(\'' +
857878
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>" : '');
859884
}
860-
content += '<td class="td4">' + verifyButtons + '</td>'
885+
content += '<td class="td4"><div class="verify-btn-group">' + verifyButtons + '</div></td>'
861886
});
862887

863888
results.inconsistent.forEach(function (r) {
@@ -971,45 +996,45 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
971996
}
972997
}
973998

974-
async function sendTemperatureVerificationRequest(model) {
999+
async function sendTemperatureVerificationRequest(model) {
9751000
const apiUrl = document
976-
.getElementById("api_url")
977-
.value.replace(/\/+$/, "");
1001+
.getElementById("api_url")
1002+
.value.replace(/\/+$/, "");
9781003
const apiKey = document.getElementById("api_key").value;
9791004
try {
980-
const response = await fetch(`${apiUrl}/v1/chat/completions`, {
1005+
const response = await fetch(`${apiUrl}/v1/chat/completions`, {
9811006
method: "POST",
9821007
headers: {
983-
Authorization: `Bearer ${apiKey}`,
984-
"Content-Type": "application/json",
1008+
Authorization: `Bearer ${apiKey}`,
1009+
"Content-Type": "application/json",
9851010
},
9861011
body: JSON.stringify({
987-
messages: [
1012+
messages: [
9881013
{
989-
role: "system",
990-
content:
1014+
role: "system",
1015+
content:
9911016
"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.",
9921017
},
9931018
{
994-
role: "user",
995-
content: "5, 15, 77, 19, 53, 54,",
1019+
role: "user",
1020+
content: "5, 15, 77, 19, 53, 54,",
9961021
},
997-
],
998-
temperature: 0.01,
999-
model: model,
1022+
],
1023+
temperature: 0.01,
1024+
model: model,
10001025
}),
1001-
});
1026+
});
10021027

1003-
if (!response.ok) {
1028+
if (!response.ok) {
10041029
throw new Error(`HTTP error! status: ${response.status}`);
1005-
}
1030+
}
10061031

1007-
return await response.json();
1032+
return await response.json();
10081033
} 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 };
10111036
}
1012-
}
1037+
}
10131038

10141039
async function performOfficialVerification(model, seed) {
10151040
layui.use('layer', function () {
@@ -1135,6 +1160,168 @@ <h3>(适配 oneapi/newapi 等中转格式)</h3>
11351160
}
11361161
}
11371162

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+
}
11381325

11391326
function compareTextSimilarity(text1, text2, text3, text4) {
11401327
function calculateSimilarity(str1, str2) {

0 commit comments

Comments
 (0)