324 lines
11 KiB
Python
324 lines
11 KiB
Python
"""
|
||
===================================
|
||
@Auther:WenZ
|
||
@Company: BooWay
|
||
@project:booway_dm
|
||
===================================
|
||
"""
|
||
|
||
|
||
# from langchain_community.chat_models import ChatOpenAI
|
||
from langchain_openai import ChatOpenAI
|
||
from langchain_core.output_parsers import StrOutputParser
|
||
from langchain_core.prompts import ChatPromptTemplate
|
||
from langchain_core.prompts.prompt import PromptTemplate
|
||
from langchain_core.output_parsers import JsonOutputParser
|
||
|
||
|
||
# qwen_llm = ChatOpenAI(model='deepseek-qwen2.5-32b',base_url="http://172.20.0.145:9995/v1/",api_key='233',temperature=1)
|
||
|
||
# temperature=0.7
|
||
qwen_llm = ChatOpenAI(
|
||
openai_api_base="https://api.siliconflow.cn/v1",
|
||
model_name="Qwen/Qwen2.5-72B-Instruct",
|
||
# sk-muuqautpcyuowjtgfecbnivqodlhzydtfslqkmwbknawejsx
|
||
openai_api_key="sk-bbeamiumkouptsrueilgufqqyuumelcsivxwjbdugqwsqhwj",
|
||
temperature=0.1
|
||
)
|
||
|
||
deep_v3 = ChatOpenAI(
|
||
openai_api_base="https://api.siliconflow.cn/v1",
|
||
model_name="deepseek-ai/DeepSeek-V3",
|
||
# sk-muuqautpcyuowjtgfecbnivqodlhzydtfslqkmwbknawejsx
|
||
openai_api_key="sk-bbeamiumkouptsrueilgufqqyuumelcsivxwjbdugqwsqhwj",
|
||
temperature=0.1
|
||
)
|
||
|
||
|
||
def suffix_answers():
|
||
PromptTemplate1 = """
|
||
根据用户输入和相关知识回答问题
|
||
|
||
# 用户输入
|
||
{query}
|
||
|
||
# 相关知识
|
||
{kg}
|
||
|
||
# 注意:
|
||
- 每次回答和核心意思是:'此后缀名文件用某某或哪些软件打开'
|
||
- 对于相关知识中有多个软件的要全部回答
|
||
- 不要有过多解释,仅仅根据kg回答即可
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | qwen_llm | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
# 关于下载安装
|
||
# 查询功能(询问软件功能或用途):【新型储能计价通C1】可以做批次工程吗
|
||
# 后缀名问题(专属子意图)
|
||
# 操作指导(询问具体使用方法):【西藏造价软件Z1】怎么查看人工机械费用
|
||
# 故障排查(解决软件错误问题):【技改检修2016软件】初始化失败了
|
||
# 费用计算(专属意图,复杂计算推理)
|
||
# 下载与安装(询问软件的下载和安装):【配网D3软件】程序包发我;【配网D3软件】怎么安装
|
||
|
||
def Vertical_classification():
|
||
PromptTemplate1 = """
|
||
根据用户输入进行垂直领域分类
|
||
|
||
目前的垂直分类:【'闲聊', '软件咨询'】
|
||
|
||
# 软件咨询包括以下:
|
||
1. 查询功能(询问软件功能或用途,包括后缀名问题)
|
||
2. 操作指导(询问具体使用方法)
|
||
3. 故障排查(解决软件错误问题)
|
||
4. 下载安装(关于软件的下载和安装问题)
|
||
|
||
# 用户输入
|
||
{query}
|
||
|
||
# 注意:
|
||
1. 你只能回答是'闲聊' 或者 '软件咨询',绝对不能有其他回复
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | qwen_llm | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
# chain_vertical = Vertical_classification()
|
||
|
||
|
||
def small_talk():
|
||
PromptTemplate1 = """
|
||
你是一个开放性的聊天助手,请以礼貌的方式进行回复
|
||
|
||
# 用户输入
|
||
{query}
|
||
|
||
# 注意
|
||
1. 对于用户发送类似“你好”、“hi”、“嗨”之类的问候语,需要固定回复:“您好,尊贵的VIP,我是booway小助手,很高兴为您服务”
|
||
2. 对于用户发送类似“你是谁”、“你能干什么”、“你有什么功能”之类的询问身份和功能的语句,需要固定回复:“您好,我是booway小助手,如您需要相关电力造价软件的使用咨询,可以和我沟通”
|
||
3. 初次之外的聊天,不需要告知用户的身份和你的身份
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | qwen_llm | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
|
||
# chain_small_talk = small_talk()
|
||
|
||
|
||
# 查询功能(询问软件功能或用途):【新型储能计价通C1】可以做批次工程吗
|
||
# 后缀名问题(专属子意图)
|
||
# 操作指导(询问具体使用方法):【西藏造价软件Z1】怎么查看人工机械费用
|
||
# 故障排查(解决软件错误问题):【技改检修2016软件】初始化失败了
|
||
# 费用计算(专属意图,复杂计算推理)
|
||
# 下载与安装(询问软件的下载和安装):【配网D3软件】程序包发我;【配网D3软件】怎么安装
|
||
def intention_judge():
|
||
# 费用计算另处理
|
||
PromptTemplate1 = """
|
||
你是一个智能意图分类助手。请根据用户的问题,将其归类到以下意图中:
|
||
|
||
1. 查询功能(询问软件功能或用途)
|
||
2. 操作指导(询问具体使用方法)
|
||
3. 故障排查(解决软件错误问题)
|
||
4. 下载安装(关于软件的下载和安装问题)
|
||
|
||
用户的问题是:"{query}"
|
||
|
||
请明确指出该问题属于哪个意图类别。
|
||
|
||
输出格式:str类型
|
||
|
||
注意你的回复答案一定是[查询功能、操作指导、故障排查、下载安装]之一,不要有其他回答,不要解释说明
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | qwen_llm | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
|
||
def domain_judge():
|
||
# 费用计算另处理
|
||
PromptTemplate1 = """
|
||
你是一个领域问题分类助手。请根据用户的问题,将其归类到以下软件领域中:
|
||
|
||
1. 西藏造价软件Z1
|
||
2. 新型储能计价通C1
|
||
3. 技改检修计价通T1
|
||
4. 未知 (用户输入没有提到具体软件名称,就回答‘未知’)
|
||
|
||
用户输入:"{query}"
|
||
|
||
请明确指出该问题属于哪个领域问题分类。
|
||
|
||
输出格式:str类型
|
||
|
||
注意:
|
||
1. 你的回复答案一定是[西藏造价软件Z1、新型储能计价通C1、技改检修计价通T1、未知]之一,不要有其他回答,不要解释说明
|
||
2. 如果用户输入没有说明具体哪个软件,则回答‘未知’
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | deep_v3 | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
def domain_judge_v2():
|
||
# 费用计算另处理
|
||
PromptTemplate1 = """
|
||
你是一个不全软件名称的助手。请根据用户的问题,进行补全:
|
||
|
||
1. 西藏造价软件Z1
|
||
2. 新型储能计价通C1
|
||
3. 技改检修计价通T1
|
||
4. 未知 (用户输入没有提到具体软件名称,就回答‘未知’)
|
||
|
||
用户输入:"{query}"
|
||
|
||
输出格式:str类型
|
||
|
||
注意:
|
||
1. 你的回复答案一定是[西藏造价软件Z1、新型储能计价通C1、技改检修计价通T1、未知]之一,不要有其他回答,不要解释说明
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | deep_v3 | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
|
||
def judge_5W2H():
|
||
PromptTemplate1 = """
|
||
你是一位专业的语言分析师。请根据以下输入,识别出它属于5W2H中的哪一类:
|
||
- What: 表示“什么”。
|
||
- Why: 表示“为什么”。
|
||
- When: 表示“什么时候”。
|
||
- Where: 表示“在哪里”。
|
||
- Who: 表示“谁”。
|
||
- How: 表示“如何”。
|
||
- How much: 表示“多少”。
|
||
|
||
输入: {query}
|
||
请判断并仅返回类别名称。
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | qwen_llm | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
|
||
def extract_keywords():
|
||
PromptTemplate1 = """
|
||
你是一位专业的语言分析师。请根据以下输入内容,精准提取“需求”部分:
|
||
|
||
软件名称:{software_name}
|
||
5W2H 类型:{_5w2h_type}
|
||
用户输入:{query}
|
||
|
||
提取规则:
|
||
仅提取用户输入中,除软件名称和5W2H类型以外的“需求”部分,保持原意简洁输出,不添加解释或思考过程。
|
||
|
||
示例1:
|
||
软件名称:新型储能计价通C1
|
||
5W2H 类型:How
|
||
用户输入:储能软件,怎么批量将乙供主材改为甲供
|
||
输出:批量将乙供主材改为甲供
|
||
|
||
示例2:
|
||
软件名称:西藏造价软件Z1
|
||
5W2H 类型:What
|
||
用户输入:西藏Z1软件,海报高度选择不同影响什么
|
||
输出:海报高度选择不同影响什么
|
||
|
||
注意事项:
|
||
- 输出仅包含“需求”内容
|
||
- “需求”需要你根据语义总结
|
||
- 不要输出任何解释或推理过程
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | qwen_llm | StrOutputParser()
|
||
|
||
return Chain
|
||
|
||
# def answer_questions():
|
||
# PromptTemplate1 = """
|
||
# 你是一个回答助手,请根据检索到的知识内容来回答用户的问题。
|
||
#
|
||
# # 用户问题:
|
||
# {query}
|
||
#
|
||
# # 检索到的知识内容:
|
||
# {kg}
|
||
#
|
||
# # 回答要求:
|
||
# 1. 仅依据检索到的知识内容进行回答,不要引入任何其他未提供的知识。
|
||
# 2. 如果检索内容中仅有部分信息与你判断相关,请结合有用部分作答,忽略无关内容。
|
||
# 3. 如果你无法根据检索内容推理或回答用户问题,请回答:“没有相关知识”。
|
||
#
|
||
# """
|
||
#
|
||
# Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
#
|
||
# Chain = Prompt | deep_v3 | StrOutputParser()
|
||
#
|
||
# return Chain
|
||
|
||
def answer_questions():
|
||
PromptTemplate1 = """
|
||
请严格根据以下框架回答用户问题:
|
||
|
||
# 用户问题:
|
||
{query}
|
||
|
||
# 检索到的知识内容:
|
||
{kg}
|
||
|
||
# 回答规则 (必须逐条遵守):
|
||
1. 相关性优先原则
|
||
- 必须严格检查检索内容与用户问题的相关性
|
||
- 仅当检索内容中存在至少一条与问题直接相关的明确证据时,才允许作答
|
||
- 若检索内容整体与问题无关,即使内容正确,也必须回答"没有相关知识"
|
||
|
||
2. 精准引用原则
|
||
- 回答必须完全基于检索内容中的有效证据
|
||
- 禁止添加任何外部知识、常识推理或主观猜测
|
||
- 禁止对检索内容进行延伸解读,仅允许直接相关的事实陈述
|
||
|
||
3. 部分相关处理
|
||
- 当检索内容中只有部分段落相关时:
|
||
1. 先验证该段落是否直接对应问题核心
|
||
2. 确认无误后仅使用该部分作答
|
||
3. 主动忽略其他无关内容
|
||
|
||
4. 拒绝回答场景
|
||
- 检索内容与问题无逻辑关联时
|
||
- 需要连接多个非直接相关片段进行推理时
|
||
- 存在相关表述但缺乏明确证据支持时
|
||
|
||
# 回答要求
|
||
1. 基于以上回答规则,仅做回答,不要加上思考过程
|
||
|
||
"""
|
||
|
||
Prompt = ChatPromptTemplate.from_template(PromptTemplate1)
|
||
|
||
Chain = Prompt | deep_v3 | StrOutputParser()
|
||
|
||
return Chain |