From 41c53b9fae8de4d108b4b1d808f8ad16f708b6b2 Mon Sep 17 00:00:00 2001 From: claude_dev Date: Thu, 8 Oct 2026 22:50:53 +0800 Subject: [PATCH] =?UTF-8?q?docs(pipeline):=20D7=E8=90=BD=E6=88=90=E8=BE=B9?= =?UTF-8?q?=E4=BA=AE=E7=81=AF=E5=AE=9A=E6=A1=88+QuantaAlpha=E5=9B=A0?= =?UTF-8?q?=E5=AD=90=E5=87=BA=E7=94=9F=E8=BE=B9=E8=B0=83=E7=A0=94=E5=85=A5?= =?UTF-8?q?=E5=BA=93=20[nas]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit spec §7 新增(原§7-§10顺延): 定谳=假设→因子边「机器已在灯没开」——P4-2分解器 全链10-02已交付但零实绩+三出口半瞎; D7=可见性四件(卡片产物视图/工厂origin 徽标+回链/分解琥珀待办/结果面板持久化)+出厂验收线(真实卡从一句话到工厂 看板全程可见)+供给源可插拔(现役分解器机芯/QuantaAlpha整机远期单独立项/ AST跨批查重=factor域小件); §8开放问题#7标记已定→D7。 调研报告=六问file:line全证(第四形态/首跑零LLM模板成码/无显式状态机/ 四抄三不抄); .gitignore补.superpowers/忽略(brainstorm会话产物)。 用户VPS实测AI生成草稿报LLM上游异常,修复先行于改造(调通后按spec对比验收)。 --- .gitignore | 3 + ...6-10-08-quantaalpha-factor-birth-survey.md | 107 ++++++++++++++++++ ...2026-10-08-pipeline-console-ux-redesign.md | 39 ++++++- 3 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 docs/superpowers/reports/2026-10-08-quantaalpha-factor-birth-survey.md diff --git a/.gitignore b/.gitignore index 925b625e..8b4f72e8 100644 --- a/.gitignore +++ b/.gitignore @@ -118,3 +118,6 @@ data_xtdata_stage/ # QMT 部署身份单一权威源(P2-18 根治 10-05;须随 promote 走,无敏感值=模拟号) !config/qmt_identity.json + +# brainstorming 视觉伴侣的设计稿(会话产物,不进 git) +.superpowers/ diff --git a/docs/superpowers/reports/2026-10-08-quantaalpha-factor-birth-survey.md b/docs/superpowers/reports/2026-10-08-quantaalpha-factor-birth-survey.md new file mode 100644 index 00000000..8e48e418 --- /dev/null +++ b/docs/superpowers/reports/2026-10-08-quantaalpha-factor-birth-survey.md @@ -0,0 +1,107 @@ +# QuantaAlpha「研究想法 → 因子实现 → 注册入库」边调研(2026-10-08) + +调研对象:本地仓库 `~/.openclaw/sanguo_projects/QuantaAlpha`(只读)。焦点 = 假设→因子这条**边本身**的实现与状态管理,非 09-27 P4 调研的卡片向导/分解器。 +下文 file:line 均相对仓库根;`QA` = `quantaalpha/`。 + +## 一句话结论 + +QuantaAlpha 的这条边**全自动、零人工卡点**:LLM 生成假设→LLM 在白名单 DSL 内生成表达式→**确定性模板**渲染 factor.py(首跑根本不经过 LLM)→qlib 回测→**自动注册**进 JSON 因子库(假设全文作为血缘字段嵌进因子记录)。它不是我们的 A/B/C 任何一个,是第四形态:**「收窄 LLM 输出面(DSL 表达式而非代码)+ 确定性硬门 + 事后分级」的全自动边**。人的角色只有三个:起点给方向、中途看直播可取消、终点按质量分级翻库。 + +## ① 端到端链路图 + +``` +人(唯一入口):一句话方向 + configs/experiment.yaml 参数 + │ launcher.py:6 / QA/cli.py:30-33 (mine) / frontend app.py:466 (UI 表单覆盖参数) + ▼ +规划:方向 → N 条并行探索方向(LLM,失败降级到内置模板 patterns) + │ QA/pipeline/planning.py:69-106(fallback 模板 :51-66) + ▼ +进化编排:Original→Mutation→Crossover 轮次调度(QA/pipeline/factor_mining.py:318-511) + │ 每个任务 = 跑一个完整的 5 步小循环(step_n=5, :340) + ▼ +AlphaAgentLoop 五步(QA/pipeline/loop.py:143-249,LoopMeta 按方法定义序自动编排 + │ QA/utils/workflow.py:44-65,99-145): + ├─1 factor_propose 生成假设卡片(LLM) loop.py:143-149 + ├─2 factor_construct 假设→因子表达式(LLM+确定性门+违规反馈重生成) loop.py:153-158 + ├─3 factor_calculate 表达式→factor.py 代码(确定性模板优先,LLM 仅救火) loop.py:161-167 + ├─4 factor_backtest qlib 回测(本地/Docker) loop.py:170-182 + └─5 feedback LLM 生成反馈 + **自动注册因子库** + trace 追加 loop.py:186-249 + ▼ +反馈携 new_hypothesis 回到第 1 步(下一轮假设的输入)——闭环 +``` + +- **哪些 LLM/哪些人工**:规划、假设、表达式、(失败时的)表达式修复、反馈 = LLM;代码实现 = 模板确定性渲染(见③);回测 = qlib 进程。**环内没有任何人工审批/确认步骤**——唯一的"人工"是启动前填方向和参数、运行中可发 stop_event(workflow.py:142-144)/UI 取消(app.py:514-550)。 +- 组件装配表:QA/pipeline/settings.py:52-58(hypothesis_gen / hypothesis2experiment / coder=QlibFactorParser / runner / summarizer 五件套字符串类路径装配)。 + +## ② 边状态机与落库 + +**没有显式状态机**。边的状态隐式分布在三本不同的账上(推断:这是"流程即代码"风格,无人维护 propose→registered 状态字段): + +| 账本 | 载体 | 内容 | file:line | +|---|---|---|---| +| 会话内轨迹 | `Trace.hist: list[(Hypothesis, Experiment, HypothesisFeedback)]` 内存+pickle 快照 | 每轮三元组;SOTA=最后一个 decision=True 的轮 | QA/core/proposal.py:90-103;每步后整会话 pickle QA/utils/workflow.py:140 | +| 因子库(跨会话唯一持久库) | `data/factorlib/all_factors_library[_suffix].json` | 每因子一条:id/表达式/代码/描述/**metadata.hypothesis 假设全文**/backtest_results/feedback | QA/factors/library.py:119-147;loop.py:194-247 写入点 | +| 进化轨迹池 | `log/trajectory_pool.json` | 每完整轮一条 trajectory:假设+因子+指标+反馈+父系 lineage;`is_successful()=RankIC>0` | QA/pipeline/evolution/trajectory.py:28-97,148-205,341-358 | + +- 因子记录字段(library.py:119-140):`factor_id`(md5(name+expr)[:16])、`factor_expression`、`factor_implementation_code`、`factor_description/formulation`、`cache_location`、`metadata{experiment_id, round_number, evolution_phase, trajectory_id, parent_trajectory_ids, **hypothesis**, initial_direction, planning_direction, created_at}`、`backtest_results`、`feedback`。**假设→因子的边在数据层 = 因子记录里反规范化嵌的 hypothesis 字符串 + trajectory lineage**,不是外键、没有假设表。 +- **失败假设去哪(墓园问题)**: + - 整轮回测失败(FactorEmptyError)→ 跳过本轮、**不进** trace.hist、**不进**因子库,只留日志与逐步 pickle 快照(workflow.py:116-119;loop.py:51 skip_loop_error)。 + - 进化任务异常 → 不建 trajectory,仅 logger.error 后 continue(factor_mining.py:492-496)。 + - 回测跑通但指标差 → **照样入库**,差指标+LLM 批评原样存档,读侧再分级(见⑤)。 + - 结论:没有专门墓园;"墓园" = 日志 + 差质量因子本身留在库里(带 feedback 尸检报告)。 +- 一致性门(假设↔表达式 LLM 软校验,可改写表达式)默认**关**(configs/experiment.yaml quality_gate.consistency_enabled: false);其 except 分支默认放行 is_consistent=True——软门缺陷,09-27 已记,此次复核仍在此(QA/factors/regulator/consistency_checker.py:131-140)。 + +## ③ 注册与查重 + +**注册 = feedback 步骤末尾的自动 upsert**,try/except 包裹、失败仅 warning 不阻塞流水线(loop.py:194-249)。 + +**查重在注册之前、分两层,且都在"表达式生成"环节内完成**: + +1. **生成环内的 AST 硬门 + 反馈式重生成**(QA/factors/proposal.py:438-560):`while True` 循环——LLM 出表达式 → `is_parsable`(白名单 DSL 可解析,:461)→ `FactorRegulator.evaluate`(AST 子树匹配 factor zoo + 复杂度统计,:465;QA/factors/regulator/factor_regulator.py:61-112)→ 可选一致性门(:470-499)→ `is_expression_acceptable` 五条件硬门(factor_regulator.py:115-170:重复子树≤阈值、free_args 比值 -log(1-x)<0.693、unique_vars 同式、符号长≤300、基础特征≤6)。**不过 → 把具体违规数值(撞了 zoo 哪个因子/哪个子树/超了哪条线)渲染进 prompt 重新生成**(proposal.py:514-552),违规反馈可累积叠加。注意:该重生成环**无次数上限**(推断:靠反馈收敛,理论可无限重试)。 +2. **跨轮名字级查重**:convert_response 对 trace.hist 里历史实验的 factor_name 去重,同名直接丢弃(proposal.py:595-609)。 +3. 通过的因子当场 `add_factor` 进**会话内 factor zoo**(DataFrame,proposal.py:564;factor_regulator.py:173-191),供同会话后续轮次查重;库层 id=md5(name+expr) 天然幂等 upsert(library.py:85-87,142)。 + +**代码实现的关键护栏(本次最重要发现)**:`FactorParsingStrategy.implement_one_task`——**首次实现零 LLM**:把表达式+因子名填进 jinja2 模板直接生成 factor.py(QA/factors/coder/evolving_strategy.py:249-254);只有执行失败后 LLM 才介入,且 LLM 输出的**不是代码而是新表达式 JSON `{"expr":...}`**,再过同一模板渲染(:331-347)。即 **LLM 永远不写自由 Python,只写受约束的表达式串**;代码面 = 确定性模板。执行有 md5(code) 缓存(QA/factors/coder/factor.py:96-104)+ 子进程超时(factor.py:178-185)+ runner 兜底手动重跑(QA/factors/runner.py:100-132)。 + +## ④ 反馈闭环 + +- feedback 步:LLM 读「假设 + 各因子实现详情 + 与 SOTA 指标对比表」产出五字段:observations / hypothesis_evaluation / **new_hypothesis** / reason / decision("Replace Best Result"→bool)(QA/factors/feedback.py:216-339;指标对比表 :26-120,聚焦 IC/IR/回撤/年化)。失败重试 3 次 JSON 解析(:299-314)。 +- `new_hypothesis` 通过 trace.hist 渲染进下一轮假设生成的 prompt(proposal.py:207-229,history_limit=6 动态降级抗超长 :246-309)——**归因反哺**。 +- 确定性复杂度告警在反馈时再次计算并附给 LLM(feedback.py:239-272)。 +- 回测失败的因子:见②——整轮蒸发(skip),边状态上等于"从未发生";因子库收到的都是跑通了的(指标好坏都收)。 +- 进化层把每轮 trajectory(含指标+反馈)写入池,失败者留在池中可被 weighted_inverse 策略选为亲本继续探索(trajectory.py:94-97,251-339)。 + +## ⑤ 人类监督方式(全自动下人靠什么) + +| 通道 | 形态 | file:line | +|---|---|---| +| 起点控制 | UI 表单覆盖 num_directions/max_rounds/quality_gate 等,落临时 yaml 再起子进程 | frontend-v2/backend/app.py:227-255,466-503 | +| 过程直播 | 子进程 stdout 逐行解析→WebSocket 推前端(phase/round/metrics 实时);可 SIGTERM/SIGKILL 取消 | app.py:184-453,514-550,1135-1183 | +| 结构化日志 | logger.log_object(tag=...) 每步产物(假设/子任务/回测/反馈)落 trace 目录 | loop.py:147,157,166,180,189 | +| 终点分级 | 因子列表读时按 IR 分类 high/medium/low(>0.5 / >0.1 / 其余),可过滤可搜索 | app.py:142-165,562-672 | +| 血缘可看 | 因子详情页 = 库记录全量返回(含 metadata.hypothesis 假设全文、feedback、代码) | app.py:751-766 | +| 进化总账 | trajectory_pool.json + 结束时 Top5 轨迹与池统计打印 | factor_mining.py:498-508 | + +即:**质量监督 = 事后按指标分级翻库 + 直播日志,无过程卡点**。另发现一处读写漂移:UI 列表读 `evolution_metadata` 字段而写入侧写的是 `metadata`(app.py:646-651 vs library.py:127-137),轮次/方向列实际显示不出来(推断:前端后写的,未对齐写入侧 schema)。 + +## ⑥ 对我们 A/B/C 的映射与可抄清单 + +**本质映射:QuantaAlpha ≈ C 的骨架 + 我们世界不可能直接照搬的前提。** 它敢全自动的原因不是护栏多强,而是**输出面被收窄到表达式 DSL + 固定代码模板**——LLM 连写 Python 的机会都没有,代码正确性问题被模板消灭,剩下的只有"表达式是否重复/过复杂/与假设一致"三个可确定性判定的问题。我们的因子是自由 Python 打分代码 + registry,输出面天然宽一个量级,同款全自动=把模板护栏换成裸 LLM 写码,风险不可同日而语。**因此它不构成我们转向纯 C 的论据;它构成的是"若做 C,必须先造出等价的收窄输出面"的论据。** 宪法「LLM 不碰交易决策」也仍然否决全自动入流水线。 + +**推荐:B 为主体,抄 QuantaAlpha 的四件护栏细节;C 只借"模板收窄"思想留给远期。** + +**抄进 B 的清单**: +1. **边落在数据层,不止 UI 层**:注册记录里嵌假设血缘(hypothesis 全文/卡号/方向/轮次/父系)。我们的 factor_registry.yaml 注册项应带 `source_card_id` + 卡片摘要快照——这是 A 和 B 共同的底座,QuantaAlpha 证明了血缘反规范化进因子记录就够了,不需要独立"边表"(library.py:119-140)。 +2. **注册自动且非阻塞**:注册失败只告警不拦流水线(loop.py:248-249);upsert 幂等 id(md5(name+expr),library.py:85-87)→ 我们 version_registry 指纹已有,补"重复注册=幂等更新"语义即可。 +3. **读侧分级而非写侧门禁**:差的也入库、带"尸检"(feedback 原文),UI 按 IR 分 high/medium/low(app.py:142-165)→ 对应我们假设卡七档里的因子侧呈现:**工厂看板直接给质量档,淘汰者留在库可见**,墓园=库内低档+死因,而非删除。 +4. **违规反馈式重生成**(若未来 B 里加"LLM 预生成表达式草稿"辅助人工落成):把确定性检查的具体违规数值渲染进重生成 prompt(proposal.py:514-552),且**确定性检查必须是硬门**(AST 查重/复杂度五条件,factor_regulator.py:115-170),LLM 一致性检查只当软提示(consistency_checker.py:131-140 的教训)。 + +**不抄清单**: +- **全自动注册进"可被流水线消费"的库**:它库里好坏全收、无人审。我们有晋级闸门+月度批评人工闸门,落成(入 registry)必须留在人工卡点后——B 的"关待办"动作本身就是这个卡点。 +- **无限重生成环**(proposal.py:438 无上限,推断靠收敛)与**失败轮蒸发**(不进任何账本):我们要的是每张卡的落成史完整可回放(run 台账先于页面),失败也要留痕在待办/卡片的尝试记录里。 +- **三本账并存**(trace pickle / 库 JSON / 轨迹池 JSON)的分裂:单机会话型研究框架可以,生产流水线不行——我们的边状态三档(待办/进行中/已落成)应只有一处真相(推断:落 DB 或 registry,UI 皆读它)。 + +**C 的重新评估**:唯一值得留档的 C 模式 = **"LLM 只产受约束工件 + 确定性模板成码 + 硬门反馈重生成"**(evolving_strategy.py:249-254,331-347)。若某天我们的因子能表达成白名单算子 DSL,C 才具备安全前提;在那之前 C 不立项。 + +--- +*证据基线:commit 时的本地副本;所有行号已逐条核对。推断处均已标注。* diff --git a/docs/superpowers/specs/2026-10-08-pipeline-console-ux-redesign.md b/docs/superpowers/specs/2026-10-08-pipeline-console-ux-redesign.md index 1a7f3300..375fae4c 100644 --- a/docs/superpowers/specs/2026-10-08-pipeline-console-ux-redesign.md +++ b/docs/superpowers/specs/2026-10-08-pipeline-console-ux-redesign.md @@ -22,6 +22,7 @@ | D4 | **边一等公民**:每条迁移边四问全答——从哪来 / 什么条件 / 谁触发(自动=青 / 人工=琥珀,全站统一)/ 到哪去;以过程与状态呈现,不以文本说明书呈现 | 10-08 | | D5 | **对象详情页=过程真相载体**:一生时间线 + 权重演进 + 参数 + 证据链 + 血缘;自动事件带「▶ 看执行」回跳当时那次 run | 10-08 | | D6 | **出生页=表单即策略**(模板型配参 + 非标登记两入口);提交=登记待办(人工卡点)→ 自动排考 | 10-08(形态定,细节待议) | +| D7 | **落成边亮灯**:假设→因子这条边机器已在(P4-2 分解器全链)、灯没开——不造新机器,只做可见性四件(详见 §7) | 10-08 晚 | ## 3. 术语(本稿内精确使用) @@ -61,7 +62,31 @@ 待裁定分叉:哪些参数允许对象级覆盖?非标考窗=显式豁免+标注「与统一考卷不可比」是否成立? -## 7. 开放问题清单(compact 后逐节过) +## 7. D7 落成边亮灯(10-08 晚定案) + +**定谳(当日对账结论:spec 完整、实现完整、半的是实绩与可见性)**:假设→因子这条边,**机器已在、灯没开**——P4-2 分解器全链(白名单预校验 / 批内防换皮 / 违规反馈重生成(有 max_rounds 上限)/ 通过者自动注册 incubating+origin:decomposer / 墓园回写卡片)10-02 已交付,卡片状态机(queued/data_check/building)与 registry origin/hypothesis 字段均在库。但运行实绩=**零**(registry 无一条 origin:decomposer 产物),且三出口半瞎: + +| 出口 | 现状 | +|------|------| +| 分解结果面板 | 一次性内存态(HypothesisPool.vue decomposeResult ref),刷新即失 | +| 工厂看板 | incubating 上板,但不显 origin、不回链来源卡 | +| 晋级/墓园 | 机制工作,但「因子从哪张卡来」全程无 UI | + +全自动的准确边界:**机械部分全自动**(表达式生成+注册+月度批考试+墓园回写),三个人工卡点保留(落卡确认 / 点分解 / 五问评审)——宪法「关键 promotion 永不自动化」不动。 + +**D7 内容=可见性四件**(strategy 前后端域,不新造机器): +1. building 卡片持久产物视图:已产因子清单(名/表达式/落成日)+ 跳工厂 +2. 工厂 origin 徽标列(decomposer/manual)+ 回链来源卡 +3. 分解待办:confirmed 未分解的卡=琥珀待办(人工卡点②显性化,与 D6 登记待办同构) +4. 分解结果面板持久化(并入①,取消一次性弹层) + +**出厂验收线**:一张真实假设卡,从一句话→草稿→落卡→AI 分解→工厂看板可见 origin 与回链→月度批出 t 值,全程在控制台可见可回溯。在此之前该链路视为「未出厂」。 + +**供给源可插拔**:表达式车道机芯=P4-2 分解器(现役,含白名单+反馈重生成);QuantaAlpha 整机接入(数据桥+表达式方言翻译前置,它绑 qlib 生态不能直连)=远期单独立项 factor 域,不并入本设计;其 AST 子树级查重(跨批防换皮升级,现役仅批内表达式级)=factor 域独立小件。调研在档:`docs/superpowers/reports/2026-10-08-quantaalpha-factor-birth-survey.md`(含四抄三不抄清单)。 + +**前置事实(链路 walkthrough 核实,routes_pipeline.py:936-1023)**:入口=假设池一句话向导→确认落卡(🟡)→「AI 分解」按钮(🟡,仅 queued/data_check/building 可点)→自动注册+卡片转 building 挂 factor_id→月度批 resolve_with_yaml 动态注册链接管→工厂 t 值→近窗 t≥2 进评审候选→五问(🟡)→ promoted / graveyard 回写。前置条件:LLM 配置三层解析生效(设置页 LLM 卡)+ 假设所需数据域已接线(白名单外物理编不出=护栏)。 + +## 8. 开放问题清单(compact 后逐节过) 1. 合并页布局:地铁图/待办/任务墙/健康四块的密度与排序(一屏 vs 分区) 2. 执行详情分步粒度:多少步合适、日志/产物挂多深 @@ -69,23 +94,25 @@ 4. **run 落库模型**:新表 vs 扩 registry_events;谁写(各 job 自记 vs 统一 wrapper);跨域任务(数据 lane)怎么进墙 5. 参数粒度逐项裁定(§6 分叉) 6. 入族登记待办化(替代手工改 composite_library.py)——factor 域实现项 -7. 假设卡 ↔ 因子回链字段设计 +7. ~~假设卡 ↔ 因子回链字段设计~~ **已定 → D7(§7)**;剩细节:产物视图信息密度 / origin 徽标形态 8. 权重演进视图数据源:weight_profiles 已落库(git 白名单),缺 UI 读出 9. 现有九页映射迁移:改哪些 / 废哪些(归因·研判 / 设置去留) 10. 窄屏要不要管(倾向 YAGNI 不管) -## 8. 落地路径(草案,定稿后细化) +## 9. 落地路径(草案,定稿后细化) spec 逐节拍板 → writing-plans 出实施计划 → 分域派单:②权重透明=factor 域;③出生流/④考窗/⑤时间线+车间=strategy 前后端(run 台账=infra+strategy 共建,是地基,**先于一切页面**——调研 §8 同结论)。 铁律:spec 先行 + 用户拍板再动代码(10-08「不要乱改」已立);人工卡点不动;设计变更档随码走(本稿收编后回归总设计 spec 单档原则)。 -## 9. 引用 +## 10. 引用 - 调研报告:`docs/superpowers/reports/2026-10-08-ux-redesign-survey.md`(Top5 收敛:运行台账 / 生效参数回显 / 勾选对比只看差异 / 数字落库即成曲线 / 人工卡点内嵌主线——GitHub 正例「审批在流程页内黄条」,GitLab 反例) - 总设计:`docs/superpowers/specs/2026-09-22-research-to-trading-pipeline-design.md`(§4.3 晋级闸门 / §4.4 合成层 / §11 术语与归属) - 缺口审计与三矛盾修复:issue #92、commit 118c9df..8ed8432、memory `pipeline-ux-redesign-20261008` +- QuantaAlpha 因子出生边调研:`docs/superpowers/reports/2026-10-08-quantaalpha-factor-birth-survey.md`(第四形态定谳+四抄三不抄;本 spec §7 供给源结论的数据基础) -## 10. 变更记录 +## 11. 变更记录 -- 2026-10-08 v0.5 初稿落档(81adfbc,与调研报告同 commit;本条所在 commit=补挂 [nas] 标签备案,首条标题漏标签,工法沿用 5bb2d62 先例) +- 2026-10-08 v0.5 初稿落档(81adfbc,与调研报告同 commit;备案 69cff60 补挂 [nas] 标签) +- 2026-10-08 晚:D7 定案(落成边亮灯——「机器在灯没开」定谳 + 可见性四件 + 出厂验收线 + 供给源可插拔);新增 §7,原 §7-§10 顺延为 §8-§11;QuantaAlpha 因子出生边调研报告入库。同日用户 VPS 实测「AI 生成草稿」报 LLM 上游异常——修复先行于改造(调通后按 spec 对比验收)