getint('aikey'); $aikeyrow = null; if ($aikey > 0) { $csql = new \ciy\sql('zc_ai_key'); $csql->where('id', $aikey); $aikeyrow = $db->getone($csql); if (!is_array($aikeyrow)) return errjson('AI Key不存在'); } if (!is_array($aikeyrow)) { $csql = new \ciy\sql('zc_ai_key'); $csql->where('id', 1); $aikeyrow = $db->getone($csql); if (!is_array($aikeyrow)) return errjson('AI Key未设置'); } $system = $post->get('system'); $chat = $post->get('chat'); if(empty($chat)) return errjson('请输入聊天内容'); $openai = new \ciy\openai($aikeyrow); $openai->debug($debug); $openai->setparam($post->get('aiprange')); $openai->newsystem($system); $retai = $openai->completion($chat, strpos($chat . $system, 'JSON') !== false); if (is_string($retai)) return errjson($retai); $ret['ai'] = $retai; return succjson($ret); } public static function json_aidecision($param = null, $debug = false) { global $db; set_time_limit(0); $timespan = time(); $post = new \ciy\post($param); $id = $post->getint('id'); $csql = new \ciy\sql('zc_ai_decision'); $csql->where('id', $id); $decisionrow = $db->getone($csql); if (!is_array($decisionrow)) return errjson('AI决策单元不存在'); $csql = new \ciy\sql('zc_ai_key'); $csql->where('id', $decisionrow['aikey']); $aikeyrow = $db->getone($csql); if (!is_array($aikeyrow)) return errjson('AI Key未设置'); $funcdatarows = null; if (!empty($decisionrow['funcids'])) { $csql = new \ciy\sql('zc_ai_funcdata'); $csql->where('id in', trim($decisionrow['funcids'], ',')); $funcdatarows = $db->get($csql); } if (strpos($decisionrow['sysprompt'] . $decisionrow['roleprompt'], '{{know.') === false) { $csql = new \ciy\sql('zc_ai_knowcata'); $knowcatarows = $db->get($csql); if (count($knowcatarows) > 0) { if ($funcdatarows == null) $funcdatarows = array(); $descs = ''; foreach ($knowcatarows as $knowcatarow) { $descs .= "\n{知识库ID:" . $knowcatarow['id'] . ", " . $knowcatarow['name'] . ',' . $knowcatarow['aiguide'] . '}'; } $funcdatarows[] = array( 'id' => 0, 'name' => 'know', 'funcname' => 'know', 'descs' => '如果需要补充学习专业知识库信息,调用该函数。知识库列表有,' . $descs, 'paramjson' => '*ID=准确的知识库ID', 'funcparam' => '' ); } } $csql = new \ciy\sql('zc_ai_key'); $csql->where('id', $decisionrow['aikey']); $aikeyrow = $db->getone($csql); if (!is_array($aikeyrow)) return errjson('AI Key不存在'); $system = preg_replace_callback('/\{\{([^}]+)\}\}/', function ($matches) use ($db, $post) { $key = $matches[1]; if (substr($key, 0, 5) == 'know.') { $knowcataname = substr($key, 5); $csql = new \ciy\sql('zc_ai_knowcata'); $csql->where('name', $knowcataname); $knowcatarow = $db->getone($csql); if (!is_array($knowcatarow)) return ''; $csql = new \ciy\sql('zc_ai_knowledge'); $csql->where('cataid', $knowcatarow['id']); $knowrows = $db->get($csql); $knowstr = ''; foreach ($knowrows as $knowrow) { $knowstr .= $knowrow['content'] . "\n"; } return $knowstr; } $val = $post->get($key); if (is_array($val)) $val = json_encode($val, JSON_UNESCAPED_UNICODE); return $val . ''; }, $decisionrow['sysprompt']); $roleprompt = preg_replace_callback('/\{\{([^}]+)\}\}/', function ($matches) use ($db, $post) { $key = $matches[1]; if (substr($key, 0, 5) == 'know.') { $knowcataname = substr($key, 5); $csql = new \ciy\sql('zc_ai_knowcata'); $csql->where('name', $knowcataname); $knowcatarow = $db->getone($csql); if (!is_array($knowcatarow)) return ''; $csql = new \ciy\sql('zc_ai_knowledge'); $csql->where('cataid', $knowcatarow['id']); $knowrows = $db->get($csql); $knowstr = ''; foreach ($knowrows as $knowrow) { $knowstr .= $knowrow['content'] . "\n"; } return $knowstr; } $val = $post->get($key); if (is_array($val)) $val = json_encode($val, JSON_UNESCAPED_UNICODE); return $val . ''; }, $decisionrow['roleprompt']); $openai = new \ciy\openai($aikeyrow); $openai->debug($debug); $openai->setparam($decisionrow['aiprange']); $openai->newsystem($system); $retai = $openai->completion($roleprompt, strpos($roleprompt . $system, 'JSON') !== false, $funcdatarows, function ($funcarray) use ($funcdatarows) { $funcdatarow = ccode($funcdatarows, substr($funcarray['name'], 1), 'id', null); if (!is_array($funcdatarow)) return 'ERR未定义函数:' . $funcarray['name']; $funcname = $funcdatarow['funcname']; if ($funcname[0] != '\\') $funcname = '\\web\\admin\\aifunc\\' . $funcname; if (!class_exists($funcname)) return 'ERR无效类:' . $funcname; if (!method_exists($funcname, 'main')) return 'ERR无效函数:' . $funcname . '::main'; $funcname .= '::main'; $arguments = json_decode($funcarray['arguments'], true); $funcparams = getstrparam($funcdatarow['funcparam'], "\n"); foreach ($funcparams as $key => $val) { $arguments[$key] = $val; } return call_user_func($funcname, $arguments); }); if (is_string($retai)) return errjson('AI识别失败: ' . $retai); $decci = 0; $aichat = json_encode($openai->messages, JSON_UNESCAPED_UNICODE); $resulttxt = json_encode($retai, JSON_UNESCAPED_UNICODE); if ($decisionrow['aicalkey'] > 0 && !empty($decisionrow['calprompt'])) { $post->post['result.ai'] = $aichat; $post->post['result.data'] = $resulttxt; $csql = new \ciy\sql('zc_ai_key'); $csql->where('id', $decisionrow['aicalkey']); $aikeyrow = $db->getone($csql); if (!is_array($aikeyrow)) return errjson('AI Key不存在'); $calprompt = preg_replace_callback('/\{\{([^}]+)\}\}/', function ($matches) use ($db, $post) { $key = $matches[1]; if (substr($key, 0, 5) == 'know.') { $knowcataname = substr($key, 5); $csql = new \ciy\sql('zc_ai_knowcata'); $csql->where('name', $knowcataname); $knowcatarow = $db->getone($csql); if (!is_array($knowcatarow)) return ''; $csql = new \ciy\sql('zc_ai_knowledge'); $csql->where('cataid', $knowcatarow['id']); $knowrows = $db->get($csql); $knowstr = ''; foreach ($knowrows as $knowrow) { $knowstr .= $knowrow['content'] . "\n"; } return $knowstr; } $val = $post->get($key); if (is_array($val)) $val = json_encode($val, JSON_UNESCAPED_UNICODE); return $val . ''; }, $decisionrow['calprompt']); $openai = new \ciy\openai($aikeyrow); $openai->debug($debug); $openai->setparam($decisionrow['aicalprange']); $openai->newsystem(); $retcalai = $openai->completion($calprompt, true); $decci = toint($retcalai['confidence']); } else if ($decisionrow['aicalkey'] == 0 && !empty($decisionrow['aicalfunc'])) { $funcname = $decisionrow['aicalfunc']; if ($funcname[0] != '\\') $funcname = '\\web\\admin\\aifunc\\' . $funcname; if (!class_exists($funcname)) return errjson('无效类:' . $funcname); if (!method_exists($funcname, 'main')) return errjson('无效函数:' . $funcname . '::main'); $funcname .= '::main'; $decci = call_user_func($funcname, $retai, $decisionrow['calprompt']); } $ret['sec'] = time() - $timespan + 1; //用时 $ret['ci'] = $decci; //置信度 $ret['ai'] = $retai; //结果 if ($post->get('_more') == 'ok') { $ret['messages'] = $openai->messages; //交互过程 $ret['roleprompt'] = $roleprompt; //提示词 $ret['system'] = $system; //角色描述 } return succjson($ret); } public static function multiparam($input, $sep) { $len = strlen($input); $ips = array(); $i = 0; $inMultiline = false; $currentParam = ''; $currentValue = ''; while ($i < $len) { if (!$inMultiline) { $paramStart = $i; while ($i < $len && $input[$i] !== $sep) { if ($input[$i] === "\n") return '参数格式不合法'; $i++; } if ($i == $len) return '参数格式不合法,应用' . $sep . '号分隔'; $currentParam = trim(substr($input, $paramStart, $i - $paramStart)); if (empty($currentParam)) return '参数没有参数名'; $i++; if ($i < $len && $input[$i] === '`') { $inMultiline = true; $i++; $currentValue = ''; } else { $valueStart = $i; while ($i < $len && $input[$i] !== "\n") $i++; $currentValue = trim(substr($input, $valueStart, $i - $valueStart)); $ips[] = $currentParam . $sep . $currentValue; $i++; } } else { $valueStart = $i; while ($i < $len && $input[$i] !== '`') $i++; $currentValue .= trim(substr($input, $valueStart, $i - $valueStart)); if ($i < $len && $input[$i] === '`') { $ips[] = $currentParam . $sep . $currentValue; $inMultiline = false; $i++; if ($i < $len && $input[$i] === "\n") { $i++; } } else { $ips[] = $currentParam . $sep . $currentValue; break; } } } if (count($ips) == 0) return '参数都不符合条件'; return $ips; } }