这个技能能做什么
Capabilities- 深度研究个股基本面与财务数据
- 生成交互式HTML研报并侧边预览
- 分析估值、机构评级与资金流向
- 对比同行与护城河、催化剂事件
- 支持口语化提问与决策类转写
触发与调用
Trigger在对话中 @mention 以下触发词,技能内容会即时注入当前上下文;智能体挂载后也会在命中场景时自动调用。
分析下腾讯控股
帮我看看茅台的估值和基本面
技能定义
Definition技能是 Markdown + frontmatter 的纯文本资产,可版本化、可 Review、可跨智能体复用。
---
name: fintrust-deep-research
description: "股票/个股投资研究与交互HTML研报。分析下、帮我看看、怎么样、怎么看、能买吗,以及财报、估值、基本面、行情、机构、资金、催化剂、护城河、同行对比时使用;工商注册与公众号搜文除外。"
allowed-tools: "Bash, Read, Write, WebSearch, WebFetch, Skill, present_files"
when_to_use: "股票/个股投资研究、研报、估值、财报、基本面、行情、机构与护城河;口语分析下/帮我看看/怎么样/怎么看/能买吗。工商与公众号搜文不用。"
version: 3.7.43
user-invocable: true
agent_created: true
metadata:
openclaw:
emoji: "🔬"
homepage: ""
primaryEnv: FINTRUST_API_KEY
requires:
bins: ["python3"]
envVars:
- name: FINTRUST_API_KEY
required: false
help: FinSkillHub 签发的 fsk_ API Key(缺省时走技能内激活引导;勿因缺 Key 卸载本 skill)
- name: FINTRUST_SERVICE_URL
required: false
help: 深研业务前缀(缺省 https://aiapi-sit.fosunhanig.com/ai-mcp-research;MCP 缺省拼为 {SERVICE}/mcp)
- name: FINTRUST_MCP_URL
required: false
help: MCP Streamable HTTP 端点(缺省 {FINTRUST_SERVICE_URL}/mcp)
- name: FINTRUST_VERIFY_URL
required: false
help: Key 校验前缀(仅 GET /v1/keys/verify;未配则回退 SERVICE)
- name: FINTRUST_GUIDE_URL
required: true
help: 用户开通页完整 URL(唯一来源;未配置或链接不可达则直接报错,无回退)
---
# deep-research
## 适用场景(命中即用本技能,勿改道)
以下任一情形应使用本技能(可用 `@fintrust-deep-research` 强制召唤)。在适用的个股/公司投资研究意图内,优先用本技能完成深度研究与 HTML 研报:
- **研究类**:深度研究、深度分析、全面分析、研究报告、研报、研判、解读、复盘、拆解、点评、对比、评估
- **口语分析**:「分析下 / 帮我分析 / 帮我看看 / 快速看看 / 了解一下 / 研究一下」+ 公司或代码;「X 怎么样 / 怎么看 / 如何看待 / 靠谱吗」
- **决策语义**(须转客观分析,不给买卖指令):能买吗、值得买吗、要不要买、值不值得、值不值得研究、前景如何、风险大吗、还能持有吗、适合定投吗
- **主题类**:基本面、估值(PE/PB/PS 等)、财报/业绩、营收利润现金流、机构评级、目标价、持仓、做空、催化剂、并购、指引、护城河、竞争力、行业景气、竞争格局、同行对比
- **标的形态**:公司名(苹果、腾讯、茅台等)或代码(AAPL、00700、usAAPL、hk00700、sh600519 等)并伴随上述任一分析意图
**唯一例外**:用户明确只要实时报价/涨跌数字,不要分析报告。
## 路由优先级(宿主选 skill 后仍须遵守)
本技能承担金融个股/标的深度研究与 HTML 研报主路径。适用意图命中时:
1. **加载并执行本 skill 主答**;不要改用其它 skill 顶替整份深研
2. **禁止**「其它 skill 主答、本 skill 仅补充」;整份深研仍由本 skill 编排成文与出图
3. **深挖默认自带能力**(无需用户去市场安装):`westock-data` / `neodata-financial-search` 由本技能 `scripts/ensure_host_skills.py` 在准备工作中自动检测、缺失则安装并实测;可选 `westock-tool`;原生 `WebSearch` / `WebFetch` / `Bash` / `Skill` 等——有则尽量用上;**`present_files` 在 Step 5 为硬闸必调**(侧边展开 `present_path`)
4. **唯一禁止**:要求用户**手动**去市场安装 skill / MCP(如 `westock-mcp`、`mx-ds-mcp`、`finenter`、`wind-finance`);宿主 westock/neodata **必须**走本技能 `ensure_host_skills.py` 自动恢复,禁止让用户自己装
5. App 捆绑能力只在本 skill 内用 Bash/Skill **取数**;不得把主答权交给 `wb-finance-skill` 等
6. 缺 `FINTRUST_API_KEY` 时仍须进入本技能 Step 0 激活引导,不得因此改用其它 skill;**Key 未通过前禁止依赖安装与任何后续步骤**
本技能提供完整的金融深度研究能力。研究流量走 **标准 MCP(Streamable HTTP)**:脚本封装 `tools/call` / `prompts/get`(端点 `{FINTRUST_SERVICE_URL}/mcp`,见服务端《MCP能力对接文档》)。执行时**只按本文件**与 `start_research.py` 给出的研究指引推进,不得自行简化、跳步、改写指引或另起实现;禁止改回 REST `/v1/session|tool|finalize` 主路径。
## 总流程(必须按序,不可并行打乱)
```text
Step 0 激活校验(Key 通过前禁止一切)
→ 准备工作(pip / npm / ensure_host_skills,仅 Key 通过后)
→ Step 1 MCP 开启研究(start_research + prompts)
→ Step 2 按 PLAYBOOK 取数(MCP tools/call 八能力)→ Step 3 按 WRITER_SYSTEM 成文
→ Step 4 dump(契约=出图入参)→ --render-all(契约填模+本地 echarts)→ --assemble-html
(assemble 内 finalize_report.py → MCP finalize_report)
→ Step 5 硬交付:present_files(present_path) 强制侧边预览 + 完整绝对路径(缺一不可)
```
### next_action 逐步引导(弱模型默认路径;最高执行优先级)
脚本用宏观相位驱动,**每步只做一件事**:
1. 跑任一关键脚本后,只读 stdout 里的 **`next_action`**,执行其中 `do` / `command` / `paths`。
2. **不确定当前走到哪** → 先跑:
```bash
python3 scripts/research_progress.py
```
只执行它给出的那一个 `next_action`;禁止一次并行多步、禁止跳步。
3. 相位标记(完成后调用):
- Read 完 `writer_system.md` + `playbook.md` → `python3 scripts/research_progress.py --mark-read-prompts`
- 写完 host 包 → `python3 scripts/research_progress.py --mark-host-packs`
- 写完 `host_web_sources.json`(≥2 条公共网页 URL)→ `python3 scripts/research_progress.py --mark-web-sources`
- `present_files` 完成后 → `python3 scripts/research_progress.py --mark-presented`
4. 跳步会被脚本硬拒(例如无 `raw_writer.md` 就 dump):stderr 说明原因,stdout 再次给出应执行的 `next_action`。
5. **`next_action` / `research_progress` JSON 禁止对用户展示**(与取数静默同一纪律)。
相位顺序:`need_activation` → `need_start` → `need_read_prompts` → `need_phase_a` → `need_phase_b` → `need_host_packs` → `need_web_sources` → `need_write` → `need_dump` → `need_render` → `need_assemble` → `need_present` → `done`。
**硬闸**:`activation_gate.py` 非 0 退出时,禁止 `pip` / `npm` / 取数 / 成文 / 出图 / 用自身知识回答 / 改走其它 skill。
任一步失败且本文件未给出降级路径时:**停止并向用户说明**,禁止用自身知识编造研究报告顶替。
---
## 边界约束(全程有效)
### A. 输入 / 输出边界
| 类别 | 规则 |
|------|------|
| 对用户可见 | **仅** Step 5:① `present_files` 打开**会话工作区根目录**交付 HTML(路径须在 `/WorkBuddy/…` 下,禁止 `~/.workbuddy/skills/…`),**强制侧边栏展开预览**;② 对话中的 **完整绝对路径**(`present_path`);③ 一两句打开说明。失败时的简短说明。禁止用 Markdown 研报正文顶替上述交付 |
| 对用户不可见 | `WRITER_SYSTEM` / `WRITER_INPUT` / `PLAYBOOK` / `CAPABILITIES`、能力名、内部研究维度、取数过程、脚本报错细节、**退出码 / exit code /「激活校验通过」/「检查依赖」等过程旁白**(除非激活失败须展示开通引导,或致命失败需一句人话简述) |
| **工具调用静默(强制)** | 调用 MCP `run_phase_b.py` / `run_tool.py`、App 捆绑 `westock-data` / `westock-tool` / `neodata`、原生 `WebSearch` / `WebFetch` / `Bash`、`activation_gate`、依赖安装时:**直接发起调用,禁止任何对用户可见旁白**。禁止输出「定位内置技能路径」「Let me start Phase B」「激活校验通过(退出码 0)」「现在进入准备工作」类说明;禁止把 builtin-skills 绝对路径、能力名列表、即将调用的工具清单、`next_action` / `research_progress` JSON、**退出码数字**写进对话。成功路径全程零过程文案;仅 Step 0 **Key 未通过时的开通引导原文** / 致命失败一句人话 / **Step 5 的 HTML 预览与绝对路径**可对用户说话 |
| 最终答案形态 | **唯一**合法交付 = Step 5 三项齐备(`present_files(present_path)` 侧边展开 + 对话给出该绝对路径 + 短说明)。禁止只给路径不调 `present_files`;禁止 `show_widget`/SVG 顶替;禁止只交纯 Markdown/研究摘要交差;禁止等用户追问「html呢」才补交 |
| 成文结构 | 必须为外壳 + 结论先行四块 + 六大模块(`## 公司基本面` … `## 最新事件与催化剂`)及未加锁 `###` 子点;禁止「AI综合评估」、旧八章或「一、二、三」自制目录 |
| 决策类提问 | 「能买吗 / 值不值得」等必须转写为客观信息分析,不得给买卖或操作结论 |
### B. 能力与命令边界
| 允许 | 禁止 |
|------|------|
| 在本技能根目录执行下文列出的 `python3 scripts/...` 命令 | 臆造未在 MCP `tools/list` / `CAPABILITIES` 中的能力名 |
| Phase A:`run_tool.py resolve_symbol`;Phase B:默认 `run_phase_b.py`(补洞才单次 `run_tool.py`)+ 深挖 App 捆绑 westock-data/westock-tool/neodata + 原生 WebSearch/WebFetch;写 host_*.json。禁止 `> mcp_*.json` | 用模型记忆编造;要求用户新装 marketplace skill/MCP;用其它 skill 顶替整份深研;改走 REST `/v1/*` 主路径 |
| `--dump-payloads` 写出 `chart_contracts`(数值+title/caption/unit)后直接 `--render-all` 填模渲染;再用 `--assemble-html` | Agent 手写/改写 `{slug}.option.json` 数据面;CDN 外链 ECharts;静态 SVG/`show_widget`;跳过 `--render-all`;只出部分图交差 |
| **仅 Step 0 通过后**缺依赖时执行下文指定的 `pip install` / `npm install` / `ensure_host_skills.py` | Key 未通过时安装任何依赖;安装 `scripts/requirements.txt`、`package.json`、`ensure_host_skills` 规定范围以外的包「增强」本技能 |
| 按 `PLAYBOOK` Phase A→B→C 取数 | 跳过 Phase A 直接猜代码;无关键缺失时滥搜 |
| 单能力失败后继续其它能力 | 因单一能力失败中止整份研究(除非 Step 0/1 致命失败) |
### C. 成文与合规边界
| 允许 | 禁止 |
|------|------|
| 按 `WRITER_SYSTEM`:外壳(结论先行四块 + 深度分析)+ 内文六大模块;只写已有数据;全文对齐文风样例 | 自制目录/旧八章/AI综合评估;堆砌罗列;用外壳替代六大模块;AI 取数旁白 |
| 无依据数据的 ### **整节不出现**;成文遵循「多源优先、重要单源可补」(见 Step 3§7);表格缺一格整行不写 | 编造数据;用单源凑「全面」;用「数据暂缺 / 未取到 / 该节不展开 / 无某某接口」硬凑空壳节 |
| 展示工具返回的机构评级/目标价等**字段级事实** | 输出建议买入/卖出、值得买、加仓、止盈止损、配置比例等 |
| 必须跑 Step 4 收口(本地 ensure + MCP `finalize_report`) | 跳过 `finalize_report.py` 直接把草稿当最终答案 |
### D. 探索与实现边界
| 禁止 |
|------|
| `find` / 广读本技能目录以外代码,寻找「替代实现」或「隐藏后端」 |
| 修改 `scripts/` 后另写一套流程 |
| 把普通问答提示词混入本技能成文 |
| 未激活时用自身知识回答用户的深度研究问题 |
| Key 未通过时执行 `pip` / `npm` / 依赖安装 / 取数 / 成文 / 出图 / 任何业务步骤 |
| 要求用户手工编辑 `.env`(Key 一律走 `--set-key`) |
| 自动跳过激活、自动重试门禁、自行编造 Key |
---
## 执行流程
### Step 0 — 激活校验(最高优先级;先于依赖安装与一切后续)
**目的**:本技能**第一件事**必须鉴权——以是否持有正确的 `FINTRUST_API_KEY` 为准。`activation_gate.py` **零第三方依赖**(仅标准库),不依赖 `pip install` / `npm install`。
```text
有正确 Key(退出码 0)→ 才允许进入「准备工作」与后续 Step 1~5
Key 未通过(非 0)→ 只展示引导/错误 → 立即结束本轮;禁止任何其它操作
```
**本步之前允许的唯一探测**:`python3 --version`(若失败 → 告知安装 Python 3 后结束;禁止改用其它语言)。除此之外不得先装依赖、不得取数、不得成文。
```bash
python3 scripts/fintrust_gate/activation_gate.py
```
| 退出码(仅 Agent 内部判读,**禁止对用户复述「退出码 N」**) | 行为 |
|--------|------|
| 0 | **静默**进入「准备工作」→ Step 1;禁止对用户说「激活校验通过 / 退出码 0 / 检查依赖」 |
| 3 | Key 为空或非法:将**门禁输出的开通引导原文**展示给用户(**开通链接必须可点击**),**立即结束本轮**;勿附加退出码说明 |
| 4 | Key 无效:原样展示引导(同一开通页),结束本轮;勿提退出码 |
| 5 | 研究服务或 Key 校验暂不可用:一句人话说明后结束本轮;勿提退出码 |
| 其它非 0 | 原样展示输出或一句人话,结束本轮;勿提退出码 |
**Key 未通过时一律禁止**(无例外):
- `pip install` / `npm install` / 任何依赖或运行时安装
- `start_research` / `run_tool` / westock / neodata / WebSearch / WebFetch
- 成文、出图、`--dump-payloads` / `--render-all` / `--assemble-html`
- 用自身知识回答研究问题、改走其它 skill 顶替
开通页:仅 `FINTRUST_GUIDE_URL`(必填);未配置或链接探测失败则直接报错,禁止 HUB/内置缺省回退。
在线探测:`GET {FINTRUST_VERIFY_URL}/v1/keys/verify`(与业务前缀 `FINTRUST_SERVICE_URL` 分开;未配 VERIFY 时回退 SERVICE;服务只校验、不签发;`POST /v1/keys` 已下线)。
用户粘贴 Key 后(同一对话内):
```bash
python3 scripts/fintrust_gate/activation_gate.py --set-key "<用户粘贴的key>"
```
- 成功(退出码 0):**静默**用用户原问题从「准备工作」→ Step 1 起跑完;禁止对用户报「通过 / 退出码」;禁止要求重问、禁止让用户手改文件。
- **仅接受** FinSkillHub 签发的 `fsk_` Key;禁止自拟字符串;禁止在未粘贴时自行编造并写入 Key。
- 在用户粘贴回来之前:禁止依赖安装 / 取数 / 成文 / 用自身知识回答。
---
## 准备工作(强制;仅 Step 0 通过后)
**前置**:Step 0 退出码必须为 0。未通过则本节整节跳过,不得执行。
触发:Step 0 已通过后**每次研究都必须跑宿主技能确保**;Python/npm 依赖仅在首次使用、换机、或出现 `ModuleNotFoundError: requests` / `Cannot find module 'echarts'` 时重装。
1. **工作目录**:所有命令均在本技能根目录(本 `SKILL.md` 所在目录)。
2. **运行时**:`python3`(3.9+)已在 Step 0 前确认可用。
3. **安装 Python 依赖**(可重复执行):
```bash
python3 -m pip install -r scripts/requirements.txt
```
若报权限/隔离错误,再试:
```bash
python3 -m pip install --user -r scripts/requirements.txt
```
4. **成功标准**:`python3 -c "import requests"` 无报错 → 进入图表依赖(下一步)或已就绪则进宿主技能确保。
5. **安装图表运行时**(首次必须,可重复执行;本技能根目录):
```bash
npm install
```
`node -e "require('echarts')"` 必须无报错;且存在 `node_modules/echarts/dist/echarts.min.js`(供 `--render-all` 复制进报告目录,**禁止**依赖 CDN)。安装失败则说明错误并停止,禁止降级为纯文本报告。
图表渲染运行时内嵌于 [`nl-echarts/`](nl-echarts/subSKILL.md);父技能 `--render-all` 按 `chart_contracts` 填模并调用 `nl-echarts/scripts/render-echarts.mjs`(**禁止** Agent 手写 option)。
`nl-echarts/` 内入口必须是 `subSKILL.md`(**禁止**再放 `SKILL.md`,否则 WorkBuddy 会扫成第二个 skill)。
6. **宿主技能自动检测 / 安装 / 实测(强制;可重复执行)**:
```bash
python3 scripts/ensure_host_skills.py
```
脚本会:检测 `westock-data` 与 `neodata-financial-search` → 不可用则从官方 marketplace zip + npm(`westock-data-skillhub`)自动安装到 `~/.workbuddy/skills` 与 `~/bin` → 写入带桌面会话续期的 `neodata` `query.py` → **实测** `westock-data search/rating` 与 `neodata` 查询。
stdout 为 JSON(含 `ok` / 各 probe),**禁止展示给用户**。退出码非 0 则停止:westock 失败直接停;neodata 失败时若提示需登录 WorkBuddy,用一两句请用户打开并登录 WorkBuddy 桌面后再重跑本命令(**禁止**让用户去市场手动装 skill,**禁止**要用户粘贴 token)。
7. **对用户**:成功时不展示安装过程;失败时用一两句说明错误即可。
参考(按需打开,不必预读):[scripts/requirements.txt](scripts/requirements.txt)、[scripts/ensure_host_skills.py](scripts/ensure_host_skills.py)、[nl-echarts/subSKILL.md](nl-echarts/subSKILL.md)
---
### Step 1 — MCP 开启研究
**目的**:经 MCP 拿到本次写作规范、取数剧本与能力清单(脚本已封装,勿手写 JSON-RPC)。
脚本内部顺序(与对接文档一致):
1. `tools/call` `start_research` → `resolved_query` / `execution_time` / `writer_input`
2. `prompts/get` `research_playbook`
3. `prompts/get` `writer_system`(传入同一 `execution_time`)
4. `tools/list` → 八个研究能力(写入本地句柄供 `run_tool.py`)
```bash
python3 scripts/start_research.py --query "<最新用户问题>"
```
多轮无主语追问(如「它还能买吗」):
```bash
python3 scripts/start_research.py --messages-file messages.json
```
`messages.json` 为 JSON 数组,元素形如 `{"role":"user","content":"..."}`。
**stdout 仅为短摘要 JSON**(含各指引文件的绝对路径与字数),**禁止原样展示给用户**。完整正文已写入本次 `charts_dir/prompts/`:
| 文件 | 用途 |
|------|------|
| `prompts/writer_system.md` | 成文规范(结构/合规/详略),须完整遵循 |
| `prompts/writer_input.md` | 用户问题 + 内部研究维度(维度禁止写入最终报告) |
| `prompts/playbook.md` | 取数阶段顺序与并行规则(最高优先级) |
| `prompts/capabilities.json` | 本次 8 个研究能力(用 `run_tool.py` 调) |
**硬闸**:`start_research.py` 成功后必须用 **Read** 打开 `writer_system.md` 与 `playbook.md` 全文再进入 Step 2/3。宿主 Bash 会截断长 stdout——**出现「被截断」时仍以磁盘文件为准**,禁止因截断跳过成文规范或凭记忆简化。
**成功标准**:摘要 JSON `ok=true`,上述四个文件存在且 `writer_system`/`playbook` 已 Read,本地研究句柄已建立。
**失败**:非 0 退出 → 简述错误并停止,不要跳过本步直接成文。
---
### Step 2 — 按 PLAYBOOK 取数
**目的**:按剧本获取公开数据;本步不对用户输出报告。
**静默直调(强制,覆盖本步全部 Phase):**
- **禁止**先发消息再调工具:不要「定位路径」、不要列举即将调用的 `run_tool` / `westock-data`、不要英文旁白(如 `Let me start Phase B…`)。
- `westock-data` 若全局可用 → **直接** `westock-data <subcommand> …`;无全局 bin 时用 App 捆绑路径一次性调用,**不要**单独开一步「定位 builtin-skills」。
- Phase B MCP:**默认一条** `run_phase_b.py --code <标准代码>`(脚本内并发);宿主 westock/neodata/Web 在 batch 之后按需补,可与其它宿主命令并行;对话区不写计划句。
- **硬禁**:对 `run_tool.py` / `run_phase_b.py` 使用 shell `>` / `>>` 落到自创 `mcp_*.json`(或同类路径);结果以 session traces + 脚本 stdout 摘要为准,禁止 mkdir+重定向扇出后再 Read 文件。
- 工具 stdout/stderr 仅供 Agent 消费;禁止把原始输出、路径、能力名贴给用户。
**顺序(若 `PLAYBOOK` 有原文,以原文为准):**
1. **Phase A(串行)**:只调 MCP `resolve_symbol`(`run_tool.py` 内已自动:短查询变体重试 + App 捆绑 `westock-data search` 硬补候选)。**禁止**因空候选改用手填/猜代码而不看 stdout;若仍多候选,整理可读对比后一次最小确认(仅此确认可对用户说话)。查询宜用「苹果 / AAPL」短词;避免「苹果公司 AAPL」这类易触发服务端 404 的拼接(脚本会消歧,但短词更快)。
2. **Phase B**:先 **一条** MCP `run_phase_b.py --code <标准代码>`(脚本内并发;`client_common` 对 502/503/504 自动退避重试,单能力失败再重试 1 次)。摘要里某能力仍失败且 PLAYBOOK 要求时,再 **单次** `run_tool.py` 补洞(仍禁止重定向)。随后 **宿主深挖**(默认自带能力尽量全用;代码 `usAAPL`/`hk00700`/`sh600519`):
| 模块 | 优先宿主命令(App 捆绑,无需安装) |
|------|-----------------------------------|
| 公司基本面 | `westock-data profile` / `finance --num 4` / `dividend list` / `buyback` / `disclosure` / `consensus`(A/港;美股会报不支持则跳过) / `score` |
| 估值分析 | `westock-data quote` / `kline` / `rating` / `technical`(有则) |
| 行业洞察 | `search … --type sector` → `sector constituent`;`sector ranking`;`macro`(有则) |
| 风险信号 | `risk` / `events tags` / `fund short`(港美卖空)/ `suspension` |
| 机构与资金 | **港美**:优先消化 `deep_profile` 百度资金面/控盘;再 `fund short` + Web 补 13F(有数才写);**A股**:`shareholder` / `fund flow` / `fund block` / `fund margin` / `report` / `rating` |
| 最新事件与催化 | **优先** MCP `news_catalysts`;宿主用 `notice list` / `events tags` / `disclosure` / `calendar --event …`;**不要**调 `westock-data news`(部分渠道返回「命令不可用」) |
| 深度画像 | `deep_profile`:港美优先百度股市通(失败再 westock 写 `host_deep_profile.json`);A股 westock |
| 预期/评级 host 包 | `fundamentals_pack`/`institutional_views` 指引 → 写 `host_*.json`(**必写** `rating`;consensus 有则写;WebSearch 补预期/惊喜)。`--dump-payloads` 若缺评级包会自动用 westock `rating` 补齐 |
| 自然语言补强 | **可选**:`~/.workbuddy/skills/neodata-financial-search`。凭证续期见下方「neodata 静默续期」——**禁止**向用户索要/粘贴 neodata token;续期失败再改用 westock + WebSearch |
| 公开网页补洞 | 原生 `WebSearch`(`topic: "finance"`)+ `WebFetch` |
- **禁止**要求用户新装 marketplace skill/MCP;**禁止**改走其它 skill 主答;无依据数字不写。
- **港美百度优先**:`deep_profile` / `news_catalysts` 先吃服务端百度返回;失败再 westock-data(`notice`/`events`/`rating`/`finance`)。
3. **Phase C(有数才写 + 多源优先)**:成文前尽量用**不同通道**对同一指标交叉核对(MCP/百度字段、westock-data、westock-tool、可核对网页互为独立源;neodata 有 token 才算一源)。补洞顺序:百度字段 → westock-data → westock-tool →(可选 neodata)→ WebSearch/WebFetch。
- **选用优先级**:① ≥2 独立源一致/可对齐 → **优先写、优先出图**;② 仅单源、但该点对结论/模块**确属关键且需要** → 可写(仍须有本轮工具/痕迹依据);③ 单源且非关键 → **宁缺**,不堆砌。
- 多源冲突且无法对齐 → **不写定值**(可写已核对区间,或整点不写);禁止随便采信一侧。
- **同行对比强制**:本标的 + 3~6 家知名可比,每家使用相同口径且 ≥2 项可核对指标(能多源则多源);数据不足时继续用 westock/Web 补齐,禁止只写本标的一行。
- 除强制「同行对比」外,仍无可用结果则该 ### 整节不写。
```bash
python3 scripts/run_tool.py --list
python3 scripts/run_tool.py --schema <capability_name>
python3 scripts/run_tool.py <capability_name> '<json_args>' # 仅补洞/Phase A;禁止 > mcp_*.json
python3 scripts/run_phase_b.py --code '<标准代码>' # Phase B 默认主路径
```
个股主路径示例(Phase A → Phase B 一条 batch → host 深挖):
```bash
python3 scripts/run_tool.py resolve_symbol '{"query":"<标的>"}'
python3 scripts/run_phase_b.py --code '<标准代码>'
# 摘要 failed 且需补洞时再单次(禁止重定向):
# python3 scripts/run_tool.py deep_profile '{"code":"<标准代码>"}'
```
宿主深挖示例(在本 skill 内 Bash;深度画像主路径;勿改走其它 skill 主答):
```bash
westock-data profile usAAPL
westock-data finance usAAPL --num 4
westock-data quote usAAPL
westock-data kline usAAPL --period day --limit 60
westock-data consensus usAAPL # A/港更全;美股无则跳过
westock-data rating usAAPL
westock-data report usAAPL --limit 20
westock-data shareholder hk00700 # 仅 A/港;美股会报「无数据源」
westock-data fund flow sh600519 # 仅 A/港;美股不支持
westock-data fund short usAAPL # 美股/港股卖空(美股机构持仓改 Web 补 13F)
westock-data notice list usAAPL --type 0
westock-data calendar --event financial_report --market us --limit 20
westock-data events tags usAAPL
westock-data score usAAPL
westock-data risk usAAPL
westock-data search <行业词> --type sector
westock-data sector constituent <板块码>
# 禁止:westock-data news …(渠道常不可用;个股资讯走 MCP news_catalysts + notice/events + WebSearch)
# neodata(~/.workbuddy/skills/neodata-financial-search;见「neodata 静默续期」)
# python3 "$HOME/.workbuddy/skills/neodata-financial-search/scripts/query.py" --query "AAPL 营收 EPS 一致预期 机构评级"
# westock-tool(无全局 bin 时用 node 入口)
node "<WESTOCK_TOOL_SKILL>/scripts/index.js" ranking CompScore --limit 10
# 仍缺:WebSearch topic=finance … / WebFetch <URL>
→ 写入 charts_dir/host_deep_profile.json
→ 写入 charts_dir/host_fundamentals_pack.json
→ 写入 charts_dir/host_institutional_views.json
```
**neodata 静默续期(对用户零操作;禁止要用户粘贴 token)**
本机 `query.py` 会在缓存缺失/过期时,用已登录的 WorkBuddy 桌面会话自动签发 tempkey 并写入 `~/.workbuddy/.neodata_token`(与 `connect_cloud_service` 同源)。Agent **直接查**即可,不对用户说话:
1. 直接:`python3 "$HOME/.workbuddy/skills/neodata-financial-search/scripts/query.py" --query "…"`
2. 若仍 stderr 含 `TOKEN_MISSING` / `TOKEN_EXPIRED` / 401/403/`40101`(桌面未登录等):
- 调用宿主工具 `connect_cloud_service`(无参)→ 取 **`tempToken`(优先)** 否则 `token` → `--save-token` → 再查一次
3. 仍失败 → **静默放弃 neodata**,改 westock/`rating`/`finance` + WebSearch;**禁止**因此中止整份研究,**禁止**让用户粘贴 neodata token
另:`FINTRUST_API_KEY`(`fsk_`)与 neodata 无关,仍走 Step 0 激活引导。
**失败降级**:百度 → westock → westock-tool →(neodata:上表静默续期成功才用)→ WebSearch/WebFetch;仍无数则该 ### 整节不写;禁止编造。
**502/网关**:由 `client_common` / `run_phase_b` 自动重试;仍失败则该能力改走 westock/Web,**禁止**整份研究因单次 502 停摆。
**选用**:多源一致优先;重要单源可补;非关键单源不写(细则 Step 3§7)。
**边界**:接近调用上限时优先:行情/画像 + host 预期/评级包 + 财报/股东/资金 + 同行对比(先保证关键点有第二源可核)。
**前置**:默认自带能力即可;**不要**让用户去市场安装 skill/MCP。
---
### Step 3 — 按 WRITER_SYSTEM 成文
**目的**:基于 Step 2 返回的公开数据写中文 Markdown 草稿(尚未对外)。
**必须:**
1. 以 `WRITER_SYSTEM` 为系统级指令,完整遵循,禁止改写。
2. 整份结构必须为(标题原样,与 `WRITER_SYSTEM` / `report_sections.json` 一致):
```markdown
# <标的简称>(<代码>)深度研究报告
## 结论先行与要点摘要
### 投资概览
### 投资亮点
### 投资风险
### 前瞻催化剂
## 深度分析
## 公司基本面
### 商业模式 … ### 收入构成(**每篇强制必出**,挂产品收入饼图)… ### 资本与研发
## 估值分析
### 估值倍数 … ### 相对强弱(**每篇强制必出**,挂日K)
## 行业洞察
### …
## 风险信号
### …
## 机构与资金动向
### …
## 最新事件与催化剂
### …
```
顺序必须是:结论先行与要点摘要 → 深度分析 → 公司基本面…;全文仅一份,禁止重复。H1 只保留一个短标题,禁止把用户整句问题或关键词列表拼进标题,也禁止在「## 深度分析」后再写 H1。结论先行四块须有实质事实,禁止「已完成公开信息整理 / 详见后文」占位句;摘要宜短,细节放后文模块,避免前后大段重复。脚本**不代写/不注入**外壳,格式不对会打回重写。未加锁 `###` 为白名单、**有数才写**:无已验证事实则标题与正文都不出现;加锁子点不要写入。禁止「本节不展开 / 未取到 / 无某某接口」类空壳与取数元叙述。
2b. **「### 相对强弱」强制例外(每篇必出日K)**:不受「有数才写可省略」约束。Phase B 必须取到 `price_technical` 日K;成文必须写 `### 相对强弱`(昨收/涨跌幅/样本区间/最新收盘),挂 **candlestick**。缺节时 `--dump-payloads` **强制补节并回写草稿**;缺可绘制日K → dump 打回 `need_phase_b`。禁止用成交量图或其它图顶替。
2c. **「### 收入构成」强制例外(每篇必出产品收入饼图)**:不受「有数才写可省略」约束。成文必须写 `### 收入构成`。**占比扇区由大模型理解提炼**(禁止脚本正则抠正文)→ 写入 `charts_dir/host_revenue_mix.json`:`{"parts":[{"name":"短业务名","value":85.05},…]}`(≥2 扇区,`value`=百分比数值,勿改口径)。缺文件/扇区不足 → dump 打回 `need_write`。有地区占比时另写 `host_revenue_geo.json`。挂 **pie**;禁止改柱/折顶替。
3. **受众=股民**:全文用听得懂的话;**只基于本轮已取到的数据**写关键事实 + 客观推论;禁止堆砌罗列;禁止正文出现工具名/能力名;**辅助决策、不代做决策**(无买卖建议)。
3b. **段末精简出处(强制)**:含事实/数字的自然段只在**整段最后**加一次合并后的全角小括号出处,如 `(来源:公司财报)`、`(来源:公司财报、公开报道)`;同段多句禁止逐句重复标注。每个有实质的 `###`(含结论先行四块)至少 1 处;禁止工具名入出处。缺出处 → dump/assemble 打回 `need_write`。
3c. **「公开报道」必须对应网页**:正文出现 `公开报道`/`媒体报道` 等,须先有 `host_web_sources.json` 中真实 `http(s)`(门槛只认 ≥2,不必凑满);assemble 必出「## 参考文献」(最多展示 4 条)。空口「公开报道」而参考文献缺失 → 打回 `need_web_sources`。
4. **全文文风**:必须对齐 `WRITER_SYSTEM`「文风样例」正例(事实密集、先数后因、无 AI 旁白)——摘要与六大模块同一调性。
5. **「## 结论先行与要点摘要」**:必须为四块——### 投资概览(含 **核心结论:**)、### 投资亮点、### 投资风险、### 前瞻催化剂;有依据才写;禁止买卖建议;禁止占位空话;勿与后文模块逐段重复粘贴。
6. **一次性成文禁止「AI综合评估」**:首稿即不得写入该 H2 及子点;综合判断只在结论先行;收口脚本遇该章会直接失败(不会代删)。不要自建「## 参考文献」(由 `--assemble-html` 根据 `host_web_sources` 注入;缺公共网页 → 打回 `need_web_sources`)。
7. **数据可信度(最高原则:多源优先,重要单源可补)**
- **零源禁止**:无本轮工具/可核对痕迹支撑的数字一律不写;禁止推测、禁止用模型记忆补数。
- **多源优先**:同一指标若 ≥2 个**独立**来源(如 MCP/百度 vs westock;westock vs 可核对网页;neodata vs 财报页等)数值一致或可合理对齐 → **优先采用**,结论要点与出图优先用这类数。
- **重要单源可补**:仅单源有数、且该点对投资概览/模块论点**确属关键**(缺了会明显削弱报告)→ **可以使用**,不得因「只有一源」而冒然丢弃;仍须能指向本轮取数结果。
- **非关键单源不写**:单源且只是锦上添花、凑全面 → 不写,避免不可靠堆砌。
- **冲突**:多源明显冲突且无法对齐 → 不写单一定值(可写区间或整点省略);禁止随意站队。
- 正文**不写**「多源已验证 / 单源」等元叙述,也不泄露工具名;子点无数则**整节不输出**;表格任一格无数 → 整行不写。
8. 能用小表说清的用小表;禁止为「全面」堆字段;内文标题处含时间日期。
9. **「### 同行对比」强制**:本标的 + 3~6 家知名可比,每家使用相同口径且 ≥2 项可核对指标(能多源则多源);该节和表格不得省略,禁止只写本标的一行。若不足 4 家,必须继续取数补齐后再成文。
10. **产品收入饼图强制 + 地区饼有数必出**:`### 收入构成` **每篇必写**;成文后大模型提炼 → `host_revenue_mix.json`(≥2 扇区)→ dump 锁死 pie 契约。`### 地区分布` 有数则写 `host_revenue_geo.json` 同样必出。脚本**禁止正则/正文抠数**,只读 JSON;缺额可补「其他」使总和=100;**禁止省略、禁止改柱/折**;label `{b} {c}%`(禁 `{d}`)。
11. **金额/市值/成交额等大数必须带单位**:绝对值 ≥1e8 写成「×.×× 亿{币种}」;禁止无单位长整数。
11b. **浮点数一律两位小数**:正文与图表(含 HTML 终态)中的浮点最多保留两位(如 `12.345%`→`12.35%`);整数不补小数位。assemble 会再规范化一次。
12. 成文前自检:无操作性建议;无取数元叙述;正文从未出现「AI综合评估」;关键数字已按§7 选用(多源优先,非关键单源已剔除);每个事实段仅在段末挂一次 `(来源:…)`;同行对比含本标的 + 至少 3 家可比公司。
13. 成文后自检:结论先行四块 + 六大 `##` 必须存在;已写的 `###` 须有实质数据与出处;含空壳节或「AI综合评估」或缺出处 → 必须重写,不得进入 Step 4。
**禁止**:自制「一、二、三」目录;用外壳二级标题替代或删减六大模块;**首稿写入「AI综合评估」**;把草稿直接发给用户;另写 HTML/`*.html` 报告顶替模块正文。
建议将草稿写入临时文件(如 `raw_writer.md`)供 Step 4 管道使用。
---
### Step 4 — 交互 HTML 图文报告准备(强制)
**目的**:导出同源图表契约(数值 + title/caption/unit)→ **脚本按契约填模并全量渲染** → 组装**单文件自包含** `report.html`(ECharts + 各图 option 全部内联;无 iframe / 无相对路径)。
**唯一出图渠道**:`--render-all`(`build_option_from_contract` 填模 + `nl-echarts/scripts/render-echarts.mjs`)。视觉规范见 [`nl-echarts/references/visual-theme.md`](nl-echarts/references/visual-theme.md)。**禁止** Agent 手写/改写 `{slug}.option.json` 数据面。
**图表必显硬约束(根治预览空白图 / 大面积留白):**
- 禁止 HTML 引用 `cdn.jsdelivr` / `unpkg` / 任何 `http(s)://` 外链 ECharts
- `--render-all` 按契约生成 option、校验可绘制(空/全 0 series → 退出码 3);`--assemble-html` 把 `echarts.min.js` 与可绘制 option **内联**进唯一 `report.html`
- 图表用 `<div class="chart-box">` 直渲染;**禁止**嵌套 `<iframe>`、**禁止** `script src="./echarts.min.js"` 等相对路径依赖
- **空白图直接删除,禁止占位**:无有效 series 的图不得写入 suggested、不得嵌入 HTML;组装产物默认隐藏图表容器,仅初始化成功后显示;失败或 JS 未跑则移除/不可见整块 `.charts`/`figure`,正文紧接下一节;禁止定高空白框 / 巨大 `min-height` 留白;**禁止**用静态 SVG 顶替
- `### 目标价`:**不出图**(共识/评级写正文即可;`price_target` / `institutional_views` 永不进 suggested)
- 契约缺失 / 渲染失败 / 终态仍含 iframe 或外链 → 退出码 3,禁止交付
**强制顺序:**
1. 导出同源契约(出图工具入参;不渲染):
```bash
python3 scripts/prepare_workbuddy_report.py --report-file raw_writer.md --dump-payloads
```
stdout 给出 `payloads`、`contracts`(`chart_contracts.json`)、`charts_dir`、`suggested_charts`。
**出图只认 `chart_contracts.json`**:含 categories/series/ohlc + `title`/`caption`/`unit`/`subsection`。比例 pie 扇区已从对应 `###` 正文锁定;营收等大数已换算为「亿」。
**每篇强制必出日K** `price_technical`(挂 `### 相对强弱`,title=相对强弱,caption=日K线 OHLC):
- 成文缺/空壳 `### 相对强弱` → dump **按行情强制补节并回写** `raw_writer.md`
- 缺可绘制日K 序列 → dump 打回 `need_phase_b`;`suggested` / 契约 / HTML **禁止省略**该图
- H3 过滤不得剔除 `price_technical`;禁止用 `price_volume` / 快照柱顶替
**每篇强制必出产品收入饼图** `revenue_mix`(挂 `### 收入构成`,title=收入构成;**caption 为空**):
- **大模型提炼** → 写 `host_revenue_mix.json`(`parts≥2`);缺 → dump 打回 `need_write`
- dump 按 JSON 回写/补齐 `### 收入构成` 要点列表;脚本不解析散文/表格
- `suggested` / 契约 / HTML **禁止省略**;H3 过滤不得剔除 `revenue_mix`
- 有地区占比时写 `host_revenue_geo.json`,进 `mandatory_pie_slugs`
- **饼图禁止副标题/注释**:禁止 `title.subtext`、禁止「单位:%」、禁止任何 host JSON / 锁定扇区等实现向说明;扇区仅用 label `{b} {c}%`
`suggested` ≤5、每 `###` 至多 1 张;未进 suggested 的 slug 禁止出图。
2. **一次性契约填模 + 全量渲染**(禁止 Agent 写 option / 手写 `node …`;禁止 CDN):
```bash
python3 scripts/prepare_workbuddy_report.py --render-all --charts-dir <charts_dir>
```
成功标准:stdout `ok=true`,`rendered` 覆盖全部 `suggested_charts`,option 由契约填模并通过硬校验,`charts_dir/echarts.min.js` 存在。
契约缺失 / 填模失败 / 渲染失败 / CDN → 退出码 3 并打回 `need_dump`,**禁止**跳过直接 assemble。
3. 组装完整报告(收集 HTML 图,不做绘图;再次校验本地运行时):
```bash
HOST_WS="$PWD"
cd "<本技能根目录>"
FINTRUST_PRESENT_DIR="$HOST_WS" python3 scripts/prepare_workbuddy_report.py \
--report-file raw_writer.md --assemble-html --charts-dir <charts_dir>
```
(WorkBuddy Bash 启动 cwd=会话工作区;须先保存 `HOST_WS="$PWD"` 再 `cd` 进技能目录,否则交付会落到技能目录、侧栏不展开。脚本也会读 `OLDPWD` 自动解析工作区,但仍建议显式设 `FINTRUST_PRESENT_DIR`。)
`--assemble-html` stdout **不是报告正文**,只返回 `report`(artifacts 内 `report.html`)、**`present_path` / `htmlFilePath`**(**会话工作区根目录**下中文命名 HTML,供 Step 5 `present_files`;禁止落在 `~/.workbuddy/skills/`)、`charts` 与 `references` 数量。脚本保证:
1. 图表数据来自本轮 traces/正文(经 `chart_contracts.json` 锁定并由 render 填模硬校验);
2. 对「估值分析 / 公司基本面 / 机构与资金动向」同源回填后经 `finalize_report.py`:**本地 ensure**(结构+合规,毫秒级)后 MCP `finalize_report`;
3. 缺任一 `suggested_charts` 对应 `{slug}.html` / option、或中间 HTML 仍含 CDN → 退出码 3;
4. 将正文转为 HTML,**在对应 ### 数据段之后**嵌入 `<div class="chart-box">`(图紧跟数据),并把 **ECharts 库 + 全部 option 内联**进唯一 `report.html`;
5. **底部「## 参考文献」必出**:先按 `need_web_sources` 写 `host_web_sources.json`(门槛 ≥2 条公共 URL;**每条仅一个 url + 对应 title 说明**,禁止一条多链、禁止重复 URL);assemble 注入免责声明前,**最多展示 4 条**(一点一链一说明、按 URL 去重);**禁止**罗列 westock/能力名;URL 不足 → 打回 `need_web_sources`;写出 `references.json` / `references.md`;
6. 终态禁止 `<iframe>`、禁止 `script src` 加载 echarts;单文件即可在预览面板/浏览器打开。
写 host 包后必须完成 `need_web_sources`:WebSearch/WebFetch → `host_web_sources.json`:`[{title, url, retrieved_at}, …]`(**每项仅一条 url**,title 为对应说明;重复 url 只留一条)。成文**不要**自建「## 参考文献」。
禁止:Agent 手写/改写 option 数据面、静态 SVG/`show_widget`、CDN、iframe 嵌套图、跳过 `--render-all`、超过 5 张图、图全部堆在文末、为单点涨跌幅/两点昨收最新单独出图、只出部分 suggested。
---
### Step 5 — 交付 HTML 报告(硬闸;缺一不可)
`--assemble-html` 成功后 stdout 含 `present_path`(**会话工作区根目录**中文命名 HTML,例如 `/Users/…/WorkBuddy/2026-08-07-17-24-51/深度研究报告谷歌_GOOGL.html`)与 `report`(`.artifacts/.../report.html`)。**本轮必须立刻完成下列三项**,然后才能结束对话。未做完 Step 5 = 研究未完成(即使用户已看到中间 Markdown/摘要也不算交付)。
**强制交付清单(按序执行,全部必做):**
1. **强制侧边展开预览(WorkBuddy)**:立刻调用原生 **`present_files`**,且 `files` **必须**使用 stdout 的 **`present_path`**(须在会话工作区 `/WorkBuddy/…` 下;**禁止** `~/.workbuddy/skills/.../outputs/...`),打开对话右侧 HTML 预览面板。调用形态:
```json
{
"files": ["<present_path 绝对路径>"],
"explanation": "深度研究报告(交互 HTML,侧边预览)"
}
```
- **禁止**用 `.artifacts/.../report.html` 或技能目录 `outputs/` 代替 `present_path`
- **禁止**只写「已生成 / 右侧已展开」而不调用 `present_files`(文案声称展开不算交付)
- **禁止**跳过本步;无 `present_files` 工具时本轮视为交付失败并简述,不得用 Markdown 顶替
- 自检:`present_path` 必须包含会话工作区目录名,且**不得**包含 `/.workbuddy/skills/`
2. **完整文件地址**:在对用户可见回复中单独给出 **`present_path` 的完整绝对路径**(须可点击或可整段复制;禁止只写相对路径、文件名或「见 artifacts」)。
3. **短说明**:一两句说明右侧侧栏已展开图文混排报告(亦可浏览器打开),图表支持悬停;**不要**再贴研究 Markdown 正文、不要输出整份 HTML 源码、不要改写六大模块标题、不要调用 `show_widget` 顶替。
**硬约束:**
- 未成功生成 `present_path` / `report.html` 不得声称已完成图文报告;
- 禁止用纯 Markdown / 研究摘要 / SVG widget 流代替 HTML 终态;
- **禁止**在未执行 `present_files(present_path)` 且未给出该绝对路径时结束本轮;禁止等用户追问「html呢 / 报告在哪」再补交;
- 对外不附加能力名、内部流程或过程文件清单(除 `present_path` 绝对路径外)。
---
## 退出码速查(脚本)
| 场景 | 常见退出码 | 你的动作 |
|------|------------|----------|
| 激活成功 / `--set-key` 成功 | 0 | 进入准备工作 → Step 1 |
| 未配置 Key | 3 | 原样展示引导,结束本轮 |
| 无研究会话 / 参数错误 | 2 | 回到 Step 1 或修正参数 |
| 能力调用业务失败 | 1(`run_tool`) | 记录缺失,继续其它能力 |
| HTML 图表不足 / suggested 缺失 / CDN 残留 / 缺本地 echarts / 章节一致性失败 | 3 | 停止,重跑 `--dump-payloads` / `--render-all`,不得输出伪图文报告 |
| Key 无效 | 4 | 提示重新开通/粘贴 Key |
| 网络/校验不可用/额度/会话过期 | 5 | 简述原因,可请用户稍后重试 |
---
## 验收清单
- [ ] **最先**跑 Step 0;Key 非 0 时不装依赖、不取数、不成文、不答研究问题
- [ ] 仅 Step 0 通过后才跑指定 `pip install` / `npm install`,无自主摸索
- [ ] 出图:`--dump-payloads`(必含 `price_technical` + 契约 title/caption/unit)→ `--render-all`(契约填模,禁止 Agent 写 option)→ `--assemble-html`;无 CDN
- [ ] `report.html` 单文件自包含:内联 echarts + option;无 iframe / 无 `script src` 相对路径;预览与浏览器均可显示图表
- [ ] 未配置 Key 时只输出开通引导并停止
- [ ] 用户粘贴 Key 后 `--set-key` 成功并从准备工作 → Step 1 续跑原问题
- [ ] 严格顺序:0 → 准备 → 1 → 2 → 3 → 4 → 5,无跳步
- [ ] **Step 5 三项齐备**:`present_files(present_path)` 已强制侧边展开 + 对话中有该 HTML **完整绝对路径** + 短说明;`present_path` 在会话工作区根目录(非 `~/.workbuddy/skills/`);未用 `.artifacts/report.html` 顶替;未等用户追问;无 Markdown/摘要顶替 HTML 终态;无 CDN / `show_widget`
- [ ] 报告内容:**强制**日K + **强制**产品收入饼(`host_revenue_mix.json` 大模型提炼,禁正则抠正文);**强制同行对比本标的 + ≥3 家可比**;`host_revenue_geo.json` 有数时必出;底部「## 参考文献」一点一链;图表 ≤5;每个事实段仅段末一次 `(来源:…)`;股民向正文、文风对齐样例
- [ ] **数据可信度**:多源一致优先写/出图;重要单源可补;非关键单源不堆;冲突不定值;零源不写;正文无「多源/单源」元叙述
- [ ] 研究流量走 MCP(`start_research` / 八能力 / `finalize_report` + prompts);Phase B 默认 `run_phase_b.py`,补洞/Phase A 用 `run_tool.py`;禁止 `> mcp_*.json`
- [ ] 取数全程静默:无「定位内置技能路径」/ Phase 旁白 / 工具清单 / **退出码** /「激活校验通过」对用户输出;直接调 `run_phase_b` / `run_tool` 与 westock/neodata
- [ ] next_action:每步只执行脚本 stdout 的唯一步(含 `need_web_sources`);不确定时先 `research_progress.py`;禁止跳步;progress/next_action JSON 不对用户展示
- [ ] 成文含外壳与六大模块;未加锁 ### 有数才写(无「未取到/该节不展开/无接口」空壳);正文无工具名泄露;图表说明无 `###` 井号;饼图无字面 `\n`
- [ ] 成文即合规;finalize 本地 ensure + MCP 收口后无投资建议、含免责、无过程/能力名/维度泄露、无编造数据
- [ ] 人为植入「建议买入」等句经本地 ensure 后被删除