OpenAI 标准接口
在 ThinkPHP 6 中对接 OpenAI 标准接口并实现同步阻塞返回,使用 TP6 内置的 think\facade\Http 客户端最为快捷。
以下是完整的生产级代码实现:
1. 配置环境变量 (.env)
在项目根目录的 .env 文件中配置大模型凭证,方便管理和切换(例如切换为国内的 DeepSeek、通义千问等 OpenAI 兼容接口):
env
[OPENAI]
API_KEY = sk-xxxxxxxxxxxxxxxxxxxxxxxx
BASE_URL = https://openai.com
MODEL = gpt-4o
请谨慎使用此类代码。
2. 创建大模型服务类
新建 app/service/OpenAiService.php,负责封装 HTTP 请求:
php
<?php
namespace app\service;
use think\facade\Http;
use think\facade\Log;
class OpenAiService
{
protected $apiKey;
protected $baseUrl;
protected $model;
public function __construct()
{
// 自动读取 .env 配置,设置默认值
$this->apiKey = env('OPENAI.API_KEY', '');
$this->baseUrl = env('OPENAI.BASE_URL', 'https://openai.com');
$this->model = env('OPENAI.MODEL', 'gpt-4o');
}
/**
* 发送同步阻塞请求
* @param string $prompt 用户输入
* @param float $temperature 随机性 (0-2)
* @return string 模型的文本回复
*/
public function ask(string $prompt, float $temperature = 0.7): string
{
if (empty($this->apiKey)) {
throw new \Exception('OpenAI API Key 未配置');
}
// 构造 OpenAI 标准请求体
$payload = [
'model' => $this->model,
'temperature' => $temperature,
'messages' => [
['role' => 'user', 'content' => $prompt]
],
'stream' => false // 明确指定同步阻塞模式
];
// 发起 HTTP POST 请求 (设置 60 秒超时防止大模型响应过慢)
$response = Http::header([
'Authorization' => 'Bearer ' . $this->apiKey,
'Content-Type' => 'application/json',
])->timeout(60)->post($this->baseUrl, $payload);
// 处理响应
if ($response->successful()) {
$result = $response->json();
// 解析 OpenAI 标准返回结构
if (isset($result['choices'][0]['message']['content'])) {
return $result['choices'][0]['message']['content'];
}
throw new \Exception('接口返回数据格式异常:' . $response->getBody());
}
// 记录错误日志并抛出异常
Log::error('OpenAI API 请求失败:' . $response->getBody());
throw new \Exception('AI 接口调用失败,状态码:' . $response->status());
}
}
请谨慎使用此类代码。
3. 在控制器中调用
新建 app/controller/Chat.php,接收前端参数并调用服务:
php
<?php
namespace app\controller;
use app\BaseController;
use app\service\OpenAiService;
use think\Response;
class Chat extends BaseController
{
/**
* 对话接口
* @param OpenAiService $aiService 自动依赖注入
*/
public function index(OpenAiService $aiService): Response
{
// 获取前端传入的提示词
$prompt = $this->request->param('prompt', '');
if (empty($prompt)) {
return json(['code' => 400, 'msg' => '提示词不能为空']);
}
try {
// 调用服务层获取回复
$reply = $aiService->ask($prompt);
return json([
'code' => 200,
'msg' => 'success',
'data' => [
'reply' => $reply
]
]);
} catch (\Exception $e) {
return json([
'code' => 500,
'msg' => $e->getMessage()
]);
}
}
}
请谨慎使用此类代码。
为了让这个接口更贴合你的项目,请问:
是否需要支持多轮对话(历史聊天记录传递)?
许可协议:
CC BY 4.0