feat: 为 AI 摘要功能添加详细的错误报告

- 新增 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等)
This commit is contained in:
2026-01-26 11:49:38 +08:00
parent a025a6bdd8
commit da90fb9971

View File

@@ -6651,6 +6651,35 @@ function argon_set_active_api($provider, $api_id) {
return false; 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 摘要 * 生成 AI 摘要
* @param WP_Post $post 文章对象 * @param WP_Post $post 文章对象
@@ -6661,7 +6690,15 @@ function argon_generate_ai_summary($post) {
$config = argon_get_ai_provider_config($provider); $config = argon_get_ai_provider_config($provider);
$api_key = $config['api_key']; $api_key = $config['api_key'];
// 错误检查API 密钥
if (empty($api_key)) { 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; return false;
} }
@@ -6670,39 +6707,85 @@ function argon_generate_ai_summary($post) {
$content = preg_replace('/\s+/', ' ', $content); $content = preg_replace('/\s+/', ' ', $content);
$content = mb_substr($content, 0, 8000); // 限制长度 $content = mb_substr($content, 0, 8000); // 限制长度
$prompt = get_option('argon_ai_summary_prompt', '你是一个专业的内容摘要助手。请仔细阅读以下文章内容用简洁、准确的语言总结文章的核心观点和主要内容。要求1) 控制在 100-150 字以内2) 突出文章的关键信息和亮点3) 使用通俗易懂的语言4) 保持客观中立的语气。'); // 错误检查:文章内容
if (empty($content) || mb_strlen($content) < 50) {
// 根据不同服务商调用 API argon_log_ai_error($provider, '内容错误', '文章内容过短至少需要50字', $post->ID, [
switch ($provider) { 'content_length' => mb_strlen($content)
case 'openai': ]);
return argon_call_openai_api($api_key, $prompt, $content);
case 'anthropic':
return argon_call_anthropic_api($api_key, $prompt, $content);
case 'deepseek':
return argon_call_deepseek_api($api_key, $prompt, $content);
case 'xiaomi':
return argon_call_xiaomi_api($api_key, $prompt, $content);
case 'qianwen':
return argon_call_qianwen_api($api_key, $prompt, $content);
case 'wenxin':
return argon_call_wenxin_api($api_key, $prompt, $content);
case 'doubao':
return argon_call_doubao_api($api_key, $prompt, $content);
case 'kimi':
return argon_call_kimi_api($api_key, $prompt, $content);
case 'zhipu':
return argon_call_zhipu_api($api_key, $prompt, $content);
case 'siliconflow':
return argon_call_siliconflow_api($api_key, $prompt, $content);
default:
return false; 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':
$result = argon_call_openai_api($api_key, $prompt, $content, $post->ID);
break;
case 'anthropic':
$result = argon_call_anthropic_api($api_key, $prompt, $content, $post->ID);
break;
case 'deepseek':
$result = argon_call_deepseek_api($api_key, $prompt, $content, $post->ID);
break;
case 'xiaomi':
$result = argon_call_xiaomi_api($api_key, $prompt, $content, $post->ID);
break;
case 'qianwen':
$result = argon_call_qianwen_api($api_key, $prompt, $content, $post->ID);
break;
case 'wenxin':
$result = argon_call_wenxin_api($api_key, $prompt, $content, $post->ID);
break;
case 'doubao':
$result = argon_call_doubao_api($api_key, $prompt, $content, $post->ID);
break;
case 'kimi':
$result = argon_call_kimi_api($api_key, $prompt, $content, $post->ID);
break;
case 'zhipu':
$result = argon_call_zhipu_api($api_key, $prompt, $content, $post->ID);
break;
case 'siliconflow':
$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 * 调用 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'; $provider = 'openai';
$config = argon_get_ai_provider_config($provider); $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)) { if (is_wp_error($response)) {
argon_log_ai_error('OpenAI', '网络错误', $response->get_error_message(), $post_id, [
'endpoint' => $endpoint
]);
return false; return false;
} }
$status_code = wp_remote_retrieve_response_code($response);
$body = json_decode(wp_remote_retrieve_body($response), true); $body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($body['choices'][0]['message']['content'])) { // 检查 HTTP 状态码
return trim($body['choices'][0]['message']['content']); 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;
} }
// 检查响应格式
if (!isset($body['choices'][0]['message']['content'])) {
argon_log_ai_error('OpenAI', '响应格式错误', '未找到预期的响应字段', $post_id, [
'response_keys' => array_keys($body),
'model' => $model
]);
return false; 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;
} }
/** /**