feat(pua): 新增重复检测——LLM语义相似度判断,相似60%效果降级,相似80%强制翻车,额外扣HC惩罚

This commit is contained in:
Cloud Bot
2026-03-24 08:44:35 +00:00
parent 1473542f65
commit a36c8af344
2 changed files with 163 additions and 36 deletions

View File

@@ -2,70 +2,118 @@ import { NextResponse } from 'next/server'
import { llmClient } from '@/app/api/llm-client'
const SYSTEM_PROMPT = `你是一个专门分析互联网大厂老板PUA话术的AI裁判。
用户输入一段老板/领导对员工说的"打鸡血"或"PUA"的话,你需要分析这段话并给出评分和游戏效果。
评分标准1-10分
1-3分废话/没营养("大家加油"之类)→ 轻微效果
4-6分标准大厂黑话"对齐""闭环""狼性")→ 中等效果
7-8分强力PUA"996是福报""不拼搏对不起父母")→ 强力效果
9-10分终极毒鸡汤极限施压/情感绑架)→ 全场爆发
你的任务分两步
1. 判断当前输入是否与历史记录重复或高度相似(意思相近算相似,不只是字面相同)
2. 对当前输入进行鸡血值评分
相似度判断标准similarity字段0.0-1.0
- 0.0-0.3:全新内容,没有相似之处
- 0.3-0.6:有一定相关,但表达不同
- 0.6-0.8:明显相似,换汤不换药
- 0.8-1.0:基本重复,几乎一样的意思
评分标准score字段1-10分
- 1-3分废话/没营养 → backfire效果
- 4-6分标准大厂黑话 → 中等效果
- 7-8分强力PUA → 攻速暴增
- 9-10分终极毒鸡汤 → 全场狂暴
只返回如下JSON不要其他内容
{
"similarity": 数字(0.0-1.0),
"similarTo": "最相似的历史内容摘要,没有则为空字符串",
"score": 数字(1-10),
"title": "效果名称2-6个汉字有创意",
"desc": "对话语的一句话点评15字以内带点讽刺",
"effect": "attack_boost" | "speed_boost" | "money_rain" | "rage_mode" | "backfire"
}
}`
effect说明
- attack_boost: 攻击力提升score 4-6
- speed_boost: 攻击速度提升score 7-8
- money_rain: HC暴增score 5-7话语中强调利益
- rage_mode: 全场狂暴score 9-10
- backfire: 话太废了反而debuffscore 1-2`
// 重复惩罚倍率:根据相似度递增
function getDuplicatePenaltyMultiplier(similarity: number): number {
if (similarity >= 0.8) return 2.0 // 严重重复:再扣双倍
if (similarity >= 0.6) return 1.0 // 明显相似:再扣一倍
return 0 // 不额外惩罚
}
export async function POST(req: Request) {
try {
const { text } = await req.json()
const { text, history } = await req.json() as {
text: string
history: string[] // 最近N条历史原文
}
if (!text || typeof text !== 'string' || text.trim().length < 2) {
return NextResponse.json({ error: '输入内容太短了' }, { status: 400 })
}
// 构建带历史的 prompt
const historyBlock = history && history.length > 0
? `\n\n历史记录已经说过的话按时间倒序\n${history.slice(0, 5).map((h, i) => `${i + 1}. "${h}"`).join('\n')}`
: '\n\n历史记录暂无'
const userMsg = `当前输入:"${text.slice(0, 200)}"${historyBlock}`
const resp = await llmClient.chat({
model: 'gpt-4o-mini',
messages: [
{ role: 'system', content: SYSTEM_PROMPT },
{ role: 'user', content: text.slice(0, 200) },
{ role: 'user', content: userMsg },
],
maxTokens: 150,
temperature: 0.7,
maxTokens: 200,
temperature: 0.6,
})
const raw = resp.choices?.[0]?.message?.content ?? ''
// 提取 JSON防止 LLM 多输出文字)
const match = raw.match(/\{[\s\S]*\}/)
if (!match) throw new Error('LLM 返回格式异常')
const result = JSON.parse(match[0])
const score = Math.max(1, Math.min(10, Number(result.score) || 5))
const similarity = Math.max(0, Math.min(1, Number(result.similarity) || 0))
const penaltyMultiplier = getDuplicatePenaltyMultiplier(similarity)
const isDuplicate = similarity >= 0.6
// 如果重复,效果强制降级或 backfire
let effect = result.effect || 'attack_boost'
let adjustedScore = score
if (isDuplicate && similarity >= 0.8) {
effect = 'backfire'
adjustedScore = Math.max(1, score - 3)
} else if (isDuplicate && similarity >= 0.6) {
// 效果打半折rage_mode→speed_boostspeed_boost→attack_boostetc.
const downgrade: Record<string, string> = {
rage_mode: 'speed_boost',
speed_boost: 'attack_boost',
money_rain: 'attack_boost',
attack_boost: 'backfire',
backfire: 'backfire',
}
effect = downgrade[effect] ?? 'backfire'
adjustedScore = Math.max(1, score - 2)
}
return NextResponse.json({
score,
score: adjustedScore,
title: result.title || '打鸡血',
desc: result.desc || '还行吧',
effect: result.effect || 'attack_boost',
effect,
similarity,
similarTo: result.similarTo || '',
isDuplicate,
penaltyMultiplier, // 前端据此额外扣 HC
})
} catch (e) {
console.error('[pua-score]', e)
// 降级:随机给个分数
const score = Math.floor(Math.random() * 7) + 3
return NextResponse.json({
score,
score: 3,
title: '随机鸡血',
desc: 'AI开小差了随机发力',
effect: 'attack_boost',
similarity: 0,
similarTo: '',
isDuplicate: false,
penaltyMultiplier: 0,
})
}
}