import { NextResponse } from 'next/server' import { llmClient } from '@/app/api/llm-client' const SYSTEM_PROMPT = `你是一个专门分析互联网大厂老板PUA话术的AI裁判。 你的任务分两步: 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" }` // 重复惩罚倍率:根据相似度递增 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, 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: userMsg }, ], maxTokens: 200, temperature: 0.6, }) const raw = resp.choices?.[0]?.message?.content ?? '' 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_boost,speed_boost→attack_boost,etc. const downgrade: Record = { 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: adjustedScore, title: result.title || '打鸡血', desc: result.desc || '还行吧', effect, similarity, similarTo: result.similarTo || '', isDuplicate, penaltyMultiplier, // 前端据此额外扣 HC }) } catch (e) { console.error('[pua-score]', e) return NextResponse.json({ score: 3, title: '随机鸡血', desc: 'AI开小差了,随机发力', effect: 'attack_boost', similarity: 0, similarTo: '', isDuplicate: false, penaltyMultiplier: 0, }) } }