Skip to content

Commit 0ed6010

Browse files
authored
fix: 升级 AlphaSift 并兼容热点详情龙头股字段 (#1714)
* fix: update AlphaSift pin and hotspot detail fields * fix(review-feedback-1714): fix still returning no concept stocks despite the leaders being
1 parent cd37608 commit 0ed6010

11 files changed

Lines changed: 147 additions & 22 deletions

.env.example

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ ALPHASIFT_ENABLED=false
3131
# - ALPHASIFT_ENABLED 只影响 AlphaSift 选股流程,不会改写/迁移/清理现有 LITELLM_*/LLM_* 配置。
3232
# - 关闭/回退只需将 ALPHASIFT_ENABLED 置 false;现有 provider/base_url/custom headers 与 fallback 语义保持原状。
3333
# - 兼容依据(运维核验):LiteLLM providers 与 OpenAI-compatible 语义说明见下方注释;运行时默认使用 requirements.txt 中固定 litellm 版本。
34-
ALPHASIFT_INSTALL_SPEC=git+https://github.com/ZhuLinsen/alphasift.git@14e74fc0819267f7c04c3117a0dd0fe3f9b19404
34+
ALPHASIFT_INSTALL_SPEC=git+https://github.com/ZhuLinsen/alphasift.git@377049857cc04175dc3cca62121ee41adec6cdb8
3535
# 兼容说明:
3636
# - ALPHASIFT_INSTALL_SPEC 仅用于显式调用 /api/v1/alphasift/install;不会自动覆盖历史 .env 配置。
37-
# - 升级后想使用新 pin,请清理旧 `.env` 中该变量后重建依赖/重启服务;或直接改为 14e74fc... 并重建后端。
37+
# - 升级后想使用新 pin,请清理旧 `.env` 中该变量后重建依赖/重启服务;或直接改为 3770498... 并重建后端。
3838
# - 仅改 .env 里该字段而不回退 `requirements.txt` 与 `src/config.py` 会触发 allow-list 拒绝(alphasift_install_spec_not_allowed)。
3939
# AlphaSift 全市场快照源优先级;未配置时 DSA 会按是否配置 TUSHARE_TOKEN 自动注入:
4040
# - 有 TUSHARE_TOKEN:tushare,sina,efinance,akshare_em,em_datacenter
@@ -52,6 +52,8 @@ ALPHASIFT_INSTALL_SPEC=git+https://github.com/ZhuLinsen/alphasift.git@14e74fc081
5252
# INDUSTRY_PROVIDER_MAX_BOARDS=80
5353
# 单次 LLM 请求超时秒数;AlphaSift 选股会复用 DSA 的该配置,超时后降级返回非 LLM 排序结果。
5454
# LLM_TIMEOUT_SEC=60
55+
# AlphaSift LLM 重排请求输出上限;仅影响 AlphaSift 选股重排,默认 2048。
56+
# LLM_MAX_TOKENS=2048
5557

5658
# Finnhub(可选,美股数据源,免费 tier 60 calls/min)
5759
# 获取: https://finnhub.io/register

apps/dsa-web/src/api/__tests__/alphasift.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ describe('alphasiftApi', () => {
205205
summary: '玻璃基板盘中发酵',
206206
route: [{ title: '盘中发酵', description: '出现大笔买入' }],
207207
stocks: [{ code: '920438', name: '戈碧迦', role: '异动核心' }],
208+
leader_stocks: [{ code: '920438', name: '戈碧迦', role: '异动核心' }],
208209
stock_count: 1,
209210
},
210211
});
@@ -218,6 +219,7 @@ describe('alphasiftApi', () => {
218219
expect(result.topic).toBe('玻璃基板');
219220
expect(result.stockCount).toBe(1);
220221
expect(result.stocks[0].name).toBe('戈碧迦');
222+
expect(result.leaderStocks?.[0].name).toBe('戈碧迦');
221223
});
222224

223225
it('uses a long timeout for LLM-backed screening', async () => {

apps/dsa-web/src/api/alphasift.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ export type AlphaSiftHotspotDetail = {
153153
route: AlphaSiftHotspotRouteItem[];
154154
timeline?: AlphaSiftHotspotRouteItem[];
155155
stocks: AlphaSiftHotspotStock[];
156+
leaderStocks?: AlphaSiftHotspotStock[];
156157
stockCount: number;
157158
sourceErrors?: string[];
158159
qualityStatus?: 'available' | 'partial' | 'stale' | 'failed' | string;

docs/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
3636
<!-- 新条目格式:- [类型] 描述(类型取值:新功能/改进/修复/文档/测试/chore)-->
3737
<!-- 每条独立一行追加到本段末尾,无需分类标题,合并时冲突最小 -->
3838
- [修复] 发布说明生成查询 PR 作者失败时保留降级并输出包含 PR 编号和异常类型的 warning,便于排查 token、权限、网络或 GitHub API 异常。
39-
- [改进] DSA 数据源链路新增 Tencent 日 K 直连 fetcher、daily source health 短期熔断,并升级 AlphaSift 默认 pin/runtime bridge,默认启用 `DAILY_SOURCE=auto`、Sina snapshot 优先级和候选级 quote context。
39+
- [改进] DSA 数据源链路新增 Tencent 日 K 直连 fetcher、daily source health 短期熔断,并升级 AlphaSift 默认 pin/runtime bridge,默认启用 `DAILY_SOURCE=auto`、Sina snapshot 优先级、候选级 quote context 与 LLM ranking timeout/max tokens 边界
4040
- [文档] 补充 AlphaSift 迁移与回退边界:明确 `ALPHASIFT_INSTALL_SPEC` 显式覆盖语义、`requirements.txt + DEFAULT_ALPHASIFT_INSTALL_SPEC` 与运行时兼容边界、以及回滚路径(关闭功能/完整 revert)说明,覆盖旧 pin 用户升级行为。
4141
- [新功能] #1707 新增合规 RSS/Atom 资讯源配置、拉取、去重、入库、查询、retention 与基础安全校验 API,作为个股/市场资讯情报池基线。
4242
- [文档] 本次 #1707 情报源基线仅新增 `NEWS_INTEL_*` 配置,不变更 LITELLM / ANSPIRE / Base URL / provider/model 清理与回退语义;回退策略为移除或禁用这三项情报源变量后恢复既有 LLM 配置行为。
4343

4444
- [新功能] 个股分析历史成功保存后会从最终报告 best-effort 提取 `DecisionSignal` 决策信号,复用现有信号去重、计划质量计算和脱敏契约。
45+
- [修复] AlphaSift 热点详情兼容 `leader_stocks``stocks` 双字段,避免旧合约或缓存只提供其中一个字段时概念股详情报缺失字段。
4546
- [改进] 问股页移动端策略选择改为默认收起的按钮入口,展开后仍可多选策略并在发送后自动收起,减少对对话内容的遮挡。
4647

4748

docs/alphasift-integration.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ AlphaSift 作为独立仓库维护的选股引擎接入 DSA。DSA 默认不启
66

77
- 默认关闭:`ALPHASIFT_ENABLED=false`
88
- 启用入口:设置页或选股页点击开启,或在 `.env` 中配置 `ALPHASIFT_ENABLED=true`
9-
- 依赖来源:`requirements.txt` 固定到已验证的 AlphaSift 适配层 commit:`git+https://github.com/ZhuLinsen/alphasift.git@14e74fc0819267f7c04c3117a0dd0fe3f9b19404#egg=alphasift`(对应提交 `https://github.com/ZhuLinsen/alphasift/commit/14e74fc0819267f7c04c3117a0dd0fe3f9b19404`,来源 PR `https://github.com/ZhuLinsen/alphasift/pull/16`)。该来源覆盖 `alphasift.dsa_adapter` 契约、`screen/list_strategies/get_status` 调用,以及 Tencent 日 K、Sina snapshot、source health、stale daily fallback 与候选级 quote context。
9+
- 依赖来源:`requirements.txt` 固定到已验证的 AlphaSift 适配层 commit:`git+https://github.com/ZhuLinsen/alphasift.git@377049857cc04175dc3cca62121ee41adec6cdb8#egg=alphasift`(对应提交 `https://github.com/ZhuLinsen/alphasift/commit/377049857cc04175dc3cca62121ee41adec6cdb8`,来源 PR `https://github.com/ZhuLinsen/alphasift/pull/16``https://github.com/ZhuLinsen/alphasift/pull/19`)。该来源覆盖 `alphasift.dsa_adapter` 契约、`screen/list_strategies/get_status` 调用Tencent 日 K、Sina snapshot、source health、stale daily fallback、候选级 quote context,以及 LLM ranking 的 `LLM_MAX_TOKENS` 输出上限和 timeout 后不重复 JSON-mode 重试的边界
1010
- 修复安装来源:`ALPHASIFT_INSTALL_SPEC` 仍保留,默认等于同一个受信任 commit。它不再是策略列表或选股接口的运行时安装主路径,只用于显式调用 `/api/v1/alphasift/install` 时做修复安装和来源校验;未显式配置时才按代码常量 `DEFAULT_ALPHASIFT_INSTALL_SPEC` 回退。
1111
- 迁移边界(显式 `.env` 优先):
1212
-`.env` 中显式保留旧 pin(如 `...de54ea0da367be85770d9589a5bf7ded4f62d386`),DSA 会把该值当作用户覆盖,不会在运行期自动替换为新 pin;
@@ -21,7 +21,7 @@ AlphaSift 作为独立仓库维护的选股引擎接入 DSA。DSA 默认不启
2121

2222
## 外部契约来源与迁移边界
2323

24-
- 外部契约依据:本次 AlphaSift 运行契约(含 `schema_version=2` 的热点缓存与题材详情字段)对应 GitHub 提交 `https://github.com/ZhuLinsen/alphasift/commit/14e74fc0819267f7c04c3117a0dd0fe3f9b19404`
24+
- 外部契约依据:本次 AlphaSift 运行契约(含 `schema_version=2` 的热点缓存与题材详情字段)对应 GitHub 提交 `https://github.com/ZhuLinsen/alphasift/commit/377049857cc04175dc3cca62121ee41adec6cdb8`
2525
该 commit 在 DSA 中通过以下链路生效:`requirements.txt` 安装 pin、`src/config.py` 默认 `DEFAULT_ALPHASIFT_INSTALL_SPEC``.env.example` 默认示例值。
2626
- 升级路径:
2727
- 部署侧只需按部署方式 `git pull` + `pip install -r requirements.txt` + 重启服务;
@@ -35,9 +35,9 @@ AlphaSift 作为独立仓库维护的选股引擎接入 DSA。DSA 默认不启
3535

3636
- DSA 增强:AlphaSift 通过 DSA provider context 在 LLM 重排前只补充 Top 候选的轻量实时行情和基本面上下文,不在初筛阶段抓新闻;DSA API 返回阶段会对最终 Top 候选补新闻和辅助摘要,并通过 `dsa_enrichment` 记录复用或补全情况。
3737
- 日 K 线补特征:DSA 调用 AlphaSift 时会优先复用 DSA 历史行情加载链路(数据库缓存、Tushare、Efinance、Akshare、Pytdx、Baostock、Yfinance 等 fallback),仅在 DSA 链路无可用数据时回退到 AlphaSift 原始日线数据源,减少单一上游超时拖垮选股。
38-
- LLM 环境:DSA 调用 AlphaSift 时会桥接 DSA 已解析的 `LITELLM_MODEL``LITELLM_FALLBACK_MODELS``LLM_CHANNELS``LLM_<NAME>_*``LITELLM_CONFIG`、渠道额外请求头和各模型密钥;AlphaSift 独立运行时仍使用自己的 `.env`/环境变量。
38+
- LLM 环境:DSA 调用 AlphaSift 时会桥接 DSA 已解析的 `LITELLM_MODEL``LITELLM_FALLBACK_MODELS``LLM_CHANNELS``LLM_<NAME>_*``LITELLM_CONFIG`、渠道额外请求头和各模型密钥;AlphaSift 独立运行时仍使用自己的 `.env`/环境变量。`LLM_TIMEOUT_SEC``LLM_MAX_TOKENS` 可被 AlphaSift 选股 LLM 重排读取,分别限制单次请求耗时和输出 token 上限。
3939
- 快照源:DSA 调用 AlphaSift 时,未显式配置 `SNAPSHOT_SOURCE_PRIORITY` 会按 token-aware 顺序注入:有 `TUSHARE_TOKEN` 时为 `tushare,sina,efinance,akshare_em,em_datacenter`,无 token 时为 `sina,efinance,akshare_em,em_datacenter`;同时注入 `DAILY_SOURCE=auto` 和默认候选上下文 `news,fund_flow,announcement,quote`。显式配置的源顺序和候选上下文 provider 会原样保留。
40-
- 最新 AlphaSift 能力:锁定 commit `14e74fc0819267f7c04c3117a0dd0fe3f9b19404` 包含选股 pipeline 性能优化、Tencent 日 K、Sina snapshot、source health、stale daily fallback、candidate quote context、last-good snapshot fallback、日线历史缓存、行业/概念 provider cache、热点/行业热度因子、hotspot 热点题材榜单与本地 scorecard/post-analysis 元信息。DSA 调用时会注入隔离缓存默认路径 `data/alphasift`、`data/alphasift/snapshot.last_good.json`、`data/alphasift/daily_history`、`data/alphasift/industry_provider_cache`;Web 选股页提供“热点题材”手动刷新入口,请求 `/api/v1/alphasift/hotspots` 时会显式使用 `akshare` provider 优先拉取具体概念/题材异动(例如钼、铅锌、铜、诊断服务等实时板块异动),行业板块仅作为兜底;默认打开页面时优先读取上一次成功且不少于 3 条的热点题材缓存,点击刷新才实时拉取并覆盖缓存,实时拉取失败时会尽量回退旧缓存;如果 AlphaSift 合约层只返回少量或缺少涨跌幅等关键字段的热点,DSA 会用东方财富板块异动直连榜单替代。点击题材会请求 `/api/v1/alphasift/hotspots/{topic}` 展示发酵路线与概念股;题材详情另有 DSA 侧 30 分钟磁盘缓存,路径为 `data/alphasift/hotspot_details` 或自定义 `ALPHASIFT_DATA_DIR/hotspot_details`,重复点开同一题材会优先返回缓存,实时详情失败时可回退过期缓存;手动刷新热点榜单并保留当前题材时会对详情请求传入 `refresh=true` 绕过详情缓存;不会默认触发 AlphaSift 的 DSA deep-analysis 回调,避免无提示扩大递归调用面。
40+
- 最新 AlphaSift 能力:锁定 commit `377049857cc04175dc3cca62121ee41adec6cdb8` 包含选股 pipeline 性能优化、Tencent 日 K、Sina snapshot、source health、stale daily fallback、candidate quote context、LLM ranking timeout/max tokens 边界、last-good snapshot fallback、日线历史缓存、行业/概念 provider cache、热点/行业热度因子、hotspot 热点题材榜单与本地 scorecard/post-analysis 元信息。DSA 调用时会注入隔离缓存默认路径 `data/alphasift`、`data/alphasift/snapshot.last_good.json`、`data/alphasift/daily_history`、`data/alphasift/industry_provider_cache`;Web 选股页提供“热点题材”手动刷新入口,请求 `/api/v1/alphasift/hotspots` 时会显式使用 `akshare` provider 优先拉取具体概念/题材异动(例如钼、铅锌、铜、诊断服务等实时板块异动),行业板块仅作为兜底;默认打开页面时优先读取上一次成功且不少于 3 条的热点题材缓存,点击刷新才实时拉取并覆盖缓存,实时拉取失败时会尽量回退旧缓存;如果 AlphaSift 合约层只返回少量或缺少涨跌幅等关键字段的热点,DSA 会用东方财富板块异动直连榜单替代。点击题材会请求 `/api/v1/alphasift/hotspots/{topic}` 展示发酵路线与概念股;题材详情另有 DSA 侧 30 分钟磁盘缓存,路径为 `data/alphasift/hotspot_details` 或自定义 `ALPHASIFT_DATA_DIR/hotspot_details`,重复点开同一题材会优先返回缓存,实时详情失败时可回退过期缓存;手动刷新热点榜单并保留当前题材时会对详情请求传入 `refresh=true` 绕过详情缓存;不会默认触发 AlphaSift 的 DSA deep-analysis 回调,避免无提示扩大递归调用面。
4141
- 热点刷新容错:东方财富热点直连源遇到连接中断、超时或 `Connection aborted` 会做短 backoff 重试;手动刷新失败且没有可用热点缓存时,`/api/v1/alphasift/hotspots` 返回稳定空态 payload、`source_errors=["eastmoney_hotspot_unavailable"]` 和用户可读 `message`,原始异常仅保留在服务端日志或诊断链路中。桌面端更新会保留 `data/alphasift/hotspots.json``data/alphasift/hotspot.history.jsonl``data/alphasift/hotspot_details``data/alphasift/snapshot.last_good.json`,避免更新后丢失 last-good 缓存。
4242
- 热点数据源补充:DSA provider 使用直连 HTTP 思路,东财板块兜底源使用 `push2.eastmoney.com/api/qt/clist/get` 并保留涨跌幅、领涨股、上涨/下跌家数等字段;题材详情会在一次 provider 生命周期内缓存并合并东方财富成分股、同花顺页面解析和板块异动龙头兜底,优先返回多只概念股,发酵路线按日期聚合展示,避免把同一盘中观察拆成多条同时间节点;事件催化不再使用 DSA 内置静态文案,只展示 AlphaSift 合约时间线、同花顺摘要、已配置新闻搜索源或东财板块异动结构拿到的真实信息;新闻搜索命中的消息会优先通过已配置 LLM 压缩成一句题材催化摘要,LLM 不可用时回退本地短摘要,避免在时间线中展示完整报道。
4343
- 风险提示:前端设置页和选股页展示第三方来源与投资风险说明;不会弹窗打断用户。
@@ -121,7 +121,7 @@ context = {
121121

122122
AlphaSift 会在 L1 初筛后、LLM 重排前调用 `context["dsa"]` 中的 provider,为有限 Top 候选补充 DSA 行情和基本面轻量上下文,并把 `dsa_context` 随候选返回。新闻搜索、完整摘要和缺失字段补全由 DSA API 在最终 Top 候选阶段执行;若候选已经携带完整新闻上下文,DSA API 返回阶段会复用这些字段,避免重复请求。
123123

124-
AlphaSift 侧已在 `ZhuLinsen/alphasift@14e74fc0819267f7c04c3117a0dd0fe3f9b19404` 提供 DSA provider context 支持、DSA adapter contract,并支持复用 DSA 的 `LLM_TIMEOUT_SEC`
124+
AlphaSift 侧已在 `ZhuLinsen/alphasift@377049857cc04175dc3cca62121ee41adec6cdb8` 提供 DSA provider context 支持、DSA adapter contract,并支持复用 DSA 的 `LLM_TIMEOUT_SEC`;同一 pin 还会读取 `LLM_MAX_TOKENS` 限制 LLM 重排输出,且 timeout 后不再盲目重试无 JSON mode 请求
125125

126126
## DSA 后端行为
127127

@@ -135,7 +135,7 @@ AlphaSift 侧已在 `ZhuLinsen/alphasift@14e74fc0819267f7c04c3117a0dd0fe3f9b1940
135135
## 配置兼容边界(LLM / LiteLLM / Base URL)
136136

137137
- 兼容语义与版本证据(可追溯):
138-
- 运行依赖约束:`requirements.txt` 中将 LiteLLM 固定到 `litellm>=1.80.10,!=1.82.7,!=1.82.8,<2.0.0`,并通过 `git+https://github.com/ZhuLinsen/alphasift.git@14e74fc0819267f7c04c3117a0dd0fe3f9b19404` 安装 AlphaSift 适配层。
138+
- 运行依赖约束:`requirements.txt` 中将 LiteLLM 固定到 `litellm>=1.80.10,!=1.82.7,!=1.82.8,<2.0.0`,并通过 `git+https://github.com/ZhuLinsen/alphasift.git@377049857cc04175dc3cca62121ee41adec6cdb8` 安装 AlphaSift 适配层。
139139
- 文档依据:
140140
- LiteLLM Providers: https://docs.litellm.ai/docs/providers
141141
- LiteLLM OpenAI-compatible: https://docs.litellm.ai/docs/providers/openai_compatible
@@ -168,7 +168,7 @@ AlphaSift 侧已在 `ZhuLinsen/alphasift@14e74fc0819267f7c04c3117a0dd0fe3f9b1940
168168

169169
- 依赖与源码约束核验:`requirements.txt` 中的 `litellm` 约束与 `src/config.py`/`requirements.txt` 一致。
170170
- Hotspot 契约兼容核验:`docs/alphasift-integration.md``api/v1/endpoints/alphasift.py``src/services/alphasift_service.py` 保持 `hotspots`/`hotspots/{topic}` 字段与 `tests/test_alphasift_api.py` 一致,调用前后默认使用 `snapshot.last_good` 缓存兜底。
171-
- 外部版本来源:本次集成依赖来源为 `https://github.com/ZhuLinsen/alphasift/commit/14e74fc0819267f7c04c3117a0dd0fe3f9b19404`,需在复验时按该 commit pin 回放导入与接口契约。
171+
- 外部版本来源:本次集成依赖来源为 `https://github.com/ZhuLinsen/alphasift/commit/377049857cc04175dc3cca62121ee41adec6cdb8`,需在复验时按该 commit pin 回放导入与接口契约。
172172
- 行为核验:`src/services/alphasift_service.py``_build_alphasift_runtime_env``_build_alphasift_context` 仅在调用期写入进程环境;`/api/v1/alphasift/screen``strategies``status` 在运行期不回写 `.env`
173173
- 回退核验:关闭 `ALPHASIFT_ENABLED` 并重启配置链路后,系统恢复原始 `LITELLM_MODEL/FALLBACK_MODELS``LLM_CHANNELS``LLM_*` 运行语义,不执行迁移清理脚本。
174174
- 语义来源核验:LiteLLM 文档(https://docs.litellm.ai/docs/providers)、OpenAI-compatible 文档(https://docs.litellm.ai/docs/providers/openai_compatible)与 LiteLLM 配置文档(https://docs.litellm.ai/docs/proxy/configs)用于核对 provider/model/base_url/extra_headers 映射链路。

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ yfinance>=0.2.0 # Priority 4: Yahoo Finance (Fallback)
1919
longbridge>=0.2.77 # Priority 5: Longbridge OpenAPI fallback for US/HK stocks; OAuth capability checked at runtime
2020
tickflow>=0.1.0 # TickFlow official SDK (Issue #632, market review enhancement)
2121
# Built-in optional AlphaSift screening engine
22-
git+https://github.com/ZhuLinsen/alphasift.git@14e74fc0819267f7c04c3117a0dd0fe3f9b19404#egg=alphasift
22+
git+https://github.com/ZhuLinsen/alphasift.git@377049857cc04175dc3cca62121ee41adec6cdb8#egg=alphasift
2323

2424
# Feishu
2525
lark-oapi>=1.0.0 # Feishu API

src/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
logger = logging.getLogger(__name__)
4141

4242
DEFAULT_ALPHASIFT_INSTALL_SPEC = (
43-
"git+https://github.com/ZhuLinsen/alphasift.git@14e74fc0819267f7c04c3117a0dd0fe3f9b19404"
43+
"git+https://github.com/ZhuLinsen/alphasift.git@377049857cc04175dc3cca62121ee41adec6cdb8"
4444
)
4545

4646

0 commit comments

Comments
 (0)