TradingAgents-CN 新闻分析工具链与提示词系统深度解析
【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN
导读
本文基于 docs/features/news/news-analysis-system.md,系统拆解 TradingAgents-CN 中文金融交易框架中的新闻分析模块:从多源新闻聚合、去重排序、紧急程度评估、相关性评分,到面向 LLM 的系统提示词设计与动态注入,再到 A 股/港股/美股自动分流的工具链执行流程。读完本文,你将掌握该框架"新闻 → 数据 → LLM 分析 → 结构化报告"的完整链路,并能在实际项目中复现、配置与扩展这套新闻分析能力。
1. 新闻分析工具链整体架构
TradingAgents-CN 将新闻分析设计为一条独立、可插拔的工具链。从源码结构看,整个链路可概括为:新闻分析师(NewsAnalyst)→ 工具选择 → 多源新闻获取 → 新闻处理流水线 → 格式化报告 → LLM 分析 → 结构化报告。
新闻分析师 (NewsAnalyst) ↓ 工具选择(根据股票类型和运行模式) ↓ ┌───────────────┬───────────────┬───────────────┐ │ A股工具链 │ 非A股工具链 │ 离线工具链 │ └───────────────┴───────────────┴───────────────┘ ↓ 实时新闻聚合器 (RealtimeNewsAggregator) ↓ ┌─────────────┬─────────────┬─────────────┬─────────────┐ │ FinnHub │ Alpha │ NewsAPI │ 中文财经 │ │ 实时新闻 │ Vantage │ 新闻源 │ 新闻源 │ └─────────────┴─────────────┴─────────────┴─────────────┘ ↓ 新闻处理流水线(去重 / 时效性评估 / 紧急程度评估 / 相关性评分) ↓ 格式化新闻报告 ↓ LLM 分析(基于提示词模板) ↓ 结构化分析报告需要说明的是,这一架构在 tradingagents/agents/analysts/news_analyst.py 的当前实现中已经进一步收敛:工具选择不再由分析师节点手工拼装多个工具,而是统一交给create_unified_news_tool创建的get_stock_news_unified单工具,由它在内部完成"股票类型识别 → 数据源路由"的完整逻辑。文档描述的分市场工具链逻辑并未消失,而是被下沉到了统一新闻工具内部(详见第 4 节),这既保留了多市场分流的智能性,又显著降低了 LLM 工具调用的失败率。
2. 工具链组件详解
2.1 新闻分析师(NewsAnalyst)
位置:tradingagents/agents/analysts/news_analyst.py
create_news_analyst(llm, toolkit)返回一个以@log_analyst_module("news")装饰的图节点news_analyst_node(state),负责:
- 智能工具选择(根据股票类型和运行模式)
- 提示词模板管理(
ChatPromptTemplate+partial动态注入) - LLM 调用和结果处理(含 Google 模型与 DashScope/DeepSeek/Zhipu 模型的分流处理)
- 分析报告生成
股票类型识别:节点通过StockUtils.get_market_info(ticker)获取is_china / is_hk / is_us三组标志,并据此调用对应的公司名称解析逻辑——A 股走get_china_stock_info_unified统一接口,港股走get_hk_company_name_improved,美股则使用内置的名称映射表(如 AAPL→苹果公司)。公司名称会被拼入提示词,帮助 LLM 建立标的上下文。
工具调用防死循环:源码中显式引入了news_tool_call_count计数器,max_tool_calls = 3,每次执行后以不携带 tool_calls 的干净AIMessage返回(clean_message = AIMessage(content=report)),确保 LangGraph 工作流能正确判定分析已完成,避免节点被无限重入。
文档中描述的按is_china与online_tools拆分工具链的逻辑如下(当前版本已由统一新闻工具承载):
# 文档描述的历史/参考逻辑 if is_china: tools = [ toolkit.get_realtime_stock_news, # 实时新闻(包含东方财富) toolkit.get_google_news, # Google新闻(中文搜索) toolkit.get_global_news_openai # OpenAI全球新闻(作为补充) ] else: tools = [ toolkit.get_realtime_stock_news, toolkit.get_global_news_openai, toolkit.get_google_news ] if not online_tools: tools = [ toolkit.get_realtime_stock_news, toolkit.get_finnhub_news, toolkit.get_reddit_news, toolkit.get_google_news, ]这些底层工具在 tradingagents/agents/utils/agent_utils.py 的Toolkit类中均有真实实现(get_reddit_news、get_finnhub_news、get_google_news、get_global_news_openai等),可供统一新闻工具在内部按需路由调用。
2.2 实时新闻聚合器(RealtimeNewsAggregator)
位置:文档标注为 tradingagents/dataflows/realtime_news_utils.py;从当前源码看,该文件已演化为向后兼容导出层,真正的实现位于 tradingagents/dataflows/news/realtime_news.py,两者均导出get_realtime_stock_news、RealtimeNewsAggregator、NewsItem,旧调用方无需改动。
聚合器核心能力:
- 多源新闻聚合
- 新闻去重和排序
- 紧急程度评估
- 相关性评分
- 时效性分析
数据源优先级:
- FinnHub 实时新闻(最高优先级,
_get_finnhub_realtime_news) - Alpha Vantage 新闻(
NEWS_SENTIMENT接口,_get_alpha_vantage_news) - NewsAPI 新闻源(
_get_newsapi_news,仅配置NEWSAPI_KEY时启用) - 中文财经新闻源(
_get_chinese_finance_news:东方财富 + 财联社 RSS)
每个数据源在源码中都有独立的容错封装:未配置密钥直接跳过、API 异常被捕获并记录日志后返回空列表,保证单个源失败不会拖垮整条链路。
新闻项目数据结构(realtime_news.py 中定义):
@dataclass class NewsItem: title: str # 新闻标题 content: str # 新闻内容 source: str # 新闻来源 publish_time: datetime # 发布时间 url: str # 新闻链接 urgency: str # 紧急程度 (high, medium, low) relevance_score: float # 相关性评分2.3 新闻处理流水线
去重处理(_deduplicate_news):以title.lower().strip()作为去重键;标题长度 ≤ 10 的新闻会被视为信息量不足直接丢弃;命中已见标题的重复项被剔除。源码会分别统计"重复数"与"标题过短数"并写入日志。
紧急程度评估(_assess_news_urgency):对标题+正文做小写拼接后按关键词分级。源码中的实际关键词分为两组:
# 高紧急度关键词(命中即 high) high_urgency_keywords = [ 'breaking', 'urgent', 'alert', 'emergency', 'halt', 'suspend', '突发', '紧急', '暂停', '停牌', '重大' ] # 中等紧急度关键词(命中即 medium) medium_urgency_keywords = [ 'earnings', 'report', 'announce', 'launch', 'merger', 'acquisition', '财报', '发布', '宣布', '并购', '收购' ]文档中给出的中文关键词清单(如"破产、诉讼、收购、合并、FDA批准、盈利警告、重组、违规、调查、制裁"以及"财报、业绩、合作、新产品、市场份额、分红、回购、增持、减持")代表了该评估思路的扩展方向:接入方可以像第 6 节自定义示例那样,直接替换high_urgency_keywords/medium_urgency_keywords列表来适配自身业务语义。
相关性评分算法(_calculate_relevance)分四档:
| 命中条件 | 评分 |
|---|---|
股票代码(如aapl)直接出现在标题 | 1.0 |
股票代码纯数字部分(A 股,如000001)出现在标题 | 0.9 |
| 公司相关关键词(如 apple/iphone/tesla/nvidia)出现在标题 | 0.8 |
| 均未命中 | 0.3(默认值) |
时效性分析:format_news_report会计算最新一条新闻距今的分钟数,并以三档标签输出——30 分钟内为"🟢 优秀"、1 小时内为"🟡 良好"、超过 1 小时为"🔴 一般"。
3. 提示词系统设计
3.1 系统提示词模板
新闻分析师的系统提示词(news_analyst.py 中完整保留)以"专业财经新闻分析师"角色为核心,结构如下:
system_message = """您是一位专业的财经新闻分析师,负责分析最新的市场新闻和事件对股票价格的潜在影响。 您的主要职责包括: 1. 获取和分析最新的实时新闻(优先15-30分钟内的新闻) 2. 评估新闻事件的紧急程度和市场影响 3. 识别可能影响股价的关键信息 4. 分析新闻的时效性和可靠性 5. 提供基于新闻的交易建议和价格影响评估 重点关注的新闻类型: - 财报发布和业绩指导 - 重大合作和并购消息 - 政策变化和监管动态 - 突发事件和危机管理 - 行业趋势和技术突破 - 管理层变动和战略调整 分析要点: - 新闻的时效性(发布时间距离现在多久) - 新闻的可信度(来源权威性) - 市场影响程度(对股价的潜在影响) - 投资者情绪变化(正面/负面/中性) - 与历史类似事件的对比 📊 新闻影响分析要求: - 评估新闻对股价的短期影响(1-3天)和市场情绪变化 - 分析新闻的利好/利空程度和可能的市场反应 - 评估新闻对公司基本面和长期投资价值的影响 - 识别新闻中的关键信息点和潜在风险 - 对比历史类似事件的市场反应 - 不允许回复'无法评估影响'或'需要更多信息' 请特别注意: ⚠️ 如果新闻数据存在滞后(超过2小时),请在分析中明确说明时效性限制 ✅ 优先分析最新的、高相关性的新闻事件 📊 提供新闻对市场情绪和投资者信心的影响评估 💰 必须包含基于新闻的市场反应预期和投资建议 🎯 聚焦新闻内容本身的解读,不涉及技术指标分析 请撰写详细的中文分析报告,并在报告末尾附上Markdown表格总结关键发现。"""3.2 提示词设计原则
从上述模板可以提炼出四组设计原则,这也是将任何"分析型 Agent"提示词工程化的可复用范式:
角色定位:专业身份为财经新闻分析师;核心职责是新闻分析和价格影响评估;专业要求是量化分析与具体建议,拒绝空泛表述。
任务导向:主要任务明确为 5 条核心职责;关注重点限定 6 类新闻类型;分析维度锁定 5 个关键要点。职责、类型、维度全部显式编号,降低 LLM 理解成本。
输出要求:价格影响分析为强制项(模板明确"不允许回复'无法评估影响'");输出格式固定为中文报告 + 末尾 Markdown 表格;质量标准要求详细分析叠加量化评估。
约束条件:时效性约束(优先 15–30 分钟内的新闻,滞后超 2 小时必须说明);可靠性约束(评估来源权威性);完整性约束(必须包含价格影响分析)。
3.3 动态提示词注入
提示词通过ChatPromptTemplate构建,使用MessagesPlaceholder承接历史消息,再以partial注入运行时变量:
prompt = ChatPromptTemplate.from_messages([ ( "system", "您是一位专业的财经新闻分析师。" "\n🚨 CRITICAL REQUIREMENT - 绝对强制要求:" "\n1. 您的第一个动作必须是调用 get_stock_news_unified 工具" "\n2. 该工具会自动识别股票类型(A股、港股、美股)并获取相应新闻" "\n3. 只有在成功获取新闻数据后,才能开始分析" "\n\n您可以访问以下工具:{tool_names}。" "\n标的约束:{instrument_context}" "\n{system_message}" "\n供您参考,当前日期是{current_date}。我们正在查看公司{ticker}。" "\n请按照上述要求执行,用中文撰写所有分析内容。", ), MessagesPlaceholder(variable_name="messages"), ]) # 动态参数注入 prompt = prompt.partial(system_message=system_message) prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools])) prompt = prompt.partial(current_date=current_date) prompt = prompt.partial(ticker=ticker) prompt = prompt.partial(instrument_context=instrument_context)与文档版本相比,当前实现额外注入了两个关键变量:
{tool_names}:由统一新闻工具的名称拼接而成,配合"必须调用工具"的强约束指令,从提示词层面强制 LLM 走工具调用而非凭空作答;{instrument_context}:由 tradingagents/agents/utils/instrument_utils.py 的build_instrument_context(ticker)生成,把标的约束信息固化进系统提示词,进一步压缩幻觉空间。
4. 工具链执行流程
4.1 初始化阶段
def create_news_analyst(llm, toolkit): @log_analyst_module("news") def news_analyst_node(state): # 1. 提取状态信息 current_date = state["trade_date"] ticker = state["company_of_interest"] session_id = state.get("session_id", "未知会话") # 2. 股票类型识别 market_info = StockUtils.get_market_info(ticker) is_china = market_info['is_china'] # 3. 工具选择(当前版本:统一新闻工具) unified_news_tool = create_unified_news_tool(toolkit) unified_news_tool.name = "get_stock_news_unified" tools = [unified_news_tool] # 4. 提示词构建 prompt = build_prompt_template(system_message, tools, current_date, ticker)4.2 新闻获取阶段:统一新闻工具的内部路由
位置:tradingagents/tools/unified_news_tool.py
UnifiedNewsAnalyzer是当前版本的新闻获取中枢。它先通过_identify_stock_type用正则识别股票类型,再路由到对应市场的获取方法:
def _identify_stock_type(self, stock_code: str) -> str: stock_code = stock_code.upper().strip() if re.match(r'^(00|30|60|68)\d{4}$', stock_code) or re.match(r'^(SZ|SH)\d{6}$', stock_code): return "A股" elif re.match(r'^\d{4,5}\.HK$', stock_code) or (re.match(r'^\d{4,5}$', stock_code) and len(stock_code) <= 5): return "港股" elif re.match(r'^[A-Z]{1,5}$', stock_code) or ('.' in stock_code and not stock_code.endswith('.HK')): return "美股" return "A股" # 默认按A股处理各市场的新闻源优先级(工具 description 中明确声明):
| 市场 | 优先级 1 | 优先级 2 | 优先级 3 |
|---|---|---|---|
| A 股 | 东方财富(数据库缓存优先) | Google 中文搜索 | OpenAI 全球新闻 |
| 港股 | Google 中文搜索 | OpenAI 全球新闻 | 实时新闻聚合器 |
| 美股 | OpenAI 全球新闻 | Google 英文搜索 | FinnHub |
A 股路径还有一个显著增强:优先查 MongoDB 数据库缓存(_get_news_from_database,查询tradingagents库的stock_news集合,按symbol匹配、publish_time倒序、最近 30 天窗口);缓存未命中时通过_sync_news_from_akshare在新线程中创建独立事件循环调用AKShareProvider.get_stock_news拉取东方财富新闻并入库,随后重新查询。这一"DB → 同步 → 重查"的三段式设计,既规避了异步事件循环冲突,也让新闻数据具备可复用的持久化能力。
get_realtime_stock_news的传统多源聚合实现(兼容层仍可用)对应文档描述的流程:
def get_realtime_stock_news(ticker: str, hours_back: int = 6): # 1. 多源新闻获取 finnhub_news = _get_finnhub_realtime_news(ticker, hours_back) av_news = _get_alpha_vantage_news(ticker, hours_back) newsapi_news = _get_newsapi_news(ticker, hours_back) chinese_news = _get_chinese_finance_news(ticker, hours_back) # 2. 新闻聚合 all_news = finnhub_news + av_news + newsapi_news + chinese_news # 3. 去重和排序 unique_news = _deduplicate_news(all_news) sorted_news = sorted(unique_news, key=lambda x: x.publish_time, reverse=True) # 4. 格式化报告 report = format_news_report(sorted_news, ticker) return report4.3 LLM 分析阶段:多模型适配与补救机制
news_analyst_node对 LLM 调用做了细致的模型分流(这是文档未展开、但源码中非常关键的部分):
- DashScope / DeepSeek / Zhipu 模型:在正式调用前先"预处理"强制调用
unified_news_tool(stock_code=ticker, max_news=10)预取新闻。若预取内容超过 100 字符,则直接以"系统提示 + 新闻数据"两段消息调用 LLM 生成分析,完全跳过工具调用环节——因为这类模型对 function calling 的支持不稳定; - Google / Gemini 模型:走
GoogleToolCallHandler(tradingagents/agents/utils/google_tool_handler.py),由统一处理器完成工具调用解析与二次分析; - 其他模型(标准路径):
chain = prompt | llm.bind_tools(tools)后chain.invoke({"messages": state["messages"]}); - 工具零调用补救:若标准路径下
result.tool_calls为空,会强制拉取真实新闻(forced_news = unified_news_tool(...)),将新闻数据拼进forced_prompt重新请求 LLM,杜绝"没拿到数据就凭空分析"的情况。
4.4 报告生成阶段
聚合器侧的format_news_report(realtime_news.py)按紧急程度分组输出:
def format_news_report(news_items: List[NewsItem], ticker: str) -> str: high_urgency = [n for n in news_items if n.urgency == 'high'] medium_urgency = [n for n in news_items if n.urgency == 'medium'] report = f"# {ticker} 实时新闻分析报告\n\n" report += f"📅 生成时间: ...\n📊 新闻总数: {len(news_items)}条\n\n" if high_urgency: report += "## 🚨 紧急新闻\n\n" for news in high_urgency[:3]: # 最多3条 report += f"### {news.title}\n**来源**: {news.source} | **时间**: ...\n{news.content}\n\n" if medium_urgency: report += "## 📢 重要新闻\n\n" for news in medium_urgency[:5]: # 最多5条 report += f"### {news.title}\n**来源**: {news.source} | **时间**: ...\n{news.content}\n\n" # 时效性说明(30分钟内优秀 / 1小时内良好 / 超1小时一般) report += f"\n## ⏰ 数据时效性\n最新新闻发布于: {time_diff_minutes:.0f}分钟前\n" return report同时源码会统计并记录新闻来源分布(如"东方财富: 5条, FinnHub: 3条"),为后续数据质量审计提供依据。
5. 关键特性和优势
智能工具选择:自动识别 A 股、港股、美股;A 股优先中文新闻源、美股优先英文新闻源;在线/离线模式可切换(在线开关由 tradingagents/default_config.py 的online_tools、online_news、realtime_data三个环境变量控制)。
多源新闻聚合:FinnHub、Alpha Vantage 提供高质量专业金融新闻;NewsAPI 提供广泛通用覆盖;东方财富、财联社 RSS 提供中文本地化新闻支持 A 股分析。
智能新闻处理:基于标题相似度的去重;关键词匹配 + 内容分析的紧急程度评估;多维度的相关性评分;发布时间与当前时间的时效性对比。
强化提示词设计:角色明确(专业财经新闻分析师);任务具体(5 大职责 + 6 类新闻类型);输出标准强制(必须包含价格影响分析);质量保证(详细分析 + 量化评估 + Markdown 表格收尾)。
完整的日志追踪:每个步骤都有耗时统计、工具调用记录、新闻数量与来源分布统计、异常详细记录(借助 tradingagents/utils/tool_logging.py 的log_analyst_module装饰器与统一日志体系)。
6. 使用示例
6.1 基本使用(分析师节点方式)
from tradingagents.agents.analysts.news_analyst import create_news_analyst from tradingagents.agents.utils.agent_utils import Toolkit from tradingagents.llm_adapters import ChatDashScope # 创建LLM和工具包 llm = ChatDashScope() toolkit = Toolkit() # 创建新闻分析师 news_analyst = create_news_analyst(llm, toolkit) # 执行分析 state = { "trade_date": "2024-01-15", "company_of_interest": "AAPL", "messages": [], "session_id": "test_session" } result = news_analyst(state) print(result["news_report"])6.2 自定义配置(聚合器方式)
# 自定义新闻聚合器 from tradingagents.dataflows.realtime_news_utils import RealtimeNewsAggregator aggregator = RealtimeNewsAggregator() # 自定义紧急程度关键词 aggregator.high_urgency_keywords = ["破产", "收购", "FDA批准"] aggregator.medium_urgency_keywords = ["财报", "合作", "新产品"] # 获取新闻 news_items = aggregator.get_realtime_stock_news("AAPL", hours_back=12) report = aggregator.format_news_report(news_items, "AAPL")6.3 统一新闻工具方式(推荐)
from tradingagents.tools.unified_news_tool import create_unified_news_tool unified_tool = create_unified_news_tool(toolkit) # A股: 000001 港股: 0700.HK 美股: AAPL report = unified_tool(stock_code="000001", max_news=10, model_info="ChatDashScope:qwen-max")7. 配置要求
7.1 API 密钥配置
聚合器在构造时通过os.getenv读取以下环境变量(缺失的源会被自动跳过):
# .env 文件配置 FINNHUB_API_KEY=your_finnhub_key ALPHA_VANTAGE_API_KEY=your_alpha_vantage_key NEWSAPI_KEY=your_newsapi_key此外,A 股新闻链路依赖 AKShare 与 MongoDB(stock_news集合),后者由项目统一的数据层管理;在线工具总开关ONLINE_TOOLS_ENABLED默认关闭(false),需要时在.env中显式开启。
7.2 依赖包要求
# requirements.txt requests>=2.28.0 langchain-core>=0.1.0 akshare>=1.9.0 # 用于东方财富新闻 feedparser # 用于财联社RSS解析(_parse_rss_feed)其中feedparser是财联社 RSS 路径的运行时依赖:源码中_parse_rss_feed在ImportError时会优雅降级并记录错误日志,不会中断整个聚合流程。
8. 性能优化
缓存机制:新闻缓存(数据库stock_news集合按股票代码 + 30 天窗口查询,避免重复 API 调用);相同股票的分析结果缓存;工具调用结果缓存。
并发与异步处理:多新闻源顺序容错获取 + 单源异常隔离;A 股同步任务通过ThreadPoolExecutor+ 新事件循环在独立线程执行,规避异步事件循环冲突,并带 30 秒超时保护;每个外部请求都有超时与raise_for_status()校验。
错误处理:API 失败自动降级到下一数据源;网络错误记录堆栈后返回空列表而非抛异常;聚合器、统一新闻工具、分析师节点三层均捕获异常并回退(如 LLM 零工具调用时强制预取新闻补救)。
9. 扩展性设计
新数据源接入:统一标准接口(_get_xxx_news(ticker, hours_back) -> List[NewsItem]),新增源只需实现该方法并加入get_realtime_stock_news的聚合列表;或直接在UnifiedNewsAnalyzer对应市场的优先级链中插入;_parse_rss_feed预留了 RSS 源列表(如财联社),可批量追加。
分析能力扩展:可基于NewsItem.content扩展情感分析(数据库新闻已含sentiment字段)、关键事件自动提取、基于历史数据的影响预测。
多语言与本地化:中英文新闻统一处理;A 股/港股走中文源、美股走英文源的市场级路由;提示词模板支持在_format_news_result中对 Google 系模型做智能长度控制(关键词优先保留 + 目标长度截断),避免超长上下文。
总结
TradingAgents-CN 的新闻分析工具链,本质上是一套"多源容错的数据获取层 + 规则化的质量加工层 + 强约束的提示词驱动层"三层架构。数据获取层通过统一新闻工具按股票类型自动路由并叠加数据库缓存与同步机制;质量加工层用关键词分级、相关性评分、时效性标注把原始新闻转成 LLM 友好的结构化输入;提示词层则用角色定义、职责编号、强制输出与动态注入,把分析结果稳定约束为"中文报告 + 量化评估 + Markdown 表格"。对于希望在自己的量化分析系统中引入新闻信号、或想借鉴提示词工程实践的开发者,本文涉及的源码路径——news_analyst.py、unified_news_tool.py、realtime_news.py、agent_utils.py——都是可直接阅读和复用的第一手参考。
【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考