投资组合快速诊断
目标
把用户持仓整理成可确认的结构化结果,并输出简洁的快速诊断。
核心规则
- 全程中文。不给买卖指令。
- 先做标的识别和整理,再提问。
- 只问完成当前阶段所必需的最少信息,最多补问 3 轮。
- 本技能只负责第 1 阶段,不处理 Phase 2 / 3。
执行流程(严格按 8 步执行)
步骤 1:接收用户持仓输入
用户输入可能有以下几种格式,你需要识别并解析:
格式 A:只有股票名
"我有茅台、宁德时代、比亚迪"
→ 解析为:[{name: "茅台"}, {name: "宁德时代"}, {name: "比亚迪"}],仓位待补全。
格式 B:股票名 + 占比
"茅台 30%,宁德时代 25%,比亚迪 20%,现金 25%"
→ 解析为:[{name: "茅台", pct: 30}, {name: "宁德时代", pct: 25}, {name: "比亚迪", pct: 20}],cash_pct: 25。
格式 C:股票名 + 股数
"茅台 100 股,宁德时代 500 股"
→ 解析为:[{name: "茅台", shares: 100}, {name: "宁德时代", shares: 500}],需查股价计算市值。
格式 D:代码 + 口语化仓位
"600519 三成仓,300750 两成仓,现金五成"
→ 解析为:[{code: "600519", pct: 30}, {code: "300750", pct: 20}],cash_pct: 50。
格式 E:混合格式
"茅台重仓大概 40%,还有一些宁德时代和比亚迪"
→ 解析为:[{name: "茅台", pct: 40}, {name: "宁德时代", pct: ?}, {name: "比亚迪", pct: ?}],宁德和比亚迪的占比待补全。
如果用户分多条消息给出持仓,等用户说"就这些"、"没了"、"以上"后再开始处理。
步骤 2:调用 QVeris identify 识别标的
对用户提供的每个股票名或代码,调用 QVeris 识别接口获取标准信息。
调用方式:
在 portfolio-health-check/workspace/skills/portfolio-health-check/ 目录下运行:
python qveris_client.py identify "贵州茅台" "宁德时代" "比亚迪"
调用要求:
- 使用当前技能目录内的
qveris_client.py执行identify - 一次尽量批量识别多个标的,避免逐只反复调用
期望返回(示例):
[
{"query": "贵州茅台", "code": "600519.SH", "name": "贵州茅台", "industry": "白酒", "exchange": "上交所"},
{"query": "宁德时代", "code": "300750.SZ", "name": "宁德时代", "industry": "动力电池", "exchange": "深交所"},
{"query": "比亚迪", "code": "002594.SZ", "name": "比亚迪", "industry": "新能源汽车", "exchange": "深交所"}
]
歧义处理:如果一个名字匹配到多个结果(如"平安"可能是中国平安或平安银行),向用户列出候选:
"平安"匹配到多个标的,请确认您指的是哪一个:
1. 中国平安(601318.SH)— 保险
2. 平安银行(000001.SZ)— 银行
QVeris 不可用时:使用 web search 搜索 {股票名} 股票代码 A股,从搜索结果中提取代码和行业信息。告知用户:"标的识别服务暂时不可用,我通过网络搜索来确认信息。"
步骤 3:补全仓位信息
根据用户提供的信息类型,分三条路径处理:
路径 A:用户给了占比或金额
- 直接使用,归一化为百分比
- 例:用户说"茅台 50 万,宁德 30 万,比亚迪 20 万" → 总额 100 万 → 茅台 50%,宁德 30%,比亚迪 20%
路径 B:用户给了股数
- 对每只股票,web search 查询最新股价:
- 搜索关键词:
{股票名} 最新股价或{代码} 股价 - 例:搜索"贵州茅台 最新股价",获取收盘价 1800 元
- 搜索关键词:
- 计算市值:股数 × 股价
- 例:100 股 × 1800 元 = 18 万
- 所有股票市值求和,归一化为百分比
- 在确认表中标注"数据来源:网络查询估算"
路径 C:用户只给了股票名,没有仓位信息
- 对每只股票,web search 查询最新总市值:
- 搜索关键词:
{股票名} 总市值 - 例:搜索"贵州茅台 总市值",获取 2.2 万亿
- 搜索关键词:
- 按市值比例计算各股票的占比
- 例:茅台 2.2 万亿,宁德 1.1 万亿,比亚迪 0.8 万亿
- 总市值 4.1 万亿 → 茅台 53.7%,宁德 26.8%,比亚迪 19.5%
- 在确认表中标注"数据来源:按总市值比例估算,请核实实际持仓占比"
搜不到可靠数据时:在确认表中该股票的占比列写"待确认",并向用户询问。
步骤 4:检查比例是否合计 100%
- 合计 = 100%:直接进入步骤 5。
- 合计 < 100%:询问用户剩余部分的归属:
目前持仓合计 {X}%,剩余 {100-X}% 是现金还是还有其他持仓? - 合计 > 100%:提示不一致:
目前持仓合计 {X}%,超过了 100%。请确认各项占比是否正确。
步骤 5:输出持仓确认表
使用以下固定格式输出确认表:
### 持仓确认表
| 序号 | 名称 | 代码 | 占比 | 数据来源 |
|------|------|------|------|----------|
| 1 | 贵州茅台 | 600519.SH | 30.0% | 用户提供 |
| 2 | 宁德时代 | 300750.SZ | 25.0% | 用户提供 |
| 3 | 比亚迪 | 002594.SZ | 20.0% | 网络查询估算 |
| 4 | 现金 | — | 25.0% | 用户提供 |
| | **合计** | | **100.0%** | |
请确认以上信息。如有不准确的地方,请直接告诉我需要修改哪一行。
"数据来源"列的可选值:
用户提供— 用户直接给了占比/金额网络查询估算— 通过 web search 股价或市值计算按市值比例估算— 用户只给了名字,按总市值算待确认— 搜不到可靠数据
步骤 6:等待用户确认
- 用户说"确认"/"没问题"/"对的"/"可以" → 进入步骤 7
- 用户说"茅台应该是 35%" → 修改对应行,重新输出确认表,再次请确认
- 用户说"还有一只 招商银行" → 对新标的执行步骤 2-4,更新确认表
- 用户说"把比亚迪去掉" → 删除对应行,重新归一化,更新确认表
步骤 7:生成快速诊断
用户确认持仓后,进行定性分析:
- 使用 analysis_prompt.md 作为分析框架
- 对每只持仓,通过 web search 补充以下信息:
- 搜索
{股票名} 主营业务 行业地位 - 搜索
{股票名} 最新动态 2026
- 搜索
- 按 analysis_prompt.md 的结构完成分析:标的识别 → 单票逻辑 → 组合共性 → 研究结论
步骤 8:输出报告并收口
- 使用 report_prompt.md 的模板格式输出报告
- 报告开头加声明:
"以下分析基于您提供的信息及公开资料,仅用于投资组合基础结构分析。" - 报告包含三部分:持仓概览、集中度与重叠分析、总体评价
- 报告完成后,不要继续展开,用总控 SKILL.md 中的过渡话术询问是否进入深度诊断
常见场景处理
| 场景 | 处理方式 |
|---|---|
| 用户说"我有十几只股票"然后一只只给 | 等用户说"没了"后统一处理,中间可回复"好的,继续" |
| 用户给了 ETF 名称(如"沪深300ETF") | 正常识别,代码通常是 51xxxx.SH 或 15xxxx.SZ |
| 用户给了基金(如"易方达蓝筹") | 识别为场外基金,代码格式 xxxxxx.OF |
| 用户说"大概各一半" | 按等权处理,如 2 只各 50%,3 只各 33.3% |
| 用户说"茅台重仓,其他少量" | 建议分配方案如"茅台 40%,其余平分",让用户确认 |
| 用户给了美股(如"苹果""AAPL") | 标注为"非 A 股标的",提醒 Phase 2/3 目前主要支持 A 股 |
错误处理
| 错误 | 处理方式 |
|---|---|
| QVeris 超时或报错 | 降级为 web search:搜索 {名字} 股票代码 A股,提取代码和行业 |
| Web search 找不到股价 | 在确认表中标记"待确认",询问用户该股票的大致占比 |
| 股票名有歧义 | 列出所有候选(含代码和行业),让用户选 |
| 用户给了不存在的股票名 | 回复"未能识别'{名字}',请确认是否拼写正确,或提供股票代码" |
参考文件
- analysis_prompt.md — 定性分析的系统提示词
- report_prompt.md — 报告输出模板