106 lines
3.3 KiB
Python
106 lines
3.3 KiB
Python
"""
|
||
问题改写
|
||
"""
|
||
from langchain_core.output_parsers import JsonOutputParser
|
||
from langchain_core.prompts import PromptTemplate
|
||
|
||
from app.chat_qa_query.query_qa_state import QueryQAState
|
||
from app.llm import llm
|
||
from app.core.log import logger
|
||
|
||
problem_rewriting_prompt = """
|
||
你是一名智能客服意图理解助手。你的任务是根据用户的历史会话和当前问题,提取用户的核心诉求,并将其改写为一个语义完整、信息自包含的独立问题。
|
||
|
||
## 改写规则(必须严格遵守)
|
||
|
||
1. **核心诉求提取**:
|
||
- 从当前问题中提取用户明确表达的诉求(可能有一个或多个,去重)
|
||
- 如果当前问题包含代词(如"这个"、"它"、"那"等),必须结合历史会话进行指代消解,用具体名词替换代词
|
||
|
||
2. **信息补全**:
|
||
- 如果当前问题缺少主语或关键上下文(如只问"费用多少"),必须从历史会话中提取相关主题补全
|
||
- 改写后的问题必须是一个**不依赖历史会话也能被独立理解**的完整问题
|
||
|
||
3. **语义保持**:
|
||
- 不得改变用户的原始意图
|
||
- 不得引入历史会话中不存在的新信息
|
||
- 不得遗漏当前问题中的任何关键诉求
|
||
|
||
4. **输出格式**:
|
||
- 仅输出JSON,不要任何解释性文字
|
||
|
||
## 改写示例
|
||
|
||
### 示例1(信息补全)
|
||
历史会话:
|
||
- 用户:我想了解游戏特效培训
|
||
- 助手:好的,请问您想了解哪方面?
|
||
当前问题:培训的费用
|
||
改写结果:
|
||
{{
|
||
"rewritten_query": "游戏特效培训的费用是多少?"
|
||
}}
|
||
|
||
### 示例2(指代消解)
|
||
历史会话:
|
||
- 用户:你们有Python课程吗?
|
||
- 助手:有的,我们有Python基础班和进阶班。
|
||
当前问题:这个课程的时长是多久?
|
||
改写结果:
|
||
{{
|
||
"rewritten_query": "Python课程的时长是多久?"
|
||
}}
|
||
|
||
### 示例3(多诉求提取)
|
||
历史会话:
|
||
- 用户:我想报名数据分析培训
|
||
当前问题:流程、费用和就业支持
|
||
改写结果:
|
||
{{
|
||
"rewritten_query": "数据分析培训的报名流程、费用以及就业支持分别是什么?"
|
||
}}
|
||
|
||
### 示例4(无需改写)
|
||
历史会话:(空)
|
||
当前问题:Java培训的课程内容有哪些?
|
||
改写结果:
|
||
{{
|
||
"rewritten_query": "Java培训的课程内容有哪些?"
|
||
}}
|
||
|
||
---
|
||
|
||
## 现在请处理以下输入
|
||
|
||
历史会话:
|
||
{history_text}
|
||
|
||
历史会话字段说明:
|
||
EXTERNAL:客户
|
||
INTERNAL:销售
|
||
当前问题:{query}
|
||
|
||
请直接输出JSON:
|
||
"""
|
||
|
||
async def rewrite_query(state:QueryQAState):
|
||
"""
|
||
问题改写
|
||
:param query: 用户问题
|
||
:param history_text: 历史会话
|
||
:return: 改写后的问题
|
||
"""
|
||
history_text = state.get("history", "")
|
||
query = state.get("original_query", "")
|
||
logger.info(f"问题改写:{query},历史会话:{history_text}")
|
||
prompt = PromptTemplate(template=problem_rewriting_prompt, input_variables=["history_text", "query"])
|
||
output = JsonOutputParser()
|
||
chain = prompt | llm | output
|
||
|
||
try:
|
||
result = await chain.ainvoke({"history_text": history_text, "query": query})
|
||
rewritten_query = result.get("rewritten_query", "")
|
||
return {"rewritten_query": rewritten_query}
|
||
except Exception as e:
|
||
logger.error(f"QA质量检查prompt模板错误:{e}")
|
||
return {"rewritten_query": query} # 兜底 |