From 774dc7263535fce43d532b991932ffa11ee9ee8d Mon Sep 17 00:00:00 2001 From: chengxl Date: Thu, 27 Nov 2025 10:29:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/common/OpenAi.php | 50 ++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/application/common/OpenAi.php b/application/common/OpenAi.php index 258ac87..bd29020 100644 --- a/application/common/OpenAi.php +++ b/application/common/OpenAi.php @@ -445,16 +445,21 @@ class OpenAi $model = empty($aParam['model']) ? 'gpt-4.1' : $aParam['model']; //接口地址 - $sUrl = $this->sUrl; + $sUrl = empty($aParam['url']) ? $this->sUrl : $aParam['url']; // 降低随机性(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 = [ 'model' => $model, 'messages' => $aMessage, 'temperature' => $iTemperature, + "max_tokens" => 1500, // 足够容纳结构化结论,避免截断 + // "top_p" => $iTop, // 控制多样性,1.0 表示不限制 + // "frequency_penalty" => 0.0, // 避免重复内容 + // "presence_penalty" => 0.0 ]; $this->curl = curl_init(); @@ -463,7 +468,7 @@ class OpenAi // 设置头信息 curl_setopt($this->curl, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', - 'Authorization: Bearer ' . $this->sApiKey + 'Authorization: Bearer ' . $sApiKey ]); curl_setopt($this->curl, CURLOPT_PROXY,$this->proxy); curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,true); @@ -522,6 +527,7 @@ class OpenAi $sUrl = empty($aParam['url']) ? $this->sUrl : $aParam['url']; $iTemperature = empty($aParam['temperature']) ? '0.2' : $aParam['temperature']; $iTop = empty($aParam['top_p']) ? '0.9' : $aParam['top_p']; + $sApiKey = empty($aParam['api_key']) ? '' : $aParam['api_key']; // 组装数据 - 增加流式传输必要参数 $data = [ 'model' => $model, @@ -539,7 +545,7 @@ class OpenAi curl_setopt($this->curl, CURLOPT_URL, $sUrl); curl_setopt($this->curl, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', - 'Authorization: Bearer ' . $this->sApiKey, + 'Authorization: Bearer ' . $sApiKey, 'Accept: text/event-stream', 'Cache-Control: no-cache', 'Connection: keep-alive', // 保持长连接 @@ -879,6 +885,8 @@ class OpenAi if(empty($sSysMessagePrompt)){ return []; } + // 解析JSON + $sSysMessagePrompt = $this->fixEncoding($sSysMessagePrompt); $aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel]; if(empty($aQuestion)){ return []; @@ -892,7 +900,10 @@ class OpenAi } //系统角色 $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 = $this->fixEncoding($sUserPrompt); $aMessage[] = [ ['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo], ['role' => 'user', 'content' => $sUserPrompt], @@ -1025,6 +1036,8 @@ class OpenAi if(empty($sSysMessagePrompt)){ return []; } + // 解析JSON + $sSysMessagePrompt = $this->fixEncoding($sSysMessagePrompt); $aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel]; if(empty($aQuestion)){ return []; @@ -1039,7 +1052,7 @@ class OpenAi if(empty($sSysMessageInfo)){ return []; } - + $sSysMessageInfo = $this->fixEncoding($sSysMessageInfo); //处理数据 $aContent = empty($aSearch['content']) ? '' : $aSearch['content']; if(empty($aContent)){ @@ -1048,6 +1061,7 @@ class OpenAi foreach ($aContent as $key => $value) { $aSearch['content'] = $value; $sUserPrompt = str_replace(array_keys($aSearch), array_values($aSearch), $aQuestion[$sQuestionFields]); + $sUserPrompt = $this->fixEncoding($sUserPrompt); $aMessage[] = [ ['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo], ['role' => 'user', 'content' => $sUserPrompt], @@ -1055,6 +1069,30 @@ class OpenAi } 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) */