Skip to content

feat(data): retry missing data from reports / 支持缺失数据重试与报告页 PDF 提示 - #58

Open
zhanghang02 wants to merge 1 commit into
simonlin1212:mainfrom
zhanghang02:codex/pr-missing-data-retry
Open

feat(data): retry missing data from reports / 支持缺失数据重试与报告页 PDF 提示#58
zhanghang02 wants to merge 1 commit into
simonlin1212:mainfrom
zhanghang02:codex/pr-missing-data-retry

Conversation

@zhanghang02

Copy link
Copy Markdown
Contributor

Summary / 摘要

  • Track tool calls that return failed or explicitly missing data, and store per-ticker/date missing-data tasks with stage/tool labels and retry metadata.

  • 记录失败或显式缺失的工具调用,按股票/日期保存缺失数据任务,并附带分析阶段、工具标签和重试信息。

  • Add retry support for active missing-data tasks, cache successful retry output, and feed recovered output into the next full analysis before marking it consumed.

  • 支持对仍未补齐的缺失数据任务重新取数,缓存成功重试结果,并在下一次完整分析中复用后标记为已消费。

  • Surface missing-data status in the report page: users can inspect failed tool calls, retry them, start reanalysis after recovery, and still download a current-content PDF with a clear incomplete-data warning.

  • 在报告页展示缺失数据状态:用户可以查看失败工具调用、重新取数、补齐后重新分析;即使仍有缺失项,也可以下载基于当前内容生成的 PDF,并看到明确的不完整数据提示。

Validation / 验证

  • python3 -m pytest tests/test_missing_data_tasks.py tests/test_report_viewer_pdf_gate.py -q -> 9 passed
  • python3 -m py_compile tests/test_missing_data_tasks.py tests/test_report_viewer_pdf_gate.py tradingagents/agents/utils/agent_states.py tradingagents/dataflows/missing_data.py tradingagents/graph/trading_graph.py web/components/report_viewer.py -> passed
  • git diff origin/main..HEAD --check -> clean
  • Sensitive-info scan on the final diff found no credentials, private endpoints, local paths, env files, lock files, .codex/.cc-switch files, or provider-specific additions.
  • 最终 diff 敏感信息扫描未发现凭据、私有 endpoint、本机路径、env 文件、lock 文件、.codex/.cc-switch 文件或新增 provider 相关信息。

Notes / 说明

  • The focused tests stub external UI/runtime modules (streamlit, fpdf, langchain_core, and the pandas-heavy dataflow utility import) so this PR can be validated in the lightweight local Python environment without installing the full project dependency set.
  • 聚焦测试对外部 UI/运行时模块(streamlitfpdflangchain_core,以及会拉入 pandas 的 dataflow utility import)做了测试内 stub,因此无需安装完整项目依赖也能验证本 PR 行为。

@simonlin1212

Copy link
Copy Markdown
Owner

感谢 PR!👏 (你这一串 PR 帮了大忙——#64 / #57 / #56 / #55 都已经合进 v0.2.15 了 🙏)

关于这个「缺失数据重试」:

方便的话rebase 一下,我再 review 这层增强。先留着不关。再次感谢你这一波贡献!

@zcc2xj

zcc2xj commented Jun 21, 2026

Copy link
Copy Markdown

还缺2个数据
📊 关键财务指标与估值汇总
指标项目 数值/状态 备注
PE(TTM) 14.56倍 处于历史估值低位区间
PB 1.69倍 重资产龙头安全边际较高
总市值 1504.94亿元 流通市值1661.2亿元
营收同比增长率 2025年: +8.37%​
​2026Q1: +6.14% 价值驱动转型期,增速趋稳
归母净利润 2025年: 111.17亿元 ​
​2026Q1: 25.26亿元 利润修复斜率向上
归母净利润同比增长率 2025年: +9.31%​
​2026Q1: +13.05% 扣非净利增速达17.42%
ROE 2025年: 11.51%​
​2026E: 11.29% 资本开支见顶后有望回升
资产负债率 [数据缺失: 资产负债率] 接口限制未获取
经营性现金流与净利润比值 [数据缺失: 经营性现金流与净利润比值] 接口限制未获取
机构一致预期 EPS (2026E) 2.42元 19家机构覆盖,区间2.35-2.54元
前向PE (2026E) 13.28倍 对应股价31.55元
机构评级分布 买入(15) / 增持(3) 卖方共识高度看好
这个是顺丰控股的例子。

资产负债率 [数据缺失: 资产负债率] 接口限制未获取
经营性现金流与净利润比值 [数据缺失: 经营性现金流与净利润比值] 接口限制未获取

@zcc2xj

zcc2xj commented Jun 21, 2026

Copy link
Copy Markdown

还缺2个数据 📊 关键财务指标与估值汇总 指标项目 数值/状态 备注 PE(TTM) 14.56倍 处于历史估值低位区间 PB 1.69倍 重资产龙头安全边际较高 总市值 1504.94亿元 流通市值1661.2亿元 营收同比增长率 2025年: +8.37%​​2026Q1: +6.14% 价值驱动转型期,增速趋稳 归母净利润 2025年: 111.17亿元 ​​2026Q1: 25.26亿元 利润修复斜率向上 归母净利润同比增长率 2025年: +9.31%​​2026Q1: +13.05% 扣非净利增速达17.42% ROE 2025年: 11.51%​​2026E: 11.29% 资本开支见顶后有望回升 资产负债率 [数据缺失: 资产负债率] 接口限制未获取 经营性现金流与净利润比值 [数据缺失: 经营性现金流与净利润比值] 接口限制未获取 机构一致预期 EPS (2026E) 2.42元 19家机构覆盖,区间2.35-2.54元 前向PE (2026E) 13.28倍 对应股价31.55元 机构评级分布 买入(15) / 增持(3) 卖方共识高度看好 这个是顺丰控股的例子。

资产负债率 [数据缺失: 资产负债率] 接口限制未获取 经营性现金流与净利润比值 [数据缺失: 经营性现金流与净利润比值] 接口限制未获取

抱歉我这个是0214版本还有关键数据确实,0215好像没了

@zhanghang02

Copy link
Copy Markdown
Contributor Author

抱歉才看到,我找时间结合各位反馈改一下

@zhanghang02
zhanghang02 force-pushed the codex/pr-missing-data-retry branch from 3bedc47 to 1ac5114 Compare July 3, 2026 09:25
@zhanghang02

Copy link
Copy Markdown
Contributor Author

已根据前面的 review comments 把这条 PR 重新整理并 force-push 到原分支 codex/pr-missing-data-retry

这次更新的目标不是重复修 #64 已经处理的根因,而是把 #58 的“缺失数据记录 / 重试 / 报告页提示”能力,正确接到当前最新主线的执行流程上。

这次调整的基线

  • 已 rebase 到最新 main,当前基线包含:
    • #57 feat(web): resume interrupted runs from sidebar
    • #64 Fix stale A-share daily kline fallback
    • 后续主线里的 stock display / PDF / 其他兼容性修复

这次 PR 相对当前 main 的实际改动

只保留了和缺失数据追踪/重试直接相关的 7 个文件:

  • tradingagents/dataflows/missing_data.py
  • tradingagents/graph/trading_graph.py
  • web/components/report_viewer.py
  • tradingagents/agents/utils/agent_states.py
  • tradingagents/agents/analysts/market_analyst.py
  • tests/test_missing_data_tasks.py
  • tests/test_report_viewer_pdf_gate.py

具体改了什么

1. 缺失数据任务的记录与重试

  • 对工具调用失败、空结果、显式 [数据缺失: ...] 标记进行统一记录
  • 缺失任务按 ticker + trade_date + stage + tool + args 去重并持久化
  • 支持对 active missing tasks 重新取数
  • 对重试成功的结果做缓存,并在下一次完整分析时复用
  • 完整分析成功后,把已经消耗过的 resolved retry output 标记为 consumed

2. 接到 #57 之后的新 graph 生命周期

  • reset_missing_tasks_for_run(...) 只在 fresh run 里执行
  • 如果是 checkpoint resume,不会误清空当前 run 的缺失数据状态
  • finalize_graph_run(...) 里统一做:
    • attach_missing_data_snapshot(...)
    • mark_resolved_tasks_consumed(...)

也就是说,现在这条 PR 已经适配了 #57 带来的 prepare_graph_run / finalize_graph_run / close_graph_run 结构,不再停留在旧版 propagate() 流程上。

3. 报告页交互与当前主线保持一致

  • 保留了当前主线的股票代码/名称显示逻辑
  • 报告文本继续做 stock mention normalization
  • 即使仍有缺失项,也允许下载“当前内容版本”的 PDF
  • 报告页可以:
    • 查看缺失/失败取数项
    • 重新取数这些缺失项
    • 在补齐后触发重新分析

另外把“重新取数这些缺失项”按钮放到了缺失详情前面,和后续 review 的小修保持一致。

4. A 股场景里更容易漏的技术面数据

  • 技术分析链路里补回了 get_northbound_flow
  • 市场分析测试也覆盖了 No realtime data 这类北向资金非交易时段返回,被正确记录为 missing task 的情况

验证

本次 rebase 后重新跑过的聚焦验证:

  • PYTHONPATH=. python3 -m pytest -q tests/test_missing_data_tasks.py tests/test_report_viewer_pdf_gate.py

    • 结果:11 passed
  • python3 -m compileall tradingagents/graph/trading_graph.py tradingagents/agents/analysts/market_analyst.py tradingagents/dataflows/missing_data.py web/components/report_viewer.py

    • 结果:通过

为什么这样收敛

结合前面的 comments,我这次的处理原则是:

  • 不去重复解决 #64 已修的 stale data fallback 根因
  • #58 的价值收敛为:
    • 缺失任务可见
    • 缺失任务可重试
    • 重试后可重新分析
    • 报告页在“数据未完全齐”时仍然给出清晰反馈和可下载产物

如果 reviewer 继续希望缩 scope,这版也比较容易再往下裁,因为改动边界已经基本只围绕 missing-data workflow 本身。

@simonlin1212

Copy link
Copy Markdown
Owner

抱歉隔了这么久才回 🙏

你 7 月初那次 rebase 做得很扎实,说明也写得很清楚:把 #58 的价值收敛成「缺失任务可见 / 可重试 / 重试后可重新分析」,并且正确接到了 #57 之后的 prepare_graph_run / finalize_graph_run / close_graph_run 生命周期上,也没有去重复解决 #64 已修的根因 —— 这些判断都对,方向我是认可的。

现在的问题是主干这两天又推了一批修复(提示词 A 股规则、920 号段路由、docker Web UI 服务),这条 PR 重新变成冲突状态。麻烦再 rebase 一次。

另外为了让 review 能真正推进,想跟你约一下范围:我这轮重点看 tradingagents/dataflows/missing_data.pytradingagents/graph/trading_graph.py 两个核心文件,web/ 那几处只做兼容性检查。如果 rebase 后能顺手把改动再压一压更好,压不动也没关系。

rebase 完 @ 我一下,这次不会再让你等这么久。

Record failed or partial analyst tool calls without interrupting graph execution. Persist task metadata so reports can expose incomplete inputs and retry the exact tool invocation later.

Cache successful retry outputs for the next fresh analysis, consume them through ToolNode wrappers, and archive them only after that reanalysis completes. Keep task-index updates serialized for parallel analyst nodes.

Add report controls for inspecting and retrying missing data while keeping current PDF exports available. A successful retry explicitly starts a fresh analysis so downstream reports and decisions are regenerated.

Cover task detection, retries, cache lifecycle, snapshot synchronization, PDF behavior, and fresh reanalysis with focused regression tests.
@zhanghang02
zhanghang02 force-pushed the codex/pr-missing-data-retry branch from 1ac5114 to c8061b7 Compare July 28, 2026 09:41
@zhanghang02

Copy link
Copy Markdown
Contributor Author

@simonlin1212 已按你 7 月 26 日的意见完成第二次 rebase 和范围压缩,现在 PR 已恢复为可合并状态。

Rebase 基线

  • 已基于当前最新 main11045d6v0.3.0)重新整理。
  • PR 分支现为单一 commit:c8061b7
  • GitHub 当前状态:MERGEABLE / CLEAN

本轮范围收敛

最终 diff 只保留 5 个文件:

  • 核心实现:tradingagents/dataflows/missing_data.py
  • 图生命周期接入:tradingagents/graph/trading_graph.py
  • Web 兼容:web/components/report_viewer.py
  • 聚焦回归测试:tests/test_missing_data_tasks.pytests/test_report_viewer_pdf_gate.py

这次 rebase 冲突只发生在 market_analyst.py。该文件中原 PR 的提示词和北向资金工具改动已全部放弃,完整保留主干近期的 A 股规则、920 号段路由等实现;同时也从本 PR 的 market ToolNode diff 中移除了额外的 get_northbound_flow 接入,避免重复或覆盖主干修复。Docker/Web UI 服务相关主干改动同样未被本 PR 修改。

两个核心文件的 review 要点

missing_data.py

  • analyst 工具返回错误、空数据或显式 [数据缺失: ...] 时,记录可持久化、可重试的缺失任务;记录失败不会中断正常分析图。
  • 任务 ID 由 ticker、交易日、分析阶段、工具名和参数稳定生成,因此重试的是原始精确调用。
  • 重试成功结果进入本地缓存;下一次 fresh 全量分析时由对应 ToolNode 读取,确保分析师报告、辩论和最终决策都真正吸收补齐数据。
  • 缓存只有在被重新分析实际读取后,才会在完成阶段归档和删除;无关的已完成 run 不会误删尚未消费的重试结果。
  • fresh run 会清理同 ticker/date 的旧 active/consumed 记录,但保留等待重新分析消费的 resolved 记录。
  • 索引 read-modify-write 路径增加了进程内 RLock,避免并行 analyst ToolNode 相互覆盖任务记录。
  • 同步历史报告 JSON 时会保留已有的 missing_data_requires_reanalysis 标记,后续无新增 resolved 项的重试不会把它错误清掉。

trading_graph.py

改动仅限两类接入:

  • 给现有 7 个 analyst ToolNode 增加 wrap_tool_call,统一记录缺失结果并在重新分析时复用精确缓存。
  • 接入现有 prepare_graph_run / finalize_graph_run 生命周期:fresh 开始前整理任务,完成后附加缺失快照、写入日志,并归档已被本轮实际消费的缓存。

没有修改 analyst prompt、工具集合、路由规则或图拓扑。

Web 兼容

  • 当前报告仍允许下载 Markdown/PDF,同时明确展示缺失项和“报告需重新分析”状态。
  • 可在报告页重试缺失接口;全部补齐后触发重新分析。
  • 重新分析请求显式带上 fresh: True,与当前 web/app.py 的 checkpoint / incomplete task 清理逻辑保持一致。

验证

PYTHONPATH=. python3 -m pytest -q \
  tests/test_missing_data_tasks.py \
  tests/test_report_viewer_pdf_gate.py

15 passed in 0.05s

另外已通过:

  • 目标实现与测试文件 compileall
  • git diff --check
  • 本地已测试 tree 与远端 PR commit tree SHA 一致:8d7faa6d

当前环境未安装完整项目依赖中的 langgraph,因此没有在这个隔离 worktree 中运行依赖完整图环境的全量 checkpoint 测试;本轮新增的任务生命周期、缓存消费、报告状态与 fresh=True 行为均已有聚焦回归覆盖。

麻烦再看一下,重点可以直接落在上面两个核心文件;Web 部分仍只是兼容接入。

@zhanghang02

zhanghang02 commented Jul 29, 2026 via email

Copy link
Copy Markdown
Contributor Author

@simonlin1212

Copy link
Copy Markdown
Owner

先说结论:功能方向我认可,但这个 PR 现在的形态没法合,需要你决定要不要继续推进。

认可的部分

"报告里有数据缺失但用户看不出来"是这个项目的真实痛点 —— 工具调用失败时报告照样生成,读的人不知道哪块是空的。你这套做法(记录失败的工具调用 → 按标的/日期存任务 → 支持重试 → 报告页展示状态并允许补齐后重新分析 → PDF 带不完整警告)是对的,而且是完整闭环,不是打补丁。

卡住的原因

问题 现状
体量 +1377/-10,5 个文件,跨 dataflows / graph / web 三层
冲突 CONFLICTING —— 从 06-06 至今 main 动了很多,trading_graph.py 刚被 #94 改过
时间 已经 2 个多月没更新

1377 行跨三层的改动,一次性 review 的风险太高 —— 这个项目最近几轮审计的经验是,大改动里最容易藏"看着修好了、实际没生效"的东西,而缺失数据追踪这类功能一旦有静默失败,比没有这个功能更糟(用户以为"没提示就是数据齐全")。

想问你的

你还愿意继续推进吗? 如果愿意,建议这样拆:

  • PR A:缺失数据的记录与存储 —— dataflows/missing_data.py + trading_graph.py 的埋点。这是地基,独立可测,我优先合。
  • PR B:重试与消费 —— 建立在 A 之上。
  • PR C:报告页 UI + PDF 警告 —— web/components/report_viewer.py,纯前端,最容易验。

拆开后每个都能快速过,也不用一次 rebase 1377 行。

如果你没时间继续了也完全没关系 —— 说一声,我会把这个 PR 关掉,然后按上面的顺序自己实现,并在 CHANGELOG 里注明设计思路来自你这个 PR。你已经把最难的部分(怎么定义"缺失"、怎么串进下一次分析)想清楚了,这个是有价值的。

两周内没回复的话我就按后一种处理,你随时可以再开。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants