新增:AI 接口连通性测试功能;修复:Ollama 超时问题

- 后台 AI 厂商列表新增「 测试」按钮,实时验证接口连通性
- 显示响应耗时(含冷启动)和模型返回内容
- AiChatService 请求超时从 30s 调整为 120s(兼容 Ollama 本地冷启动)
- 测试接口超时设为 60s
This commit is contained in:
2026-03-06 03:29:13 +08:00
parent 6c9db806ae
commit 318eb6f234
4 changed files with 101 additions and 4 deletions
@@ -200,6 +200,67 @@ class AiProviderController extends Controller
]);
}
/**
* 测试指定 AI 厂商的接口连通性
*
* 发送一条简短的测试消息,返回响应结果和耗时,用于验证配置是否正确。
*
* @param int $id 厂商配置 ID
* @return JsonResponse 测试结果
*/
public function testConnection(int $id): JsonResponse
{
$provider = AiProviderConfig::findOrFail($id);
$apiKey = $provider->getDecryptedApiKey();
$base = rtrim($provider->api_endpoint, '/');
$endpoint = str_ends_with($base, '/v1')
? $base.'/chat/completions'
: $base.'/v1/chat/completions';
$startTime = microtime(true);
try {
$response = \Illuminate\Support\Facades\Http::withToken($apiKey)
->timeout(60) // Ollama 本地模型冷启动较慢,给 60s
->post($endpoint, [
'model' => $provider->model,
'messages' => [
['role' => 'user', 'content' => '请用一句话介绍你自己。'],
],
'max_tokens' => 64,
]);
$ms = (int) ((microtime(true) - $startTime) * 1000);
$data = $response->json();
if (! $response->successful()) {
return response()->json([
'ok' => false,
'message' => "HTTP {$response->status()}{$response->body()}",
'ms' => $ms,
]);
}
$reply = $data['choices'][0]['message']['content'] ?? '(无回复内容)';
return response()->json([
'ok' => true,
'message' => trim($reply),
'ms' => $ms,
'model' => $data['model'] ?? $provider->model,
]);
} catch (\Illuminate\Http\Client\ConnectionException $e) {
$ms = (int) ((microtime(true) - $startTime) * 1000);
return response()->json([
'ok' => false,
'message' => '连接失败:'.$e->getMessage(),
'ms' => $ms,
]);
}
}
/**
* 删除 AI 厂商配置
*
+4 -4
View File
@@ -32,7 +32,7 @@ class AiChatService
/**
* AI 请求超时时间(秒)
*/
private const REQUEST_TIMEOUT = 30;
private const REQUEST_TIMEOUT = 120; // Ollama 本地模型冷启动较慢,给足时间
/**
* Redis 上下文 key 前缀
@@ -54,7 +54,7 @@ class AiChatService
$charmCross = Sysparam::getValue('charm_cross_sex', '2');
$charmSame = Sysparam::getValue('charm_same_sex', '1');
$charmLimit = Sysparam::getValue('charm_hourly_limit', '20');
$levelWarn = Sysparam::getValue('level_warn', '5');
$levelMute = Sysparam::getValue('level_mute', '8');
$levelKick = Sysparam::getValue('level_kick', '10');
@@ -123,8 +123,8 @@ PROMPT;
// 将用户消息加入上下文(包含发送者信息)
$context[] = [
'role' => 'user',
'content' => "【当前发言人:{$username}\n" . $message
'role' => 'user',
'content' => "【当前发言人:{$username}\n".$message,
];
// 构建完整的 messages 数组(系统提示 + 对话上下文)