ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

TradingAgents-CN 分析报告模块结构深度解析:9 个后端报告与 13 个前端展示模块的设计原理

TradingAgents-CN 分析报告模块结构深度解析:9 个后端报告与 13 个前端展示模块的设计原理 TradingAgents-CN 分析报告模块结构深度解析9 个后端报告与 13 个前端展示模块的设计原理【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN导读TradingAgents-CN 采用多智能体协作Multi-Agent Collaboration的方式生成股票分析报告其核心难点在于后端如何保存各智能体产出的报告前端又如何将不同粒度的报告组织呈现给用户。本文基于仓库中的模块结构说明文档结合app/services/simple_analysis_service.py、tradingagents/agents/utils/agent_states.py与frontend/src/views/Reports/ReportDetail.vue等源码实现完整拆解「9 个后端报告模块 → 13 个前端展示模块」的映射机制、五阶段多智能体流水线、MongoDB 存储结构、State 对象设计以及分析深度对报告数量的影响。读完本文你将掌握该框架报告数据的完整生命周期从智能体产出、State 汇聚、后端提取入库到前端按角色拆分展示的每一环。一、总体设计一次分析两套视图TradingAgents-CN 的报告体系遵循一个核心设计原则保存层面精炼展示层面灵活。保存层面系统实际保存9 个主要报告模块外加 1 个可选的旧版investment_plan字段展示层面前端可以展示为13 个细分模块外加若干兼容旧字段。产生这种差异的根本原因是研究团队决策research_team_decision和风险管理决策risk_management_decision这两个「综合报告」内部封装了多个角色的独立观点前端可以选择整体展示也可以拆分出多头/空头研究员、激进/保守/中性分析师等子模块分别呈现从而让用户看到完整的团队辩论过程。该设计思路在仓库前端注释中也有印证见 frontend/src/views/Reports/ReportDetail.vue 中getModuleDisplayName的说明「统一与单股分析的中文标签映射完整的 13 个报告」。二、报告生成流程五阶段多智能体协作流水线整份分析报告由 5 个阶段的智能体协作产出从分析师独立研究到研究团队辩论再到交易员规划、风险管理团队辩论最终形成交易决策第一阶段分析师团队4个独立报告 市场分析师() 基本面分析师() 情绪分析师() 新闻分析师() └──────────────────┬──────────────────┘ ↓ 第二阶段研究团队辩论1个综合报告 研究团队决策research_team_decision ├── 多头研究员bull_history ├── 空头研究员bear_history └── 研究经理judge_decision ↓ 第三阶段交易团队1个独立报告 交易员计划trader_investment_plan ↓ 第四阶段风险管理团队辩论1个综合报告 风险管理决策risk_management_decision ├── 激进分析师risky_history ├── 保守分析师safe_history ├── 中性分析师neutral_history └── 投资组合经理judge_decision ↓ 第五阶段最终决策1个独立报告 最终交易决策final_trade_decision各阶段角色与产出阶段参与智能体后端报告字段类型一市场分析师、基本面分析师、情绪分析师、新闻分析师market_report、fundamentals_report、sentiment_report、news_report4 个独立报告二多头研究员、空头研究员、研究经理research_team_decision1 个综合报告三交易员trader_investment_plan1 个独立报告四激进分析师、保守分析师、中性分析师、投资组合经理risk_management_decision1 个综合报告五风险分析师最终决策final_trade_decision1 个独立报告三、AgentState贯穿分析全程的状态容器分析过程中所有中间产出都存储在AgentState对象中。它继承自 LangGraph 的MessagesState定义于 tradingagents/agents/utils/agent_states.pyclass AgentState(MessagesState): # 基础信息 company_of_interest: Annotated[str, Company that we are interested in trading] trade_date: Annotated[str, What date we are trading at] sender: Annotated[str, Agent that sent this message] # 第一阶段分析师报告 market_report: Annotated[str, Report from the Market Analyst] sentiment_report: Annotated[str, Report from the Social Media Analyst] news_report: Annotated[str, Report from the News Researcher of current world affairs] fundamentals_report: Annotated[str, Report from the Fundamentals Researcher] # 死循环修复: 工具调用计数器 market_tool_call_count: Annotated[int, Market analyst tool call counter] news_tool_call_count: Annotated[int, News analyst tool call counter] sentiment_tool_call_count: Annotated[int, Social media analyst tool call counter] fundamentals_tool_call_count: Annotated[int, Fundamentals analyst tool call counter] # 第二阶段研究团队辩论状态 investment_debate_state: Annotated[InvestDebateState, Current state of the debate on if to invest or not] investment_plan: Annotated[str, Plan generated by the Analyst] # 第三阶段交易员计划 trader_investment_plan: Annotated[str, Plan generated by the Trader] # 第四阶段风险管理团队辩论状态 risk_debate_state: Annotated[RiskDebateState, Current state of the debate on evaluating risk] # 第五阶段最终决策 final_trade_decision: Annotated[str, Final decision made by the Risk Analysts]从源码可以看到两个值得注意的实现细节工具调用计数器源码中额外定义了market_tool_call_count等 4 个计数器字段注释标明用于「死循环修复」防止分析师 Agent 在调用数据工具时陷入无限循环这是仓库针对实际运行问题做的增强。Annotated注解所有字段使用Annotated[str, 描述]形式同时利用 LangGraph 的 TypedDict 通道channel机制在各节点之间传递状态。四、辩论状态结构综合报告的来源两个综合报告研究团队决策、风险管理决策的「角色观点」分别来自两个辩论状态对象它们同样是 TypedDict定义于同一文件 tradingagents/agents/utils/agent_states.py。InvestDebateState研究团队辩论class InvestDebateState(TypedDict): bull_history: Annotated[str, Bullish Conversation history] # 多头研究员的完整对话历史 bear_history: Annotated[str, Bearish Conversation history] # 空头研究员的完整对话历史 history: Annotated[str, Conversation history] # 整体对话历史 current_response: Annotated[str, Latest response] # 最新回复 judge_decision: Annotated[str, Final judge decision] # 研究经理的最终决策 → research_team_decision count: Annotated[int, Length of the current conversation] # 对话轮数RiskDebateState风险管理团队辩论class RiskDebateState(TypedDict): risky_history: Annotated[str, Risky Agents Conversation history] # 激进分析师的完整对话历史 safe_history: Annotated[str, Safe Agents Conversation history] # 保守分析师的完整对话历史 neutral_history: Annotated[str, Neutral Agents Conversation history] # 中性分析师的完整对话历史 history: Annotated[str, Conversation history] # 整体对话历史 latest_speaker: Annotated[str, Analyst that spoke last] # 最后发言的分析师 current_risky_response: Annotated[str, Latest response by the risky analyst] # 激进分析师的最新回复 current_safe_response: Annotated[str, Latest response by the safe analyst] # 保守分析师的最新回复 current_neutral_response: Annotated[str, Latest response by the neutral analyst] # 中性分析师的最新回复 judge_decision: Annotated[str, Judges decision] # 投资组合经理的最终决策 → risk_management_decision count: Annotated[int, Length of the current conversation] # 对话轮数关键点judge_decision研究经理/投资组合经理的最终决策是唯一被写入reports的辩论内容而完整的辩论历史bull_history、bear_history、risky_history等保留在辩论状态对象中不直接保存到 reports 字段——但它们会在后端提取阶段被单独拆分为独立模块见下文第六节。五、MongoDB 存储结构analysis_reports 集合分析完成后报告以文档形式保存到 MongoDB 的analysis_reports集合保存逻辑见 app/services/simple_analysis_service.py 的_save_analysis_result_web_style方法。核心文档结构如下{ analysis_id: 000001_20251014_120000, stock_symbol: 000001, stock_name: 平安银行, market_type: A股, model_info: qwen-plus, analysis_date: 2025-10-14, timestamp: 2025-10-14T12:00:00Z, status: completed, source: api, summary: 执行摘要..., analysts: [市场分析师, 基本面分析师, 情绪分析师, 新闻分析师], research_depth: 3, reports: { market_report: 市场技术分析内容..., fundamentals_report: 基本面分析内容..., sentiment_report: 市场情绪分析内容..., news_report: 新闻事件分析内容..., research_team_decision: 研究经理的综合决策内容包含多空辩论摘要..., trader_investment_plan: 交易员计划内容..., risk_management_decision: 投资组合经理的综合决策内容包含风险辩论摘要..., final_trade_decision: 最终交易决策内容..., investment_plan: 投资建议内容...可选早期版本字段 }, decision: { action: 买入, confidence: 0.75, risk_score: 0.3, target_price: 12.5, reasoning: ... }, recommendation: 投资建议买入。目标价格12.5元。, confidence_score: 0.75, risk_level: 中等, key_points: [], execution_time: 123, tokens_used: 4567, created_at: 2025-10-14T12:00:00Z, updated_at: 2025-10-14T12:00:00Z }补充说明来自源码analysis_id由股票代码 时间戳拼接生成f{stock_symbol}_{timestamp.strftime(%Y%m%d_%H%M%S)}如000001_20251014_120000除reports外文档还保存decision格式化后的结构化决策动作/置信度/风险分/目标价/推理、summary从final_trade_decision截取前 200 字符并去除#、*后生成等字段保存到analysis_reports的同时会同步更新analysis_tasks集合中的result字段以保持 API 兼容另有一套_save_modular_reports_to_data_dir方法将模块化报告落盘到data/analysis_results目录见 app/services/simple_analysis_service.py。六、后端保存逻辑从 State 提取 9 个模块后端报告提取的核心代码位于 app/services/simple_analysis_service.py以及重复实现于 web 风格保存路径 L2370 起。提取流程分三步第一步提取 7 个独立报告字段report_fields [ market_report, sentiment_report, news_report, fundamentals_report, investment_plan, # 可选 trader_investment_plan, final_trade_decision ] for field in report_fields: if hasattr(state, field): value getattr(state, field, ) elif isinstance(state, dict) and field in state: value state[field] else: value if isinstance(value, str) and len(value.strip()) 10: # 只保存有实际内容的报告 reports[field] value.strip()注意源码中的空内容过滤策略len(value.strip()) 10才入库内容为空或太短的报告会被跳过logger.debug记录。第二步从研究团队辩论状态拆分出 3 个模块if investment_debate_state in state: debate_state state[investment_debate_state] reports[bull_researcher] debate_state[bull_history] # 多头研究员 reports[bear_researcher] debate_state[bear_history] # 空头研究员 reports[research_team_decision] debate_state[judge_decision] # 研究经理决策第三步从风险管理团队辩论状态拆分出 4 个模块if risk_debate_state in state: risk_state state[risk_debate_state] reports[risky_analyst] risk_state[risky_history] # 激进分析师 reports[safe_analyst] risk_state[safe_history] # 保守分析师 reports[neutral_analyst] risk_state[neutral_history] # 中性分析师 reports[risk_management_decision] risk_state[judge_decision] # 投资组合经理决策这样reports字典最终最多包含13 个键4分析师 3研究团队 1交易员 4风险管理 1最终决策 1可选投资建议 14 个候选键其中 2 个旧字段仅兼容。若某字段内容为空则不入库因此常规完整分析深度 3约得到 9 个实际报告。七、前端展示逻辑13 个模块映射与拆分报告模块映射表前端getModuleDisplayName函数定义了完整的映射见 frontend/src/views/Reports/ReportDetail.vueconst getModuleDisplayName (moduleName: string) { const nameMap: Recordstring, string { // 第一阶段分析师团队4个独立报告 market_report: 市场技术分析, sentiment_report: 市场情绪分析, news_report: 新闻事件分析, fundamentals_report: 基本面分析, // 第二阶段研究团队从 research_team_decision 拆分展示 bull_researcher: 多头研究员, bear_researcher: 空头研究员, research_team_decision: 研究经理决策, // 第三阶段交易团队1个独立报告 trader_investment_plan: 交易员计划, // 第四阶段风险管理团队从 risk_management_decision 拆分展示 risky_analyst: ⚡ 激进分析师, safe_analyst: ️ 保守分析师, neutral_analyst: ⚖️ 中性分析师, risk_management_decision: 投资组合经理, // 第五阶段最终决策1个独立报告 final_trade_decision: 最终交易决策, // 兼容旧字段 investment_plan: 投资建议, investment_debate_state: 研究团队决策旧, risk_debate_state: ⚖️ 风险管理团队旧, detailed_analysis: 详细分析 } // 未匹配到时做一个友好的回退下划线转空格 return nameMap[moduleName] || moduleName.replace(/_/g, ) }源码中比文档版本多了两个映射detailed_analysis: 详细分析兼容字段以及最终兜底策略moduleName.replace(/_/g, )下划线转空格保证任何未知字段都能友好展示。展示逻辑分类独立报告7 个直接从reports对象读取无需拆分market_report、fundamentals_report、sentiment_report、news_report、trader_investment_plan、final_trade_decision以及可选的investment_plan综合报告2 个需要拆分展示research_team_decision包含多头/空头/研究经理的观点risk_management_decision包含激进/保守/中性/投资组合经理的观点前端拆分策略前端可以选择直接展示综合报告1 个模块也可以拆分展示各个角色的观点3 个或 4 个子模块通过字段名映射实现。即研究团队决策可展示为bull_researcherbear_researcherresearch_team_decision3 个模块风险管理决策可展示为risky_analystsafe_analystneutral_analystrisk_management_decision4 个模块加上 4 个分析师独立报告、1 个交易员计划、1 个最终决策合计 13 个展示模块。八、报告内容说明9 个模块的职责边界第一阶段分析师团队4 个独立报告 市场技术分析market_reportK 线/技术指标与趋势判断支撑阻力位与形态识别市场情绪、资金流向与板块表现阶段性买卖时机评估 基本面分析fundamentals_report财务数据分析盈利能力评估成长性分析估值分析 市场情绪分析sentiment_report社交媒体与社区舆情监测热点传播强度与扩散路径短期情绪对股价的可能影响 新闻事件分析news_report相关新闻汇总事件影响评估与新闻情绪风险与不确定性提示第二阶段研究团队决策1 个综合报告 研究团队决策research_team_decision——研究经理的综合决策通常包含多头研究员的主要观点摘要空头研究员的主要观点摘要研究经理综合两方观点后的最终判断投资建议初步结论注意完整的辩论历史存储在investment_debate_state中bull_history/bear_history但不直接保存到 reports 字段仅在后端提取时单独拆分为bull_researcher/bear_researcher模块。第三阶段交易团队1 个独立报告 交易员计划trader_investment_plan具体交易策略仓位管理建议买卖时机规划止损止盈设置第四阶段风险管理团队决策1 个综合报告 风险管理决策risk_management_decision——投资组合经理的综合决策通常包含激进分析师的主要观点摘要保守分析师的主要观点摘要中性分析师的主要观点摘要投资组合经理综合三方观点后的最终决策最终风险等级和投资组合建议注意完整的辩论历史存储在risk_debate_state中不直接保存到 reports 字段但会拆分为risky_analyst/safe_analyst/neutral_analyst模块。第五阶段最终决策1 个独立报告 最终交易决策final_trade_decision综合所有团队分析最终投资建议置信度评分风险等级执行计划可选报告 投资建议investment_plan早期版本的投资建议部分报告可能包含此字段在有研究团队决策时此字段可能为空九、分析深度与报告数量的关系不同的分析深度research_depth会执行不同阶段的智能体流程从而产生不同数量的报告。从 app/services/simple_analysis_service.py 的深度分支逻辑可以印证深度等级决定是否进入研究团队辩论、交易员、风险管理与最终决策阶段。分析深度报告数量包含的报告深度 14-5 个分析师团队报告 投资建议可选深度 26-7 个深度 1 研究团队决策 交易员计划深度 38-9 个深度 2 风险管理决策 最终交易决策深度参数同时支持**数字1-5与中文等级快速/基础/标准/深度/全面**两种输入方式后端会自动归一化转换见 app/services/simple_analysis_service.py数字 1-5 分别映射到快速/基础/标准/深度/全面非法值回退为「标准」分析。十、设计总结与可扩展性TradingAgents-CN 的报告模块体系可以总结为四个关键设计保存层面系统实际保存9 个主要报告模块4 分析师 1 研究团队决策 1 交易员计划 1 风险管理决策 1 最终交易决策 1 可选投资建议展示层面前端可以展示为13 个细分模块对 2 个综合报告按角色拆分多出多头/空头研究员、激进/保守/中性分析师 5 个子模块核心设计研究团队决策和风险管理决策是综合报告内部封装了各角色的观点和最终决策完整辩论历史存放于辩论状态对象而不直接落入 reports灵活性前端可以选择展示综合报告或拆分展示各个角色的观点通过字段名映射实现无需后端改动可扩展性未来可以根据需要调整展示粒度而不需要修改后端保存逻辑——因为底层 state 中始终保留了所有角色的完整产出。这种「后端保存精炼 前端拆分灵活」的设计既保证了数据的完整性又提供了多层次的展示方式让用户既可以快速查看综合结论也可以深入查看每一个智能体角色的完整分析过程是理解 TradingAgents-CN 数据流与前端报告页面的关键入口。【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表