intent_classifier.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. from enum import Enum
  2. from langchain_openai import ChatOpenAI
  3. from app.config import settings
  4. from app.prompt_service import get_prompt
  5. import logging
  6. logger = logging.getLogger(__name__)
  7. class Intent(str, Enum):
  8. CHAT = "chat" # 日常聊天 / 育儿交流
  9. ANALYSIS = "analysis" # 报告解读 / 数据分析
  10. RECOMMEND = "recommend" # 商品 / 活动推荐
  11. TASK = "task" # 任务创建 / 进度查询
  12. MIND = "mind" # 情绪疏导 / 心理支持
  13. HEALTH = "health" # 健康咨询 / 舌诊
  14. CLASSIFY_PROMPT = """从用户消息中识别意图, 只返回意图代码, 不要解释:
  15. - chat: 日常聊天、育儿交流、询问建议(非具体商品/报告)
  16. - analysis: 报告解读\数据分析\趋势查看(提到"报告"/"分析"/"评分")
  17. - recommend: 商品\活动\文章推荐(提到"推荐"/"买"/"吃什么"/"适合")
  18. - task: 任务相关(提到"任务"/"打卡"/"完成"/"奖励")
  19. - mind: 情绪问题\心理支持(提到"心情"/"难过"/"焦虑"/"不开心")
  20. - health: 健康咨询\舌诊(提到"舌"/"健康"/"体质")
  21. 用户消息: {query}
  22. 历史上下文: {context}
  23. 意图代码:
  24. """
  25. class IntentClassifier:
  26. def __init__(self):
  27. self.llm = ChatOpenAI(
  28. model=settings.llm_model,
  29. api_key=settings.llm_api_key,
  30. base_url=settings.llm_base_url,
  31. temperature=settings.llm_temperature,
  32. max_tokens=20,
  33. )
  34. async def classify(self, query: str, context: str = "") -> Intent:
  35. template = await get_prompt("intent_classifier") or CLASSIFY_PROMPT
  36. try:
  37. prompt = template.format(query=query[:200], context=context[:300])
  38. except (KeyError, IndexError, ValueError):
  39. logger.warning("Java 配置的 intent_classifier 模板缺少占位符,回退本地模板")
  40. prompt = CLASSIFY_PROMPT.format(query=query[:200], context=context[:300])
  41. try:
  42. resp = await self.llm.ainvoke(prompt)
  43. intent_str = resp.content.strip().lower()
  44. for intent in Intent:
  45. if intent.value in intent_str:
  46. return intent
  47. logger.warning("无法识别的意图: %s, 默认 chat", intent_str)
  48. return Intent.CHAT
  49. except Exception as e:
  50. logger.warning("意图分类失败: %s, 默认 chat", e)
  51. return Intent.CHAT