Files
test1/app/api/pua-score/route.ts

120 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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_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: 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,
})
}
}