ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

TradingAgents-CN 异步进度跟踪系统深度解析:LangGraph 多智能体循环工作流与前端实时进度显示

TradingAgents-CN 异步进度跟踪系统深度解析:LangGraph 多智能体循环工作流与前端实时进度显示 TradingAgents-CN 异步进度跟踪系统深度解析LangGraph 多智能体循环工作流与前端实时进度显示【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN本文围绕 TradingAgents-CN 的异步进度跟踪系统展开先解释基于 LangGraph 的多智能体分析为何会呈现重复调用日志再深入到AsyncProgressTracker的步骤检测、动态步骤生成、权重平衡与双存储持久化实现并给出前端进度组件的刷新机制、测试脚本与常见问题排查方案。读完本文你将掌握这套系统后端如何计算进度、前端如何展示进度、测试如何验证进度的完整技术链路。为什么会在日志中看到重复的分析师调用TradingAgents-CN 使用 LangGraph 框架编排多智能体分析流程。每个分析师节点并不是一次执行即结束而是遵循如下的循环流程分析师节点 → 条件判断 → 工具节点 → 回到分析师节点 → 条件判断 → ...以市场分析师为例一次完整的分析会经历两个阶段第一轮工具获取 [模块开始] market_analyst—— 分析师节点开始工作 [市场分析师] 工具调用: [get_stock_market_data_unified]—— LLM 决定调用统一行情工具执行工具获取真实市场数据控制流回到分析师节点。第二轮结果处理分析师节点读取工具返回的数据进行推理与加工生成分析报告此时不再有新的工具调用 [模块完成] market_analyst—— 分析师节点完成流程推进到下一个模块。因此日志中出现的两次market_analyst并非重复执行而是 LangGraph 图结构中工具调用-回到节点-继续推理的同一节点多轮往返。这套设计带来四个关键能力多轮工具调用一个分析师可能需要依次调用多个数据工具行情、基本面、新闻等数据处理工具返回原始数据后分析师还需进一步归纳、计算与结构化错误恢复工具调用失败时可以在节点内重试而不至于让整个图崩溃复杂推理支持基于工具结果的多步推理链让分析报告更有依据。这些模块开始/模块完成/工具调用日志由 tradingagents/utils/logging_manager.py 中的log_module_start/log_module_complete统一产出格式固定为 [模块开始] {module_name} - 股票: {stock_symbol}与 [模块完成] {module_name} - {status} - 股票: {stock_symbol}, 耗时: {duration:.2f}s。这套结构化日志正是进度跟踪系统赖以工作的信号源。进度跟踪系统的五大核心能力异步进度跟踪器AsyncProgressTracker位于 web/utils/async_progress_tracker.py围绕上述循环工作流设计具备五项核心能力智能步骤检测准确识别所有分析节点的开始模块开始与完成模块完成工具调用处理正确区分工具调用消息——它不推进步骤只更新当前步骤描述动态步骤生成根据分析师配置与研究深度动态生成完整步骤序列而非写死固定步骤权重平衡为每个步骤分配权重并自动归一化保证进度百分比计算平滑准确状态持久化同时支持 Redis 与文件两种存储方式具备自动降级与恢复能力。在 web/app.py 中创建跟踪器的调用如下async_tracker AsyncProgressTracker( analysis_idanalysis_id, analystsform_data[analysts], research_depthform_data[research_depth], llm_providerconfig[llm_provider] )构造参数analysts、research_depth、llm_provider会直接决定后续步骤数量与预估时长。分析任务则在后台线程中运行并通过progress_callback将每一步消息回传给跟踪器任务成功时调用async_tracker.mark_completed(✅ 分析成功完成, resultsresults)异常时调用async_tracker.mark_failed(str(e))。步骤检测逻辑三种消息的三种语义步骤推进的核心逻辑是_detect_step_from_message它对三类关键消息采取完全不同的处理策略def _detect_step_from_message(self, message: str): if 模块开始 in message: # 推进到对应分析师步骤 return analyst_step_index elif 工具调用 in message: # 保持当前步骤更新描述 return None elif 模块完成 in message: # 推进到下一个分析师 return next_step_index实际的源码实现web/utils/async_progress_tracker.py 第 389-452 行比伪代码更细致 开始股票分析/ 数据验证 / 预获取→ 归入步骤 0准备阶段环境 / API / 密钥→ 步骤 1环境检查成本 / 预估→ 步骤 2成本估算配置 / 参数→ 步骤 3参数设置初始化 / 引擎→ 步骤 4启动引擎模块开始→ 根据日志中携带的分析师关键字market_analyst、fundamentals_analyst、bull_researcher、trader、graph_signal_processing等通过_find_step_by_keyword定位到动态生成的步骤名如市场分析多头观点投资建议工具调用→ 返回None即不推进步骤仅在update_progress中改写步骤描述如识别到get_stock_market_data_unified则显示正在获取市场数据和技术指标...模块完成→ 不依赖模块名直接基于当前进度min(self.current_step 1, len(self.analysis_steps) - 1)向后推进避免因步骤名映射偏差导致的卡死。此外更新时有两处保护逻辑步骤只允许前进不允许倒退step self.current_step才更新并且当消息包含分析完成 / 分析成功时直接把current_step置为最后一步确保终态收敛到 100%。动态步骤生成与权重平衡_generate_dynamic_steps根据分析师数量与研究深度实时拼装步骤序列固定前置步骤准备阶段、环境检查、成本估算、参数设置、启动引擎权重合计约占 15%每个分析师按0.6 / len(self.analysts)分配权重分析师团队合计占用约 60%research_depth 2时追加多头观点 / 空头观点 / 观点整合辩论环节所有深度都包含投资建议步骤research_depth 3时追加激进策略 / 保守策略 / 平衡策略 / 风险控制完整风险评估否则使用简化的风险提示最后追加生成报告收尾。所有步骤权重在拼接完成后统一除以总和做归一化保证权重和恒为 1.0。进度百分比由_calculate_weighted_progress计算已完成步骤的权重和除以总权重最后一步直接返回 1.0。这套机制保证分析师越多、研究深度越深步骤越多进度不会因配置变化而失真。时间预估基于配置的动态模型_estimate_total_duration根据三个维度预估总时长秒影响因素取值说明基础时间60s环境准备、配置等固定开销单分析师耗时深度1180s深度2360s深度3600s基于真实测试数据分别约 3/6/10 分钟模型速度倍率dashscope1.0deepseek0.7google1.3DeepSeek 较快、Google 较慢深度倍率深度10.8深度21.0深度31.3深度越高工具调用与推理越多总时长公式为(base_time 分析师数 × 单分析师耗时) × 模型倍率 × 深度倍率。剩余时间_estimate_remaining_time采用预估总时长 - 已用时间的固定值计算并在完成后归零。状态持久化Redis 优先、文件兜底AsyncProgressTracker初始化时通过_init_redis判断存储方式读取环境变量REDIS_ENABLED默认false非true直接使用文件存储启用 Redis 时从REDIS_HOST默认 localhost、REDIS_PORT默认 6379、REDIS_PASSWORD、REDIS_DB默认 0读取配置ping()通过才确认启用Redis 键为progress:{analysis_id}使用setex设置 1 小时过期文件存储写入./data/progress_{analysis_id}.json自动创建目录。保存时使用safe_serialize对数据进行安全序列化对 LangChain 消息对象Message类实例依次尝试dict()/to_dict()失败则手动提取content、additional_kwargs、response_metadata对 Pydantic 对象、普通对象、列表字典递归处理最终兜底转为字符串从而避免json.dumps序列化异常导致进度写入失败。若主存储写入失败还会自动降级Redis 失败写文件、文件失败写简化字段保证进度数据尽量不丢。读取侧提供三个全局函数get_progress_by_id(analysis_id)先查 Redis 再查文件供前端轮询使用get_latest_analysis_id()遍历progress:*键或data/progress_*.json文件按last_update/ 修改时间找出最近一次分析用于页面刷新后的断线恢复format_time(seconds)将秒数格式化为X秒 / X分钟 / X小时供前端展示。前端进度显示组件web/components/async_progress_display.py 提供多层显示能力核心是静态进度显示 手动/自动刷新组合display_static_progress不自动触发页面刷新通过四个列展示当前步骤 / 进度百分比 / 已用时间 / 预计剩余避免 Streamlit 因高频刷新导致页面跳转display_unified_progress/display_static_progress_with_controls统一入口通过show_refresh_controls参数控制是否渲染 刷新进度按钮与自动刷新复选框streamlit_auto_refresh_progressStreamlit 专用自动刷新运行时每 3 秒st.rerun()完成后自动关闭自动刷新避免死循环AsyncProgressDisplay类面向组件的封装内部创建进度条、状态文本、步骤信息、时间信息与刷新按钮占位符。各显示函数的共同数据来源是get_progress_by_id读取的字段包括current_step、total_steps、progress_percentage、current_step_name、current_step_description、elapsed_time、remaining_time、last_message、status。状态用图标区分 running、✅ completed、❌ failed。分析完成时还会渲染 查看分析报告按钮通过format_analysis_results恢复保存在raw_results中的分析结果并跳转到报告页。由于进度数据持久化在 Redis / 文件而非内存页面刷新、多设备访问都能继续读到同一份进度实现断线恢复与多设备同步。日志集成模块消息如何自动转发给跟踪器web/utils/progress_log_handler.py 是连接 LangGraph 日志与进度跟踪器的桥梁ProgressLogHandler是自定义logging.Handler只处理包含[模块开始]或[模块完成]的日志记录setup_progress_log_integration将其挂载到tools日志器上模块消息正是来自该日志器register_tracker/unregister_tracker用类级字典_trackers维护 analysis_id 到跟踪器的映射并加锁防止并发死锁emit中先尝试用正则股票:\s*([A-Za-z0-9])提取股票代码再遍历处于running状态的跟踪器把消息转发给tracker.update_progress(message)。在AsyncProgressTracker.__init__中注册动作被放入带 2 秒超时的守护线程中执行避免日志集成阻塞分析主流程mark_completed/mark_failed结束时调用unregister_analysis_tracker完成注销。此外 web/app.py 中progress_callback也会直接调用async_tracker.update_progress(message, step)形成日志自动转发 显式回调双通道。测试与验证文档中描述的测试场景可归纳为三类仓库中提供了可直接运行的验证脚本 scripts/test_async_progress.py步骤检测测试构造三类消息验证语义—— [模块开始] market_analyst应检测到市场分析师步骤 [工具调用] get_stock_market_data_unified不应推进步骤 [模块完成] market_analyst应推进到下一步。进度计算测试用不同配置验证权重分配与总进度——{analysts: [market], research_depth: 1}快速分析、{analysts: [market, fundamentals], research_depth: 2}标准分析、{analysts: [market, fundamentals, news], research_depth: 3}深度分析分析师数量与深度不同时步骤总数与进度曲线应不同。完整流程测试scripts/test_async_progress.py用AsyncProgressTracker(analysis_idtest_analysis_12345, analysts[market, fundamentals], research_depth2, llm_providerdashscope)创建跟踪器后台线程按真实消息序列含带耗时的模块完成消息如耗时: 41.73s模拟完整分析主线程每秒轮询一次get_progress_by_id打印步骤 x/y、百分比、当前步骤名、已用时、剩余时间最终断言状态进入completed、进度达 100%。运行方式python scripts/test_async_progress.py另外 tests/test_async_analysis.py 覆盖异步分析的完整调用链。测试要点还包括进度平滑推进不倒退、不跳变、完成消息强制收敛到最终步骤、时间预估准确性、以及失败路径下mark_failed后状态置为failed。常见问题排查Q: 为什么进度有时会停留在某个步骤A: 这通常是因为分析师正在进行复杂的多轮推理或正在等待外部 API 响应。此时工具调用消息不会推进步骤进度会暂时停留属正常现象。可以点击 刷新进度或等待自动刷新查看最新状态若长时间卡在同一描述可检查data/progress_{analysis_id}.json或 Redis 中progress:*键的最后更新内容辅助定位。Q: 分析失败了怎么办A: 系统会把状态置为failed并在界面显示详细错误信息红色错误提示与last_message。常见原因包括 API 限额、网络问题或数据源异常。分析结果的历史记录仍会保存为失败记录便于事后排查。也可在侧边栏使用 清理分析状态清理僵尸状态与死亡线程见 web/app.py 第 1096-1118 行。Q: 可以同时运行多个分析吗A: 目前每个用户会话只支持一个分析任务。如需并行分析请使用不同的浏览器会话——进度数据以analysis_id为键独立存储多会话之间互不干扰。Q: 进度时间预估准确吗A: 预估基于历史数据单分析师 3/6/10 分钟基准、模型速度倍率与研究深度倍率动态计算但实际耗时仍可能因网络状况、API 响应速度、模型负载等因素有所差异。前端展示的预计剩余取的是预估总时长 - 已用时间若实际运行慢于预估会出现剩余时间先到 0 而分析仍在进行的情况此时应以步骤推进为准。未来改进方向文档明确了两个方向的演进计划性能优化并行分析部分分析师节点如多空研究员可并行执行以缩短总时长缓存机制重复分析同一股票时复用已获取的数据与结果增量更新进度数据只更新变化的部分降低 Redis / 文件写入开销。用户体验进度预测基于历史分析耗时做更精准的剩余时间预估替代当前的固定值估算中断恢复支持分析任务的暂停与恢复批量分析支持同一会话内多只股票排队或并行分析。结合当前实现web/utils/async_progress_tracker.py、web/components/async_progress_display.py上述方向均有清晰的落点并行分析需要将_generate_dynamic_steps中线性步骤改为并行权重模型缓存机制可复用safe_serialize持久化的raw_results而增量更新只需在_save_progress中做字段级 diff。相关文档与源码索引进度跟踪说明文档docs/features/progress-tracking/progress-tracking-explanation.md异步进度跟踪器实现web/utils/async_progress_tracker.py进度显示组件web/components/async_progress_display.py进度日志集成web/utils/progress_log_handler.py模块开始/完成日志生成tradingagents/utils/logging_manager.pyWeb 入口与后台分析线程web/app.py进度功能测试脚本scripts/test_async_progress.py、tests/test_async_analysis.py【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表