首次提交:上传本地文件夹
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
from typing import List, Dict, Any
|
||||
# from llm import llm as llm_model
|
||||
from utils.llm import search_llm as llm_model
|
||||
from utils.prompt import RESPONSE_TEMPLATE
|
||||
import time
|
||||
import logging
|
||||
import sys
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=[logging.StreamHandler(sys.stdout)]
|
||||
)
|
||||
logger = logging.getLogger("ResponseGenerator")
|
||||
|
||||
class ResponseGenerator:
|
||||
def __init__(self):
|
||||
"""初始化响应生成器,使用自定义的llm模型"""
|
||||
logger.info("ResponseGenerator初始化完成")
|
||||
|
||||
def generate_response(self, query: str, retrieved_info: List[Dict[str, Any]], nlu_data: Dict = None) -> str:
|
||||
"""
|
||||
生成响应
|
||||
|
||||
参数:
|
||||
query: 用户查询
|
||||
retrieved_info: 检索到的信息
|
||||
nlu_data: 意图识别和槽位提取的结果
|
||||
|
||||
返回:
|
||||
生成的响应
|
||||
"""
|
||||
# 如果没有检索到信息,返回默认回答
|
||||
if not retrieved_info:
|
||||
logger.warning("没有检索到相关信息,返回默认回答")
|
||||
return "抱歉,我没有找到与您问题相关的信息。请尝试使用其他关键词或更具体的问题。"
|
||||
|
||||
# 构建提示
|
||||
logger.info("开始构建提示")
|
||||
prompt = self._build_prompt(query, retrieved_info, nlu_data)
|
||||
logger.info(f"提示构建完成,长度: {len(prompt)}")
|
||||
|
||||
# 调用自定义LLM模型生成回答
|
||||
logger.info("开始调用LLM模型生成回答")
|
||||
start_time = time.time()
|
||||
|
||||
try:
|
||||
# 添加超时处理
|
||||
response = llm_model.invoke(prompt)
|
||||
logger.info(f"LLM响应完成,耗时: {time.time() - start_time:.2f}秒")
|
||||
|
||||
# 检查响应是否为空
|
||||
if not response or not response.strip():
|
||||
logger.error("LLM返回了空响应")
|
||||
return "抱歉,生成回答时出现了问题。请稍后再试。"
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"调用LLM模型时出错: {str(e)}")
|
||||
return f"抱歉,生成回答时出现了错误: {str(e)}"
|
||||
|
||||
def _build_prompt(self, query: str, retrieved_info: List[Dict[str, Any]], nlu_data: Dict = None) -> str:
|
||||
"""
|
||||
构建提示
|
||||
|
||||
参数:
|
||||
query: 用户查询
|
||||
retrieved_info: 检索到的信息
|
||||
nlu_data: 意图识别和槽位提取的结果
|
||||
|
||||
返回:
|
||||
构建的提示
|
||||
"""
|
||||
context_parts = []
|
||||
|
||||
for info in retrieved_info:
|
||||
node = info.get("node", {})
|
||||
text = info.get("text", "")
|
||||
|
||||
node_type = node.get("labels", [""])[0] if "labels" in node else ""
|
||||
name = node.get("original_name", "") or node.get("display_name", "")
|
||||
description = node.get("描述", "")
|
||||
|
||||
if node_type == "功能名称":
|
||||
context_parts.append(f"功能: {name}\n描述: {description}")
|
||||
else:
|
||||
context_parts.append(f"{node_type}: {name}")
|
||||
|
||||
context = "\n\n".join(context_parts)
|
||||
|
||||
# 添加意图和槽位信息
|
||||
intent_info = ""
|
||||
if nlu_data and '意图' in nlu_data:
|
||||
intent_data = nlu_data['意图']
|
||||
|
||||
# 获取一级意图
|
||||
first_intent = "未知"
|
||||
if '一级意图' in intent_data and 'name' in intent_data['一级意图']:
|
||||
first_intent = intent_data['一级意图']['name']
|
||||
|
||||
# 获取二级意图
|
||||
second_intent = "未知"
|
||||
if '二级意图' in intent_data and 'name' in intent_data['二级意图']:
|
||||
second_intent = intent_data['二级意图']['name']
|
||||
|
||||
intent_info = f"用户一级意图: {first_intent}\n用户二级意图: {second_intent}\n"
|
||||
|
||||
# 添加槽位信息
|
||||
if '二级意图' in intent_data and 'slot_lv2' in intent_data['二级意图']:
|
||||
slots = intent_data['二级意图']['slot_lv2']
|
||||
if slots:
|
||||
intent_info += "提取的槽位:\n"
|
||||
for slot_name, slot_value in slots.items():
|
||||
if slot_value and slot_value != '未知':
|
||||
intent_info += f"- {slot_name}: {slot_value}\n"
|
||||
|
||||
prompt = RESPONSE_TEMPLATE.format(
|
||||
intent_info=intent_info,
|
||||
context=context,
|
||||
query=query
|
||||
)
|
||||
|
||||
return prompt
|
||||
Reference in New Issue
Block a user