148 lines
5.1 KiB
JavaScript
148 lines
5.1 KiB
JavaScript
|
|
// 改进版的AI意图识别方法
|
|||
|
|
// 复制这段代码替换 xinlidsj/pages/index/index.vue 中的 parseUserIntentWithAI 方法
|
|||
|
|
|
|||
|
|
async parseUserIntentWithAI(userInput) {
|
|||
|
|
const llmCfg = this.getBailianConfig() || this.getOllamaConfig()
|
|||
|
|
if (!llmCfg) {
|
|||
|
|
console.log('AI意图识别:未配置大模型')
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 定义系统可以执行的指令列表
|
|||
|
|
const availableCommands = {
|
|||
|
|
navigation: [
|
|||
|
|
{ action: 'goWarning', params: ['status', 'warningLevel'], desc: '打开预警中心,可选参数:status(0=未处理,1=处理中,2=已完成), warningLevel(严重/高/中/低)' },
|
|||
|
|
{ action: 'goProfile', params: ['keyword', 'userId'], desc: '打开个体画像,可选参数:keyword(姓名/编号), userId(用户ID)' },
|
|||
|
|
{ action: 'goComprehensive', params: [], desc: '打开综合报告' },
|
|||
|
|
{ action: 'goInterventionTask', params: ['status'], desc: '打开干预任务,可选参数:status(0,1=未完成,2=已完成)' },
|
|||
|
|
{ action: 'goReport', params: ['keyword', 'reportId', 'sourceType'], desc: '打开报告列表或详情,可选参数:keyword(搜索关键词), reportId(报告ID), sourceType(assessment/questionnaire)' },
|
|||
|
|
{ action: 'goMessage', params: ['tab'], desc: '打开消息/收件箱,可选参数:tab(unread=未读)' },
|
|||
|
|
{ action: 'goNotice', params: [], desc: '打开通知公告' },
|
|||
|
|
{ action: 'goDashboard', params: [], desc: '打开监区看板' },
|
|||
|
|
{ action: 'goTagFilter', params: [], desc: '打开标签筛选' },
|
|||
|
|
{ action: 'goVoice', params: [], desc: '打开语音助手' }
|
|||
|
|
],
|
|||
|
|
analysis: [
|
|||
|
|
{ action: 'analyzeReport', params: ['keyword', 'reportId'], desc: '分析报告,必需参数:keyword(姓名/编号)或reportId(报告ID)' },
|
|||
|
|
{ action: 'analyzeProfile', params: ['keyword', 'userId'], desc: '分析个体画像,必需参数:keyword(姓名/编号)或userId(用户ID)' },
|
|||
|
|
{ action: 'analyzeData', params: ['dataType'], desc: '分析平台数据,可选参数:dataType(overview=概览/trend=趋势/dept=监区统计)' }
|
|||
|
|
],
|
|||
|
|
control: [
|
|||
|
|
{ action: 'clearChat', params: [], desc: '清空对话记录' },
|
|||
|
|
{ action: 'toggleChat', params: [], desc: '展开或收起AI对话框' },
|
|||
|
|
{ action: 'goBack', params: [], desc: '返回上一页' },
|
|||
|
|
{ action: 'goHome', params: [], desc: '返回首页' }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const systemPrompt = `你是一个指令解析助手,负责理解用户的自然语言输入并转换为结构化的系统指令。
|
|||
|
|
|
|||
|
|
可用的指令类型:
|
|||
|
|
${JSON.stringify(availableCommands, null, 2)}
|
|||
|
|
|
|||
|
|
你的任务:
|
|||
|
|
1. 理解用户输入的意图
|
|||
|
|
2. 从可用指令中选择最匹配的action
|
|||
|
|
3. 提取用户输入中的参数值
|
|||
|
|
4. 返回JSON格式的结构化指令
|
|||
|
|
|
|||
|
|
返回格式(必须是有效的JSON,不要有任何其他文字):
|
|||
|
|
{
|
|||
|
|
"action": "指令名称",
|
|||
|
|
"params": {
|
|||
|
|
"参数名": "参数值"
|
|||
|
|
},
|
|||
|
|
"confidence": 0.9,
|
|||
|
|
"reasoning": "简短说明"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
如果无法识别用户意图,返回:
|
|||
|
|
{
|
|||
|
|
"action": null,
|
|||
|
|
"confidence": 0,
|
|||
|
|
"reasoning": "无法理解用户意图"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
示例:
|
|||
|
|
用户输入:"打开张三的报告"
|
|||
|
|
返回:{"action":"goReport","params":{"keyword":"张三"},"confidence":0.95,"reasoning":"用户想查看张三的报告"}
|
|||
|
|
|
|||
|
|
重要:只返回JSON,不要有markdown代码块,不要有任何其他文字。`
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
console.log('AI意图识别:开始解析用户输入:', userInput)
|
|||
|
|
|
|||
|
|
const messages = [
|
|||
|
|
{ role: 'system', content: systemPrompt },
|
|||
|
|
{ role: 'user', content: userInput }
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
const result = await this.callBailianChat({
|
|||
|
|
model: llmCfg.model,
|
|||
|
|
apiUrl: llmCfg.apiUrl,
|
|||
|
|
apiKey: llmCfg.apiKey,
|
|||
|
|
messages,
|
|||
|
|
temperature: 0.1,
|
|||
|
|
max_tokens: 500
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
let content = ''
|
|||
|
|
if (result && result.choices && result.choices[0] && result.choices[0].message) {
|
|||
|
|
content = result.choices[0].message.content
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('AI意图识别:原始响应:', content)
|
|||
|
|
|
|||
|
|
// 检查是否有内容
|
|||
|
|
if (!content || !content.trim()) {
|
|||
|
|
console.log('AI意图识别:响应为空')
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 提取JSON
|
|||
|
|
let jsonStr = content.trim()
|
|||
|
|
|
|||
|
|
// 移除markdown代码块
|
|||
|
|
jsonStr = jsonStr.replace(/```(?:json)?\s*/g, '').replace(/```\s*/g, '')
|
|||
|
|
|
|||
|
|
// 提取第一个完整的JSON对象
|
|||
|
|
const jsonMatch = jsonStr.match(/\{[\s\S]*?\}/)
|
|||
|
|
if (jsonMatch) {
|
|||
|
|
jsonStr = jsonMatch[0]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('AI意图识别:提取的JSON字符串:', jsonStr)
|
|||
|
|
|
|||
|
|
// 解析JSON
|
|||
|
|
let intent = null
|
|||
|
|
try {
|
|||
|
|
intent = JSON.parse(jsonStr)
|
|||
|
|
} catch (parseError) {
|
|||
|
|
console.error('AI意图识别:JSON解析失败', parseError.message)
|
|||
|
|
console.log('尝试解析的字符串:', jsonStr.substring(0, 200))
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('AI意图识别:解析结果:', intent)
|
|||
|
|
|
|||
|
|
// 验证intent结构
|
|||
|
|
if (!intent || typeof intent !== 'object') {
|
|||
|
|
console.log('AI意图识别:intent不是对象')
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 验证置信度
|
|||
|
|
const confidence = parseFloat(intent.confidence)
|
|||
|
|
if (isNaN(confidence) || confidence < 0.6) {
|
|||
|
|
console.log('AI意图识别:置信度过低或无效', confidence)
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return intent
|
|||
|
|
} catch (e) {
|
|||
|
|
console.error('AI意图识别失败:', e.message || e)
|
|||
|
|
console.error('错误堆栈:', e.stack)
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
}
|