docs(agent): 新增「买卖理由词表」与「长任务反馈」两条硬约束(§27.1 / §27.2)
把这两次踩过的坑固化成约束,避免后续 agent 各自发挥: - §27.1:买卖点必须带结构化理由(成交与未成交都要),原因分类封闭词表、两个引擎共用; data 只放引擎当时的真实数字,前端不推算;跌出 TopN / 不在候选池 / 全量换仓 / Tmin / Tmax / 涨跌停 / 现金不足必须区分,宁可新增 code 也不套语义不符的旧 code; 因子曲线口径(持仓市值加权原始值、空仓不落点)+ 方向/单位必须写明; 每条曲线可新页面放大且放大页从归档读。 - §27.2:长任务点了立刻有字、显示真实作业号/阶段/逐秒已用、可取消、失败给后端原文、 成功给归档入口、自动滚入视野;同步接口没有作业号时如实说明,禁止伪造。
This commit is contained in:
@@ -817,6 +817,38 @@ factor_exposure
|
||||
|
||||
前端组件只依赖这个结构。
|
||||
|
||||
## 27.1 买卖理由:必须能回答「为什么买 / 为什么卖」,且数字来自引擎
|
||||
|
||||
用户看回测结果时的第一个问题不是「赚了多少」,而是「**为什么在这里买 / 卖**」。
|
||||
因此每个买卖点(**成交的与未成交的都要**)必须带结构化理由
|
||||
(`TradeReason{code, text, data}`,见 `backend/app/quant/trade_reasons.py`):
|
||||
|
||||
- **原因分类是封闭词表**:组合引擎(`combo_engine.py`)与单策略引擎(`local_engine.py`)
|
||||
共用同一套 code 与文案构造器,禁止各自手写措辞 —— 否则同一件事会出现两种说法。
|
||||
- **`data` 里只能是引擎当时的真实数字**(名次 / 候选数 / 综合分 / 各因子**原始值** /
|
||||
持有交易日 / 预算 / 涨停比值…)。前端**只展示不推算**;拿不到名次就写「未给出名次」,
|
||||
不拿旧名次或其他日期的数据冒充。
|
||||
- **把事实说准**:跌出 TopN ≠ 不在候选池(被股票池/条件过滤)≠ 全量换仓
|
||||
(策略每次调仓先清仓,被卖的股票可能仍排在前列)≠ Tmin 保护暂留 ≠ 超 Tmax 强制了结
|
||||
≠ 涨停/跌停/停牌/现金不足。宁可为一种情况新增一个 code,也不要套一个语义不符的旧 code。
|
||||
- **因子曲线**(`result.factor_curves`)= 当日**持仓按市值加权平均的原始值**
|
||||
(不做 z-score、不按方向取反,空仓日不落点、不插值、不用 0 填充),
|
||||
界面必须同时写出方向与单位(如「股息率 %,越高越好」),否则读者会误判曲线的含义。
|
||||
- **每条曲线都要能新页面放大**(`/charts/{归档id}?s=...`):放大页从**归档**读同一份数据
|
||||
(URL 可分享、口径不漂移);没有归档 id 时如实说明「未归档,无法放大」,不给坏链接。
|
||||
|
||||
## 27.2 长任务反馈:点了立刻有字、看得出在动、出事了能自救
|
||||
|
||||
用户原话:「点了回测没有任何反馈,不清楚是不是已经开始」。因此跑异步 Job 的页面必须:
|
||||
|
||||
- 提交**瞬间**就有反馈(提交中 → 排队中),不等到后端返回;
|
||||
- 显示**真实**作业号 / 阶段 / 逐秒自增的已用时间(用 `lib/jobs.ts` 的 `useJobRunner`
|
||||
+ `components/JobProgress.tsx`,不要各页手写一套);
|
||||
- 排队/运行中可**取消**;失败显示后端原文;成功给「打开归档 / 去对比」入口;
|
||||
- 反馈条出现时**自动滚入视野**,并带 `role="status" aria-live="polite"`;
|
||||
- 同步接口(如 `POST /api/signals`)**没有**作业号与阶段时,如实说明「同步请求、无阶段、
|
||||
不可取消」,**禁止**合成假作业号或假进度喂给反馈组件。
|
||||
|
||||
---
|
||||
|
||||
# 28. AI Agent 约束
|
||||
|
||||
Reference in New Issue
Block a user