""" 问题改写 """ 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(信息补全) 历史会话: - 用户:我想了解游戏特效培训 - 助手:好的,请问您想了解哪方面? 当前问题:培训的费用 分类结果: {{ "intents": "费用咨询" }} ### 示例2(指代消解) 历史会话: - 用户:你们有Python课程吗? - 助手:有的,我们有Python基础班和进阶班。 当前问题:这个课程的时长是多久? 分类结果: {{ "intents": ["课程内容", "报名流程"] }} ### 示例3(多诉求提取) 历史会话: - 用户:我想报名数据分析培训 当前问题:流程、费用和就业支持 分类结果: {{ "intents": ["报名流程"] }} ### 示例4(无需改写) 历史会话:(空) 当前问题:Java培训的课程内容有哪些? 分类结果: {{ "intents": ["课程内容"] }} ### 示例5(用户提供的案例) 历史会话:(空) 当前问题:老师这个课程多少钱啊,老师我想报班 分类结果: {{ "intents": ["报名流程"] }} --- ## 现在请处理以下输入 当前问题:{query} 历史聊天:{history_text} 请直接输出JSON: """ async def rewrite_query(state:QueryQAState): """ 问题改写 :param query: 用户问题 :param history_text: 历史会话 :return: 改写后的问题 """ history_text = state.get("history", "") query = state.get("original_query", "") 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("intents", "") if rewritten_query: rewritten_query = rewritten_query[0] logger.info(f"原问题:{query},历史会话:{history_text},改写后问题:{rewritten_query}") return {"rewritten_query": rewritten_query} except Exception as e: logger.error(f"QA质量检查prompt模板错误:{e}") return {"rewritten_query": query} # 兜底