Skip to content

feat: 新增 AI 选股推荐功能#980

Open
EansonLee wants to merge 2 commits intoZhuLinsen:mainfrom
EansonLee:feature/stock-recommendation
Open

feat: 新增 AI 选股推荐功能#980
EansonLee wants to merge 2 commits intoZhuLinsen:mainfrom
EansonLee:feature/stock-recommendation

Conversation

@EansonLee
Copy link
Copy Markdown

@EansonLee EansonLee commented Apr 2, 2026

  • 后端:新增 /api/v1/recommendation 端点(推荐提交、状态轮询、历史查询)
  • 前端:新增 /recommend 选股页面(表单提交、进度展示、结果与历史记录)
  • 服务层:股票筛选器、内容提取器、LLM 推荐服务
  • 数据层:RecommendationHistory 模型与 Repository
  • 支持按市场/价格区间筛选,结合舆情 URL/文件/备注进行 AI 分析
  • 新增 python-docx 依赖用于 DOCX 文件解析
  • 包含单元测试覆盖

PR Type

  • fix
  • feat
  • refactor
  • docs
  • chore
  • test

Background And Problem

请描述当前问题、影响范围与触发场景。
(EN) Describe the problem, its impact, and what triggers it.

Scope Of Change

请列出本 PR 修改的模块和文件范围。
(EN) List the modules and files changed in this PR.

Issue Link

必须填写以下之一 / Fill in one of:

  • Fixes #<issue_number>
  • Refs #<issue_number>
  • 无 Issue 时说明原因与验收标准 / If no issue, explain the motivation and acceptance criteria

Verification Commands And Results

请填写你实际执行过的命令和关键结果(不要只写"已测试")。
(EN) Paste the commands you actually ran and their key output (don't just write "tested"):

# example
./scripts/ci_gate.sh
python -m pytest -m "not network"

关键输出/结论 / Key output & conclusion:

Compatibility And Risk

请说明兼容性影响、潜在风险(如无请写 None)。
(EN) Describe compatibility impact and potential risks (write None if not applicable).

Rollback Plan

请至少写一句可执行的回滚方案(必填)。
(EN) Provide at least one actionable rollback step (required).

EXTRACT_PROMPT Change (if applicable)

若本 PR 修改了 src/services/image_stock_extractor.py 中的 EXTRACT_PROMPT,请在此处粘贴完整变更后的 prompt。
If this PR changes EXTRACT_PROMPT in src/services/image_stock_extractor.py, paste the full updated prompt here:

展开 / Expand: Full EXTRACT_PROMPT
(paste full prompt here)

Checklist

  • 本 PR 有明确动机和业务价值 / This PR has a clear motivation and value
  • 已提供可复现的验证命令与结果 / Reproducible verification commands and results are included
  • 已评估兼容性与风险 / Compatibility and risk have been assessed
  • 已提供回滚方案 / A rollback plan is provided
  • 若涉及用户可见变更,已同步更新相关文档与 docs/CHANGELOG.md;若未更新 README.md,已说明原因与文档落点 / If user-visible changes are included, the relevant docs and docs/CHANGELOG.md are updated; if README.md was not updated, the reason and documentation location are explained

- 后端:新增 /api/v1/recommendation 端点(推荐提交、状态轮询、历史查询)
- 前端:新增 /recommend 选股页面(表单提交、进度展示、结果与历史记录)
- 服务层:股票筛选器、内容提取器、LLM 推荐服务
- 数据层:RecommendationHistory 模型与 Repository
- 支持按市场/价格区间筛选,结合舆情 URL/文件/备注进行 AI 分析
- 新增 python-docx 依赖用于 DOCX 文件解析
- 包含单元测试覆盖
@EansonLee EansonLee requested a review from ZhuLinsen as a code owner April 2, 2026 10:05
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@github-actions github-actions bot added documentation Improvements or additions to documentation size/XL testing labels Apr 2, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

🤖 自动审查报告

项目 结果
📊 变更文件 30 个
➕ 新增行数 3751 行
➖ 删除行数 73 行
🔍 静态检查 ✅ 通过
🧠 AI 审查 ✅ 已完成

📁 修改的文件

  • 📝 api/v1/endpoints/__init__.py (+2/-0)
  • 🆕 api/v1/endpoints/recommendation.py (+304/-0)
  • 📝 api/v1/router.py (+7/-1)
  • 🆕 api/v1/schemas/recommendation.py (+108/-0)
  • 📝 apps/dsa-web/package-lock.json (+9/-23)
  • 📝 apps/dsa-web/src/App.tsx (+2/-0)
  • 🆕 apps/dsa-web/src/api/recommendation.ts (+60/-0)
  • 📝 apps/dsa-web/src/components/layout/SidebarNav.tsx (+2/-1)
  • 🆕 apps/dsa-web/src/components/recommend/MarketSelector.tsx (+36/-0)
  • 🆕 apps/dsa-web/src/components/recommend/PriceRangeInput.tsx (+40/-0)
  • 🆕 apps/dsa-web/src/components/recommend/RecommendForm.tsx (+104/-0)
  • 🆕 apps/dsa-web/src/components/recommend/RecommendHistoryList.tsx (+104/-0)
  • 🆕 apps/dsa-web/src/components/recommend/RecommendResultPanel.tsx (+106/-0)
  • 🆕 apps/dsa-web/src/components/recommend/RecommendedStockCard.tsx (+97/-0)
  • 🆕 apps/dsa-web/src/components/recommend/SentimentFileUpload.tsx (+101/-0)
  • 🆕 apps/dsa-web/src/components/recommend/UrlListInput.tsx (+70/-0)
  • 🆕 apps/dsa-web/src/pages/RecommendPage.tsx (+63/-0)
  • 🆕 apps/dsa-web/src/stores/recommendStore.ts (+209/-0)
  • 🆕 apps/dsa-web/src/types/recommendation.ts (+59/-0)
  • 📝 docs/CHANGELOG.md (+3/-0)

... 还有 10 个文件


🧠 AI 代码审查意见

结论

Not Ready

结构化审查结果

  • 必要性通过。理由:PR 标题和描述明确指出“新增 AI 选股推荐功能”,是一个新的业务功能,具有明确的业务价值,符合 feat 类型。

  • 关联性不通过。理由:PR 描述中 Issue Link 字段为空,且未说明无 Issue 时的动机与验收标准。

  • 类型:建议类型为 feat,与 PR 标题和描述完全相符。

  • 描述完整性不完整

    • Background And Problem 字段为空。
    • Scope Of Change 字段为空。
    • Issue Link 字段为空,且未提供无 Issue 的原因与验收标准。
    • Verification Commands And Results 字段内容为空,尽管 Checklist 勾选了“已提供可复现的验证命令与结果”。
    • Compatibility And Risk 字段为空。
    • Rollback Plan 字段为空,且 Checklist 中 [ ] 已提供回滚方案 未勾选。
    • [ ] 若涉及用户可见变更,已同步更新相关文档与 docs/CHANGELOG.md 未勾选,但文件列表显示 docs/CHANGELOG.mddocs/webserver-setup.md 已修改。需要确认是否已更新并勾选。
    • PR 描述未说明 ./scripts/ci_gate.sh 是否执行或给出跳过原因。
  • 风险级别

    • 关键风险
      1. 依赖管理:引入新依赖 python-docx,需要确保生产环境的 requirements.txt 更新并正确安装,避免部署问题。
      2. 异步任务管理RecommendationTaskManager 作为异步任务的核心,其任务调度、状态持久化、错误处理及资源消耗(尤其是当任务量增加时)的健壮性需要进一步考虑和验证。目前看,进行中的任务状态可能不持久。
      3. 外部服务依赖:LLM 推荐服务依赖外部 AI 模型,其稳定性和响应时间将直接影响功能可用性。
      4. 安全风险:文件上传和 URL 解析(尽管有初步校验)仍是潜在的入口,需警惕解析过程中可能存在的漏洞或资源消耗问题。
  • 必改项 (阻断项):

    1. 缺少回滚方案:PR 描述中的 Rollback Plan 字段为空,且 Checklist 中对应的项未勾选。这是强制要求,必须提供至少一句可执行的回滚方案。
    2. 验证命令与结果内容缺失:尽管 CI 检查结果显示 Python 语法和关键 Flake8 通过,但 Verification Commands And Results 字段内容为空。对于 feat 类型,请提供实际执行过的功能验证命令和关键结果,例如 API 调用的 curl 命令示例、请求/响应 JSON 截图,或前端页面操作步骤及截图。
    3. 关联 Issue / 动机说明Issue Link 字段为空。请关联一个现有 Issue,或详细说明无 Issue 时的开发动机和验收标准。
  • 建议项 (非阻断项):

    1. 完善 PR 描述:建议补充 Background And Problem (说明当前问题或痛点,以及为何需要此功能),Scope Of Change (概述本次修改涉及的模块和主要文件),Compatibility And Risk (具体说明兼容性影响、潜在风险或明确写 None),以提高 PR 的可读性和信息完整性。
    2. Checklist 勾选更新:请检查 [ ] 若涉及用户可见变更,已同步更新相关文档与 docs/CHANGELOG.md 是否已正确勾选。根据文件列表,docs/CHANGELOG.mddocs/webserver-setup.md 有改动,应确保其已同步更新。
    3. Python 导入规范:在 api/v1/endpoints/recommendation.py 中,from src.repositories.recommendation_repo import RecommendationRepositoryfrom src.services.recommendation_service import RecommendationService, RecommendationTaskManager 的导入被放置在 submit_recommendation 函数内部。建议将这些导入语句移至文件顶部,以符合 Python 模块导入的最佳实践,提高代码可读性和模块的初始化效率。
    4. ci_gate.sh 执行情况说明:对于 Python 后端改动,建议在 PR 描述中补充说明 ./scripts/ci_gate.sh 是否已在本地执行,或给出跳过执行的原因。
    5. 文件上传/URL解析的错误处理:在 submit_recommendation 端点中,json.loads(urls) 处缺少对 url_list 中单个 URL 格式的进一步校验,例如是否是合法的 URL 格式。虽然 json.JSONDecodeError 被捕获,但内部 URL 的有效性可能需要更严格的检查,以避免后续服务层出现问题。

💡 提示: 请确保代码已通过本地测试,并遵循项目代码规范。

Copy link
Copy Markdown
Owner

@ZhuLinsen ZhuLinsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审结论

  • 必要性:通过,新增独立的 AI 选股推荐能力,覆盖后端接口、服务层、持久化和 Web 工作台,业务目标明确。
  • 是否有对应 issue:无(PR 描述未填写 Fixes #... / Refs #...,也未说明无 Issue 时的验收标准)
  • PR 类型:feat,新增 /api/v1/recommendation 端点、推荐服务、历史表与 /recommend 页面,属于新能力扩展。
  • description 完整性:不完整,缺少 Background And ProblemScope Of ChangeIssue Link、实际执行过的 Verification Commands And ResultsCompatibility And RiskRollback Plan;另外按 AGENTS.md,未更新 README.md 时需要说明原因和信息实际落点,当前描述也未补充。
  • 是否可直接合入:不可,核心阻断点是多市场联合筛选时的候选排序存在跨币种直接比较的正确性风险,会直接影响最终推荐结果。

主要问题

  1. [Correctness blocker] src/services/stock_screener.pyscreen() 把 A 股、港股、美股候选合并后,直接按 amount 做全局降序截断;但同文件前面又明确港股/美股成交额阈值是“对应币种”。这意味着多市场模式下实际在用 CNY/HKD/USD 的原始数值做同量纲比较,最终 Top N 候选会被系统性偏置,进而改变 LLM 可见候选集和推荐结果。该 PR 又把“按市场组合筛选”作为主打能力,所以这不是旧债旁支,而是本 PR 新放大的核心正确性问题。置信度:高。
  2. [Process blocker] README.md / docs / PR 描述:仓库已有通用部署文档和 changelog,但本次新增的 /api/v1/recommendation/* 语义、输入约束(文件数量/大小/格式、URL 数量、价格区间、多市场组合)以及 /recommend 页面交互,除了 docs/CHANGELOG.md 外没有看到对应专题说明;同时按 AGENTS.md,未更新 README.md 时应在交付说明或 PR 描述中写明原因和文档落点,当前也缺失。对用户可见新功能来说,这部分仍不满足仓库约束。置信度:中。
  3. tests/:当前新增测试主要覆盖了解析、筛选和文本提取的单元逻辑,没有看到 recommendation API 的 multipart 提交、任务状态/历史/详情接口,以及“多市场联合筛选”场景的回归用例;因此上面的核心风险没有被自动化验证兜住。置信度:高。

🤖 此回复由 OpenReview Bot 自动生成,仅供参考。如有疑问请 @维护者。

@EansonLee
Copy link
Copy Markdown
Author

@ZhuLinsen 大佬麻烦看看

Copy link
Copy Markdown
Owner

@ZhuLinsen ZhuLinsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

跟进结论

  • 结论:部分接受 + 重新核对当前 head 后,文档覆盖这一点可以收窄,但 PR 描述层面的必填信息仍然没有补齐。
  • 是否仍有阻断:有 + 当前代码与文档改动已基本覆盖功能说明,但 PR 描述里仍缺少 Issue 关联/验收标准、实际验证结果和可执行回滚方案,未满足仓库既定合入要求。

说明

  1. 之前如果把问题表述成“缺少用户可见变更文档”,这条需要收窄。当前 diff 里 docs/CHANGELOG.md 已按扁平格式补充 3 条 [新功能]docs/webserver-setup.md 也新增了这套能力的接入说明;就“新增能力是否完全无文档”这一点,现状不成立。
  2. 但这不等于 PR 描述已经完整。当前 PR 正文里 Background And ProblemScope Of ChangeIssue LinkVerification Commands And ResultsCompatibility And RiskRollback Plan 这些模板项仍是空的,结构化事实也明确显示未检测到 Fixes #... / Refs #...。这属于 PR 元数据未补齐,不是文档文件能替代的。
  3. README.md 未改本身不构成单独阻断,因为本次已经把说明落到了 docs/webserver-setup.mddocs/CHANGELOG.md;但按仓库规则,若不更新 README.md,应在 PR 描述中说明原因以及信息实际落点,当前也还没有补。
  4. 当前 CI 为 success,mergeable_state=blocked 这里不能单独作为阻断依据;我保留“有阻断”的原因仅来自仓库协作规则中对 PR 描述完整性和回滚方案的要求,而不是合并状态本身。

🤖 此回复由 OpenReview Bot 自动生成,仅供参考。如有疑问请 @维护者。

Copy link
Copy Markdown
Owner

@ZhuLinsen ZhuLinsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审结论

  • 必要性:通过 + 新增独立的 AI 选股推荐能力,覆盖 API、服务层、持久化和 Web 工作台,业务目标明确。
  • 是否有对应 issue:无(PR 描述未填写 Fixes #... / Refs #...,也未说明无 Issue 时的验收标准)
  • PR 类型:feat + 新增 /api/v1/recommendation 端点、推荐服务、历史表与 /recommend 页面,属于用户可见的新能力扩展。
  • description 完整性:不完整 + 缺少 Background And ProblemScope Of ChangeIssue Link、实际执行过的验证命令与结果、Compatibility And RiskRollback Plan,Checklist 也未补齐。
  • 是否可直接合入:不可 + 当前存在合并冲突;此外还有异步任务状态持久化问题需要先补齐,否则服务重启后会出现任务永久卡住/历史状态失真的情况。

主要问题

  1. [Correctness blocker] src/services/recommendation_service.pyapi/v1/endpoints/recommendation.pysrc/repositories/recommendation_repo.py:任务生命周期只在 RecommendationTaskManager 这个进程内内存结构里维护,落库时仅在提交前写一条 pending,完成/失败时再回写结果。这样一旦服务在任务执行中重启,内存状态丢失,但数据库里仍是旧的 pending 记录;GET /api/v1/recommendation/status/{task_id} 的 fallback 逻辑会直接把这条库记录当成当前状态返回,前端就会看到一个永远 0%/pending 的任务,且没有恢复或兜底失败标记。对这个 PR 新增的“状态轮询 + 历史查询”主链路是实质性正确性风险。置信度:高。
  2. [Correctness blocker] api/v1/endpoints/recommendation.pysrc/repositories/recommendation_repo.py:提交接口里 repo.create(...) 的返回值没有校验,而仓库层在写库失败时会吞掉异常并返回 0。这意味着数据库写入失败时,接口仍会返回“推荐任务已提交”,后台线程也会继续跑;但后续历史记录、重启后的状态查询、详情查询都没有可靠持久化依据。这会把“提交成功”与“可追踪可回放”分离,和本仓库对稳定性优先的要求不一致。置信度:高。
  3. [Process blocker] 结合仓库 AGENTS.md 与 PR 模板,本 PR 已更新了 docs/CHANGELOG.mddocs/webserver-setup.md,所以“完全无文档”这一点不成立;但 PR 描述仍缺少必填的 issue/验收标准、实际验证结果、兼容性影响、回滚方案。当前这些不是单纯格式问题,而是仓库默认合入要求的一部分,尤其这次改动同时触达 API、Schema 风格、Web 页面、依赖和持久化层,缺少这些信息会降低后续回归和回滚可操作性。

🤖 此回复由 OpenReview Bot 自动生成,仅供参考。如有疑问请 @维护者。

Copy link
Copy Markdown
Owner

@ZhuLinsen ZhuLinsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审结论

  • 必要性:通过 + 新增 AI 选股推荐能力,覆盖 API、服务层、持久化和 Web 工作台,业务价值明确,和仓库现有股票分析主链路相关。
  • 是否有对应 issue:无(PR 描述未填写 Fixes #... / Refs #...,也未说明无 Issue 时的验收标准)
  • PR 类型:feat + 新增 /api/v1/recommendation 相关接口、推荐服务、历史记录存储和 /recommend 页面,属于用户可见的新功能扩展。
  • description 完整性:不完整 + 缺少 Background And ProblemScope Of ChangeIssue LinkVerification Commands And Results 未给出实际执行命令和关键结果;Compatibility And Risk 未填写;Rollback Plan 缺失;且本次未更新 README.md 也未按 AGENTS.md 说明信息实际落点。
  • 是否可直接合入:不可 + 当前分支存在冲突,且 PR 描述仍未满足仓库 AGENTS.md / PR 模板要求,至少需要补齐可执行回滚方案、Issue/验收标准、实际验证结果后再评估。

主要问题

  1. [Process blocker] 当前结构化事实显示“存在冲突,当前不能直接合并”。这不是单纯的分支保护状态,而是明确的合并冲突;在冲突未解决前不能判定可直接合入。
  2. [Process blocker] PR 描述缺少仓库明确要求的合入信息。按 AGENTS.md 第 8、9 节,至少应补齐 Issue 关联或无 Issue 时的验收标准、实际执行过的验证命令与关键结果、兼容性/风险说明、可执行回滚方案;这些目前仍为空或只勾选了 checklist,没有形成可审计证据。
  3. [Process blocker] 本次是用户可见新能力,代码侧已补 docs/CHANGELOG.mddocs/webserver-setup.md,但未改 README.md。按 AGENTS.md,如果不更新 README.md,需要在交付或 PR 描述中明确说明原因,以及信息实际落在哪份文档;当前这部分说明缺失。
  4. [Nice to have] 从前端状态管理实现看,apps/dsa-web/src/stores/recommendStore.ts 使用 setInterval 轮询异步 poll,没有请求互斥控制;当接口响应时间超过 3 秒时,可能出现并发轮询请求重叠。现有 diff 还不足以证明一定出错,但这是本 PR 新引入的行为风险,置信度:中。

🤖 此回复由 OpenReview Bot 自动生成,仅供参考。如有疑问请 @维护者。

- 添加新浪和腾讯的批量接口,提供 A 股全市场快照获取功能,增强数据源的多样性
- 实现 A 股代码列表的缓存机制,优化性能
- 更新相关函数以支持新的数据获取方式,确保在不同情况下的可靠性
- 增强日志记录,便于调试和监控数据获取过程
Copy link
Copy Markdown
Owner

@ZhuLinsen ZhuLinsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审结论

  • 必要性:通过 + 新增 AI 选股推荐能力,覆盖 API、服务层、持久化和 Web 工作台,和仓库现有股票分析主链路相关,业务价值明确。
  • 是否有对应 issue:无(描述中未填写 Fixes #... / Refs #...,也未说明无 Issue 时的验收标准)
  • PR 类型:feat + 新增 /api/v1/recommendation 相关接口、推荐服务、历史记录存储和 /recommend 页面,属于用户可见的新功能扩展。
  • description 完整性:不完整 + 缺少 Background And ProblemScope Of ChangeIssue Link、实际执行过的验证命令与关键结果、可执行回滚方案;且 README.md 未改动时,描述里也没有按 AGENTS.md 说明本次为什么不更新 README 以及信息实际落到哪份文档。
  • 是否可直接合入:不可 + 当前结构化事实已明确“存在冲突,当前不能直接合并”;此外 PR 描述仍未满足仓库模板和 AGENTS.md 对 issue/验证/回滚的合入要求。

主要问题

  1. [Correctness blocker] apps/dsa-web/src/api/recommendation.ts 在提交 FormData 时显式写死 Content-Type: multipart/form-data。这类请求通常应由浏览器自动补 boundary;当前写法有兼容性风险,可能在部分环境下导致后端无法正确解析上传文件或表单字段。置信度:中。
  2. [Process blocker] PR 描述未补齐仓库要求的关键信息:没有 issue 关联或无 issue 的验收标准,没有实际执行过的验证命令和结果,没有回滚方案。按 AGENTS.md 的默认交付结构,这些都属于合入前应补齐的必填项。
  3. [Process blocker] 本次是用户可见的新能力,代码侧已经补了 docs/CHANGELOG.mddocs/webserver-setup.md,所以“完全无文档”这一点不成立;但 README.md 未更新时,PR 描述也没有说明为何不更新以及信息实际落在哪份文档,这一点仍不满足仓库文档治理要求。

🤖 此回复由 OpenReview Bot 自动生成,仅供参考。如有疑问请 @维护者。

@EansonLee
Copy link
Copy Markdown
Author

@ZhuLinsen 请问可以合并了吗

Copy link
Copy Markdown
Owner

@ZhuLinsen ZhuLinsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

跟进结论

  • 结论:部分接受 + 当前 head 的功能实现和 CI 状态已经基本到位,但还不能认定“现在可以直接合并”,因为仍有明确冲突,且 PR 描述/文档收口没有完全补齐。
  • 是否仍有阻断:有 + 结构化事实已经明确显示当前分支存在冲突、不能直接合并,同时 PR 描述里的回滚方案仍未补齐。

说明

  1. docs/CHANGELOG.md 已按 Unreleased 扁平格式补了 3 条新功能记录,所以“完全没有用户可见文档”这条判断可以收窄。
  2. 但 docs/webserver-setup.md 目前是 Web + Server 部署指南,未看到 /recommend 或 /api/v1/recommendation 的功能说明;README.md 也没有同步更新,因此“新增能力的相关文档已经补齐”这条现在还不能完全成立。
  3. PR 描述里,Issue Link 仍没有 Fixes/Refs 或“无 issue 时的验收标准”,Rollback Plan 仍为空;按仓库 AGENTS.md,回滚方案缺失仍是合入前需要补齐的项。
  4. 当前 CI 是 success,所以我这里不再把阻断放在测试失败上;现阶段真正阻断的是“明确存在合并冲突”以及上面的 PR 元信息缺口。

🤖 此回复由 OpenReview Bot 自动生成,仅供参考。如有疑问请 @维护者。

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

Labels

documentation Improvements or additions to documentation size/XL testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants