self_check_trend_graph.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import json
  2. import logging
  3. from typing import TypedDict, Optional
  4. from langgraph.graph import StateGraph, START, END
  5. from langchain_core.messages import SystemMessage, HumanMessage
  6. from app.llm.client import get_llm
  7. from app.monitoring import monitor_agent
  8. logger = logging.getLogger(__name__)
  9. SYSTEM_PROMPT = """分析用户近3次五维自检趋势,输出:
  10. - aiInsight: 趋势解读(2-3句,指出最大变化维度和可能原因,口语化)
  11. - trendSummary: 各维度 delta 简写(如"身-2 智+1 富0 行-1 心+2")
  12. 返回 JSON:{"aiInsight": "...", "trendSummary": "..."}
  13. """
  14. class TrendState(TypedDict):
  15. history: list
  16. user_id: int
  17. insight: Optional[dict]
  18. error: Optional[str]
  19. class SelfCheckTrendAgent:
  20. def __init__(self):
  21. self.llm = get_llm()
  22. @monitor_agent("self_check_trend")
  23. async def run(self, history: list, user_id: int) -> dict:
  24. try:
  25. if len(history) < 2:
  26. return {"insight": {"aiInsight": "自检次数不足,建议完成至少2次自检后查看趋势", "trendSummary": ""}, "error": None}
  27. history_text = "\n".join(
  28. f"{h.get('createdAt', '')}: 总分{h.get('totalScore', 0)}," +
  29. " ".join(f"{d.get('name','')}{d.get('score',0)}分" for d in h.get('dimensions', []))
  30. for h in history[-3:]
  31. )
  32. messages = [
  33. SystemMessage(content=SYSTEM_PROMPT),
  34. HumanMessage(content=f"用户{user_id}的自检历史:\n{history_text}"),
  35. ]
  36. response = await self.llm.ainvoke(messages)
  37. text = response.content.strip()
  38. if "```json" in text:
  39. text = text.split("```json")[1].split("```")[0].strip()
  40. elif "```" in text:
  41. text = text.split("```")[1].split("```")[0].strip()
  42. data = json.loads(text)
  43. return {"insight": data, "error": None}
  44. except Exception as e:
  45. logger.warning("趋势分析失败: %s", e)
  46. return {"insight": {"aiInsight": "", "trendSummary": ""}, "error": str(e)}
  47. def build_trend_graph():
  48. agent = SelfCheckTrendAgent()
  49. async def call_llm(state: TrendState) -> dict:
  50. return await agent.run(state["history"], state["user_id"])
  51. graph = StateGraph(TrendState)
  52. graph.add_node("llm", call_llm)
  53. graph.add_edge(START, "llm")
  54. graph.add_edge("llm", END)
  55. return graph.compile()
  56. _trend_graph = None
  57. def get_trend_graph():
  58. global _trend_graph
  59. if _trend_graph is None:
  60. _trend_graph = build_trend_graph()
  61. return _trend_graph