浏览代码

feat: palm ai based llm backend

M1Screw 2 年之前
父节点
当前提交
6f6d02bba0
共有 4 个文件被更改,包括 106 次插入8 次删除
  1. 7 2
      config/.config.example.php
  2. 15 5
      src/Controllers/Admin/TicketController.php
  3. 1 1
      src/Services/ChatGPT.php
  4. 83 0
      src/Services/PaLM.php

+ 7 - 2
config/.config.example.php

@@ -144,9 +144,14 @@ $_ENV['sentry_dsn'] = '';
 $_ENV['maxmind_license_key'] = '';
 $_ENV['maxmind_license_key'] = '';
 $_ENV['geoip_locale'] = 'en';
 $_ENV['geoip_locale'] = 'en';
 
 
-// OpenAI API Key for GPT powered ticket reply and more
+// Large language model powered ticket reply and more
+$_ENV['llm_backend'] = 'openai'; // openai or palm
+// OpenAI ChatGPT
 $_ENV['openai_api_key'] = '';
 $_ENV['openai_api_key'] = '';
-$_ENV['ai_model'] = 'gpt-3.5-turbo';
+$_ENV['openai_model'] = 'gpt-3.5-turbo-16k-0613';
+// Google PaLM API
+$_ENV['palm_api_key'] = '';
+$_ENV['palm_text_model'] = 'text-bison-001';
 
 
 // ClientDownload 命令解决 API 访问频率高而被限制使用的 Github access token
 // ClientDownload 命令解决 API 访问频率高而被限制使用的 Github access token
 $_ENV['github_access_token'] = '';
 $_ENV['github_access_token'] = '';

+ 15 - 5
src/Controllers/Admin/TicketController.php

@@ -8,6 +8,7 @@ use App\Controllers\BaseController;
 use App\Models\Ticket;
 use App\Models\Ticket;
 use App\Models\User;
 use App\Models\User;
 use App\Services\ChatGPT;
 use App\Services\ChatGPT;
+use App\Services\PaLM;
 use App\Utils\Tools;
 use App\Utils\Tools;
 use Exception;
 use Exception;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ResponseInterface;
@@ -103,7 +104,7 @@ final class TicketController extends BaseController
     }
     }
 
 
     /**
     /**
-     * 喊 ChatGPT 帮忙回复工单
+     * 喊 LLM 帮忙回复工单
      */
      */
     public function updateAI(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
     public function updateAI(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
     {
     {
@@ -119,15 +120,24 @@ final class TicketController extends BaseController
         }
         }
 
 
         $content_old = json_decode($ticket->content, true);
         $content_old = json_decode($ticket->content, true);
-        // 获取用户的第一个问题,作为 ChatGPT 的输入
+        // 获取用户的第一个问题,作为 LLM 的输入
         $user_question = $content_old[0]['comment'];
         $user_question = $content_old[0]['comment'];
         // 这里可能要等4-5秒
         // 这里可能要等4-5秒
-        $ai_reply = ChatGPT::askOnce($user_question);
+        if ($_ENV['llm_backend'] === 'openai') {
+            $ai_reply = ChatGPT::askOnce($user_question);
+        } elseif ($_ENV['llm_backend'] === 'palm') {
+            $ai_reply = PaLM::textPrompt($user_question);
+        } else {
+            return $response->withJson([
+                'ret' => 0,
+                'msg' => 'LLM 后端配置错误',
+            ]);
+        }
 
 
         $content_new = [
         $content_new = [
             [
             [
                 'comment_id' => $content_old[count($content_old) - 1]['comment_id'] + 1,
                 'comment_id' => $content_old[count($content_old) - 1]['comment_id'] + 1,
-                'commenter_name' => 'AI Admin by GPT',
+                'commenter_name' => 'AI Admin',
                 'comment' => $ai_reply,
                 'comment' => $ai_reply,
                 'datetime' => time(),
                 'datetime' => time(),
             ],
             ],
@@ -138,7 +148,7 @@ final class TicketController extends BaseController
             $_ENV['appName'] . '-工单被回复',
             $_ENV['appName'] . '-工单被回复',
             'warn.tpl',
             'warn.tpl',
             [
             [
-                'text' => '你好,ChatGPT 回复了<a href="' . $_ENV['baseUrl'] . '/user/ticket/' . $ticket->id . '/view">工单</a>,请你查看。',
+                'text' => '你好,AI 回复了<a href="' . $_ENV['baseUrl'] . '/user/ticket/' . $ticket->id . '/view">工单</a>,请你查看。',
             ],
             ],
             []
             []
         );
         );

+ 1 - 1
src/Services/ChatGPT.php

@@ -20,7 +20,7 @@ final class ChatGPT
 
 
         $client = OpenAI::client($_ENV['openai_api_key']);
         $client = OpenAI::client($_ENV['openai_api_key']);
         $response = $client->chat()->create([
         $response = $client->chat()->create([
-            'model' => $_ENV['ai_model'],
+            'model' => $_ENV['openai_model'],
             'messages' => [
             'messages' => [
                 [
                 [
                     'role' => 'user',
                     'role' => 'user',

+ 83 - 0
src/Services/PaLM.php

@@ -0,0 +1,83 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Services;
+
+use function json_decode;
+use function json_encode;
+
+final class PaLM
+{
+    public static function textPrompt(string $q): string
+    {
+        if ($_ENV['palm_api_key'] === '') {
+            return 'PaLM API key not set';
+        }
+
+        if ($q === '') {
+            return 'No question provided';
+        }
+
+        $postdata = json_encode(
+            [
+                "prompt" => [
+                    "text" => $q,
+                ],
+                "temperature" => 1,
+                "candidate_count" => 1,
+                "top_k" => 40,
+                "top_p" => 0.95,
+                "max_output_tokens" => 1024,
+                "stop_sequences" => [
+                ],
+                "safety_settings" => [
+                    [
+                        "category" => "HARM_CATEGORY_DEROGATORY",
+                        "threshold" => 3,
+                    ],
+                    [
+                        "category" => "HARM_CATEGORY_TOXICITY",
+                        "threshold" => 3,
+                    ],
+                    [
+                        "category" => "HARM_CATEGORY_VIOLENCE",
+                        "threshold" => 3,
+                    ],
+                    [
+                        "category" => "HARM_CATEGORY_SEXUAL",
+                        "threshold" => 3,
+                    ],
+                    [
+                        "category" => "HARM_CATEGORY_MEDICAL",
+                        "threshold" => 3,
+                    ],
+                    [
+                        "category" => "HARM_CATEGORY_DANGEROUS",
+                        "threshold" => 3,
+                    ],
+                ],
+            ]
+        );
+
+        $opts = [
+            'http' => [
+                'method' => 'POST',
+                'header' => 'Content-type: application/json',
+                'content' => $postdata,
+                'timeout' => 5,
+            ],
+        ];
+
+        $response = json_decode(file_get_contents(
+            'https://generativelanguage.googleapis.com/v1beta2/models/' .
+            $_ENV['palm_text_model'] .
+            ':generateText?key=' .
+            $_ENV['palm_api_key'],
+            false,
+            stream_context_create($opts)
+        ));
+
+        return $response->candidates[0]->output;
+    }
+}