Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -445,16 +445,21 @@ class OpenAi
|
|||||||
$model = empty($aParam['model']) ? 'gpt-4.1' : $aParam['model'];
|
$model = empty($aParam['model']) ? 'gpt-4.1' : $aParam['model'];
|
||||||
|
|
||||||
//接口地址
|
//接口地址
|
||||||
$sUrl = $this->sUrl;
|
$sUrl = empty($aParam['url']) ? $this->sUrl : $aParam['url'];
|
||||||
|
|
||||||
// 降低随机性(0-1,0为最确定)
|
// 降低随机性(0-1,0为最确定)
|
||||||
$iTemperature = empty($aParam['temperature']) ? '0.1' : $aParam['temperature'];
|
$iTemperature = empty($aParam['temperature']) ? 0 : $aParam['temperature'];
|
||||||
|
$iTop = empty($aParam['top_p']) ? 0.9 : $aParam['top_p'];
|
||||||
|
$sApiKey = empty($aParam['api_key']) ? '' : $aParam['api_key'];
|
||||||
//组装数据
|
//组装数据
|
||||||
$data = [
|
$data = [
|
||||||
'model' => $model,
|
'model' => $model,
|
||||||
'messages' => $aMessage,
|
'messages' => $aMessage,
|
||||||
'temperature' => $iTemperature,
|
'temperature' => $iTemperature,
|
||||||
|
"max_tokens" => 1500, // 足够容纳结构化结论,避免截断
|
||||||
|
// "top_p" => $iTop, // 控制多样性,1.0 表示不限制
|
||||||
|
// "frequency_penalty" => 0.0, // 避免重复内容
|
||||||
|
// "presence_penalty" => 0.0
|
||||||
];
|
];
|
||||||
$this->curl = curl_init();
|
$this->curl = curl_init();
|
||||||
|
|
||||||
@@ -463,7 +468,7 @@ class OpenAi
|
|||||||
// 设置头信息
|
// 设置头信息
|
||||||
curl_setopt($this->curl, CURLOPT_HTTPHEADER, [
|
curl_setopt($this->curl, CURLOPT_HTTPHEADER, [
|
||||||
'Content-Type: application/json',
|
'Content-Type: application/json',
|
||||||
'Authorization: Bearer ' . $this->sApiKey
|
'Authorization: Bearer ' . $sApiKey
|
||||||
]);
|
]);
|
||||||
curl_setopt($this->curl, CURLOPT_PROXY,$this->proxy);
|
curl_setopt($this->curl, CURLOPT_PROXY,$this->proxy);
|
||||||
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,true);
|
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,true);
|
||||||
@@ -522,6 +527,7 @@ class OpenAi
|
|||||||
$sUrl = empty($aParam['url']) ? $this->sUrl : $aParam['url'];
|
$sUrl = empty($aParam['url']) ? $this->sUrl : $aParam['url'];
|
||||||
$iTemperature = empty($aParam['temperature']) ? '0.2' : $aParam['temperature'];
|
$iTemperature = empty($aParam['temperature']) ? '0.2' : $aParam['temperature'];
|
||||||
$iTop = empty($aParam['top_p']) ? '0.9' : $aParam['top_p'];
|
$iTop = empty($aParam['top_p']) ? '0.9' : $aParam['top_p'];
|
||||||
|
$sApiKey = empty($aParam['api_key']) ? '' : $aParam['api_key'];
|
||||||
// 组装数据 - 增加流式传输必要参数
|
// 组装数据 - 增加流式传输必要参数
|
||||||
$data = [
|
$data = [
|
||||||
'model' => $model,
|
'model' => $model,
|
||||||
@@ -539,7 +545,7 @@ class OpenAi
|
|||||||
curl_setopt($this->curl, CURLOPT_URL, $sUrl);
|
curl_setopt($this->curl, CURLOPT_URL, $sUrl);
|
||||||
curl_setopt($this->curl, CURLOPT_HTTPHEADER, [
|
curl_setopt($this->curl, CURLOPT_HTTPHEADER, [
|
||||||
'Content-Type: application/json',
|
'Content-Type: application/json',
|
||||||
'Authorization: Bearer ' . $this->sApiKey,
|
'Authorization: Bearer ' . $sApiKey,
|
||||||
'Accept: text/event-stream',
|
'Accept: text/event-stream',
|
||||||
'Cache-Control: no-cache',
|
'Cache-Control: no-cache',
|
||||||
'Connection: keep-alive', // 保持长连接
|
'Connection: keep-alive', // 保持长连接
|
||||||
@@ -879,6 +885,8 @@ class OpenAi
|
|||||||
if(empty($sSysMessagePrompt)){
|
if(empty($sSysMessagePrompt)){
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
// 解析JSON
|
||||||
|
$sSysMessagePrompt = $this->fixEncoding($sSysMessagePrompt);
|
||||||
$aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel];
|
$aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel];
|
||||||
if(empty($aQuestion)){
|
if(empty($aQuestion)){
|
||||||
return [];
|
return [];
|
||||||
@@ -892,7 +900,10 @@ class OpenAi
|
|||||||
}
|
}
|
||||||
//系统角色
|
//系统角色
|
||||||
$sSysMessageInfo = empty($aScopeReturn[$key]) ? '' : json_encode($aScopeReturn[$key],JSON_UNESCAPED_UNICODE);
|
$sSysMessageInfo = empty($aScopeReturn[$key]) ? '' : json_encode($aScopeReturn[$key],JSON_UNESCAPED_UNICODE);
|
||||||
|
// 解析JSON
|
||||||
|
$sSysMessageInfo = $this->fixEncoding($sSysMessageInfo);
|
||||||
$sUserPrompt = str_replace(array_keys($aSearch), array_values($aSearch), $value);
|
$sUserPrompt = str_replace(array_keys($aSearch), array_values($aSearch), $value);
|
||||||
|
$sUserPrompt = $this->fixEncoding($sUserPrompt);
|
||||||
$aMessage[] = [
|
$aMessage[] = [
|
||||||
['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo],
|
['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo],
|
||||||
['role' => 'user', 'content' => $sUserPrompt],
|
['role' => 'user', 'content' => $sUserPrompt],
|
||||||
@@ -1025,6 +1036,8 @@ class OpenAi
|
|||||||
if(empty($sSysMessagePrompt)){
|
if(empty($sSysMessagePrompt)){
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
// 解析JSON
|
||||||
|
$sSysMessagePrompt = $this->fixEncoding($sSysMessagePrompt);
|
||||||
$aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel];
|
$aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel];
|
||||||
if(empty($aQuestion)){
|
if(empty($aQuestion)){
|
||||||
return [];
|
return [];
|
||||||
@@ -1039,7 +1052,7 @@ class OpenAi
|
|||||||
if(empty($sSysMessageInfo)){
|
if(empty($sSysMessageInfo)){
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
$sSysMessageInfo = $this->fixEncoding($sSysMessageInfo);
|
||||||
//处理数据
|
//处理数据
|
||||||
$aContent = empty($aSearch['content']) ? '' : $aSearch['content'];
|
$aContent = empty($aSearch['content']) ? '' : $aSearch['content'];
|
||||||
if(empty($aContent)){
|
if(empty($aContent)){
|
||||||
@@ -1048,6 +1061,7 @@ class OpenAi
|
|||||||
foreach ($aContent as $key => $value) {
|
foreach ($aContent as $key => $value) {
|
||||||
$aSearch['content'] = $value;
|
$aSearch['content'] = $value;
|
||||||
$sUserPrompt = str_replace(array_keys($aSearch), array_values($aSearch), $aQuestion[$sQuestionFields]);
|
$sUserPrompt = str_replace(array_keys($aSearch), array_values($aSearch), $aQuestion[$sQuestionFields]);
|
||||||
|
$sUserPrompt = $this->fixEncoding($sUserPrompt);
|
||||||
$aMessage[] = [
|
$aMessage[] = [
|
||||||
['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo],
|
['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo],
|
||||||
['role' => 'user', 'content' => $sUserPrompt],
|
['role' => 'user', 'content' => $sUserPrompt],
|
||||||
@@ -1055,6 +1069,30 @@ class OpenAi
|
|||||||
}
|
}
|
||||||
return $aMessage;
|
return $aMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function fixEncoding($content) {
|
||||||
|
// 1. 检查是否为UTF-8,不是则尝试多种常见编码转换
|
||||||
|
if (!mb_check_encoding($content, 'UTF-8')) {
|
||||||
|
// 优先尝试西方编码(因"10.1016/j"是DOI格式,常见于英文文献)
|
||||||
|
$encodings = ['Windows-1252', 'ISO-8859-1', 'GBK', 'GB2312'];
|
||||||
|
foreach ($encodings as $encoding) {
|
||||||
|
$converted = mb_convert_encoding($content, 'UTF-8', $encoding);
|
||||||
|
if (mb_check_encoding($converted, 'UTF-8')) {
|
||||||
|
$content = $converted;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 过滤残留的乱码字符(保留字母、数字、空格及DOI相关符号)
|
||||||
|
// 允许的字符:a-z、A-Z、0-9、空格、.、:、/、-、_、(、)、,
|
||||||
|
$content = preg_replace('/[^\p{L}\p{N}\s\.\:\/\-\_\(\),]/u', '', $content);
|
||||||
|
|
||||||
|
// 3. 去除首尾多余空格
|
||||||
|
$content = trim($content);
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 微信公众号-生成公微内容(CURL)
|
* 微信公众号-生成公微内容(CURL)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user