sentiment_agent.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. """
  2. 智能股票分析助手 — 舆情分析Agent
  3. 基于 HelloAgents ReActAgent,使用 mx-search 工具搜索金融资讯,
  4. 并结合LLM进行情感倾向分析和舆情研判。
  5. 使用方式:
  6. from agents.sentiment_agent import create_sentiment_agent
  7. agent = create_sentiment_agent(api_key="...", llm=llm)
  8. result = agent.run("分析贵州茅台的舆情情况")
  9. """
  10. import sys
  11. from pathlib import Path
  12. # 将框架路径加入sys.path
  13. _PROJECT_ROOT = Path(__file__).parent.parent
  14. _HELLO_PATH = _PROJECT_ROOT / "HelloAgents Optimized"
  15. _AGENTS_DIR = _PROJECT_ROOT / "agents"
  16. _BACKEND_DIR = _PROJECT_ROOT / "backend"
  17. _SKILLS_SEARCH = _PROJECT_ROOT / "skills" / "资讯搜索" / "mx-search"
  18. for p in [_HELLO_PATH, _AGENTS_DIR, _BACKEND_DIR, _SKILLS_SEARCH]:
  19. if str(p) not in sys.path:
  20. sys.path.insert(0, str(p))
  21. from typing import Iterator
  22. from hello_agents.tools import ToolRegistry
  23. from hello_agents.agents.react_agent import ReActAgent
  24. from hello_agents.core.llm import HelloAgentsLLM
  25. from hello_agents.core.config import Config
  26. from hello_agents.core.stream import StreamEvent
  27. from agents.tools.mx_search_tool import MXSearchTool
  28. # 默认舆情分析系统提示词
  29. SENTIMENT_SYSTEM_PROMPT = """你是一位专业的金融舆情分析师,精通A股市场和各种政策分析方法论。
  30. ## 你的职责
  31. 1. 搜索目标股票/行业的最新金融资讯(新闻、研报、公告)
  32. 2. 分析各条资讯的情感倾向(正面/负面/中性)
  33. 3. 识别关键事件和潜在影响
  34. 4. 综合判断市场舆情趋势
  35. 5. 提供客观、有数据支撑的舆情研判结论
  36. ## 分析方法
  37. - 关注信息来源的权威性(官方公告 > 权威研报 > 新闻报道)
  38. - 关注资讯的时效性(越新越重要)
  39. - 区分短期情绪波动和长期趋势变化
  40. - 注意识别潜在的利好/利空事件
  41. - 结合行业政策环境进行分析
  42. ## 输出格式
  43. 分析结果应包含以下部分:
  44. 1. **舆情总览**:情感分布统计(正面X条/负面X条/中性X条)
  45. 2. **核心事件**:最重要的2-3个关键资讯摘要
  46. 3. **情感趋势**:整体舆情偏向及变化趋势
  47. 4. **风险提示**:需要关注的潜在风险和不确定性
  48. 5. **综合研判**:基于舆情分析的投资参考建议(不构成投资建议)
  49. ## 重要提醒
  50. - 始终保持客观中立,不夸大也不隐瞒风险
  51. - 所有分析结论需有搜索结果支撑
  52. - 末尾必须标注"以上分析仅供参考,不构成投资建议"
  53. """
  54. def create_sentiment_agent(
  55. api_key: str = None,
  56. llm: HelloAgentsLLM = None,
  57. system_prompt: str = None,
  58. max_steps: int = 8,
  59. ) -> ReActAgent:
  60. """创建舆情分析Agent
  61. Args:
  62. api_key: 东方财富MX_APIKEY,不提供则从环境变量读取
  63. llm: HelloAgentsLLM实例(必需),不提供则从环境变量自动创建
  64. system_prompt: 自定义系统提示词(可选)
  65. max_steps: 最大推理步数,默认8(搜索+综合常需多步)
  66. Returns:
  67. 配置好的ReActAgent实例
  68. Raises:
  69. RuntimeError: 若LLM未配置且无法从环境变量创建
  70. """
  71. # 创建LLM实例(如果未提供)
  72. if llm is None:
  73. llm = _create_default_llm()
  74. # 创建工具注册表并注册资讯搜索工具
  75. registry = ToolRegistry()
  76. search_tool = MXSearchTool(api_key=api_key)
  77. registry.register_tool(search_tool)
  78. # 使用自定义或默认系统提示词
  79. prompt = system_prompt or SENTIMENT_SYSTEM_PROMPT
  80. # 创建ReActAgent
  81. agent = ReActAgent(
  82. name="舆情分析Agent",
  83. llm=llm,
  84. tool_registry=registry,
  85. system_prompt=prompt,
  86. config=Config(temperature=0.3, max_tokens=4096), # 低温度确保分析稳定
  87. max_steps=max_steps,
  88. )
  89. return agent
  90. def _create_default_llm() -> HelloAgentsLLM:
  91. """从环境变量创建默认LLM实例"""
  92. import os
  93. model = os.getenv("LLM_MODEL_ID")
  94. api_key = os.getenv("LLM_API_KEY")
  95. base_url = os.getenv("LLM_BASE_URL")
  96. provider = os.getenv("LLM_PROVIDER", "auto")
  97. if not api_key:
  98. raise RuntimeError(
  99. "LLM_API_KEY 环境变量未设置,请先设置环境变量:\n"
  100. "export LLM_API_KEY=your_llm_api_key_here\n"
  101. "或在创建Agent时传入 llm 参数"
  102. )
  103. return HelloAgentsLLM(
  104. model=model,
  105. api_key=api_key,
  106. base_url=base_url,
  107. provider=provider,
  108. temperature=0.3,
  109. )
  110. def analyze_sentiment_stream(
  111. agent: ReActAgent,
  112. stock_code: str = "",
  113. stock_name: str = "",
  114. ) -> Iterator[dict]:
  115. """流式舆情分析 - 通过ReActAgent搜索资讯并分析舆情
  116. Args:
  117. agent: 已配置的舆情分析Agent
  118. stock_code: 股票代码
  119. stock_name: 股票名称
  120. Yields:
  121. dict: {"type": "meta"|"status"|"delta"|"done"|"error", "content": str}
  122. """
  123. stock_label = f"{stock_name}({stock_code})" if stock_name else stock_code
  124. yield {"type": "meta", "stock_code": stock_code, "stock_name": stock_name}
  125. yield {"type": "status", "content": f"正在搜索 {stock_label} 的相关资讯..."}
  126. task = f"请搜索并分析股票 {stock_label} 的最新金融资讯、研究报告和公告,判断市场舆情趋势。"
  127. try:
  128. for event in agent.stream_run(task):
  129. if event.event_type == "status":
  130. yield {"type": "status", "content": event.content}
  131. elif event.event_type in ("text", "observation"):
  132. yield {"type": "delta", "content": event.content}
  133. elif event.event_type == "tool_call":
  134. yield {"type": "status", "content": f"正在调用工具: {event.metadata.get('tool_name', '')}"}
  135. elif event.event_type == "done":
  136. yield {"type": "done"}
  137. elif event.event_type == "error":
  138. yield {"type": "error", "content": event.content}
  139. except Exception as e:
  140. yield {"type": "error", "content": f"舆情分析出错: {e}"}