报告多维度审查 Skill(业务技能)
定位
.agents/business/ 存放交付/生产类技能。本技能与 html-report 配对:
| 技能 | 职责 | 时机 |
|---|---|---|
html-report | 怎么把分析结果做成报告 | 生成时 |
report-review(本技能) | 报告审得对不对 | 生成后、交付前(自动触发) |
自动触发规则:任何报告(reports/**/*.md、reports/**/*.html、watchlist/**/*.md)生成或修改完毕后,必须自动调用本技能完成 review,向用户输出审查结论后才算交付完成。用户单独要求 "review / 审查 / 核对 / 校对" 某份报告时同样调用。
七个审查维度
按顺序执行,前 5 个维度必须实证核验(跑 CLI / 算数 / 读图表 JS),不允许只凭报告自述判断。
D1 · 行情与基础数据核验
- 报告中每个价格 / 涨跌幅 / 市值 / 规模逐项与本地 CLI 对账:
bash
bun run main.ts -s sh603799 --pretty # 个股/ETF 现价、涨跌、市值 bun run main.ts -f 006493 --pretty # 基金净值 bun run main.ts --dividend sh603799 # 股息率 - 输出一张「报告值 vs 实测值」对照表,精确到报告披露的小数位。
D2 · 时间窗口与口径核验 ⭐ 最高频错误
同一只股票在不同时间窗口下的"最高价 / 回撤 / 分位"完全不同。 必须核实报告口径词与实际取数窗口一致:
| 报告用词 | 合法口径 | 核验方法 |
|---|---|---|
| "年内高点/年内最高" | 自然年至今 | --kline <code> --period monthly 找全年 max high |
| "90 日高点 / 8/14 以来" | 明确窗口 | --period weekly/daily 对应窗口 max high |
| "距高点回撤 -X%" | 写明是哪个高点 | (现价/该窗口最高价-1)×100 复算 |
| "PE 分位" | 必须写明区间 | 近 1 年 / 近 10 年 / 基日以来三者数值差异巨大,禁止混用 |
⚠️ 陷阱:只看近 2 个月 K 线会把"阶段高点"误当"年内高点"。凡报告出现"年内/今年/YTD"字样,必须用 monthly K 线验证。
接口降级:K 线接口 socket 故障时(--kline 连续失败),改用公开披露的收盘价/盘中价快照交叉验证(证券之星行情快报、每经、交易所),并在报告中标注口径与数据来源;不可因接口不可用而跳过核验。
复权口径:K 线接口通常为前复权,行情快报为不复权价,两者可差一个分红额(例:华友 1/26 盘中高点 82.17 不复权 / 81.67 前复权,差额即 2026-05 分红 0.5 元)。引用"高点/低点/回撤基准"时必须标注复权口径。
D3 · 计算自洽性
- 复算所有派生数字:持仓成本/市值/浮亏额/浮亏%/回本涨幅/仓位占比/PE/PB。
- 常用公式:回本涨幅 = 成本/现价 - 1;PE = 市值/净利润;PB = 市值/净资产。
- 交叉校验:正文、指标卡、图表 JS 三处同一数字必须一致。
D4 · 估值与财务口径
- PE 是静态(上年报)/ TTM / 年化 / 动态哪种口径?报告若并列多种口径,各自注释是否清晰?
- 周期股低 PE 警示:低 PE 常出现在盈利顶部,报告是否提示"便宜有便宜的原因"?
- 分位数数据标注来源与区间(见 D2)。
D5 · 图表与文本一致性
- 打开
assets/charts.js(或内联 JS),逐项核对 series 数据与正文数字。 - 检查坐标轴是否截断(
yAxis.min/max把关键数据裁掉会视觉误导,如 K 线图 min/max 未覆盖年内高点)。 - 检查数据窗口是否与正文口径一致(正文讲"年内",图表只画 8/14 以来 = 口径错位)。
- 每个 chart 是否有
<figcaption>标题;引用参考线标注(如"年内高点 X")是否与 D2 核验结果一致。
D6 · 逻辑客观性
- 多空平衡:看多理由与看空/证伪风险是否都呈现?是否只堆利好?
- 沉没成本:决策建议是否围绕"成本价/回本"展开?正确的框架是"今天这个价位还愿不愿意持有"。
- 目标位语义:反弹目标位 ≠ 回本位,是否明确标注避免误读?
- 窗口期一致:触发条件(如"财报前不动手")与操作建议是否自洽。
- 静默假设:仓位占比、风险承受力等未给定的输入,是否以"若…则…"分支表达而非硬编码结论。
D7 · 来源引用与合规
- 正文每个
sup [n]在 footer#cite-n是否都有对应条目,且来源确实支撑该句论断。 - 引用的是原始数据源还是一手转述?第三方口径是否标注?
- 免责声明必备三要素:不构成投资建议、市场有风险、以官方披露为准。
结构化检查脚本
机械项交给脚本(引用锚点配对、离线可开、figcaption 覆盖、口径词扫描等):
bashbun run .agents/business/report-review/scripts/check-report.ts <report.md|report.html>
.html:生成标记 / 引用锚点配对 / figcaption / 离线可开 / 免责声明 / 图表 JS 线索 / 口径词.md:免责声明关键词 / 口径词 / 表格数字线索(md 无 HTML 标记项,自动跳过)
脚本只查结构项,数据正确性必须人工/Agent 实证核验(D1–D5)。
输出格式
markdown## 📋 Review 结论:<一句话总评> ### ✅ 实证通过(逐项列表 + 实测值) ### 🔴 硬伤(动摇结论的事实错误,必须改) ### 🟡 口径/表述问题(建议改) ### 🟢 分析质量评价(框架、客观性) ### 📌 修正清单(按优先级,可直接执行) ### ✅ 复查确认(修正后):逐项记录"问题 → 修正内容 → 复查结果",闭环留痕
分级铁律:
- 🔴 硬伤 = 事实性错误且影响结论(错的数字、错的口径、错的窗口)
- 🟡 问题 = 数字对但口径/表述有误导性
- ✅ 通过 = 实证核对一致(不能写"看起来没问题",要写实测值)
总评必须回答两个问题:① 数据层是否可信 ② 叙事层是否客观。
常见错误陷阱库(历次 review 沉淀,新增错误请追加)
| # | 陷阱 | 判定方法 | 案例 |
|---|---|---|---|
| 1 | 阶段高点冒充年内高点 | monthly K 线 max high ≠ 报告"年内高点" | 47.17(8月反弹)被写成年内高点,实为 1/26 盘中 82.17 元 |
| 2 | 图表截断误导 | yAxis.min/max 未覆盖关键价位 | K 线 max:56 裁掉年内高点 82.17 |
| 3 | 回撤基准不统一 | 同文混用盘中高点/收盘高点/90日高点 | 触发线用一个基准、回撤表用另一个 |
| 4 | 分位数口径混用 | 同文出现两种区间口径 | "近 10 年 4.5% 分位"与"近 1 年 1.2%"混排 |
| 5 | "规模最大/第一"过时 | 交叉搜同类产品规模排名 | 电池 ETF 规模排名随时间变动 |
| 6 | 目标位 = 回本位误读 | 目标价全部低于成本却未标注 | 35.4→38→42 被误读为回本路径 |
| 7 | 单期分红口径失真 | 股息率与实际到账/公告核对 | 第三方单期分红数据误导 |
| 8 | 跌得多 = 便宜 | 回撤大但估值分位仍高 | 半导体设备 -25% 后 PE 分位仍 80%+ |
| 9 | 复权口径混用 | K 线(前复权)≠ 行情快报(不复权),差一个分红额 | 82.17 不复权 / 81.67 前复权被当两个数 |
工作流
- 报告生成/修改完毕(或用户点名 review)
- 跑
check-report.ts过机械项(按扩展名自动分流:.html走 HTML 项,.md走 Markdown 项) - D1–D5 逐项实证:CLI 对账 → 口径核验(接口故障走降级路径)→ 复算 → 图表 JS 核对
- D6–D7 主观审阅:客观性、来源、合规
- 按输出格式给结论 + 修正清单
- 有 🔴 硬伤时主动提出可代改,经用户确认后修正,修正后复查对应项并写入「✅ 复查确认」区块闭环
约定
- Review 语言跟随用户语言
- 不因报告是自己生成的就放低标准——自审更严
- 新发现的陷阱追加到「常见错误陷阱库」


