From da90fb9971b0d11be01236a84f29544976579caa Mon Sep 17 00:00:00 2001 From: nanhaoluo <3075912108@qq.com> Date: Mon, 26 Jan 2026 11:49:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=BA=20AI=20=E6=91=98=E8=A6=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=B7=BB=E5=8A=A0=E8=AF=A6=E7=BB=86=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 argon_log_ai_error() 统一错误处理函数 - 记录错误到 WordPress error_log 和文章 meta - 添加配置完整性检查(API 密钥、端点、模型) - 添加文章内容长度检查(至少50字) - 改进 OpenAI API 调用的错误处理 - 网络错误详细记录 - HTTP 状态码检查 - 响应格式验证 - 空内容检查 - 记录详细的调用信息(文章ID、标题、提供商、模型、内容长度) - 保存错误信息到文章 meta(_argon_ai_summary_error) - 保存错误时间到文章 meta(_argon_ai_summary_error_time) - 成功时清除错误记录 - 所有错误信息包含上下文数据(endpoint、model等) --- functions.php | 144 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 129 insertions(+), 15 deletions(-) diff --git a/functions.php b/functions.php index d089a59..14e433d 100644 --- a/functions.php +++ b/functions.php @@ -6651,6 +6651,35 @@ function argon_set_active_api($provider, $api_id) { return false; } +/** + * 记录 AI API 错误 + * @param string $provider 提供商名称 + * @param string $error_type 错误类型 + * @param string $error_message 错误信息 + * @param int $post_id 文章ID + * @param array $extra_data 额外数据 + */ +function argon_log_ai_error($provider, $error_type, $error_message, $post_id = 0, $extra_data = []) { + $log_message = sprintf( + 'Argon AI Summary Error (%s): %s - %s', + $provider, + $error_type, + $error_message + ); + + if (!empty($extra_data)) { + $log_message .= ' | 额外信息: ' . json_encode($extra_data, JSON_UNESCAPED_UNICODE); + } + + error_log($log_message); + + if ($post_id > 0) { + $user_message = sprintf('%s %s: %s', $provider, $error_type, $error_message); + update_post_meta($post_id, '_argon_ai_summary_error', $user_message); + update_post_meta($post_id, '_argon_ai_summary_error_time', current_time('mysql')); + } +} + /** * 生成 AI 摘要 * @param WP_Post $post 文章对象 @@ -6661,7 +6690,15 @@ function argon_generate_ai_summary($post) { $config = argon_get_ai_provider_config($provider); $api_key = $config['api_key']; + // 错误检查:API 密钥 if (empty($api_key)) { + argon_log_ai_error($provider, '配置错误', 'API 密钥未配置', $post->ID); + return false; + } + + // 错误检查:配置完整性 + if (!isset($config['api_endpoint']) || !isset($config['model'])) { + argon_log_ai_error($provider, '配置错误', 'API 配置不完整', $post->ID, $config); return false; } @@ -6670,39 +6707,85 @@ function argon_generate_ai_summary($post) { $content = preg_replace('/\s+/', ' ', $content); $content = mb_substr($content, 0, 8000); // 限制长度 + // 错误检查:文章内容 + if (empty($content) || mb_strlen($content) < 50) { + argon_log_ai_error($provider, '内容错误', '文章内容过短(至少需要50字)', $post->ID, [ + 'content_length' => mb_strlen($content) + ]); + return false; + } + $prompt = get_option('argon_ai_summary_prompt', '你是一个专业的内容摘要助手。请仔细阅读以下文章内容,用简洁、准确的语言总结文章的核心观点和主要内容。要求:1) 控制在 100-150 字以内;2) 突出文章的关键信息和亮点;3) 使用通俗易懂的语言;4) 保持客观中立的语气。'); + // 记录调用信息 + error_log(sprintf( + 'Argon AI Summary: 开始生成摘要 (文章ID: %d, 标题: %s, 提供商: %s, 模型: %s, 内容长度: %d)', + $post->ID, + $post->post_title, + $provider, + $config['model'], + mb_strlen($content) + )); + // 根据不同服务商调用 API + $result = false; switch ($provider) { case 'openai': - return argon_call_openai_api($api_key, $prompt, $content); + $result = argon_call_openai_api($api_key, $prompt, $content, $post->ID); + break; case 'anthropic': - return argon_call_anthropic_api($api_key, $prompt, $content); + $result = argon_call_anthropic_api($api_key, $prompt, $content, $post->ID); + break; case 'deepseek': - return argon_call_deepseek_api($api_key, $prompt, $content); + $result = argon_call_deepseek_api($api_key, $prompt, $content, $post->ID); + break; case 'xiaomi': - return argon_call_xiaomi_api($api_key, $prompt, $content); + $result = argon_call_xiaomi_api($api_key, $prompt, $content, $post->ID); + break; case 'qianwen': - return argon_call_qianwen_api($api_key, $prompt, $content); + $result = argon_call_qianwen_api($api_key, $prompt, $content, $post->ID); + break; case 'wenxin': - return argon_call_wenxin_api($api_key, $prompt, $content); + $result = argon_call_wenxin_api($api_key, $prompt, $content, $post->ID); + break; case 'doubao': - return argon_call_doubao_api($api_key, $prompt, $content); + $result = argon_call_doubao_api($api_key, $prompt, $content, $post->ID); + break; case 'kimi': - return argon_call_kimi_api($api_key, $prompt, $content); + $result = argon_call_kimi_api($api_key, $prompt, $content, $post->ID); + break; case 'zhipu': - return argon_call_zhipu_api($api_key, $prompt, $content); + $result = argon_call_zhipu_api($api_key, $prompt, $content, $post->ID); + break; case 'siliconflow': - return argon_call_siliconflow_api($api_key, $prompt, $content); + $result = argon_call_siliconflow_api($api_key, $prompt, $content, $post->ID); + break; default: + argon_log_ai_error($provider, '配置错误', '不支持的服务商', $post->ID); return false; } + + // 检查结果 + if ($result === false) { + error_log('Argon AI Summary: API 调用失败 (文章ID: ' . $post->ID . ', 提供商: ' . $provider . ')'); + // 错误信息已在具体的 API 调用函数中记录 + } else { + error_log(sprintf( + 'Argon AI Summary: 摘要生成成功 (文章ID: %d, 摘要长度: %d字)', + $post->ID, + mb_strlen($result) + )); + delete_post_meta($post->ID, '_argon_ai_summary_error'); + delete_post_meta($post->ID, '_argon_ai_summary_error_time'); + } + + return $result; } /** * 调用 OpenAI API */ -function argon_call_openai_api($api_key, $prompt, $content) { +function argon_call_openai_api($api_key, $prompt, $content, $post_id = 0) { $provider = 'openai'; $config = argon_get_ai_provider_config($provider); @@ -6729,16 +6812,47 @@ function argon_call_openai_api($api_key, $prompt, $content) { ]); if (is_wp_error($response)) { + argon_log_ai_error('OpenAI', '网络错误', $response->get_error_message(), $post_id, [ + 'endpoint' => $endpoint + ]); return false; } + $status_code = wp_remote_retrieve_response_code($response); $body = json_decode(wp_remote_retrieve_body($response), true); - if (isset($body['choices'][0]['message']['content'])) { - return trim($body['choices'][0]['message']['content']); + // 检查 HTTP 状态码 + if ($status_code !== 200) { + $error_msg = isset($body['error']['message']) ? $body['error']['message'] : '未知错误'; + $error_type = isset($body['error']['type']) ? $body['error']['type'] : 'unknown'; + argon_log_ai_error('OpenAI', 'API 错误 (HTTP ' . $status_code . ')', $error_msg, $post_id, [ + 'error_type' => $error_type, + 'model' => $model, + 'endpoint' => $endpoint + ]); + return false; } - - return false; + + // 检查响应格式 + if (!isset($body['choices'][0]['message']['content'])) { + argon_log_ai_error('OpenAI', '响应格式错误', '未找到预期的响应字段', $post_id, [ + 'response_keys' => array_keys($body), + 'model' => $model + ]); + return false; + } + + $summary = trim($body['choices'][0]['message']['content']); + + // 检查摘要内容 + if (empty($summary)) { + argon_log_ai_error('OpenAI', '内容错误', '返回的摘要为空', $post_id, [ + 'model' => $model + ]); + return false; + } + + return $summary; } /**