"use strict"; /** * AI 法务审核(对齐 zhenqianba handleLegalCheck / _i) * 由 `/api/v1/nodejs-scripts?name=script_legal_check.js` 下发 */ const pipelineNative = require("./pipeline_native.js"); const desktopConfig = require("./desktop_config.js"); function buildLegalPrompt(content) { return `你是一名专业的短视频法务审核专家。请审核以下短视频的文案是否存在违禁词、敏感词、虚假宣传、极限词(如"第一"、"最好")等法律风险以及短视频平台常见的违禁词,避免绝对化表述和违禁词,避免负向,消极的立场,对大健康,医疗等重点行业要严格审核。 【待审核文案】 ${content} 【审核要求】 1. 找出文案中的所有违禁词/敏感词。 2. 为每个违禁词提供一个合规的替换词(如果建议直接删除,替换词为空字符串)。 3. 说明每个违禁词的违规原因。 4. 给出整体审核意见。 5. 给出修正后的完整优化文案。 【输出格式】 请直接返回 JSON 格式: { "risks": [ { "word": "违禁词原文", "recommendation": "替换词", "reason": "违规原因" } ], "analysis": "整体审核意见", "fixedText": "修正后的完整文案", "hasRisk": true } 除 JSON 外不要输出任何其他内容。`; } function parseLegalJson(raw) { let text = String(raw || "").trim(); const m = text.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/) || text.match(/\{[\s\S]*\}/); if (m) text = m[1] || m[0]; try { const data = JSON.parse(text); const risks = Array.isArray(data.risks) ? data.risks : []; return { risks, analysis: data.analysis || "", fixedText: data.fixedText || "", hasRisk: data.hasRisk === true || risks.length > 0, }; } catch { return { risks: [], analysis: text, fixedText: "", hasRisk: true }; } } globalThis.__nodejsMain = async function (params) { const content = String(params?.content || "").trim(); if (!content) { return { success: false, error: "缺少待审核文案" }; } const modelConfig = desktopConfig.buildModelConfig(); const check = desktopConfig.validateModelConfig(modelConfig); if (!check.ok) { return { success: false, error: check.error }; } const chat = await pipelineNative.openaiChat({ apiUrl: modelConfig.apiUrl, apiKey: modelConfig.apiKey, model: modelConfig.apiModelId, messages: [{ role: "user", content: buildLegalPrompt(content) }], temperature: 0.3, max_tokens: 3000, }); if (!chat?.success || !chat.content) { return { success: false, error: chat?.error || "AI 审核请求失败" }; } const parsed = parseLegalJson(chat.content); return { success: true, hasViolations: parsed.hasRisk, risks: parsed.risks, analysis: parsed.analysis, fixedText: parsed.fixedText, totalCount: parsed.risks.length, }; };