mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: 调整Claude Code相似度检测并恢复401处理
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
export const haikuSystemPrompt = `Analyze if this message indicates a new conversation topic. If it does, extract a 2-3 word title that captures the new topic. Format your response as a JSON object with two fields: 'isNewTopic' (boolean) and 'title' (string, or null if isNewTopic is false). Only include these fields, no other text.`
|
||||
export const claudeOtherSystemPrompt1 = `You are Claude Code, Anthropic's official CLI for Claude.`
|
||||
export const claudeOtherSystemPrompt2 = `
|
||||
const haikuSystemPrompt = `Analyze if this message indicates a new conversation topic. If it does, extract a 2-3 word title that captures the new topic. Format your response as a JSON object with two fields: 'isNewTopic' (boolean) and 'title' (string, or null if isNewTopic is false). Only include these fields, no other text.`
|
||||
const claudeOtherSystemPrompt1 = `You are Claude Code, Anthropic's official CLI for Claude.`
|
||||
const claudeOtherSystemPrompt2 = `
|
||||
You are an interactive CLI tool that helps users 'according to your "Output Style" below, which describes how you should respond to user queries.' : 'with software engineering tasks.'} Use the instructions below and the tools available to you to assist the user.
|
||||
|
||||
IMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident that the URLs are for helping the user with programming. You may use URLs provided by the user in their messages or local files.
|
||||
@@ -163,3 +163,9 @@ user: Where are errors from the client handled?
|
||||
assistant: Clients are marked as failed in the \`connectToServer\` function in src/services/process.ts:712.
|
||||
</example>
|
||||
`
|
||||
|
||||
module.exports = {
|
||||
haikuSystemPrompt,
|
||||
claudeOtherSystemPrompt1,
|
||||
claudeOtherSystemPrompt2
|
||||
}
|
||||
|
||||
@@ -1,18 +1,81 @@
|
||||
import stringSimilarity from 'string-similarity'
|
||||
const MAX_TEXT_LENGTH = 4000
|
||||
|
||||
function normalize(value) {
|
||||
return value.replace(/\s+/g, ' ').trim()
|
||||
return value.replace(/\s+/g, ' ').trim().toLowerCase()
|
||||
}
|
||||
|
||||
export function simple(actual, expected, threshold) {
|
||||
function clamp(value) {
|
||||
if (value.length <= MAX_TEXT_LENGTH) {
|
||||
return value
|
||||
}
|
||||
|
||||
// 截断极长文本,避免耗时的相似度计算
|
||||
return value.slice(0, MAX_TEXT_LENGTH)
|
||||
}
|
||||
|
||||
function buildBigramStats(text) {
|
||||
const stats = new Map()
|
||||
|
||||
for (let index = 0; index < text.length - 1; index += 1) {
|
||||
const gram = text[index] + text[index + 1]
|
||||
stats.set(gram, (stats.get(gram) || 0) + 1)
|
||||
}
|
||||
|
||||
return {
|
||||
stats,
|
||||
total: Math.max(text.length - 1, 0)
|
||||
}
|
||||
}
|
||||
|
||||
function diceCoefficient(left, right) {
|
||||
if (left === right) {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (left.length < 2 || right.length < 2) {
|
||||
return left === right && left.length > 0 ? 1 : 0
|
||||
}
|
||||
|
||||
const { stats: leftStats, total: leftTotal } = buildBigramStats(left)
|
||||
const { stats: rightStats, total: rightTotal } = buildBigramStats(right)
|
||||
|
||||
let intersection = 0
|
||||
const [smaller, larger] =
|
||||
leftStats.size <= rightStats.size ? [leftStats, rightStats] : [rightStats, leftStats]
|
||||
|
||||
smaller.forEach((count, gram) => {
|
||||
if (larger.has(gram)) {
|
||||
intersection += Math.min(count, larger.get(gram))
|
||||
}
|
||||
})
|
||||
|
||||
if (leftTotal + rightTotal === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return (2 * intersection) / (leftTotal + rightTotal)
|
||||
}
|
||||
|
||||
function simple(actual, expected, threshold = 0.9) {
|
||||
if (typeof expected !== 'string' || !expected.trim()) {
|
||||
throw new Error('Expected prompt text must be a non-empty string')
|
||||
throw new Error('期望的提示词必须是非空字符串')
|
||||
}
|
||||
|
||||
if (typeof actual !== 'string' || !actual.trim()) {
|
||||
return { score: 0, threshold, passed: false }
|
||||
}
|
||||
|
||||
const score = stringSimilarity.compareTwoStrings(normalize(actual), normalize(expected))
|
||||
return { score, threshold, passed: score >= threshold }
|
||||
const normalizedExpected = clamp(normalize(expected))
|
||||
const normalizedActual = clamp(normalize(actual))
|
||||
const score = diceCoefficient(normalizedActual, normalizedExpected)
|
||||
|
||||
return {
|
||||
score,
|
||||
threshold,
|
||||
passed: score >= threshold
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
simple
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user