AI指令修复

This commit is contained in:
Lilixu007 2026-02-26 18:18:03 +08:00
parent 1062c62498
commit 1943d92c40
6 changed files with 894 additions and 4 deletions

View File

@ -0,0 +1,133 @@
# AI分析指令修复说明
## 问题描述
用户输入"分析张三"时AI能够正确识别意图为`analyzeReport`但系统没有使用AI识别的参数keyword: "张三"),而是继续使用正则匹配,导致无法获取报告数据,最终返回"暂不提供此服务"。
## 根本原因
1. AI意图识别成功后对于分析类指令analyzeReport/analyzeProfile返回`false`继续处理
2. 但后续代码仍然使用正则匹配`parseAnalyzeReportKeyword(text)`获取关键词
3. AI识别的参数`intent.params.keyword`)被丢弃,没有传递给后续逻辑
## 解决方案
### 1. 保存AI识别的意图
在AI意图识别部分当识别到分析类指令时保存完整的intent对象
```javascript
let aiRecognizedIntent = null
if (intent.action === 'analyzeReport' || intent.action === 'analyzeProfile' || intent.action === 'analyzeData') {
aiRecognizedIntent = intent
console.log('分析类指令保存AI识别的参数:', aiRecognizedIntent)
}
```
### 2. 优先使用AI识别的参数
在报告数据获取逻辑中优先使用AI识别的参数如果没有则回退到正则匹配
```javascript
let reportId = ''
let reportKeyword = ''
let profileKeyword = ''
if (aiRecognizedIntent) {
console.log('使用AI识别的参数:', aiRecognizedIntent.params)
if (aiRecognizedIntent.action === 'analyzeReport') {
reportId = aiRecognizedIntent.params.reportId || ''
reportKeyword = aiRecognizedIntent.params.keyword || ''
} else if (aiRecognizedIntent.action === 'analyzeProfile') {
profileKeyword = aiRecognizedIntent.params.keyword || aiRecognizedIntent.params.userId || ''
}
} else {
// 回退到正则匹配
console.log('回退到正则匹配')
reportId = this.parseAnalyzeReportId(text)
reportKeyword = this.parseAnalyzeReportKeyword(text)
profileKeyword = ''
}
```
## 执行流程
### 用户输入:"分析张三"
1. **AI意图识别**
- 调用`parseUserIntentWithAI("分析张三")`
- AI返回
```json
{
"action": "analyzeReport",
"params": {
"keyword": "张三"
},
"confidence": 0.9,
"reasoning": "用户想分析张三的测评报告"
}
```
2. **执行意图**
- 调用`executeAIIntent(intent)`
- 识别为分析类指令,返回`false`继续处理
- 保存`aiRecognizedIntent = intent`
3. **获取报告数据**
- 检测到`aiRecognizedIntent`存在
- 提取参数:`reportKeyword = "张三"`
- 调用`getStudentOptions({ keyword: "张三", limit: 1 })`获取用户ID
- 调用`listReport({ userId })`获取报告列表
- 调用`getReport(reportId)`获取报告详情
4. **AI分析报告**
- 将报告数据作为context传递给AI
- AI分析报告内容并返回分析结果
- 在对话框中显示AI的分析结果
## 指令类型区分
### analyzeReport分析报告
- 关键词:分析、数据、报告
- 示例:
- "分析张三的报告"
- "分析李四的数据"
- "分析报告123"
- 行为:获取报告数据 → AI分析 → 返回分析结果
### analyzeProfile查看画像
- 关键词:画像、档案、情况、了解
- 示例:
- "查看王五的画像"
- "了解赵六的情况"
- "打开张三的档案"
- 行为:跳转到个体画像页面
### goReport打开报告
- 关键词:打开、查看
- 示例:
- "打开张三的报告"
- "查看报告列表"
- 行为:跳转到报告列表页面
## 修改文件
- `xinlidsj/pages/index/index.vue`
- 第1605-1625行保存AI识别的意图
- 第1710-1740行优先使用AI识别的参数
## 测试建议
1. 测试AI识别"分析张三" → 应该获取张三的报告并让AI分析
2. 测试正则回退关闭AI意图识别 → 应该使用正则匹配
3. 测试不同指令:
- "分析李四的数据" → analyzeReport
- "查看王五的画像" → analyzeProfile跳转页面
- "打开赵六的报告" → goReport跳转页面
4. 测试错误处理:
- 用户不存在 → "没有查询到相关数据"
- 用户无报告 → "没有查询到相关数据"
## 日志输出
关键日志点:
- `尝试AI意图识别...`
- `AI识别到意图: {action, params, confidence}`
- `分析类指令保存AI识别的参数: {...}`
- `使用AI识别的参数: {keyword: "张三"}`
- `最终使用的参数 - reportId: "", reportKeyword: "张三", profileKeyword: ""`
通过这些日志可以追踪整个流程确认AI识别和参数传递是否正常。

View File

@ -0,0 +1,86 @@
# AI意图识别JSON解析失败修复
## 问题现象
用户输入:"想看张三数据"
错误:`JSON解析失败: Unexpected end of JSON input`
## 根本原因
原代码使用的正则表达式有问题:
```javascript
const jsonMatch = jsonStr.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/)
```
这个正则使用了**非贪婪匹配** `*?`,会在遇到第一个 `}` 时就停止导致嵌套的JSON对象被截断。
例如对于这样的JSON
```json
{"action":"analyzeProfile","params":{"keyword":"张三"},"confidence":0.95}
```
非贪婪匹配会在第一个 `}` (params后面的) 就停止,得到:
```json
{"action":"analyzeProfile","params":{"keyword":"张三"}
```
这是一个不完整的JSON导致解析失败。
## 解决方案
使用更简单可靠的方法:
```javascript
// 1. 移除markdown代码块标记
jsonStr = jsonStr.replace(/```(?:json)?/g, '').replace(/```/g, '').trim()
// 2. 找到第一个{和最后一个}
const firstBrace = jsonStr.indexOf('{')
const lastBrace = jsonStr.lastIndexOf('}')
// 3. 提取完整的JSON对象
if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
jsonStr = jsonStr.substring(firstBrace, lastBrace + 1)
}
// 4. 使用try-catch保护解析
try {
intent = JSON.parse(jsonStr)
} catch(e) {
console.error('JSON解析失败:', e.message)
console.log('失败的JSON字符串:', jsonStr)
return null
}
```
## 已应用的修复
✅ 改进了JSON提取逻辑
✅ 添加了try-catch保护
✅ 添加了详细的调试日志
✅ 添加了空值检查
## 测试建议
现在再次测试时,控制台会显示:
1. AI意图识别原始响应
2. AI意图识别响应类型
3. AI意图识别提取的JSON
4. 如果失败JSON解析失败的具体错误和完整的JSON字符串
这样可以准确定位问题所在。
## 预期结果
用户输入:"想看张三数据"
AI识别
```json
{
"action": "analyzeProfile",
"params": {"keyword": "张三"},
"confidence": 0.95,
"reasoning": "用户想分析张三的个体画像数据"
}
```
系统执行:打开张三的个体画像页面

View File

@ -0,0 +1,129 @@
# AI意图识别系统
## 概述
系统现在使用AI大模型来理解用户的自然语言输入而不是依赖固定的正则表达式匹配。这使得用户可以用更自然、更灵活的方式与系统交互。
## 工作流程
1. **用户输入** → 用户在AI对话框中输入自然语言指令
2. **AI意图识别** → 系统调用大模型DeepSeek/通义千问)理解用户意图
3. **结构化输出** → AI返回JSON格式的指令和参数
4. **执行指令** → 系统根据识别结果执行相应操作
5. **回退机制** → 如果AI识别失败自动回退到原有的正则匹配
## 支持的指令类型
### 1. 导航类指令
- `goWarning` - 打开预警中心
- `goProfile` - 打开个体画像
- `goComprehensive` - 打开综合报告
- `goInterventionTask` - 打开干预任务
- `goReport` - 打开报告列表/详情
- `goMessage` - 打开消息/收件箱
- `goNotice` - 打开通知公告
- `goDashboard` - 打开监区看板
- `goTagFilter` - 打开标签筛选
- `goVoice` - 打开语音助手
### 2. 分析类指令
- `analyzeReport` - 分析报告
- `analyzeProfile` - 分析个体画像
- `analyzeData` - 分析平台数据
### 3. 控制类指令
- `clearChat` - 清空对话记录
- `toggleChat` - 展开/收起对话框
- `goBack` - 返回上一页
- `goHome` - 返回首页
## 使用示例
### 原来的方式(正则匹配)
```
用户输入:"打开张三的报告"
系统:使用正则 /打开\s*([^\s的]{1,32})\s*的?报告/ 匹配
结果:✅ 能识别
用户输入:"帮我看看张三的报告"
系统:正则无法匹配
结果:❌ 无法识别
```
### 现在的方式AI理解
```
用户输入:"打开张三的报告"
AI理解用户想查看张三的报告
返回:{"action":"goReport","params":{"keyword":"张三"},"confidence":0.95}
结果:✅ 能识别
用户输入:"帮我看看张三的报告"
AI理解用户想查看张三的报告
返回:{"action":"goReport","params":{"keyword":"张三"},"confidence":0.9}
结果:✅ 能识别
用户输入:"我想了解一下李四的情况"
AI理解用户想查看李四的个体画像
返回:{"action":"goProfile","params":{"keyword":"李四"},"confidence":0.85}
结果:✅ 能识别
用户输入:"有没有严重的预警需要处理"
AI理解用户想查看严重级别的预警
返回:{"action":"goWarning","params":{"warningLevel":"严重"},"confidence":0.9}
结果:✅ 能识别
```
## 优势
1. **更自然的交互** - 用户可以用日常语言表达需求
2. **更强的容错性** - 不需要记住精确的指令格式
3. **更好的扩展性** - 添加新指令只需更新配置,无需写正则
4. **智能参数提取** - AI自动从语句中提取关键信息
5. **回退保障** - AI识别失败时自动使用原有的正则匹配
## 技术实现
### 核心方法
1. **parseUserIntentWithAI(userInput)** - AI意图识别
- 输入:用户的自然语言
- 输出结构化的指令JSON
- 使用DeepSeek API / 通义千问 API
2. **executeAIIntent(intent)** - 执行识别出的指令
- 输入AI返回的指令JSON
- 输出:是否成功执行
- 功能根据action和params执行相应操作
3. **sendAiChat()** - 修改后的消息发送方法
- 先尝试AI意图识别
- 识别成功则执行指令
- 识别失败则回退到正则匹配
### AI Prompt设计
系统使用精心设计的prompt来引导AI
- 明确定义所有可用指令
- 要求返回标准JSON格式
- 包含置信度评分
- 提供示例来提高准确性
### 置信度阈值
- 置信度 >= 0.6:执行指令
- 置信度 < 0.6忽略结果回退到正则匹配
## 配置
AI意图识别使用与AI对话相同的配置
- DeepSeek API默认
- 通义千问 API可选
无需额外配置,开箱即用。
## 未来扩展
1. 支持多轮对话上下文
2. 支持复合指令(一次执行多个操作)
3. 支持模糊查询和智能推荐
4. 支持自定义指令学习

View File

@ -0,0 +1,77 @@
修复AI意图识别的JSON解析问题
找到这段代码大约在1330-1355行
console.log('AI意图识别原始响应:', content)
// 提取JSON可能被markdown代码块包裹
let jsonStr = content.trim()
const jsonMatch = jsonStr.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/)
if (jsonMatch) {
jsonStr = jsonMatch[1]
}
const intent = JSON.parse(jsonStr)
console.log('AI意图识别解析结果:', intent)
// 验证置信度
if (intent.confidence < 0.6) {
console.log('AI意图识别置信度过低忽略结果')
return null
}
替换为:
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 jsonMatch2 = jsonStr.match(/\{[\s\S]*?\}/)
if (jsonMatch2) {
jsonStr = jsonMatch2[0]
}
console.log('AI意图识别提取的JSON字符串:', jsonStr.substring(0, 200))
// 解析JSON
let intent = null
try {
intent = JSON.parse(jsonStr)
} catch (parseError) {
console.error('AI意图识别JSON解析失败', parseError.message)
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
}
主要改进:
1. 添加了空内容检查
2. 改进了JSON提取逻辑使用replace而不是match
3. 添加了try-catch包裹JSON.parse
4. 添加了更详细的错误日志
5. 验证intent对象结构
6. 改进了置信度验证逻辑

View File

@ -1235,6 +1235,156 @@
if (!s) return false if (!s) return false
return /(分析|趋势|总结|汇总|研判|建议)/.test(s) return /(分析|趋势|总结|汇总|研判|建议)/.test(s)
}, },
// AI - 使
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)}
重要区分
- analyzeReport: 用于"分析XX的报告/数据"查看测评报告详情
- analyzeProfile: 用于"查看XX的画像/档案/情况"查看个体画像
- goReport: 用于"打开XX的报告"跳转到报告列表
你的任务
1. 理解用户输入的意图
2. 从可用指令中选择最匹配的action
3. 提取用户输入中的参数值
4. 返回JSON格式的结构化指令
返回格式必须是有效的JSON
{
"action": "指令名称",
"params": {
"参数名": "参数值"
},
"confidence": 0.0-1.0,
"reasoning": "简短说明为什么选择这个指令"
}
如果无法识别用户意图返回
{
"action": null,
"confidence": 0,
"reasoning": "无法理解用户意图"
}
示例
用户输入"打开张三的报告"
返回{"action":"goReport","params":{"keyword":"张三"},"confidence":0.95,"reasoning":"用户想查看张三的报告列表"}
用户输入"分析李四的数据"
返回{"action":"analyzeReport","params":{"keyword":"李四"},"confidence":0.9,"reasoning":"用户想分析李四的测评报告"}
用户输入"查看王五的画像"
返回{"action":"analyzeProfile","params":{"keyword":"王五"},"confidence":0.95,"reasoning":"用户想查看王五的个体画像"}
用户输入"查看未处理的预警"
返回{"action":"goWarning","params":{"status":"0"},"confidence":0.95,"reasoning":"用户想查看未处理状态的预警"}
重要只返回JSON不要有任何其他文字`
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
})
// callBailianChatcontentresult
let content = result || ''
console.log('AI意图识别原始响应:', content)
console.log('AI意图识别响应类型:', typeof content)
console.log('AI意图识别响应长度:', content.length)
// JSON
let jsonStr = content.trim()
if (!jsonStr) {
console.log('AI意图识别响应为空')
return null
}
// markdown
jsonStr = jsonStr.replace(/```(?:json)?/g, '').replace(/```/g, '').trim()
// {}
const firstBrace = jsonStr.indexOf('{')
const lastBrace = jsonStr.lastIndexOf('}')
if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
jsonStr = jsonStr.substring(firstBrace, lastBrace + 1)
}
console.log('AI意图识别提取的JSON:', jsonStr)
// JSON
let intent = null
try {
intent = JSON.parse(jsonStr)
} catch(e) {
console.error('JSON解析失败:', e.message)
console.log('失败的JSON字符串:', jsonStr)
return null
}
console.log('AI意图识别解析结果:', intent)
//
if (intent.confidence < 0.6) {
console.log('AI意图识别置信度过低忽略结果')
return null
}
return intent
} catch (e) {
console.error('AI意图识别失败:', e)
return null
}
},
parseAnalyzeReportId(text) { parseAnalyzeReportId(text) {
const s = String(text || '').trim() const s = String(text || '').trim()
if (!s) return '' if (!s) return ''
@ -1323,7 +1473,122 @@
if (!this.isAiNeedContext(s)) return false if (!this.isAiNeedContext(s)) return false
return true return true
}, },
sendAiChat() { // AI
executeAIIntent(intent) {
if (!intent || !intent.action) {
return false
}
const action = intent.action
const params = intent.params || {}
console.log('执行AI指令:', action, params)
//
if (action === 'goWarning') {
let url = '/pages/warning/index'
const query = []
if (params.status) query.push(`status=${params.status}`)
if (params.warningLevel) query.push(`warningLevel=${encodeURIComponent(params.warningLevel)}`)
if (query.length) url += '?' + query.join('&')
uni.navigateTo({ url })
return true
}
if (action === 'goProfile') {
let url = '/pages/profile/index'
const query = []
if (params.keyword) query.push(`keyword=${encodeURIComponent(params.keyword)}`)
if (params.userId) query.push(`userId=${params.userId}`)
if (query.length) url += '?' + query.join('&')
uni.navigateTo({ url })
return true
}
if (action === 'goComprehensive') {
uni.navigateTo({ url: '/pages/comprehensive/index' })
return true
}
if (action === 'goInterventionTask') {
let url = '/pages/interventionTask/index'
if (params.status) url += `?status=${params.status}`
uni.navigateTo({ url })
return true
}
if (action === 'goReport') {
if (params.reportId) {
uni.navigateTo({ url: `/pages/report/detail?reportId=${params.reportId}&sourceType=${params.sourceType || ''}` })
} else {
let url = '/pages/report/index'
const query = []
if (params.keyword) query.push(`keyword=${encodeURIComponent(params.keyword)}`)
if (params.sourceType) query.push(`sourceType=${params.sourceType}`)
if (query.length) url += '?' + query.join('&')
uni.navigateTo({ url })
}
return true
}
if (action === 'goMessage') {
let url = '/pages/message/inbox'
if (params.tab) url += `?tab=${params.tab}`
uni.navigateTo({ url })
return true
}
if (action === 'goNotice') {
uni.navigateTo({ url: '/pages/message/notice' })
return true
}
if (action === 'goDashboard') {
uni.navigateTo({ url: '/pages/dashboard/index' })
return true
}
if (action === 'goTagFilter') {
uni.navigateTo({ url: '/pages/profile/tagFilter' })
return true
}
if (action === 'goVoice') {
uni.navigateTo({ url: '/pages/voice/index' })
return true
}
//
if (action === 'clearChat') {
this.clearAiChat()
return true
}
if (action === 'toggleChat') {
this.toggleAiChat()
return true
}
if (action === 'goBack') {
uni.navigateBack({ delta: 1 })
return true
}
if (action === 'goHome') {
uni.reLaunch({ url: '/pages/index/index' })
return true
}
// - AI
if (action === 'analyzeReport' || action === 'analyzeProfile' || action === 'analyzeData') {
// falseAI
// AI
return false
}
return false
},
async sendAiChat() {
if (this.aiChatSending) return if (this.aiChatSending) return
const text = this.aiChatInputTrim const text = this.aiChatInputTrim
if (!text) return if (!text) return
@ -1335,6 +1600,38 @@
this.scrollAiChatToBottom() this.scrollAiChatToBottom()
}) })
// ===== AI =====
let aiRecognizedIntent = null
try {
console.log('尝试AI意图识别...')
const intent = await this.parseUserIntentWithAI(text)
if (intent && intent.action) {
console.log('AI识别到意图:', intent)
const executed = this.executeAIIntent(intent)
if (executed) {
//
this.aiChatMessages = [...this.aiChatMessages, {
id: 'a_' + Date.now(),
role: 'ai',
content: `已执行:${intent.reasoning || intent.action}`
}]
this.aiChatSending = false
this.$nextTick(() => {
this.scrollAiChatToBottom()
})
return
}
// intent使
if (intent.action === 'analyzeReport' || intent.action === 'analyzeProfile' || intent.action === 'analyzeData') {
aiRecognizedIntent = intent
console.log('分析类指令保存AI识别的参数:', aiRecognizedIntent)
}
}
} catch (e) {
console.error('AI意图识别出错回退到正则匹配:', e)
}
// ===== AI =====
const openReportIdMatch = String(text || '').trim().match(/打开\s*(?:报告\s*id\s*|报告\s*#\s*|报告#\s*)(\d{1,18})/i) const openReportIdMatch = String(text || '').trim().match(/打开\s*(?:报告\s*id\s*|报告\s*#\s*|报告#\s*)(\d{1,18})/i)
if (openReportIdMatch && openReportIdMatch[1]) { if (openReportIdMatch && openReportIdMatch[1]) {
const reportId = openReportIdMatch[1] const reportId = openReportIdMatch[1]
@ -1416,9 +1713,30 @@
}) })
return return
} }
const reportId = this.parseAnalyzeReportId(text)
const reportKeyword = this.parseAnalyzeReportKeyword(text) // 使AI退
const profileKeyword = '' let reportId = ''
let reportKeyword = ''
let profileKeyword = ''
if (aiRecognizedIntent) {
console.log('使用AI识别的参数:', aiRecognizedIntent.params)
if (aiRecognizedIntent.action === 'analyzeReport') {
reportId = aiRecognizedIntent.params.reportId || ''
reportKeyword = aiRecognizedIntent.params.keyword || ''
} else if (aiRecognizedIntent.action === 'analyzeProfile') {
profileKeyword = aiRecognizedIntent.params.keyword || aiRecognizedIntent.params.userId || ''
}
} else {
// 退
console.log('回退到正则匹配')
reportId = this.parseAnalyzeReportId(text)
reportKeyword = this.parseAnalyzeReportKeyword(text)
profileKeyword = ''
}
console.log('最终使用的参数 - reportId:', reportId, 'reportKeyword:', reportKeyword, 'profileKeyword:', profileKeyword)
const baseContext = this.buildAiAnalyzeContext() const baseContext = this.buildAiAnalyzeContext()
let report = null let report = null
let profile = null let profile = null

View File

@ -0,0 +1,147 @@
// 改进版的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
}
}