robot.class.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <?php
  2. if (!defined('IN_ONLINE')) {
  3. exit('Access Denied');
  4. }
  5. /**
  6. * Description of robot
  7. *
  8. * @author Administrator
  9. */
  10. class robot{
  11. private static $_robot;
  12. function __construct() {
  13. }
  14. public static function getInstance() {
  15. global $memory_limit;
  16. $memory_limit = ini_get("memory_limit");
  17. ini_set("memory_limit", '2048M');
  18. if (!self::$_robot) {
  19. $c = __CLASS__;
  20. self::$_robot = new $c;
  21. }
  22. return self::$_robot;
  23. }
  24. public function robot_chat() {
  25. $operate = utils::_get('operate');
  26. $operate = strtolower($operate);
  27. /*
  28. * index page
  29. */
  30. if (empty($operate)) {
  31. $column = column::getInstance()->getDisplayColumn('Robot_Chat_Search');
  32. $OperationTableColumns = column::getInstance()->tableColumns('Operation_Search',$column);
  33. $data['OperationTableColumns'] = $OperationTableColumns;
  34. common::echo_json_encode(200,$data);
  35. exit();
  36. }
  37. /*
  38. * operation_search search
  39. */
  40. if ($operate == "search") {
  41. //$this->_operation_search();
  42. }
  43. if ($operate == "excel") {
  44. $sql = common::deCode($_POST ['tmp_search'], 'D');
  45. $sql = substr($sql, 0, strripos($sql, " limit"));
  46. if(!empty($sql)){
  47. $rss = common::excuteListSql($sql);
  48. }
  49. foreach($rss as $key =>$val){
  50. $rss[$key]['Operation Time'] = $rss[$key]['_operation_time'];
  51. }
  52. common::echo_json_encode(200,array("msg"=>"success","Data" => $rss));
  53. exit;
  54. }
  55. }
  56. public function robot_prompt_configuration() {
  57. $operate = utils::_get('operate');
  58. $operate = strtolower($operate);
  59. if (empty($operate)) {
  60. //查询所有配置信息 目前只有一个表一个数据
  61. $configuration = common::excuteObjectSql("select id, character_name,professional_field,main_tasks,table_name,table_description,
  62. table_structure_configuration,response_rule_configuration,output_format_configuration,fixed_problem_configuration
  63. from public.kln_robot_prompt_configuration where id = 1");
  64. $PromptAndVue = $this->dealPromptFormatAndVue($configuration);
  65. //tableDat-VUE
  66. $tableData = $PromptAndVue["vuedata"]["tableData"];
  67. //stepData -VUE
  68. $stepData = $PromptAndVue["vuedata"]["stepData"];
  69. //formatList -VUE
  70. $formatListType = $PromptAndVue["vuedata"]["formatListType"];
  71. $formatList = $PromptAndVue["vuedata"]["formatList"];
  72. //promptFormat
  73. $promptFormat =$PromptAndVue["promptFormat"];
  74. //获取历史变更记录
  75. $old_configuration = $this->getChangedLog($configuration["id"]);
  76. $id = $configuration['id'];
  77. $character_name = $configuration['character_name'];
  78. $professional_field = $configuration['professional_field'];
  79. $main_tasks = $configuration['main_tasks'];
  80. $table_name = $configuration['table_name'];
  81. $table_description = $configuration['table_description'];
  82. $prompt_summary = array("您是专門从事".$professional_field."的".$character_name."...",
  83. "表名:{".$table_name."}...",
  84. "响应规则,请按以下步骤处理...");
  85. $data = array(
  86. "id"=>$id,
  87. "character_name"=>$character_name,
  88. "professional_field"=>$professional_field,
  89. "main_tasks"=>$main_tasks,
  90. "table_name"=>$table_name,
  91. "table_description"=>$table_description,
  92. "tableData"=>$tableData,
  93. "stepData"=>$stepData,
  94. "formatList"=>$formatList,
  95. "formatListType"=>$formatListType,
  96. "complete_prompt"=>$promptFormat,
  97. "prompt_summary"=>$prompt_summary,
  98. "prompt_log_record"=>$old_configuration
  99. );
  100. $data = utils::arrayRemoveNull($data);
  101. common::echo_json_encode(200,$data);
  102. exit();
  103. }
  104. if ($operate == "save") {
  105. $id =common::check_input($_POST['id']);
  106. $character_name = common::check_input($_POST['role_name']);
  107. $professional_field = common::check_input($_POST['professional_field']);
  108. $main_tasks = common::check_input($_POST['main_tasks']);
  109. $table_name = common::check_input($_POST['table_name']);
  110. $table_description = common::check_input($_POST['table_description']);
  111. $outputvalue = common::check_input($_POST['outputvalue']);
  112. $tableDataList = $_POST['tableDataList'];
  113. $stepData = $_POST['stepData'];
  114. $formatList = $_POST['formatList'];
  115. $table_structure_configuration = common::check_input(json_encode($tableDataList));
  116. $response_rule_configuration = common::check_input(json_encode($stepData));
  117. $output_data = array("output_type"=>$outputvalue,"data"=>$formatList);
  118. $output_format_configuration = common::check_input(json_encode($output_data));
  119. if(empty($id)){
  120. $sql = "INSERT INTO public.kln_robot_prompt_configuration(
  121. character_name, professional_field, main_tasks, table_name,
  122. table_description, table_structure_configuration, response_rule_configuration,
  123. output_format_configuration, created_by, created_time)
  124. VALUES ('$character_name', '$professional_field', '$main_tasks', '$table_name',
  125. '$table_description', '$table_structure_configuration', '$response_rule_configuration',
  126. '$output_format_configuration', '"._getLoginName()."', now());";
  127. }else{
  128. $sql = "update public.kln_robot_prompt_configuration
  129. set character_name = '$character_name',professional_field ='$professional_field', main_tasks = '$main_tasks',
  130. table_name = '$table_name',table_description = '$table_description',
  131. table_structure_configuration = '$table_structure_configuration',
  132. response_rule_configuration = '$response_rule_configuration',
  133. output_format_configuration = '$output_format_configuration'
  134. where id = '$id';";
  135. //插入变更日志记录
  136. $sql .= "INSERT INTO public.kln_robot_prompt_configuration_log(ref_id, character_name, professional_field, main_tasks, table_name,
  137. table_description, table_structure_configuration, response_rule_configuration,
  138. output_format_configuration, created_by, created_time)
  139. VALUES ('$id','$character_name', '$professional_field', '$main_tasks', '$table_name',
  140. '$table_description', '$table_structure_configuration', '$response_rule_configuration',
  141. '$output_format_configuration', '"._getLoginName()."', now());";
  142. }
  143. error_log($sql);
  144. $rs = common::excuteUpdateSql($sql);
  145. if (!$rs) {
  146. $data = array("msg" => "save Error");
  147. } else {
  148. $data = array("msg" => "save Successful");
  149. }
  150. $data = array("msg" => "save Successful");
  151. common::echo_json_encode(200,$data);
  152. exit();
  153. }
  154. if($operate == "preview_propmpt_witout_save"){
  155. $character_name = common::check_input($_POST['role_name']);
  156. $professional_field = common::check_input($_POST['professional_field']);
  157. $main_tasks = common::check_input($_POST['main_tasks']);
  158. $table_name = common::check_input($_POST['table_name']);
  159. $table_description = common::check_input($_POST['table_description']);
  160. $outputvalue = common::check_input($_POST['outputvalue']);
  161. $tableDataList = $_POST['tableDataList'];
  162. $stepData = $_POST['stepData'];
  163. $formatList = $_POST['formatList'];
  164. $table_structure_configuration = common::check_input(json_encode($tableDataList));
  165. $response_rule_configuration = common::check_input(json_encode($stepData));
  166. $output_data = array("output_type"=>$outputvalue,"data"=>$formatList);
  167. $output_format_configuration = common::check_input(json_encode($output_data));
  168. //组合拼接需要的数据
  169. $configuration = array("character_name"=>$character_name,
  170. "professional_field"=>$professional_field,
  171. "main_tasks"=>$main_tasks,
  172. "table_name"=>$table_name,
  173. "table_description"=>$table_description,
  174. "professional_field"=>$professional_field,
  175. "table_structure_configuration"=>$table_structure_configuration,
  176. "response_rule_configuration" =>$response_rule_configuration,
  177. "output_format_configuration" =>$output_format_configuration
  178. );
  179. $PromptAndVue = $this->dealPromptFormatAndVue($configuration);
  180. //promptFormat
  181. $promptFormat =$PromptAndVue["promptFormat"];
  182. $character_name = empty($configuration['character_name']) ? "" :$configuration['character_name'];
  183. $professional_field = empty($configuration['professional_field']) ? "" :$configuration['professional_field'];
  184. $main_tasks = empty($configuration['main_tasks']) ? "" :$configuration['main_tasks'];
  185. $table_name = empty($configuration['table_name']) ? "" :$configuration['table_name'];
  186. $table_description = empty($configuration['table_description']) ? "" :$configuration['table_description'];
  187. $prompt_summary = array("您是专門从事".$professional_field."的".$character_name."...",
  188. "表名:{".$table_name."}...",
  189. "响应规则,请按以下步骤处理...");
  190. $data = array(
  191. "complete_prompt"=>$promptFormat,
  192. "prompt_summary"=>$prompt_summary
  193. );
  194. common::echo_json_encode(200,$data);
  195. exit();
  196. }
  197. if($operate == "test_with_ds_claude"){
  198. $ai_method = $_POST["test_ai_method"];
  199. $systemPrompt = $_POST["prompt"];
  200. $message = $_POST["test_question"];
  201. $model = $ai_method == 'DS' ? "deepseek" : "claude";
  202. //question_date request_time
  203. $request_question_time = date("Y-m-d H:i:s");
  204. $question_time = date("H:i:s");
  205. $item_value = common::excuteOneSql("select item_value from public.config where item = 'AIAPISetting'");
  206. $config = json_decode($item_value,true);
  207. $response = AIClientFactory::create($model, $config[$model], $systemPrompt, $message, $history = []);
  208. $response_time = date("Y-m-d H:i:s");
  209. $input_token = "";
  210. $output_token = "";
  211. $date1 = new DateTime($request_question_time);
  212. $date2 = new DateTime($response_time);
  213. $response_duration = $date2->getTimestamp() - $date1->getTimestamp();
  214. //回答问题类型,在没有超时的情况下,固定:AI回答
  215. $answer_type = "AI回答";
  216. if ($response_duration > 120){
  217. $answer_type = "回答超时";
  218. }
  219. //获取自然序列
  220. $sequence = common::getChatAiSequence();
  221. $name = $ai_method == 'DS' ? "DS" : "CD";
  222. $request_id = "R".$name."".date("Ymd").$sequence;
  223. $question_id = "Q"."".date("Ymd").$sequence;
  224. //处理一下参数
  225. $user_name = common::check_input(_getLoginName());
  226. $user_type = _isApexLogin() ? "employee" : "customer";
  227. //这里的测试,固定写自由文本
  228. $question_type = 'free text';
  229. $question_id = common::check_input($question_id);
  230. $question_content = common::check_input($message);
  231. $answer_type = common::check_input($answer_type);
  232. //记录回答展示给客户的具体内容
  233. $answer = common::check_input(common::getChatAimessage($response['message']));
  234. $ai_model = common::check_input($model);
  235. $input_token = common::check_input($input_token);
  236. $request_content = common::check_input(json_encode($response['data']));
  237. $ai_response_content = common::check_input(json_encode($response['full_response']));
  238. $output_token = common::check_input($output_token);
  239. $sql = "INSERT INTO public.kln_robot_chat_log( question_id, user_name, user_type, question_type, question_content,
  240. answer_type, answer, answer_satisfication, answer_duration, question_date,
  241. question_time, request_id, ai_model, request_content, input_token,
  242. ai_response_content, output_token, request_time, response_time,
  243. response_duration)
  244. VALUES ('$question_id', '$user_name', '$user_type', '$question_type', '$question_content',
  245. '$answer_type', '$answer', '', '$response_duration', '$request_question_time',
  246. '$question_time', '$request_id', '$ai_model','$request_content', '$input_token',
  247. '$ai_response_content', '$output_token', '$request_question_time', '$response_time',
  248. '$response_duration');";
  249. $rs = common::excuteUpdateSql($sql);
  250. if (!$rs) {
  251. $data = array("msg" => "AI Chat Save Error");
  252. common::echo_json_encode(200,$data);
  253. exit();
  254. }
  255. error_log($response['message']);
  256. // $sql ="";
  257. // //用户权限
  258. // $sqlWhere = ' and ' . common::searchExtendHand_KLN("ocean", $_SESSION["ONLINE_USER"]);
  259. // $sql .= $sqlWhere;
  260. // $rs = common::excuteListSql($sql);
  261. $response['message'] = json_decode(common::getChatAimessage($response['message']),true);
  262. $rs = $response;
  263. common::echo_json_encode(200,$rs);
  264. exit();
  265. }
  266. if ($operate == "download"){
  267. $sql = common::deCode($_POST ['tmp_search'], 'D');
  268. if(!empty($sql)){
  269. $rs = common::excuteListSql($sql);
  270. }
  271. common::echo_json_encode(200,array("msg"=>"success","Data" => $rs));
  272. exit;
  273. }
  274. }
  275. public function dealPromptFormatAndVue($configuration){
  276. //tableDat-VUE
  277. $tableData = array();
  278. $table_structure_text="[";
  279. $table_structure_configuration = json_decode($configuration['table_structure_configuration'],true);
  280. foreach($table_structure_configuration as $tk =>$tv){
  281. $tableData[] = $tv;
  282. $table_structure_text .='{
  283. "name": "'.$tv["name"].'",
  284. "type": "'.$tv["type"].'",
  285. "description": "'.$tv["description"].'",
  286. "exampledata": "'.$tv["exampledata"].'",
  287. }';
  288. if(count($table_structure_configuration)-1 > $tk){
  289. $table_structure_text .=",";
  290. }
  291. $table_structure_text .=common::splicedLlineBreaks();
  292. }
  293. $table_structure_text.="]";
  294. //stepData -VUE
  295. $stepData = array();
  296. $response_rule_text = "";
  297. $response_rule_configuration = json_decode($configuration['response_rule_configuration'],true);
  298. foreach($response_rule_configuration as $rk =>$rv){
  299. $tempTable = array();
  300. $tempTable["description"] = $rv["description"];
  301. $stepData[] = $tempTable;
  302. $response_rule_text .=($rk+1).'.'.$rv["description"];
  303. $response_rule_text .=common::splicedLlineBreaks();
  304. }
  305. //formatList -VUE
  306. $output_format_text = "{";
  307. $output_format_configuration = json_decode($configuration['output_format_configuration'],true);
  308. $formatListType = $output_format_configuration['output_type'];
  309. $formatList = empty($output_format_configuration['data']) ? array(): $output_format_configuration['data'];
  310. foreach($formatList as $ok =>$ov){
  311. $output_format_text .="\"".$ov['name']."\"".": "."\"".$ov['describe']."\"";
  312. $output_format_text .=common::splicedLlineBreaks();
  313. }
  314. $output_format_text .= "}";
  315. $promptFormat = $this->getCompletePromptFormat();
  316. $promptFormat = str_replace('<{professional_field}>', $configuration['character_name'], $promptFormat);
  317. $promptFormat = str_replace('<{character_name}>', $configuration['character_name'], $promptFormat);
  318. $promptFormat = str_replace('<{main_tasks}>', $configuration['main_tasks'], $promptFormat);
  319. $promptFormat = str_replace('<{table}>', $configuration['table_name'], $promptFormat);
  320. $promptFormat = str_replace('<{table_structure_configuration}>', $table_structure_text, $promptFormat);
  321. $promptFormat = str_replace('<{response_rule_configuration}>', $response_rule_text, $promptFormat);
  322. $promptFormat = str_replace('<{number}>', count($response_rule_configuration)+1, $promptFormat);
  323. $promptFormat = str_replace('<{output_type}>', $formatListType, $promptFormat);
  324. $promptFormat = str_replace('<{output_format_configuration}>', $output_format_text, $promptFormat);
  325. return array("vuedata"=>array("tableData"=>$tableData,"stepData"=>$stepData,"formatList"=>$formatList,"formatListType"=>$formatListType),
  326. "promptFormat" =>$promptFormat);
  327. }
  328. public function getChangedLog($id){
  329. $changeLogList = array();
  330. $configurationArr = common::excuteListSql("select id, character_name,professional_field,main_tasks,table_name,table_description,
  331. created_by,TO_CHAR(created_time, 'YYYY-mm-dd HH24:MI:SS') as created_time,
  332. table_structure_configuration,response_rule_configuration,output_format_configuration,fixed_problem_configuration
  333. from public.kln_robot_prompt_configuration_log where ref_id = '$id' order by id desc");
  334. foreach($configurationArr as $ca){
  335. $data = $this->dealPromptFormatAndVue($ca);
  336. $temp =array();
  337. $temp["time"] = $ca['created_time']." Prompt";
  338. $temp["person"] ="提交人:".$ca['created_by'];
  339. $temp["text"] = $data['promptFormat'];
  340. $changeLogList[] = $temp;
  341. }
  342. return $changeLogList;
  343. }
  344. public function getCompletePromptFormat() {
  345. $formatTpl = "
  346. 您是专门从<{professional_field}>的 <{character_name}>,请始终以<{output_type}>格式响应。您的主要任务是<{main_tasks}>
  347. 表名:<{table}>
  348. 表结构: \"columns\": <{table_structure_configuration}>
  349. 响应规则,请按以下步骤处理:
  350. <{response_rule_configuration}>
  351. <{number}>. 请用以下<{output_type}>格式回复:
  352. <{output_format_configuration}>";
  353. return $formatTpl;
  354. }
  355. }
  356. ?>