Files
shensheshou/app/api/rfm/analyze/route.ts
v0 22e725887a refactor: restructure project into 5 core modules
Organize project by 5 core modules based on requirement docs.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2026-01-31 04:18:24 +00:00

57 lines
2.0 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 { analyzeUser, type AnalyzeInput } from "@/services/rfm-engine"
import { generateText } from "ai"
import { openai } from "@ai-sdk/openai"
/**
* 可选 AI 标签增强:
* - 使用 AI SDK (generateText + openai("gpt-4o")),符合统一标准 [^1]
* - 无 OPENAI_API_KEY 时自动跳过,保持稳定
*/
async function aiTagging(chat_logs?: string[]) {
const text = (chat_logs ?? []).slice(0, 8).join("。")
if (!text) return null
if (!process.env.OPENAI_API_KEY) return null
try {
const { text: out } = await generateText({
model: openai("gpt-4o"),
system:
"请根据用户聊天片段输出JSON字段emotion(积极|中性|消极), intent(弱意图|中等意图|强意图), behavior(数组中文标签最多3个)。只输出JSON。",
prompt: `聊天片段:${text}`,
// @ts-expect-error ai sdk typings are flexible in Next.js
maxTokens: 200,
})
const json = JSON.parse(out.trim())
return json
} catch {
return null
}
}
export async function POST(req: Request) {
try {
const body = await req.json()
const inputs: AnalyzeInput[] = Array.isArray(body) ? body : [body]
const useAI = (Array.isArray(body) ? (body as any).useAI : (body as any)?.useAI) ?? false
const results = []
for (const input of inputs) {
const base = analyzeUser(input)
if (useAI) {
const ai = await aiTagging(input.chat_logs)
if (ai) {
base.tags.emotion = ai.emotion ?? base.tags.emotion
base.tags.intent = ai.intent ?? base.tags.intent
if (Array.isArray(ai.behavior)) {
base.tags.behavior = Array.from(new Set([...(base.tags.behavior ?? []), ...ai.behavior]))
}
}
}
results.push(base)
}
return NextResponse.json({ success: true, data: results })
} catch (e: any) {
return NextResponse.json({ success: false, error: e?.message || "Invalid input" }, { status: 400 })
}
}