| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import json
- import logging
- from typing import TypedDict, Optional
- from langgraph.graph import StateGraph, START, END
- from langchain_core.messages import SystemMessage, HumanMessage
- from app.llm.client import get_llm
- from app.monitoring import monitor_agent
- logger = logging.getLogger(__name__)
- SYSTEM_PROMPT = """分析用户近3次五维自检趋势,输出:
- - aiInsight: 趋势解读(2-3句,指出最大变化维度和可能原因,口语化)
- - trendSummary: 各维度 delta 简写(如"身-2 智+1 富0 行-1 心+2")
- 返回 JSON:{"aiInsight": "...", "trendSummary": "..."}
- """
- class TrendState(TypedDict):
- history: list
- user_id: int
- insight: Optional[dict]
- error: Optional[str]
- class SelfCheckTrendAgent:
- def __init__(self):
- self.llm = get_llm()
- @monitor_agent("self_check_trend")
- async def run(self, history: list, user_id: int) -> dict:
- try:
- if len(history) < 2:
- return {"insight": {"aiInsight": "自检次数不足,建议完成至少2次自检后查看趋势", "trendSummary": ""}, "error": None}
- history_text = "\n".join(
- f"{h.get('createdAt', '')}: 总分{h.get('totalScore', 0)}," +
- " ".join(f"{d.get('name','')}{d.get('score',0)}分" for d in h.get('dimensions', []))
- for h in history[-3:]
- )
- messages = [
- SystemMessage(content=SYSTEM_PROMPT),
- HumanMessage(content=f"用户{user_id}的自检历史:\n{history_text}"),
- ]
- response = await self.llm.ainvoke(messages)
- text = response.content.strip()
- if "```json" in text:
- text = text.split("```json")[1].split("```")[0].strip()
- elif "```" in text:
- text = text.split("```")[1].split("```")[0].strip()
- data = json.loads(text)
- return {"insight": data, "error": None}
- except Exception as e:
- logger.warning("趋势分析失败: %s", e)
- return {"insight": {"aiInsight": "", "trendSummary": ""}, "error": str(e)}
- def build_trend_graph():
- agent = SelfCheckTrendAgent()
- async def call_llm(state: TrendState) -> dict:
- return await agent.run(state["history"], state["user_id"])
- graph = StateGraph(TrendState)
- graph.add_node("llm", call_llm)
- graph.add_edge(START, "llm")
- graph.add_edge("llm", END)
- return graph.compile()
- _trend_graph = None
- def get_trend_graph():
- global _trend_graph
- if _trend_graph is None:
- _trend_graph = build_trend_graph()
- return _trend_graph
|