// 7. 调用DeepSeek API生成文章(修改为读取前台配置) function dsp_generate_article($core_keyword, $settings) { // 从配置中读取API参数(核心修改:替换硬编码为前台设置的值) $api_key = $settings['api_key']; $api_endpoint = isset($settings['api_endpoint']) ? trim($settings['api_endpoint']) : 'https://api.deepseek.com/v1/chat/completions'; $model = isset($settings['model_name']) ? trim($settings['model_name']) : 'deepseek-ai/deepseek-chat'; $max_tokens = (int)$settings['max_tokens']; $timeout = (int)$settings['timeout']; // 验证API端点URL格式(新增) if (!filter_var($api_endpoint, FILTER_VALIDATE_URL)) { return [ 'error' => 'API端点URL无效', 'detail' => '请在设置中填写正确的API接口地址(需以http://或https://开头)' ]; } // 从配置中读取提示词模板(核心修改:支持前台自定义) $prompt_template = isset($settings['prompt_template']) ? trim($settings['prompt_template']) : ''; if (empty($prompt_template)) { return [ 'error' => '提示词模板为空', 'detail' => '请在设置中填写提示词模板,至少包含【{$core_keyword}】占位符' ]; } // 验证提示词模板是否包含必要的占位符(新增) if (strpos($prompt_template, '【{$core_keyword}】') === false) { return [ 'error' => '提示词模板格式错误', 'detail' => '模板中必须包含【{$core_keyword}】占位符(用于替换核心关键词)' ]; } // 替换提示词中的占位符(将【{$core_keyword}】替换为实际关键词) $system_prompt = str_replace('【{$core_keyword}】', $core_keyword, $prompt_template); $system_prompt = trim($system_prompt); $system_prompt = str_replace('"', '\\"', $system_prompt); // 转义双引号 // 估算Token和构建请求(后续逻辑不变) $prompt_tokens = dsp_estimate_tokens($system_prompt . $core_keyword); $generate_tokens = $max_tokens - $prompt_tokens; if ($generate_tokens < 500) { return [ 'error' => 'Token不足', 'detail' => "提示词已占用{$prompt_tokens}Token,剩余不足500,无法生成有效内容" ]; } $request_data = [ "model" => $model, "messages" => [ ["role" => "system", "content" => $system_prompt], ["role" => "user", "content" => "严格按示例格式生成,确保四模块完整"] ], "temperature" => 0.8, "max_tokens" => $generate_tokens, "top_p" => 0.9, "stream" => false ]; // 发送cURL请求(不变) $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $api_endpoint, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($request_data, JSON_UNESCAPED_UNICODE), CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$api_key}", "Content-Type: application/json" ], CURLOPT_TIMEOUT => $timeout, CURLOPT_SSL_VERIFYPEER => true ]); $raw_response = curl_exec($ch); $curl_error = curl_errno($ch) ? curl_error($ch) : null; $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 错误处理(不变) if (!empty($curl_error)) { return ['error' => 'cURL请求失败', 'detail' => $curl_error, 'raw' => $raw_response]; } if ($http_code < 200 || $http_code >= 300) { return [ 'error' => "API请求被拒绝(状态码:{$http_code})", 'detail' => "可能原因:API密钥无效、模型名称错误、端点URL不可用", 'raw' => $raw_response ]; } $parsed = json_decode($raw_response, true); if (json_last_error() !== JSON_ERROR_NONE) { return [ 'error' => 'JSON解析失败', 'detail' => json_last_error_msg(), 'raw' => $raw_response ]; } if (isset($parsed['error'])) { $err_msg = $parsed['error']['message'] ?? '未知API错误'; return ['error' => 'API返回错误', 'detail' => $err_msg, 'raw' => $raw_response]; } if (!isset($parsed['choices'][0]['message']['content'])) { return ['error' => '内容缺失', 'detail' => 'API未返回有效文章内容', 'raw' => $raw_response]; } return [ 'raw_content' => $parsed['choices'][0]['message']['content'], 'token_usage' => $parsed['usage'] ?? ['prompt_tokens' => $prompt_tokens, 'completion_tokens' => $generate_tokens], 'raw' => $raw_response ]; }