AIGatewayService.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. namespace app\service;
  3. use think\Db;
  4. use think\Queue;
  5. class AIGatewayService{
  6. /**
  7. * 接口访问配置
  8. *
  9. * 配置说明:
  10. * - gpt:用于文本生成或图文识别模型接口(如 chat/completions)
  11. * OpenAI GPT 接口配置:支持 chat、图文结合模型(如 gpt-4-vision-preview)
  12. *
  13. * - dalle:用于文生图(图像生成)模型接口
  14. * OpenAI DALL·E 接口配置:用于文生图像(图像生成)
  15. *
  16. * 每个模块包含:
  17. * - api_key:API 调用密钥(Bearer Token)
  18. * - api_url:对应功能的服务端地址
  19. */
  20. protected $config = [
  21. 'gpt' => [
  22. 'api_key' => 'sk-Bhos1lXTRpZiAAmN06624a219a874eCd91Dc068b902a3e73',
  23. 'api_url' => 'https://one.opengptgod.com/v1/chat/completions'
  24. ],
  25. 'dalle' => [
  26. 'api_key' => 'sk-e0JuPjMntkbgi1BoMjrqyyzMKzAxILkQzyGMSy3xiMupuoWY',
  27. 'api_url' => 'https://niubi.zeabur.app/v1/images/generations'
  28. ]
  29. ];
  30. /**
  31. * 调用 GPT-4 图文识别模型接口(图生文)
  32. *
  33. * @param string $imageUrl 图像 URL,支持公网可访问地址
  34. * @param string $prompt 对图像的提问内容或提示文本
  35. *
  36. * 功能说明:
  37. * - 使用 OpenAI 的 gpt-4-vision-preview 模型对图片进行图文理解
  38. * - 支持图像与文本混合输入,返回图像内容相关的文本输出
  39. * - 限制最大 token 数为 1000
  40. *
  41. * 返回值:
  42. * - 返回调用 GPT API 后的响应结果(通常为模型生成的文本)
  43. */
  44. public function callGptApi($imageUrl, $prompt)
  45. {
  46. $data = [
  47. "model" => "gpt-4-vision-preview",
  48. "messages" => [[
  49. "role" => "user",
  50. "content" => [
  51. ["type" => "text", "text" => $prompt],
  52. ["type" => "image_url", "image_url" => [
  53. "url" => $imageUrl,
  54. "detail" => "auto"
  55. ]]
  56. ]
  57. ]],
  58. "max_tokens" => 1000
  59. ];
  60. return $this->callApi($this->config['gpt']['api_url'], $this->config['gpt']['api_key'], $data);
  61. }
  62. /**
  63. * 调用 GPT 文生文模型接口(文本生成)
  64. *
  65. * @param string $prompt 用户输入的文本提示内容
  66. *
  67. * 功能说明:
  68. * - 使用 OpenAI 的 GPT-4 模型,根据用户提供的 prompt 文本生成响应内容
  69. * - 支持上下文重置,确保每次调用为独立会话(无历史记忆)
  70. * - session_id 设为 null 表示不使用会话追踪
  71. *
  72. * 返回值:
  73. * - 返回调用 GPT 接口后的响应结果(通常为模型生成的文本)
  74. */
  75. public function txtGptApi($prompt)
  76. {
  77. $data = [
  78. 'prompt' => $prompt,
  79. 'model' => 'gpt-4',
  80. 'session_id' => null,
  81. 'context_reset' => true
  82. ];
  83. return $this->callApi(
  84. $this->config['gpt']['api_url'],
  85. $this->config['gpt']['api_key'],
  86. $data
  87. );
  88. }
  89. /**
  90. * 调用 DALL·E 图像生成接口(文生图)
  91. *
  92. * @param string $prompt 提示文本,用于指导图像生成
  93. * @param string $selectedOption 模型名称,例如 'dall-e-3' 或其他兼容模型
  94. *
  95. * 功能说明:
  96. * - 根据用户提供的文本提示,通过指定的模型生成图像
  97. * - 若选择模型为 'dall-e-3',使用标准质量(standard);其他模型使用高清质量(hd)
  98. * - 默认生成 1 张图像,尺寸为 1024x1024,风格为 vivid(生动)
  99. * - 返回的图像链接格式为 URL
  100. * - 每次调用为独立会话(session_id 为 null,context_reset 为 true)
  101. *
  102. * 返回值:
  103. * - 返回调用 DALL·E 接口后的响应结果(图像 URL)
  104. */
  105. public function callDalleApi($prompt,$selectedOption)
  106. {
  107. if($selectedOption == 'dall-e-3'){
  108. $data = [
  109. 'prompt' => $prompt,
  110. 'model' => $selectedOption,
  111. 'n' => 1,
  112. 'size' => '1024x1024',
  113. 'quality' => 'standard',
  114. 'style' => 'vivid',
  115. 'response_format' => 'url',
  116. 'session_id' => null,
  117. 'context_reset' => true
  118. ];
  119. }else{
  120. $data = [
  121. 'prompt' => $prompt,
  122. 'model' => $selectedOption,
  123. 'n' => 1,
  124. 'size' => '1024x1024',
  125. 'quality' => 'hd',
  126. 'style' => 'vivid',
  127. 'response_format' => 'url',
  128. 'session_id' => null,
  129. 'context_reset' => true
  130. ];
  131. }
  132. return $this->callApi($this->config['dalle']['api_url'], $this->config['dalle']['api_key'], $data);
  133. }
  134. /**
  135. * 通用 API 调用方法(支持重试机制)
  136. *
  137. * @param string $url 接口地址
  138. * @param string $apiKey 授权密钥(Bearer Token)
  139. * @param array $data 请求数据(JSON 格式)
  140. *
  141. * 功能说明:
  142. * - 使用 cURL 发送 POST 请求到指定 API 接口
  143. * - 设置请求头和超时时间等参数
  144. * - 支持最多重试 2 次,当接口调用失败时自动重试
  145. * - 返回成功时解析 JSON 响应为数组
  146. *
  147. * 异常处理:
  148. * - 若全部重试失败,将抛出异常并包含最后一次错误信息
  149. *
  150. * @return array 接口响应数据(成功时返回解析后的数组)
  151. * @throws \Exception 接口请求失败时抛出异常
  152. */
  153. public function callApi($url, $apiKey, $data)
  154. {
  155. $maxRetries = 2; // 最多重试次数
  156. $attempt = 0; // 当前尝试次数
  157. $lastError = ''; // 最后一次错误信息
  158. while ($attempt <= $maxRetries) {
  159. $ch = curl_init();
  160. curl_setopt_array($ch, [
  161. CURLOPT_URL => $url,
  162. CURLOPT_RETURNTRANSFER => true,
  163. CURLOPT_POST => true,
  164. CURLOPT_POSTFIELDS => json_encode($data),
  165. CURLOPT_HTTPHEADER => [
  166. 'Content-Type: application/json',
  167. 'Authorization: Bearer ' . $apiKey
  168. ],
  169. CURLOPT_TIMEOUT => 120,
  170. CURLOPT_SSL_VERIFYPEER => false,
  171. CURLOPT_SSL_VERIFYHOST => 0,
  172. CURLOPT_TCP_KEEPALIVE => 1,
  173. CURLOPT_FORBID_REUSE => false
  174. ]);
  175. $response = curl_exec($ch);
  176. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  177. $curlError = curl_error($ch);
  178. curl_close($ch);
  179. if ($response !== false && $httpCode === 200) {
  180. $result = json_decode($response, true);
  181. return $result;
  182. }
  183. $lastError = $curlError ?: "HTTP错误:{$httpCode}";
  184. $attempt++;
  185. sleep(1);
  186. }
  187. throw new \Exception("请求失败(重试{$maxRetries}次):{$lastError}");
  188. }
  189. }