优化对话转工单处理逻辑,调整LLM参数,增强用户问题和解决方案的提取功能,添加槽位填充支持,提升代码结构和可读性。

This commit is contained in:
2025-05-30 11:10:24 +08:00
parent 05caedc4fa
commit d4ff7b6fad
6 changed files with 469 additions and 123 deletions
+41 -46
View File
@@ -89,7 +89,7 @@ class DialogueToWorkorder:
# 初始化LLM模型
self.llm_params = llm_params or {
"temperature": 0.6,
"temperature": 0.2,
"model": os.getenv("LLM_MODEL_NAME"),
"api_key": os.getenv("OPENAI_API_KEY"),
"base_url": os.getenv("OPENAI_API_BASE")
@@ -207,37 +207,43 @@ class DialogueToWorkorder:
"""分析用户问题和解决方案"""
dialogue_str = self.get_dialogue_str(conversation_rows)
prompt = f"""
请从以下电力造价相关的客服对话记录中,精准提取用户提出的专业问题及对应坐席提供的解决方案。要求:
prompt = """请从以下电力造价相关的客服对话记录中,识别并精准提取用户提出的问题及对应坐席提供的解决方案。
1、理解对话记录,识别用户在此次对话中提出的诉求
2、根据用户提出的诉求,分析坐席提供的解决方法
3、使用json格式输出:
{output_format}
1. 专业识别
- 重点识别电力工程领域的专业术语(如:定额套用、工程量清单、概预算编制、造价指标分析等)
- 注意区分不同业务场景(输变电工程、配网改造、新能源项目等)
- 识别政策文件引用(如:国网Q/GDW 11337-2014标准)
输出示例
{{
"user_question": "软件打开报错",
"solution": "通过远程引导解决"
}}
2. 信息提取:
用户问题提取:
- 核心诉求(成本核算/计价争议/软件操作等)
- 涉及的专业环节(设计概算/施工图预算/竣工结算)
- 具体技术参数(电压等级/线路长度/设备型号)
坐席解决方案提取:
- 提供的计算方法(单位工程法/实物量法)
- 推荐的计价依据(电力建设工程定额2018版)
- 指导的软件操作步骤(博微软件操作)
- 政策法规应用建议
- 文件模板提供情况
3. 结构化输出:
{self.user_question_and_solution_list_parser.get_format_instructions()}
访客与坐席的对话记录如下:
=======对话记录如下所示=======
{dialogue_str}
============================
"""
output_format = self.user_question_and_solution_parser.get_format_instructions()
llm_prompt = prompt.format(output_format=output_format, dialogue_str=dialogue_str)
response = self.llm.invoke(user_prompt=prompt)
user_question_and_solution_list = self.user_question_and_solution_list_parser.parse(response.content)
response = self.llm.invoke(user_prompt=llm_prompt)
if 'reasoning_content' not in response.model_extra and self.llm._model == 'deepseek-ai/DeepSeek-R1':
print("deepseek-ai/DeepSeek-R1 解析失败")
return user_question_and_solution_list.user_question_list
try:
if response.content.count('user_question') == 1:
user_question_and_solution = self.user_question_and_solution_parser.parse(response.content)
return [user_question_and_solution]
else:
raise Exception("解析失败")
except Exception as e:
output_format = self.user_question_and_solution_list_parser.get_format_instructions()
llm_prompt = prompt.format(output_format=output_format, dialogue_str=dialogue_str)
response = self.llm.invoke(user_prompt=llm_prompt)
user_question_and_solution = self.user_question_and_solution_list_parser.parse(response.content)
return user_question_and_solution.user_question_list
return [user_question_and_solution]
@retry_llm_call(max_retries=3, delay=2)
def get_product_name_and_module_name(self, product_line, conversation_rows, product_detail_dict, user_question_str, solution_str):
@@ -343,16 +349,14 @@ class DialogueToWorkorder:
prompt = f"""
请根据以下对话记录分析访客情绪是否对博微软件或者坐席服务存在明显抱怨,并按照以下结构输出JSON格式分析结果:
1. 抱怨识别:判断访客是否对博微软件功能或者坐席服务存在明显抱怨语气或词语
1. 抱怨识别:判断访客是否对博微软件功能或者坐席服务存在**明显抱怨语气或词语**
2. 抱怨分级(如存在抱怨):
- 一般抱怨:对博微软件功者坐席服务存在轻微不满但情绪稳定
- 中等抱怨:对博微软件或者坐席服务明确表达不满并提出具体问题
- 严重抱怨:对博微软件或者坐席服务使用激烈言辞或威胁性语言
- 抗议行为:明确表示投诉/退费/法律手段
- 一般抱怨:明确提出对博微软件功能或者坐席服务存在不满
- 中等抱怨:明确提出对博微软件功能或者坐席服务存在不满,语气较为强烈
- 严重抱怨:对博微软件功能或者坐席服务使用激烈言辞或威胁性语言
3. 投诉倾向:是否明确/暗示将进行投诉
4. 抱怨对象:坐席服务态度/业务能力 或 博微功能问题(注意忽略对非博微软件或坐席的抱怨)
5. 内容摘录:标注具体抱怨语句
6. 分析理由:结合语义与上下文的判断依据
示例输出:
{{
@@ -387,13 +391,13 @@ class DialogueToWorkorder:
"""处理单个会话的函数,用于多线程并发"""
# 获取工单基本信息
workorder_dict = self.get_workorder_dict(conversation_rows)
# 分析用户问题和解决方案
user_question_list = self.get_user_question_and_solution(conversation_rows)
# 分析是否抱怨、是否投诉、抱怨级别
is_dissatisfaction, dissatisfaction_level, dissatisfaction_reasoning, is_complaint = (
self.get_is_complaint_and_is_complaint_level(conversation_rows))
# 分析用户问题和解决方案
user_question_list = self.get_user_question_and_solution(conversation_rows)
for user_question in user_question_list:
user_question_str = user_question.user_question
solution_str = user_question.solution
@@ -554,18 +558,9 @@ def main():
# 设置默认文件路径
conversation_excel_path = args.conversation_file or os.path.join('data', 'excel', '会话内容详情20250528110230.xlsx')
product_detail_excel_path = args.product_detail_file or os.path.join('data', 'excel', '产品详情_工单.xlsx')
output_file = args.output_file
# 配置LLM参数
llm_params = {
"temperature": args.temperature,
"model": args.model_name or os.getenv("LLM_MODEL_NAME"),
"api_key": os.getenv("OPENAI_API_KEY"),
"base_url": os.getenv("OPENAI_API_BASE")
}
# 创建处理实例
processor = DialogueToWorkorder(llm_params=llm_params)
processor = DialogueToWorkorder()
# 分析会话数据
workorder_dict_list = processor.analyze_conversation_data(
@@ -573,7 +568,7 @@ def main():
product_detail_excel_path,
max_workers=args.max_workers
)
output_file = conversation_excel_path.replace('.xlsx', '_转工单.xlsx')
# 保存结果
processor.save_results_to_excel(workorder_dict_list, output_file)