From 56fe7be8eca2c685de946d74c7c616720a1d3120 Mon Sep 17 00:00:00 2001 From: shaw Date: Sat, 11 Oct 2025 17:34:17 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96claude=20code=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=8F=90=E7=A4=BA=E8=AF=8D=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/claudeRelayService.js | 2 +- src/validators/clients/claudeCodeValidator.js | 59 ++++++++++++++++++- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/services/claudeRelayService.js b/src/services/claudeRelayService.js index 94f85767..389ae26f 100644 --- a/src/services/claudeRelayService.js +++ b/src/services/claudeRelayService.js @@ -91,7 +91,7 @@ class ClaudeRelayService { // 🔍 判断是否是真实的 Claude Code 请求 isRealClaudeCodeRequest(requestBody) { - return ClaudeCodeValidator.hasClaudeCodeSystemPrompt(requestBody) + return ClaudeCodeValidator.includesClaudeCodeSystemPrompt(requestBody, 1) } // 🚀 转发请求到Claude API diff --git a/src/validators/clients/claudeCodeValidator.js b/src/validators/clients/claudeCodeValidator.js index b538024b..a72928f4 100644 --- a/src/validators/clients/claudeCodeValidator.js +++ b/src/validators/clients/claudeCodeValidator.js @@ -40,7 +40,7 @@ class ClaudeCodeValidator { * @param {Object} body - 请求体 * @returns {boolean} 是否包含 Claude Code 系统提示词 */ - static hasClaudeCodeSystemPrompt(body) { + static hasClaudeCodeSystemPrompt(body, customThreshold) { if (!body || typeof body !== 'object') { return false } @@ -55,12 +55,17 @@ class ClaudeCodeValidator { return false } + const threshold = + typeof customThreshold === 'number' && Number.isFinite(customThreshold) + ? customThreshold + : SYSTEM_PROMPT_THRESHOLD + for (const entry of systemEntries) { const rawText = typeof entry?.text === 'string' ? entry.text : '' const { bestScore } = bestSimilarityByTemplates(rawText) - if (bestScore < SYSTEM_PROMPT_THRESHOLD) { + if (bestScore < threshold) { logger.error( - `Claude system prompt similarity below threshold: score=${bestScore.toFixed(4)}, threshold=${SYSTEM_PROMPT_THRESHOLD}, prompt=${rawText}` + `Claude system prompt similarity below threshold: score=${bestScore.toFixed(4)}, threshold=${threshold}, prompt=${rawText}` ) return false } @@ -68,6 +73,54 @@ class ClaudeCodeValidator { return true } + /** + * 判断是否存在 Claude Code 系统提示词(存在即返回 true) + * @param {Object} body - 请求体 + * @param {number} [customThreshold] - 自定义阈值 + * @returns {boolean} 是否存在 Claude Code 系统提示词 + */ + static includesClaudeCodeSystemPrompt(body, customThreshold) { + if (!body || typeof body !== 'object') { + return false + } + + const model = typeof body.model === 'string' ? body.model : null + if (!model) { + return false + } + + const systemEntries = Array.isArray(body.system) ? body.system : null + if (!systemEntries) { + return false + } + + const threshold = + typeof customThreshold === 'number' && Number.isFinite(customThreshold) + ? customThreshold + : SYSTEM_PROMPT_THRESHOLD + + let bestMatchScore = 0 + + for (const entry of systemEntries) { + const rawText = typeof entry?.text === 'string' ? entry.text : '' + const { bestScore } = bestSimilarityByTemplates(rawText) + + if (bestScore > bestMatchScore) { + bestMatchScore = bestScore + } + + if (bestScore >= threshold) { + return true + } + } + + logger.debug( + `Claude system prompt not detected: bestScore=${bestMatchScore.toFixed(4)}, threshold=${threshold}` + ) + + return false + } + /** * 验证请求是否来自 Claude Code CLI * @param {Object} req - Express 请求对象