investor-distiller
公众号投资博主蒸馏器。通过公众号文章数据,自动提取交易体系、市场判断、表达风格、内容深度、互动特征、热点图谱、 人设基因七维DNA,输出结构化风格画像 profile。 触发词:蒸馏投资博主、蒸馏大V、蒸馏公众号大V、分析投资博主风格、 提取交易体系、风格画像、投资博主蒸馏。
Install
npx skills add https://github.com/redfox-data/redfox-community/tree/main/skills/investor-distiller
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install redfox-data-redfox-community@llmmart
git clone https://github.com/redfox-data/redfox-community.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole redfox-data/redfox-community collection as a plugin from our marketplace. Git is the plain clone.
README
公众号投资博主蒸馏器 / investor-distiller
简介
输入公众号微信号就能自动获取文章、提取七维DNA风格画像,从交易体系到表达风格给你一份完整的大V分析报告。不像网上泛泛的介绍,每一条结论都有原文证据支撑,画像准不准还会自动打分校验,不会凭空编造风格特征。
核心价值
- 输入即分析:输入微信号就能自动获取文章、生成完整画像,支持 20/60/100 篇三档,不用自己一篇篇翻
- 七维全面还原:交易体系、选股逻辑、表达风格、互动特征……从七个维度拆解博主的投资DNA,不只是统计词频
- 自动打分校验:每次蒸馏后自动三维度评分,个股/风格/体系逐项检查,准不准一眼就能看出来
- 拿来就能用:基于画像生成风格一致的个股分析,直接当参考资料用,每份分析都标注数据来源和免责说明
适用对象
- 🧑💼 投资者 — 快速了解大V投资风格与核心逻辑,辅助投资决策参考
- ✍️ 内容创作者 — 借鉴大V表达风格与论证模式,提升内容质量
- 🔬 研究者 — 系统性分析投资博主风格特征,支持多博主对比研究
功能特性
核心功能
- 输入即分析:输入微信号就能自动获取文章、生成完整画像,支持 20/60/100 篇三档,灵活选
- 按时间由近到远采集:优先拿到博主最新的内容,画像更贴近当下的观点与状态
- 单篇数据取全:每篇文章的正文、摘要、发布时间与阅读、点赞、分享、收藏、评论数据一并获取,原文证据更充分
- 七维全面还原:从交易体系到人设基因,七大维度拆解博主投资DNA,不是简单统计词频
- 自动校验质量:每次蒸馏后自动评分,个股/风格/体系逐项检查,准确率不够会提示补充
- 拿来就能用:基于画像生成风格一致的个股分析,直接当参考资料用,每份都标注数据来源
密钥获取与安全说明
- 本技能需要使用环境变量:
REDFOX_API_KEY。 REDFOX_API_KEY由 红狐 hub (https://redfox.hk)提供。- 请前往 红狐 hub 注册账号,获取
REDFOX_API_KEY。 - 配置设备环境变量
REDFOX_API_KEY后使用本技能。 - 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。
- 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。
使用指南
直接用自然语言描述需求,无需记忆命令。
常用说法速查
| 意图 | 示例话术 | 效果 |
|---|---|---|
| 蒸馏博主画像 | 蒸馏公众号 zshbtz |
自动采集文章并生成七维DNA风格画像 |
| 指定文章数量 | 蒸馏公众号 zshbtz,采集 100 篇 |
高精度蒸馏,画像特征更稳定 |
| 校验画像质量 | 校验财躺平的蒸馏画像 |
三维度评分,确认画像准确率 |
| 风格化分析 | 用猫笔刀的风格分析一下宁德时代 |
基于蒸馏画像生成风格一致的个股分析 |
输出示例
蒸馏完成后,在 output/ 目录下得到:
{博主名}_风格画像.md— 七维DNA完整风格画像,含原文证据引用与置信度标注{博主名}_统计数据.json— 结构化统计数据,用于校验与对比{博主名}_校验报告_YYYYMMDD.json— 准确性校验报告,含三维度评分
使用场景
| 场景 | 角色 | 示例问法 | 收益 |
|---|---|---|---|
| 了解大V风格 | 投资者 | 蒸馏公众号猫笔刀 |
快速掌握博主交易体系与市场判断逻辑 |
| 多V对比研究 | 研究者 | 蒸馏财躺平和投资明见,对比他们的风格 |
横向对比不同博主的投资流派与表达特点 |
| 风格化复盘 | 内容创作者 | 用格兰投研的风格写今天的A股复盘 |
生成风格一致的复盘内容 |
| 选股辅助 | 投资者 | 用猫笔刀的视角分析一下新能源板块 |
以博主分析框架审视个股/板块 |
Skill manifest
公众号投资博主蒸馏器
免责声明:本工具仅供学习研究使用,蒸馏产物为风格模拟参考,不构成任何投资建议。 所有生成内容必须标注「AI 风格模拟,不构成投资建议」。
📝 简介
自动化的公众号投资博主风格蒸馏工具。输入公众号微信号和文章数量,自动采集文章并提取七维DNA投资风格画像,输出结构化的交易体系、市场判断、表达风格等完整分析报告。
✨ 功能特性
| 功能模块 | 能力描述 | 核心价值 |
|---|---|---|
| 文章自动采集 | 通过微信号批量拉取公众号历史文章,支持 20/60/100 篇三档 | 无需手动整理,一键获取完整素材 |
| 七维DNA蒸馏 | 提取交易体系、市场判断、表达风格、内容深度、互动特征、热点图谱、人设基因 | 结构化画像,可复用可对比 |
| 双层特征提取 | 表层(术语/个股频次)+ 思维层(分析工具/论证模式/语气量化) | 不仅像博主说的话,更像博主的思考 |
| 质量校验闭环 | 三维度评分(个股/风格/体系),≥80% 准出,双层审计 | 画像准确性有保障 |
| 风格化模拟 | 基于画像生成风格一致的个股/市场分析,含数据来源标注与免责声明 | 可复现博主风格的分析输出 |
⚠️ 蒸馏质量铁律
必须从raw全文逐篇提取,禁止依赖任何clean/NER中间层。
蒸馏准确性直接决定画像质量。经验表明,clean阶段的个股NER提取管线会遗漏大量信息(如一篇提及6只股票的文章可能只提取0-2只),导致画像基于不完整数据构建。因此:
- raw全文原则:所有提取(个股/短语/板块/风格)必须直接遍历raw文章正文,不经过任何预处理过滤
- 词典+别名匹配:个股提取使用完整词典(含口语化别名,如"上证指数"→"上证/大盘/沪指/A股"),确保宽松但准确
- 文章级板块计数:板块关注度按文章级别计数(每篇只计一次),比词频更准确反映博主真实关注方向
- 领域专用短语:使用投资领域专用关键词列表提取关键短语,比通用句子频次统计更精准
- 校验闭环:蒸馏完成后必须执行准确性校验(
--validate),≥80%方可准出
七维DNA蒸馏结构
| # | 维度 | 回答什么 | 关键字段 |
|---|---|---|---|
| 1 | 交易体系 | TA怎么交易? | 核心模式、选股逻辑、买卖信号、仓位管理 |
| 2 | 市场判断 | TA怎么看市场? | 交易流派、板块偏好、持仓周期、多空条件 |
| 3 | 表达风格 | TA怎么写/说? | 文章结构、标志性表达、标题/开头/结尾模式、语气 |
| 4 | 内容深度 | TA写多少? | 平均字数、信息密度、复盘详细度、预判明确度 |
| 5 | 互动特征 | TA怎么互动? | 读者互动、战绩展示、争议处理、免责声明 |
| 6 | 热点图谱 | TA关注什么? | 核心赛道、龙头记忆、常用指标、资金面关注 |
| 7 | 人设基因 | TA是谁? | 投资经历、哲学演变、里程碑事件、师承/影响源 |
蒸馏维度分支
蒸馏前需先判断博主属于长线还是短线交易者,再按对应维度侧重提取:
| 维度 | 长线 | 短线 |
|---|---|---|
| 投资哲学 | 价值投资/波段交易 | 龙头战法/情绪周期/题材驱动 |
| 核心能力 | 生意本质 + 估值 + 护城河 | 热点捕捉 + 情绪周期 + 量价关系 + 板块轮动 |
| 分析周期 | 年级别(10年持有视角) | 日级别(隔日~2周) |
| 数据驱动 | 财务报表 + 行业数据 | 盘面数据 + 资金流向 + 消息面 |
双层提取框架
蒸馏不仅提取「用了什么词」(表层),更要提取「怎么思考」(思维层)。二者缺一不可:
表层特征(自动量化,脚本产出):
- 个股/板块/术语/短语 频次统计
- 标题/开头/结尾 模式识别
- 字数/发布频率/免责声明 基础统计
思维层特征(脚本检测+AI深度分析):
| 分析维度 | 脚本检测内容 | AI深度补充 |
|---|---|---|
| 核心分析工具 | 宏观经济/产业链/财报/技术面/资金面/情绪/政策 8类思维框架评分 | 提炼博主独有的分析链条(如"事件→产业拆解→A股影响") |
| 论证链模式 | 事件驱动/数据驱动/逻辑推演/类比推理/产业链分析/逆向思维 6类模式 | 还原博主典型论证步骤和推导逻辑 |
| 语气量化 | 感叹句/疑问句/第一人称/口语化 四类标记篇均数值,自动分类 | 判断文风温度(高/中/低),提炼情感表达策略 |
| 数据引用密度 | 每千字数据引用次数,自动分类(数据驱动型/主观判断型) | 分析数据引用场景和方式 |
| 跨市场视角 | 美股/港股/A股/商品 四大市场引用检测 | 判断是否全球视角、多市场联动还是单一市场 |
| 信息密度 | 投资内容占比评估(干货型 vs 水文型) | 区分深度分析和浅层评论 |
多维资料采集(超越文章本身)
| 资料类型 | 来源 | 丰富哪个维度 |
|---|---|---|
| 人设背景 | 简介/置顶帖/自我介绍 | 人设基因DNA |
| 投资哲学演变 | 按时间线分析早期vs近期内容 | 人设基因DNA + 交易体系DNA |
| 里程碑事件 | 公开提及的重大盈亏/转折点 | 人设基因DNA |
| 师承/影响源 | 提及的大师/书籍/引用频率 | 人设基因DNA |
| 社交互动画像 | 评论/回复/争论/社区关系 | 互动特征DNA |
| 历史预判追踪 | 过去预判与实际走势对比 | 市场判断DNA |
| 观点一致性 | 同一主题不同时间观点演变 | 市场判断DNA |
🔑 鉴权
前往 红狐 hub 获取 API Key,通过以下方式配置:
# 方式一:配置文件(如 OpenClaw 的 ~/.openclaw/openclaw.json)
{ "env": { "REDFOX_API_KEY": "ak_xxxx..." } }
# 方式二:终端环境变量
export REDFOX_API_KEY="ak_xxxx..."
注册地址:redfox.hk/login
积分消耗参考:
| 文章数量 | 约消耗积分 | 精度评估 |
|---|---|---|
| 20篇 | ~8积分 | 基础了解,画像粗糙 |
| 60篇 | ~25积分 | 推荐档位,画像较完整 |
| 100篇 | ~50积分 | 高精度画像,特征稳定 |
前置要求
- Python 3.9+
- 依赖:
pip install requests
执行流程
Phase 0: 环境准备
python "$SKILL_PATH/scripts/distill.py" --check-env
自动检查并提示安装缺失依赖(requests 等)。
Phase 0.5: 前置交互
触发蒸馏前,必须由用户明确以下信息:
- 公众号微信号(如
zxgbtz)- 获取方式:打开公众号 → 点右上角
···→ 更多信息 → 微信号 - 注意:微信号不是公众号名称,是唯一的字母/数字ID
- 获取方式:打开公众号 → 点右上角
- 文章数量档位(20 / 60 / 100)
- 提示:数量越多积分消耗越多,但蒸馏精度越准。推荐60篇,100篇精度最佳(约50积分)
自动补充:博主背景资料(投资经历、师承、里程碑事件等)由 AI 通过 WebSearch 自动采集,无需用户提供。
Phase 1: 公众号文章采集
两步 API 流程:
Step 1:获取文章UUID列表
调用 POST https://redfox.hk/story/api/gzh/data/queryWorkList,每页返回20条,offset 步进为20,循环分页直到达到目标数量。
参数:account(微信号)、sortType: "2"、offset(从0开始,每页+20)。
Step 2:逐篇获取完整数据
对每个 UUID,调用 POST https://redfox.hk/story/api/gzh/data/workDetail 获取正文、摘要、词云等完整数据。
# 采集60篇文章
python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 60
# 采集100篇(高精度)
python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 100
输出标准化数据到 output/{博主名}/。
Phase 2: 多维资料整合分析
脚本自动完成基础统计分析(21项),AI 在此基础上执行多维资料整合:
信息丰富度分级(脚本自动评估):
| 等级 | 特征 | 应对策略 |
|---|---|---|
| A 级(信息充裕) | ≥60篇、高信息密度、多维度数据充分 | 反面检验:博主看多时,聪明人为什么看空? |
| B 级(信息适中) | 20-59篇、部分维度数据不足 | 每个推算结论标注置信度 |
| C 级(信息稀缺) | <20篇、低信息密度 | 第一性原理提问,不拼凑"看起来完整"的画像 |
分析维度并行执行:
- 表层内容分析 — 统计 + 词云 + 结构分析 + 交易术语 + 个股/板块频次
- 思维层分析 — 核心分析工具 + 论证链模式 + 语气量化 + 数据引用密度 + 跨市场视角 + 信息密度
- 社交互动分析 — 评论/回复/争论风格/社区关系
- 人设背景分析 — 简介/里程碑/师承/投资哲学演变/推荐书籍
- 投资观点追踪 — 历史预判/准确率/观点一致性/认错修正方式
Phase 3: 七维DNA蒸馏
Step A:生成数据底稿
脚本产出:
output/{博主名}_统计数据.json— 结构化统计分析结果output/{博主名}_数据底稿.md— 结构化统计数据output/{博主名}_蒸馏任务.md— AI蒸馏任务清单output/{博主名}_画像.json— 结构化JSON画像(校验用)
Step B:AI生成风格画像
AI 读取蒸馏任务,按七维DNA框架生成最终产物:
风格画像文件:output/{博主名}_风格画像.md
包含7大章节,每个章节必须包含:
- 具体特征描述(非空话)
- 原文证据引用(至少2条)
- 可复用的规则/模板
- 蒸馏置信度标注(高/中/低)
Step C:风格化分析输出规范
当使用蒸馏画像生成风格化的个股/市场分析时,输出必须包含以下两部分:
1. 数据来源与局限表格
| 数据项 | 来源 | 说明 |
|---|---|---|
| (示例)股价 XX 元、涨跌 ±XX% | 东方财富/雪球(日期) | 收盘价,非实时盘中数据;不同平台可能有分钟级延迟 |
| (示例)PE XX 倍 / EPS XX | 中财网/财报(季度) | 基于最新可获取财报数据,可能因业绩变动而失真 |
| (示例)定增 XX 亿 | 公司公告(日期) | 尚处预案阶段,存在审批不确定性 |
| (示例)负债 XX 亿 | 财报时点数据 | 当前负债状况可能已变化 |
并附加局限声明:
以上行情数据为公开平台聚合数据,非交易所直连实时数据;基本面数据基于最新可获取财报,可能与当前实际经营状况存在差异。
2. ⚠️ AI 风格模拟免责段落
⚠️ AI 风格模拟,不构成投资建议。 本文为 AI 基于对「{博主名}」公众号的七维DNA蒸馏画像生成的风格模拟内容,与原大V本人无关。文中所有观点、判断、推荐均不代表{博主名}本人立场,亦不构成任何买入/卖出/持有建议。股市有风险,投资需谨慎。
Phase 4: 质量校验
蒸馏准确性校验(硬性准出标准)
python "$SKILL_PATH/scripts/distill.py" --validate --author "博主名" --sample 10
三维度评分体系:
| 校验维度 | 说明 | 权重 |
|---|---|---|
| A. 个股提及 | 画像声明的常提及个股是否在文章中真实出现 | 40% |
| B. 风格特征 | 标志性表达、标题模式、开头/结尾模式、字数范围是否匹配 | 35% |
| C. 投资体系 | 核心流派、持仓周期、板块偏好是否与文章一致 | 25% |
准出标准:综合准确率 ≥ 80%
- ≥ 80%:蒸馏通过,画像可用于风格模拟
- < 80%:需补充蒸馏——仔细阅读raw全文,更新画像中不准确的字段后重新校验
- 任一维度低于60%:该维度需要完全重写
蒸馏质量软性检查(双层审计)
审计分两层:表层特征权重 60%,思维层特征权重 40%。二者缺一不可——表层保证「像博主说的话」,思维层保证「像博主的思考」。
表层检查(60%):
| 检查项 | 通过标准 | 权重 | 层级 |
|---|---|---|---|
| 标志性表达命中率 | > 40% | 10% | 表层 |
| 交易体系覆盖度 | > 70% | 10% | 表层 |
| 文章结构匹配度 | > 60% | 10% | 表层 |
| 盘面指标覆盖 | > 50% | 10% | 表层 |
| 语气一致性 | 偏差 < 20% | 10% | 表层 |
| 交易术语覆盖 | > 50% | 10% | 表层 |
思维层检查(40%):
| 检查项 | 通过标准 | 权重 | 层级 |
|---|---|---|---|
| 核心思维匹配度 | > 60%(核心分析工具关键词覆盖) | 15% | 思维层 |
| 论证方式匹配 | > 60%(论证链关键词覆盖) | 15% | 思维层 |
| 哲学价值观体现 | > 50%(投资格言自然融入分析逻辑) | 10% | 思维层 |
综合评分 > 70 分准出(软性),< 70 分打回重新蒸馏。
校验执行规则
- 每次画像更新后必须执行校验
- 每月全量校验所有博主画像
- 增量同步获取新文章后,如新文章涉及画像未覆盖的个股/板块,需更新画像
使用方式
自然语言触发(推荐)
直接对 AI 说:
蒸馏公众号 zshbtz
AI 会自动执行 Phase 0 → 4 完整流程。
命令行
# 蒸馏(60篇文章,推荐档位)
python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 60
# 高精度蒸馏(100篇)
python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 100
# 蒸馏后校验画像准确性(≥80%准出)
python "$SKILL_PATH/scripts/distill.py" --validate --author "财躺平" --sample 10
# 环境检查
python "$SKILL_PATH/scripts/distill.py" --check-env
数据与合规原则
- 禁止LLM编造交易记录、持仓数据、交割单等未公开信息
- 严格区分原文/原帖与AI蒸馏结论
- 交叉验证文章描述与实际市场数据(如有)
- 所有蒸馏产物标注蒸馏置信度
- 盘面数据必须实时采集,禁止 LLM 编造涨跌停、资金流向等数据
- 所有面向用户的 AI 生成投资分析输出,必须包含两段固定声明:
- [数据来源与局限] 表格 — 逐项标注引用的股价、PE、定增、负债等关键数据的来源平台及具体局限(详见 Phase 3 Step C)
- [AI 风格模拟,不构成投资建议] 段落 — 明确标注为 AI 基于蒸馏画像的风格模拟,与原大V本人无关,不构成任何买入/卖出/持有建议(详见 Phase 3 Step C 固定模板)
文件结构
investor-distiller/
├── SKILL.md # 本文件
├── scripts/
│ ├── distill.py # 主蒸馏脚本(调度+统计+校验)
│ └── gzh.py # 公众号数据采集(queryWorkList + workDetail)
├── assets/
│ └── profile_template.md # 七维DNA风格画像输出模板
├── references/
│ └── 蒸馏维度规范.md # 七维DNA详细规范
└── output/ # 蒸馏产物输出目录
├── {博主名}_uuids.json # UUID 缓存(避免重复扣积分)
├── {博主名}_统计数据.json # 脚本统计分析结果
├── {博主名}_完整文章.json # 完整正文落盘(供校验/AI精读)
├── {博主名}_数据底稿.md # 结构化数据底稿
├── {博主名}_蒸馏任务.md # AI蒸馏任务清单
├── {博主名}_画像.json # 结构化JSON画像(校验用)
├── {博主名}_风格画像.md # AI生成的七维DNA画像
└── {博主名}_校验报告_YYYYMMDD.json # 准确性校验报告
依赖
pip install requests
Files (redfox-community)
-
assets
-
profile_template.md 6.1 KB
# {博主名} 风格画像 > **蒸馏置信度**:{高/中/低} > **数据来源**:{平台列表},共 {N} 篇内容(文章/帖子/视频) > **蒸馏时间**:{YYYY-MM-DD} > **AI 风格模拟,不构成投资建议** --- ## 1. 交易体系DNA ### 1.1 核心交易模式 {描述博主的核心交易模式,如龙头战法、趋势跟随、价值投资等} **原文证据:** - {引用1} - {引用2} ### 1.2 选股逻辑 {描述博主如何选股,关注哪些维度} **原文证据:** - {引用1} - {引用2} ### 1.3 买入信号 {描述博主在什么条件下买入} **原文证据:** - {引用1} ### 1.4 卖出/止损信号 {描述博主在什么条件下卖出或止损} **原文证据:** - {引用1} ### 1.5 仓位管理 {描述博主的仓位管理策略} **原文证据:** - {引用1} ### 1.6 核心分析工具(思维框架) {列出博主分析市场时最常用的思维工具,如:产业链研究、宏观经济分析、财务报表分析、技术面分析、资金面分析、情绪周期分析、政策面分析等} **原文证据:** - {引用1——展示博主使用某分析框架的典型案例} --- ## 2. 市场判断DNA ### 2.1 交易流派 {长线/短线/波段,以及具体流派名称} ### 2.2 板块偏好 {列出博主偏好的板块及原因} ### 2.3 持仓周期 {描述典型持仓时间} ### 2.4 多空条件 {描述博主在什么条件下看多/看空} ### 2.5 历史预判追踪 | 时间 | 预判内容 | 实际结果 | 准确度 | |------|---------|---------|--------| | {日期} | {预判} | {结果} | {命中/偏差/未验证} | --- ## 3. 表达风格DNA ### 3.1 文章结构 {描述文章的典型结构,如:开头→市场概述→板块分析→操作策略→心态感悟→结尾} ### 3.2 标志性表达(TOP 10) | # | 表达 | 出现次数 | 使用场景 | |---|------|---------|---------| | 1 | {表达1} | {N}次 | {场景} | | 2 | {表达2} | {N}次 | {场景} | ### 3.3 标题模式 {描述标题的典型模式,如疑问句占比、感叹句占比等} **典型标题示例:** - {标题1} - {标题2} - {标题3} ### 3.4 开头模板 {描述文章的典型开头方式} **模板1:** {描述} **模板2:** {描述} ### 3.5 结尾模式 {描述文章的典型结尾方式} ### 3.6 语气与人称 {描述语气特征和人称使用习惯} **语气量化数据:**(参考数据底稿第16节) - 风格分类:{强语气型/中等语气型/冷静克制型} - 感叹句/疑问句/第一人称/口语化 各指标篇均数值 ### 3.7 论证链模式 {描述博主特有的分析推理路径,如:事件驱动型(从消息切入→分析影响→给出判断)、数据驱动型(从数据出发→对比分析→得出结论)、产业链分析型(事件→产业拆解→A股影响)、逆向思维型等} **原文证据:** - {引用1——展示博主论证链的典型段落} ### 3.8 数据引用风格 {描述博主引用数据的方式:高密度数据驱动型(每段都有数据支撑)、中等数据引用型(关键处引用数据)、主观判断型(以逻辑和观点为主,较少引用具体数据)} ### 3.9 文风温度 {描述文章的情感温度:高温度(情绪感染力强,感叹号多,口语化)、中温度(有观点但克制)、低温度(专业冷静,以数据和逻辑说服读者)} ### 3.10 视频/口播表达特征(如有) {视频 vs 文字的表达差异,口头禅、语速特征等} --- ## 4. 内容深度DNA ### 4.1 平均字数 {平均字数}字(最短{min},最长{max},中位数{median}) ### 4.2 信息密度 {高/中/低} — {描述信息密度特征} ### 4.3 复盘详细度 {描述复盘的详细程度} ### 4.4 预判明确度 {描述预判的明确程度,是否给出具体标的/价位} --- ## 5. 互动特征DNA ### 5.1 读者互动方式 {描述与读者互动的方式} ### 5.2 战绩展示 {描述如何展示过往战绩} ### 5.3 争议处理 {描述如何处理争议和质疑} ### 5.4 免责声明 {免责声明使用率:{X}%} — {典型免责声明内容} --- ## 6. 热点图谱DNA ### 6.1 核心赛道 | 赛道 | 关注度 | 说明 | |------|--------|------| | {赛道1} | {分数} | {说明} | | {赛道2} | {分数} | {说明} | ### 6.2 龙头记忆 {列出博主常提及的具体个股/标的} ### 6.3 常用盘面指标 {列出博主常用的技术指标和盘面数据} ### 6.4 资金面关注 {描述博主关注的资金流向维度} ### 6.5 跨市场视角 {描述博主是否关注全球市场联动:全球视角(美股+港股+A股+商品)、多市场(涉及2-3个市场)、单一市场(仅A股)} **原文证据:** - {引用1——展示博主跨市场分析的典型段落} --- ## 7. 人设基因DNA ### 7.1 投资经历 {投资年限、入市背景、职业经历} ### 7.2 投资哲学演变 {不同时期的投资理念变化,早期 vs 近期} | 时期 | 投资理念 | 代表事件/文章 | |------|---------|-------------| | {早期} | {理念} | {事件} | | {近期} | {理念} | {事件} | ### 7.3 里程碑事件 {公开提及的重大盈亏经历、投资转折点} ### 7.4 师承/影响源 {提及的投资大师、推荐书籍、引用频率最高的思想家} | 影响源 | 引用频率 | 影响体现 | |--------|---------|---------| | {大师/书籍} | {频率} | {如何影响} | --- ## 附录:原文证据索引 | 序号 | 平台 | 出处 | 原文片段 | 对应维度 | |------|------|------|---------|---------| | 1 | {平台} | {标题} ({日期}) | {原文片段} | {维度} | | 2 | {平台} | {标题} ({日期}) | {原文片段} | {维度} | --- ## 校验信息 | 校验项 | 结果 | |--------|------| | 校验日期 | {YYYY-MM-DD} | | 抽样文章数 | {N} | | A. 个股提及准确率 | {X}% | | B. 风格特征准确率 | {X}% | | C. 投资体系准确率 | {X}% | | **综合准确率** | **{X}%** | | 准出判定 | {通过/需补充蒸馏} |
-
-
references
-
蒸馏维度规范.md 56 KB
# 蒸馏维度规范 > 本文档定义了公众号投资博主风格蒸馏的**七维DNA框架**详细规范。 > 每个维度约3000字,包含定义、子维度详解、提取方法、长短线差异、证据规则和产出标准。 --- ## 总览 每位博主的风格画像包含 **7大维度**,蒸馏前需先判定交易类型(长线/短线/混合),再按对应侧重提取。 | # | 维度 | 核心问题 | 蒸馏产出 | |---|------|---------|---------| | 1 | 交易体系DNA | TA怎么交易? | 核心模式、选股逻辑、买卖信号、仓位管理 | | 2 | 市场判断DNA | TA怎么看市场? | 交易流派、板块偏好、持仓周期、多空条件 | | 3 | 表达风格DNA | TA怎么写/说? | 文章结构、标志性表达、标题/开头/结尾模式 | | 4 | 内容深度DNA | TA写多少? | 字数统计、信息密度、复盘详细度、预判明确度 | | 5 | 互动特征DNA | TA怎么互动? | 读者互动、战绩展示、争议处理、免责声明 | | 6 | 热点图谱DNA | TA关注什么? | 核心赛道、龙头记忆、常用指标、资金面关注 | | 7 | 人设基因DNA | TA是谁? | 投资经历、哲学演变、里程碑事件、师承/影响源 | **数据源**:redfox.hk 公众号文章接口(queryWorkList + workDetail)。 ### 蒸馏质量铁律 > **必须从raw全文逐篇提取,禁止依赖任何clean/NER中间层。** 蒸馏准确性直接决定画像质量。经验表明,clean阶段的个股NER提取管线会遗漏大量信息(如一篇提及6只股票的文章可能只提取0-2只),导致画像基于不完整数据构建。因此: 1. **raw全文原则**:所有提取(个股/短语/板块/风格)必须直接遍历raw文章正文,不经过任何预处理过滤 2. **词典+别名匹配**:个股提取使用完整词典(含口语化别名,如"上证指数"→"上证/大盘/沪指/A股"),确保宽松但准确 3. **文章级板块计数**:板块关注度按文章级别计数(每篇只计一次),比词频更准确反映博主真实关注方向 4. **领域专用短语**:使用投资领域专用关键词列表提取关键短语,比通用句子频次统计更精准 5. **校验闭环**:蒸馏完成后必须执行准确性校验(`--validate`),≥80%方可准出 ### 交易类型前置判定 蒸馏前**必须**先判定博主属于哪类交易者,因为不同类别的维度侧重完全不同: | 维度侧重 | 长线交易者 | 短线交易者 | 混合型 | |---------|-----------|-----------|--------| | 投资哲学 | 价值投资/波段交易 | 龙头战法/情绪周期/题材驱动 | 两种兼有,需分场景 | | 核心能力 | 生意本质 + 估值 + 护城河 | 热点捕捉 + 情绪周期 + 量价关系 | 分牛市/熊市切换 | | 分析周期 | 年级别(10年持有视角) | 日级别(隔日~2周) | 中线波段为主 | | 数据驱动 | 财务报表 + 行业数据 | 盘面数据 + 资金流向 + 消息面 | 兼顾基本面和技术面 | **判定方法**: 1. 统计长线关键词(价值投资、护城河、基本面、财报、估值、持有、长期、生意、现金流、ROE、PE、PB)出现频次 2. 统计短线关键词(涨停、跌停、连板、龙头、游资、情绪、打板、复盘、盘面、资金流向、竞价、龙虎榜、妖股、止损)出现频次 3. 长线得分 > 短线得分×1.5 → **长线**;短线得分 > 长线得分×1.5 → **短线**;其余 → **混合型** 4. 混合型需进一步分析:是否在不同市场环境下切换风格(牛市偏短线、熊市偏长线等) --- ## 蒸馏置信度标注规则 每个维度的每个子特征**必须**标注置信度,让使用者知道哪些结论是强证据支撑、哪些是推测: | 置信度 | 条件 | 标注方式 | 使用建议 | |--------|------|---------|---------| | **高** | ≥3条直接原文证据,特征明确且一致 | 🟢 高 | 可直接用于风格模拟 | | **中** | 1-2条原文证据,特征较明确但有不确定性 | 🟡 中 | 可参考但需交叉验证 | | **低** | 间接推断,原文证据不足或存在矛盾 | 🔴 低 | 仅作参考,不可作为风格模拟依据 | **置信度降级规则**: - 如果博主在不同时期对同一特征的描述矛盾,置信度降一级 - 如果特征仅从标题推断而无正文证据,置信度降一级 - 如果特征来自单篇文章而非多篇文章的共性,置信度降一级 - 如果特征来自AI推测而非原文明确表述,必须标为"低" **禁止编造规则**: - 不得编造博主未公开的交易记录、持仓数据、交割单 - 不得编造具体的收益率数字(除非博主自己公开过) - 不得编造博主未提及的投资经历或人脉关系 - 所有推断必须标注"推断"字样及推断依据 --- ## 维度1:交易体系DNA ### 定义与目标 交易体系DNA是蒸馏的核心维度,回答「TA到底怎么交易」这个根本问题。一个完整的交易体系包含五个闭环环节:**选什么 → 什么时候买 → 买多少 → 什么时候卖 → 错了怎么办**。蒸馏的目标是将博主分散在数十篇文章中的交易逻辑碎片,拼成一个自洽的交易系统。 ### 子维度详解 #### 1.1 核心交易模式 核心交易模式是博主交易体系的"总纲",决定了后续所有子维度的方向。 **长线交易者的核心模式提取**: | 模式 | 特征描述 | 典型原文信号 | |------|---------|------------| | 深度价值投资 | 低估值买入、长期持有、安全边际优先 | "PE不到15倍"、"跌破净资产"、"用5毛钱买1块钱的东西" | | 成长投资 | 关注营收/利润增速,愿为高增长付溢价 | "营收增速40%+"、"赛道天花板"、"渗透率刚过10%" | | 质量投资 | 偏好高ROE、强护城河的优质企业 | "ROE连续5年>20%"、"品牌护城河"、"转换成本高" | | 逆向投资 | 在市场恐慌时买入,在狂热时卖出 | "别人恐惧我贪婪"、"利空出尽"、"至暗时刻" | | 波段交易 | 基于估值区间做中期波段 | "估值回到历史中位数"、"均值回归"、"估值百分位" | **短线交易者的核心模式提取**: | 模式 | 特征描述 | 典型原文信号 | |------|---------|------------| | 龙头战法 | 只做板块最强龙头,追涨停板 | "只做龙头不做跟风"、"辨识度"、"空间板" | | 情绪周期 | 根据市场情绪周期(冰点→回暖→高潮→退潮)择时 | "情绪冰点"、"修复"、"高潮"、"退潮期" | | 题材驱动 | 追踪政策/事件驱动的主题投资机会 | "政策催化"、"题材发酵"、"预期差" | | 技术突破 | 基于技术形态突破做交易 | "放量突破"、"突破平台"、"站上均线" | | 打板策略 | 在涨停板买入,次日高开卖出 | "首板"、"二板"、"接力"、"封板" | **提取方法**: 1. 扫描全部文章中关于"我怎么交易"、"我的方法"、"我的策略"等直接表述 2. 统计交易术语出现频率:高频术语代表核心模式,低频术语可能是偶尔提及 3. 从具体交易案例中反推模式:博主描述的交易操作属于哪种模式 4. 交叉验证:博主宣称的模式是否与其实际操作一致(有些人说价值投资但实际操作很短线) #### 1.2 选股逻辑 选股逻辑回答「TA在几千只股票中,用什么标准筛选出目标标的」。 **长线选股逻辑提取要点**: - **行业筛选**:是否有偏好的行业/赛道?选择标准是什么(天花板、竞争格局、渗透率)? - **企业质量**:关注哪些财务指标(ROE、毛利率、现金流、负债率)?门槛值是多少? - **估值标准**:用什么估值方法(PE、PB、DCF、PEG)?可接受的估值区间? - **护城河类型**:偏好哪种护城河(品牌、成本、网络效应、转换成本、牌照)? - **管理层评估**:是否关注管理层?评估标准是什么? **短线选股逻辑提取要点**: - **题材筛选**:如何发现和筛选题材(政策文件、消息面、资金异动)? - **龙头识别**:用什么标准判断龙头(首个涨停、最高辨识度、最大封单)? - **量价关系**:关注哪些量价信号(放量突破、缩量回调、换手率)? - **板块效应**:是否要求板块内有多只个股共振? - **时机选择**:什么时间点选股(盘前竞价、盘中实时、盘后复盘)? **提取方法**: 1. 提取文章中所有提及具体股票/标的的段落 2. 分析博主给出的买入理由(显式理由 + 隐含逻辑) 3. 统计选股关键词频率:财务类术语多→基本面选股;技术类术语多→技术面选股 4. 从博主的"看好"、"关注"、"布局"等表述中提取选股逻辑链条 5. 注意区分:博主是在推荐股票还是在分析案例(前者代表真实选股逻辑,后者可能是教学) #### 1.3 买入信号 买入信号是博主交易体系中"开仓"的触发条件。 **长线买入信号提取**: - 估值低于某个阈值(如PE<15、PB<1、低于DCF估值30%以上) - 基本面拐点出现(营收增速加速、利润率改善、行业景气度回升) - 市场恐慌导致的错杀(大盘暴跌但基本面未变) - 分批买入策略(首次建仓价位、加仓位、重仓条件) - 催化剂确认(新产品发布、政策利好、业绩超预期) **短线买入信号提取**: - 涨停板打板时机(首板/二板/高位板,封单量,涨停时间) - 情绪周期位置(冰点后的首阳、高潮前的确认信号) - 技术形态突破(突破平台、站上关键均线、放量启动) - 板块共振信号(板块内3只以上个股涨停,龙头确认) - 竞价信号(高开幅度、竞价量能、竞价排名) **提取方法**: 1. 提取文章中所有"买入"、"建仓"、"加仓"、"进场"、"上车"相关表述 2. 分析买入时点的上下文:当时市场状态如何?个股状态如何? 3. 区分"计划买入"(提前设定的条件单)和"临盘买入"(盘中临时决策) 4. 注意买入的确定性程度:是"可以关注"还是"果断买入" 5. 统计买入信号的胜率和盈亏比(如果博主有公开战绩) #### 1.4 卖出/止损信号 卖出信号是交易体系中"退出"的触发条件,包括止盈和止损两部分。 **长线卖出信号提取**: - 估值过高(超过合理估值上限,如PE>50) - 基本面恶化(核心逻辑被破坏、业绩持续下滑) - 更好的替代标的出现(机会成本考量) - 持仓比例再平衡(单一标的占比过高需要减仓) - 投资论点被证伪(原来看好的逻辑被现实否定) **短线卖出/止损信号提取**: - 止盈规则(固定百分比止盈、涨停板打开止盈、情绪高潮止盈) - 止损规则(固定百分比止损如-5%、跌破关键位止损、时间止损如隔日不涨就走) - 情绪退潮信号(高潮后首日亏钱效应、连板断板、炸板率飙升) - 龙头见顶信号(龙头放量滞涨、跟风股先于龙头走弱) - 板块轮动信号(资金从当前板块撤出转向新板块) **提取方法**: 1. 提取文章中所有"卖出"、"减仓"、"清仓"、"止损"、"止盈"、"离场"相关表述 2. 特别关注博主描述亏损交易的段落:止损是否及时?止损规则是否一致? 3. 分析博主的"认错"文章/帖子:什么情况下会承认判断错误? 4. 统计止损幅度:固定比例还是灵活调整? 5. 注意言行一致性:宣称的止损规则是否在实际操作中执行 #### 1.5 仓位管理 仓位管理决定了每笔交易投入多少资金,是风控的核心。 **仓位管理模式识别**: | 模式 | 特征 | 典型表述 | |------|------|---------| | 满仓单票 | 极度集中,全仓一只 | "重仓"、"满上"、"梭哈" | | 核心+卫星 | 核心仓位长期持有 + 小仓位做短线 | "底仓"、"核心仓位"、"卫星仓" | | 等分配置 | 平均分配到N只标的 | "均分"、"各配置X%" | | 金字塔加仓 | 初始轻仓,确认后逐步加仓 | "先建底仓"、"加仓"、"浮盈加仓" | | 固定比例 | 每笔交易不超过总资金的X% | "单票不超过20%"、"严格控制仓位" | **提取方法**: 1. 提取文章中关于仓位比例的直接表述 2. 从持仓组合分析集中度(如果博主公开过持仓) 3. 分析加仓/减仓的频率和幅度 4. 关注博主在亏损时的仓位变化:是否会在下跌中加仓(补仓/摊薄成本) 5. 注意仓位管理与市场状态的关系:牛市是否加仓、熊市是否减仓 ### 维度1产出标准 **必须输出**: - 核心交易模式总结(1-2句话概括) - 5个子维度的具体特征描述 - 每个子维度至少2条原文证据引用 - 交易体系的自洽性评估(五个环节是否逻辑闭环) - 置信度标注 **加分项**: - 画出交易体系流程图(选股→择时→仓位→风控) - 识别交易体系的潜在弱点(如龙头战法在退潮期的高回撤风险) - 对比博主宣称的交易方法与实际操作的偏差 --- ## 维度2:市场判断DNA ### 定义与目标 市场判断DNA回答「TA怎么看市场」这个问题。投资不仅是选股,更是对市场整体环境的判断。有些博主擅长选时(择时能力),有些擅长选股(Alpha能力),有些两者兼备。蒸馏的目标是理解博主的市场分析框架:TA用什么视角看市场、关注哪些指标、在什么条件下看多/看空。 ### 子维度详解 #### 2.1 交易流派判定 交易流派是博主投资世界观的"门派归属",决定了分析框架的基础假设。 **主要流派分类**: | 流派 | 核心信念 | 分析方法 | 代表人物 | |------|---------|---------|---------| | 价值投资 | 股价最终反映内在价值 | 财务报表分析、估值模型 | 巴菲特、格雷厄姆 | | 成长投资 | 高增长可以消化高估值 | 行业研究、增速预测 | 费雪、彼得林奇 | | 趋势交易 | 趋势一旦形成倾向于延续 | 技术分析、趋势跟踪 | 海龟交易法 | | 情绪周期 | 市场情绪有规律可循 | 情绪指标、量价分析 | 游资群体 | | 宏观驱动 | 宏观政策决定市场方向 | 政策解读、经济数据分析 | 索罗斯 | | 事件驱动 | 突发事件创造定价错误 | 信息收集、快速反应 | 对冲基金 | | 量化/因子 | 统计规律优于主观判断 | 因子模型、回测验证 | 量化私募 | **判定方法**: 1. 统计博主文章中各流派关键词的出现频率 2. 分析博主引用的投资大师/书籍属于哪个流派 3. 从博主的分析逻辑推断:是基于基本面、技术面还是情绪面? 4. 注意"混合型"博主:可能在不同场景使用不同流派框架 5. 关注博主对其他流派的态度:是排斥还是包容? **特殊注意**: - 很多博主自称"价值投资"但实际操作偏短线,需以实际操作为准 - "波段交易"是最常见的混合形态,需区分是"有纪律的波段"还是"随意进出" - A股市场的特殊性:纯价值投资在A股较少,多数是"价值+趋势"混合 #### 2.2 板块偏好 板块偏好揭示博主"关注什么赛道",这往往与其知识背景、投资哲学和信息渠道相关。 **提取方法**: 1. 统计全部文章中提及的各板块/行业关键词频率 2. 按频率排序,识别TOP5核心赛道 3. 分析板块偏好的时间稳定性:是一直偏好某个赛道,还是跟随市场热点切换? 4. 分析偏好原因:是因为专业知识(如医药背景→偏好医药股)还是因为市场热度? 5. 关注板块轮动的预判能力:是否提前布局即将轮动的板块? **赛道关键词库**(脚本自动扫描): ``` 航天:航天、卫星、火箭、商业航天、星链、太空 半导体:半导体、芯片、光刻、存储、科创、中芯、台积电 AI:AI、人工智能、大模型、GPT、Agent、算力、英伟达、GPU 新能源:新能源、光伏、风电、储能、锂电、充电桩、宁德时代 金融:券商、银行、保险、金融、降息、降准 消费:消费、白酒、食品、零售、茅台、五粮液 医药:医药、医疗、创新药、生物、集采、CXO 军工:军工、国防、装备、中航、航天 地产:地产、房地产、楼市、保交楼、城中村 周期:有色、铜、锂、煤炭、钢铁、化工 ``` **板块偏好深度分析**: - 博主对偏好板块的理解深度如何?(泛泛而谈 vs 深入产业链分析) - 是否有"能力圈"意识?(明确表示不懂某些板块 vs 什么板块都评论) - 板块偏好与交易体系是否匹配?(短线选手偏好活跃板块、长线选手偏好确定性板块) #### 2.3 持仓周期 持仓周期是交易体系的时间维度,直接影响交易频率和风控方式。 | 周期类型 | 典型持仓时间 | 交易频率 | 典型表述 | |---------|------------|---------|---------| | 超短线/日内 | 分钟~小时 | 每日多次 | "T+0"、"日内"、"分时" | | 隔日短线 | 1-3个交易日 | 每周2-5次 | "隔日"、"次日"、"做T" | | 波段交易 | 1-4周 | 每月1-3次 | "波段"、"持有几天"、"中线" | | 中线趋势 | 1-6个月 | 每季度1-2次 | "中线持有"、"趋势"、"季度" | | 长线投资 | 6个月以上 | 每年1-3次 | "长期持有"、"陪伴成长"、"3年维度" | **提取方法**: 1. 提取文章中关于持仓时间的直接表述("持有了X个月"、"计划持有X年") 2. 从文章发布频率推断交易频率:每日复盘→可能短线;月度总结→可能长线 3. 分析博主关注的K线周期:日K/周K/月K分别对应不同持仓周期 4. 从复盘内容推断:是每日盯盘还是定期review? 5. 注意持仓周期在不同市场环境下的变化:震荡市是否缩短周期? #### 2.4 多空条件 多空条件是博主判断市场方向的决策框架,回答"什么条件下看多、什么条件下看空"。 **多头条件提取**: - 宏观面:政策宽松、经济数据改善、流动性充裕 - 基本面:企业盈利增速、行业景气度上行、估值处于低位 - 技术面:指数站上均线、MACD金叉、量能放大 - 情绪面:市场情绪从冰点回暖、赚钱效应恢复、成交量回升 - 资金面:北向资金流入、融资余额增加、新基金发行 **空头条件提取**: - 宏观面:政策收紧、经济数据恶化、外部风险事件 - 基本面:企业盈利下滑、行业产能过剩、估值泡沫 - 技术面:指数跌破均线、MACD死叉、量能萎缩 - 情绪面:市场情绪过热、全民炒股、融资余额过高 - 资金面:外资持续流出、大股东减持、IPO密集发行 **提取方法**: 1. 提取文章中明确表达看多/看空观点的段落 2. 分析观点背后的逻辑:是基于什么条件做出的判断? 3. 对比不同市场环境下的多空判断:是否有稳定的框架还是随大流? 4. 注意条件触发机制:是单一条件触发还是多条件综合? 5. 分析多空转换的速度:是渐进式(逐步加减仓)还是突变式(突然翻多/翻空) #### 2.5 历史预判追踪 历史预判追踪是对博主过去市场判断的回溯验证,是评估其判断力的重要依据。 **追踪方法**: 1. **提取预判**:从文章中提取博主过去的市场预判(含具体时间和标的) - 明确预判:"我认为下周大盘会涨"、"看好XX板块"、"建议减仓" - 隐含预判:持续推荐某类股票暗示看好该方向 2. **交叉验证**:将预判与实际市场走势对比 - 指数预判:对比预判日之后的大盘走势 - 板块预判:对比预判日之后的板块指数表现 - 个股预判:对比预判日之后的股价变化 3. **统计准确率**:仅统计可验证的明确预判 - 命中率 = 正确预判数 / 可验证预判总数 - 区分"方向正确但幅度偏差"和"完全错误" 4. **分析认错模式**: - 博主是否承认错误的预判? - 认错的速度(及时还是拖延)? - 认错后如何调整策略? - 是否从错误中总结教训? **注意事项**: - 只统计有明确时间标记的预判,模糊表述("未来可能涨")不计入 - 注意幸存者偏差:博主可能只回顾正确的预判而忽略错误的 - 部分预判需要时间验证("长期看好"可能需要数年),标注为"待验证" - 预判的颗粒度很重要:精确到价位的预判比方向性预判更有参考价值 ### 维度2产出标准 **必须输出**: - 交易流派判定及依据 - TOP5板块偏好及排序 - 持仓周期判定 - 多空条件框架总结 - 至少3条历史预判的追踪验证(如有可验证数据) **加分项**: - 预判准确率统计(需标注样本量) - 多空转换的决策流程图 - 博主分析框架的优劣势评估 --- ## 维度3:表达风格DNA ### 定义与目标 表达风格DNA回答「TA怎么写/说」这个问题。投资博主的核心竞争力不仅在于投资能力,更在于将复杂的投资逻辑用个人化的方式表达出来。蒸馏的目标是提取博主的"文字指纹"——那些让读者一眼就能认出"这是XX写的"的独特表达特征。这包括文章结构、标志性用语、标题风格、开头/结尾模式、语气特征,以及视频博主的口播风格。 ### 子维度详解 #### 3.1 文章结构 文章结构是博主内容组织的"骨架",不同博主有不同的信息组织逻辑。 **常见结构模式**: | 结构类型 | 组织方式 | 典型特征 | 适用场景 | |---------|---------|---------|----------| | 复盘型 | 按时间线叙述当日/本周操作 | 市场概述→板块分析→个股点评→操作记录→明日展望 | 每日/每周复盘 | | 分析型 | 围绕一个核心论点展开 | 提出问题→数据论证→得出结论→操作建议 | 深度个股/行业分析 | | 教学型 | 传授投资方法或知识 | 概念引入→案例演示→总结要点→注意事项 | 投资教育 | | 观点型 | 直接输出市场观点 | 核心观点→论据支撑→风险提示 | 市场预判 | | 叙事型 | 以故事/经历为主线 | 故事引入→感悟提炼→投资启示 | 投资心得分享 | | 清单型 | 列表式罗列要点 | 总论→要点1→要点2→...→总结 | 选股清单、复盘要点 | | 混合型 | 多种结构交替使用 | 无固定模式 | 日常随笔 | **提取方法**: 1. 取前20篇文章,逐篇标注段落功能和段落顺序 2. 统计各段落功能的出现频率(如"市场概述"出现在开头的频率) 3. 识别固定模块:是否有每期都出现的固定栏目(如"今日龙虎榜点评"、"本周操作回顾") 4. 分析段落间的逻辑关系:是递进、并列还是转折? 5. 关注文章长度与结构的关系:短文是否省略某些模块? **结构变异分析**: - 博主在牛市和熊市的结构是否不同?(牛市更乐观→更多机会分析;熊市更谨慎→更多风险提示) - 盈利和亏损时的结构是否不同?(盈利时可能更详细展示操作;亏损时可能更侧重反思) - 特殊事件时的结构变化(如重大政策出台、黑天鹅事件) #### 3.2 标志性表达 标志性表达是博主的"语言指纹",是区分不同博主最直观的特征。 **识别规则**(脚本自动提取): 1. 在多篇文章中重复出现(≥2次) 2. 具有个人辨识度(排除通用短语如"今天大盘"、"明天继续") 3. 长度在4-30个字符之间 4. 包含以下特征之一: - 特定比喻/类比(如"星辰大海"、"贪嗔痴"、"刀口舔血") - 特定口头禅/金句(如"敬畏市场"、"知行合一"、"慢慢变富") - 特定格式表达(如固定开头句式、固定栏目名) - 特定称谓(如将散户称为"韭菜"、将机构称为"主力") - 特定情绪词(如"绝望"、"疯狂"、"贪婪"、"恐惧") **分类提取**: | 类别 | 说明 | 示例 | |------|------|------| | 市场描述 | 描述市场状态的专属用语 | "至暗时刻"、"黎明前的黑暗"、"暴风雨来临" | | 操作描述 | 描述交易行为的专属用语 | "上车"、"下车"、"割肉"、"吃肉"、"喝汤" | | 情绪表达 | 表达投资情绪的专属用语 | "煎熬"、"煎熬中的坚守"、"心态崩了" | | 哲理金句 | 投资哲学类表述 | "买股票就是买公司"、"时间是好公司的朋友" | | 行业黑话 | 特定圈子的行话/暗语 | "打板"、"核按钮"、"天地板"、"翘板" | | 自嘲/幽默 | 自嘲或幽默化表达 | "又交学费了"、"被市场教育"、"含泪加仓" | **提取方法**: 1. 脚本自动:统计所有4-30字符短语的出现频率,过滤通用短语,保留个人特征短语 2. AI深度:分析短语的使用场景、情绪色彩和功能定位 3. 对比分析:与同领域其他博主对比,确认哪些是该博主独有的表达 4. 时间演变:标志性表达是否随时间变化(新增/淘汰某些用语) #### 3.3 标题模式 标题是内容的"门面",不同博主有截然不同的标题策略。 **标题分类统计**: - **疑问句式**:以问号结尾或包含疑问词("明天会涨吗?"、"XX还能追吗?") - **感叹句式**:以感叹号结尾或包含感叹词("大牛市来了!"、"暴跌!") - **陈述句式**:客观陈述("本周操作回顾"、"XX行业分析") - **数字开头**:以数字开头("3只潜力股"、"5个选股标准") - **悬念式**:制造悬念("这只股票我加仓了"、"明天的关键点位") - **情绪式**:直接表达情绪("绝望"、"终于等到你"、"太难了") **提取方法**: 1. 脚本自动统计标题模式占比(疑问/感叹/陈述/数字开头) 2. 分析标题长度分布(平均字数、最短/最长) 3. 提取高频标题模板(如"XX日复盘"、"XX行业深度分析") 4. 分析标题与内容的一致性:标题是否准确反映内容?还是"标题党"? 5. 分析标题的情绪强度:是克制理性还是夸张吸引眼球? #### 3.4 开头模板 开头是读者的"第一印象",好的开头能迅速抓住读者注意力。 **常见开头模式**: - **数据开场**:直接列出关键数据("今天大盘涨了1.5%,成交额突破万亿") - **情绪开场**:以情绪描写切入("今天真是煎熬的一天") - **问题开场**:以问题引入("很多人问我XX股票能不能买") - **引用开场**:引用名言/新闻/他人观点("巴菲特说过...") - **故事开场**:以个人经历或故事切入("昨天发生了一件事...") - **结论先行**:先给结论再论证("我认为现在是加仓的好时机") - **固定开场**:每期固定的开场白("大家好,今天是X月X日,复盘如下") **提取方法**: 1. 取前20篇文章的开头第一段(前100字) 2. 分类标注开头类型 3. 统计各类型的出现频率 4. 识别是否有固定的开场模板 5. 分析开头与文章整体风格的协调性 #### 3.5 结尾模式 结尾是内容的"收束",不同博主有不同的收尾方式。 **常见结尾模式**: - **总结式**:概括全文要点("总结一下今天的操作...") - **展望式**:展望后市("明天关注XX点位"、"下周重点看XX") - **免责式**:以免责声明结尾("以上仅为个人观点,不构成投资建议") - **互动式**:邀请读者互动("大家怎么看?评论区聊聊") - **鸡汤式**:以投资感悟/鸡汤结尾("投资是一场修行") - **预告式**:预告下期内容("明天继续分析XX板块") - **戛然而止**:无明确结尾,分析到哪算哪 #### 3.6 语气与人称 语气和人称决定了博主与读者的"关系定位"。 **语气维度分析**: - **权威感**:权威型("你们要记住...") vs 平等型("我们一起看看...") vs 谦逊型("不一定对,供参考...") - **情绪浓度**:理性型(数据说话) vs 感性型(大量感叹词、情绪词) - **确定性**:确定型("一定会涨") vs 弹性型("可能"、"大概率") - **口语化**:书面型(语法完整) vs 口语型(省略主语、使用俚语) **人称分析**: - 第一人称使用频率("我"、"我们") - 第二人称使用频率("你"、"你们"、"大家") - 是否有特定的读者称谓("兄弟们"、"朋友们"、"老铁们") #### 3.7 视频/口播表达特征(如有视频数据) 当博主有视频内容时,需分析口播与文字表达的差异。 **口播特征提取**: - **口头禅**:视频中反复出现的口头用语 - **语速特征**:快节奏信息输出 vs 慢节奏娓娓道来 - **情绪表达**:视频中的情绪表达是否比文字更强烈? - **内容深度差异**:同一主题,视频和文字哪个更深入? - **受众定位差异**:视频受众和文字受众是否不同? **提取方法**:通过Whisper提取口播文字,与文章文字进行对比分析。 ### 维度3产出标准 **必须输出**: - 文章结构流程图(段落功能序列) - TOP10标志性表达表格(含使用次数和场景) - 标题模式占比统计 - 开头模板TOP3 + 结尾模式TOP3 - 语气特征描述(权威感/情绪浓度/确定性/口语化) **加分项**: - 口播 vs 文字的风格对比(如有视频数据) - 表达风格的时间演变分析 --- ## 维度4:内容深度DNA ### 定义与目标 内容深度DNA回答「TA写多少、写多深」这个问题。投资博主的内容深度直接决定了其受众画像——深度长文吸引专业投资者,轻量短文吸引入门小白。蒸馏的目标是量化博主的内容深度特征,让使用者知道"如果要模拟这个博主的风格,应该写多长、写多深"。 ### 子维度详解 #### 4.1 字数统计 字数是内容深度最直观的量化指标。 **统计维度**: - 平均字数:所有文章正文的平均字符数 - 字数分布:最短/最长/中位数/标准差 - 字数趋势:近期文章是否比早期更长或更短? - 平台差异:不同平台的字数是否有显著差异? - 场景差异:复盘文 vs 分析文 vs 随笔的字数差异 **字数区间分类**: | 区间 | 字数范围 | 内容类型 | 公众号典型场景 | |------|---------|---------|----------| | 微内容 | <200字 | 短评/动态/快评 | 每日盘感、快讯点评 | | 轻内容 | 200-800字 | 简要分析/操作记录 | 盘中快报、操作记录 | | 中内容 | 800-2000字 | 标准复盘/个股点评 | 日常复盘、板块分析 | | 深内容 | 2000-5000字 | 深度分析/行业研究 | 深度研报、行业梳理 | | 超长内容 | >5000字 | 年度总结/深度报告 | 年度投资总结、深度报告 | **脚本自动统计**:distill.py 的 `analyze_articles()` 函数会自动计算均字数、最短、最长、中位数。 #### 4.2 信息密度 信息密度衡量"每千字包含多少有效信息",是内容质量的核心指标。 **密度评估框架**: | 密度等级 | 特征描述 | 典型内容 | |---------|---------|----------| | **高密度** | 每段都包含具体数据、逻辑分析或操作建议;几乎没有废话 | 行业深度研究报告、个股财务分析 | | **中密度** | 有数据和分析,但穿插了抒情/感慨/闲聊 | 标准每日复盘、板块分析 | | **低密度** | 以抒情/感悟/闲聊为主,数据和分析较少 | 投资心得、生活感悟、鸡汤文 | | **混合密度** | 开头/结尾低密度,中间核心段落高密度 | 多数公众号文章的常见模式 | **信息密度量化指标**: - **数据点密度**:每千字包含的具体数字/数据点数量 - **逻辑链密度**:每千字包含的因果推理链条数量 - **操作建议密度**:每千字包含的明确操作建议数量 - **引用密度**:每千字引用的外部数据源/研报/新闻数量 **提取方法**: 1. 取5篇代表性文章,逐段标注段落类型(数据分析/观点输出/抒情/闲聊/过渡) 2. 统计各类型段落的占比 3. 计算有效信息段落占总段落的比例 4. 标注信息密度是否均匀还是集中在某些段落 #### 4.3 复盘详细度 复盘详细度衡量博主对盘面数据的覆盖程度,是短线博主的重要深度指标。 **复盘详细度分级**: | 等级 | 覆盖内容 | 典型特征 | |------|---------|----------| | **详尽型** | 大盘指数+板块涨跌+个股点评+资金流向+情绪指标+明日展望 | 3000字以上,数据图表丰富 | | **适中型** | 大盘概述+重点板块+核心个股+简要展望 | 1000-2000字,有数据但不面面俱到 | | **简略型** | 一两句话概括市场+个人操作 | 500字以内,侧重结论而非过程 | | **主题型** | 围绕一个主题深入,不追求全面覆盖 | 字数不定,深度优先于广度 | **盘面数据覆盖检查清单**: - [ ] 三大指数涨跌幅(上证/深证/创业板) - [ ] 成交量/成交额 - [ ] 涨跌停数量 - [ ] 板块涨跌排名 - [ ] 北向资金流向 - [ ] 融资融券数据 - [ ] 龙虎榜数据 - [ ] 情绪指标(连板数/炸板率/昨日涨停今日表现) - [ ] 技术形态分析 - [ ] 消息面/政策面解读 **提取方法**:对照检查清单,统计每篇文章覆盖了哪些数据维度。 #### 4.4 预判明确度 预判明确度衡量博主给出市场判断时的清晰程度。 **明确度分级**: | 等级 | 特征 | 示例 | |------|------|------| | **精确型** | 给出具体标的、价位、时间 | "XX股票在25元附近可以建仓,目标30元" | | **方向型** | 给出方向但无具体价位 | "看好XX板块下周表现" | | **条件型** | 给出条件触发式判断 | "如果站稳3200点,则看3300" | | **模糊型** | 含糊其辞,留有退路 | "市场可能有机会也可能有风险" | | **不预判** | 明确不做预判 | "我不做预测,只做好应对" | **注意事项**: - 部分博主刻意模糊预判以规避风险,需识别"伪预判" - 预判明确度与合规意识相关:合规意识强的博主倾向于更模糊 - 预判明确度在不同平台可能不同:公众号更谨慎,私密社群更直接 ### 维度4产出标准 **必须输出**: - 字数统计四元组(均值/最短/最长/中位数) - 信息密度等级判定及依据 - 复盘详细度等级判定 - 预判明确度等级判定 **加分项**: - 不同内容类型的字数分布图 - 信息密度的段落级分析 --- ## 维度5:互动特征DNA ### 定义与目标 互动特征DNA回答「TA怎么和读者/粉丝互动」这个问题。投资博主不是写论文的学者,而是活生生的社交媒体人。TA如何回应读者的质疑、如何展示战绩、如何处理争议、是否包含免责声明——这些互动特征构成了博主的"人设外壳",决定了粉丝的粘性和忠诚度。蒸馏的目标是让使用者能够模拟博主与受众的互动方式,而不仅仅是投资观点。 ### 子维度详解 #### 5.1 读者互动方式 读者互动是博主与粉丝之间的"情感纽带",不同博主有截然不同的互动策略。 **互动模式分类**: | 模式 | 特征 | 典型表现 | |------|------|----------| | 高互动型 | 积极回复评论,主动参与讨论 | 每条评论都回复、主动提问引导讨论 | | 选择互动型 | 只回复特定类型的评论 | 只回复提问、只回复有质量的评论 | | 低互动型 | 很少回复评论 | 偶尔回复、基本不互动 | | 社群型 | 将读者转化为社群成员 | 引导加微信/进社群/加入知识星球 | | 直播型 | 通过直播实时互动 | 定期直播答疑、盘中实时解盘 | **提取方法**: 1. 统计评论区的博主回复率(回复数/评论总数) 2. 分析回复的内容特征:是专业解答还是简短回应? 3. 分析博主主动发起的互动(投票、提问、征集意见) 4. 注意公众号互动的特点:留言需博主精选后才可见,因此评论区内容代表博主认可的观点 5. 关注博主是否会置顶某些评论(代表博主认可的观点) #### 5.2 战绩展示 战绩展示是博主建立信任和权威的核心方式。 **展示模式分类**: | 模式 | 特征 | 典型表现 | |------|------|----------| | 实时晒单型 | 当天/当周公开买卖操作 | "今天买入了XX"、"清仓了XX" | | 复盘战绩型 | 在复盘中回顾操作成绩 | "本周操作总结:胜率80%" | | 收益率展示型 | 定期公布账户收益率 | "本月收益率+15%"、"年度收益曲线" | | 低调不晒型 | 不主动展示具体战绩 | "操作就不说了"、"自己心里有数" | | 选择性展示 | 只展示成功操作,忽略失败 | 盈利时高调、亏损时沉默 | | 交割单型 | 直接展示交易截图/交割单 | 截图展示买卖价格和数量 | **提取方法**: 1. 统计文章中展示操作战绩的频率 2. 分析战绩的展示方式:直接晒单、文字描述还是收益率曲线? 3. 注意选择性偏差:是否只展示成功而隐藏失败? 4. 分析战绩展示的时机:是在赚钱时更积极还是亏钱时也透明? 5. 评估战绩的可验证性:是否有时间标记?是否能事后追溯? #### 5.3 争议处理 争议处理揭示了博主面对质疑和批评时的真实人格。 **争议处理模式**: | 模式 | 特征 | 典型回应 | |------|------|----------| | 直接反击型 | 对质疑者正面回击 | "不懂就别乱说"、"你先赚到我这个数再说" | | 理性解释型 | 用数据和逻辑回应质疑 | "我的逻辑是这样的,数据如下..." | | 自嘲化解型 | 用幽默化解质疑 | "确实打脸了,市场教训了我" | | 忽略型 | 完全不回应负面评论 | 不删除不回复,置之不理 | | 删除拉黑型 | 删除负面评论或拉黑用户 | 评论区一片祥和,无负面声音 | | 主动认错型 | 主动承认错误并反思 | "这次判断错了,复盘如下..." | **提取方法**: 1. 在文章中寻找博主回应质疑的段落 2. 分析博主的"认错文章":是否有主动承认错误的文章? 3. 分析博主的情绪反应:被质疑时是否会情绪化? 4. 注意争议主题:是关于投资观点的争议还是个人行为的争议? 5. 观察争议后的行为调整:是否会因为争议而改变后续的表达策略? #### 5.4 免责声明 免责声明体现了博主的合规意识和风险认知。 **免责声明模式分析**: | 模式 | 频率 | 典型措辞 | |------|------|----------| | 标准免责 | 每篇都有 | "以上仅为个人观点,不构成投资建议" | | 随性免责 | 偶尔出现 | "个人日记,不构成建议哈" | | 口头禅式 | 融入日常表达 | "投资有风险,入市需谨慎" | | 无免责 | 从不包含 | 无任何免责声明 | | 强化免责 | 特别强调风险 | "这是高风险操作,新手请勿模仿" | **识别关键词**(脚本自动扫描): ``` 免责声明、不构成建议、不构成投资建议、投资有风险 个人日记、个人笔记、理财需谨慎、仅供学习参考 据此操作风险自担、不对其真实性负责、股市有风险 ``` **提取方法**: 1. 脚本自动扫描免责声明关键词出现频率 2. 分析免责声明的位置(开头/中间/结尾) 3. 分析免责声明的语气(正式/随意/强调) 4. 注意免责声明与实际建议的矛盾:一边说"不构成建议"一边给出具体标的 #### 5.5 社区影响力 社区影响力衡量博主在投资社区中的地位和号召力。 **影响力指标**: - **粉丝规模**:各平台粉丝总数 - **互动量级**:单篇平均点赞/评论/转发数 - **评论回复率**:博主回复评论的比例 - **被引用频率**:其他博主/媒体引用该博主观点的频率 - **观点扩散力**:博主观点是否能在评论区/社区引发讨论 **提取方法**: 1. 从平台API获取粉丝数、获赞数、评论数等基础数据 2. 计算互动率(互动数/粉丝数),衡量粉丝活跃度 3. 分析评论区的情绪倾向:支持者多还是质疑者多? 4. 关注博主在社区中的角色:是意见领袖还是普通参与者? #### 5.6 圈子关系 圈子关系揭示博主在投资社区中的"社交网络"和"观点阵营"。 **提取方法**: 1. 分析博主提及/引用的其他博主/大V 2. 分析评论区出现的其他博主(互动/互推) 3. 识别观点阵营:与哪些博主观点相似/对立? 4. 关注博主的"师承"和"传承"关系 5. 分析圈子关系的变化:是否有"脱圈"或"转圈"现象 ### 维度5产出标准 **必须输出**: - 互动模式判定及依据 - 战绩展示模式判定 - 争议处理风格描述 - 免责声明使用率及典型措辞 - 社区影响力基础数据(如有平台数据) **加分项**: - 圈子关系图谱 - 互动风格的时间演变 - 不同平台的互动差异 --- ## 维度6:热点图谱DNA ### 定义与目标 热点图谱DNA回答「TA关注什么」这个问题。每个投资博主都有自己的"注意力分配"——有些人始终关注科技股,有些人紧追政策动向,有些人只关心龙头妖股。蒸馏的目标是描绘出博主的"投资注意力地图":哪些赛道占据其认知中心,哪些龙头股是其长期跟踪对象,哪些技术指标是其决策依据。 ### 子维度详解 #### 6.1 核心赛道 核心赛道是博主投入最多注意力的行业/板块,反映其能力圈和偏好。 **赛道关键词库**(脚本自动扫描): | 赛道 | 关键词 | |------|--------| | 航天 | 航天、卫星、火箭、商业航天、星链、太空 | | 半导体 | 半导体、芯片、光刻、存储、科创、中芯、台积电 | | AI | AI、人工智能、大模型、GPT、Agent、算力、英伟达、GPU | | 新能源 | 新能源、光伏、风电、储能、锂电、充电桩、宁德时代 | | 金融 | 券商、银行、保险、金融、降息、降准 | | 消费 | 消费、白酒、食品、零售、茅台、五粮液 | | 医药 | 医药、医疗、创新药、生物、集采、CXO | | 军工 | 军工、国防、装备、中航、航天 | | 地产 | 地产、房地产、楼市、保交楼、城中村 | | 周期 | 有色、铜、锂、煤炭、钢铁、化工 | | 脑机接口 | 脑机、Neuralink、BCI | | 核聚变 | 核聚变、可控核、ITER | **提取方法**: 1. 脚本自动统计各赛道关键词出现频率 2. 按频率排序生成赛道关注度排名 3. 分析赛道的稳定性:是一直关注同一赛道,还是跟随市场热点切换? 4. 区分"深度关注"(有深入分析文章)和"浅层提及"(只是一带而过) 5. 分析赛道偏好与博主知识背景的关系 **赛道偏好深度评估**: - 博主对偏好赛道的理解深度如何?(泛泛而谈 vs 深入产业链分析) - 是否有"能力圈"意识?(明确表示不懂某些板块 vs 什么板块都评论) - 赛道偏好与交易体系是否匹配?(短线选手偏好活跃板块、长线选手偏好确定性板块) #### 6.2 龙头记忆 龙头记忆是博主长期跟踪和反复提及的具体个股/标的,这些标的往往已经成为博主"投资语言"的一部分。 **提取方法**: 1. 统计全部文章中提及的具体股票/标的名称和代码 2. 按提及频率排序,识别TOP10龙头记忆 3. 分析博主与这些标的的"关系": - 长期跟踪(持续数月的分析) - 曾经持有(公开过买卖操作) - 教学案例(用作分析教学的素材) - 情感连接(有个人故事/情结的标的) 4. 分析龙头记忆的更新频率:是否定期加入新标的、淘汰旧标的? 5. 注意龙头记忆与赛道的关系:龙头股是否集中在偏好赛道内? **典型龙头记忆类型**: - **精神图腾**:长期信仰的标的(如价投者的"茅台"、科技控的"英伟达") - **操作对象**:反复交易的标的(如短线选手的"妖股") - **行业代表**:用作行业分析的代表标的 - **反面教材**:用作风险教育的失败案例 #### 6.3 常用盘面指标 常用盘面指标反映博主做决策时关注哪些数据维度。 **技术指标类**: | 指标 | 关键词 | 适用场景 | |------|--------|----------| | MACD | MACD、金叉、死叉、红柱、绿柱 | 趋势判断 | | KDJ | KDJ、超买、超卖、金叉 | 短期择时 | | 均线 | MA5/MA10/MA20/MA60、均线多头/空头排列 | 趋势跟踪 | | 布林带 | BOLL、上轨、中轨、下轨 | 波动率判断 | | RSI | RSI、超买、超卖 | 动量判断 | | 成交量 | 放量、缩量、量价配合、地量 | 趋势确认 | **资金面指标类**: | 指标 | 关键词 | 适用场景 | |------|--------|----------| | 北向资金 | 北向、外资、陆股通 | 外资动向 | | 融资余额 | 融资、两融、杠杆 | 市场情绪 | | 主力资金 | 主力、大单、净流入/流出 | 资金流向 | | 龙虎榜 | 龙虎榜、游资、机构席位 | 机构动向 | | ETF申赎 | ETF、申购、赎回 | 机构配置 | **提取方法**: 1. 统计文章中各技术指标的出现频率 2. 分析博主使用指标的方式:是单指标决策还是多指标组合? 3. 关注指标的优先级:哪些指标是"主判断依据",哪些是"辅助确认"? 4. 分析指标使用的场景:不同市场环境下是否使用不同指标? #### 6.4 资金面关注 资金面关注揭示博主对市场资金流动的观察视角。 **资金面分析维度**: - **宏观流动性**:关注央行政策、利率变化、货币供应量 - **市场流动性**:关注成交量变化、融资余额、新基金发行 - **板块资金流**:关注行业ETF资金流、板块主力资金流向 - **个股资金流**:关注龙虎榜、大宗交易、股东变化 - **外资动向**:关注北向资金、QFII持仓变化 **提取方法**: 1. 统计资金面相关术语的出现频率 2. 分析博主对资金面的重视程度:是核心决策依据还是辅助参考? 3. 关注博主对资金面的解读方式:是正面解读(资金流入=看多)还是有更复杂的分析框架? ### 维度6产出标准 **必须输出**: - 核心赛道TOP5排名(含关注度分数) - 龙头记忆TOP10列表(含提及次数和关系类型) - 常用盘面指标TOP5(含使用场景) - 资金面关注度评估 **加分项**: - 赛道偏好的时间演变图 - 龙头记忆的更新频率分析 - 指标使用与市场环境的匹配关系 --- ## 维度7:人设基因DNA ### 定义与目标 人设基因DNA回答「TA是谁」这个问题。前6个维度描述的是博主"做什么"和"怎么做",而人设基因揭示的是"为什么"——为什么TA用这种方式投资?为什么TA关注这些赛道?为什么TA的表达风格是这样?人设基因是风格画像中最深层的部分,它让蒸馏产物从"技术模仿"升级为"人格模拟"。一个有血有肉的投资博主,不只有交易体系,还有投资经历、哲学演变、人生里程碑和精神导师。 ### 子维度详解 #### 7.1 投资经历 投资经历是博主人设的"底色",决定了TA的认知框架和行为模式。 **提取要点**: - **入市时间**:什么时候开始投资的?多少年投资经验? - **入市背景**:在什么市场环境下入市的?(牛市/熊市/震荡市) - **职业背景**:是否有金融/投资相关的职业背景?还是业余投资者? - **教育背景**:是否提及过学历/专业?与投资领域的关系? - **投资转型**:是否经历过投资方式的重大转型?(如从短线转长线、从股票转期货) - **全职/兼职**:是全职投资还是兼职?这影响投入程度和内容产出频率 **提取方法**: 1. 搜索博主的自我介绍/简介页面(置顶帖、个人简介、知识星球介绍) 2. 从文章中提取关于个人经历的表述("我刚开始炒股的时候..."、"当年入市...") 3. 从文章风格推断:是否有专业背景(使用专业术语的熟练程度) 4. 注意时间线:将分散在不同文章中的经历碎片拼成完整时间线 **可信度注意**: - 博主可能美化或夸大投资经历(如实际只有3年经验却声称10年) - 职业背景有时可通过分析深度间接推断,但不能确定 - 标注哪些是博主自述、哪些是AI推断 #### 7.2 投资哲学演变 投资哲学演变是博主人设中“最富戏剧性”的部分,揭示TA的思想成长轨迹。 **提取方法**: 1. 将全部文章按发布时间排序 2. 取最早 20% 和最近 20% 的文章 3. 对比两组文章的: - 高频关键词变化(如从"涨停"变为"估值") - 交易术语变化(如从短线术语变为长线术语) - 提及标的变化(如从妖股变为白马股) - 情绪基调变化(如从激进变为稳健) 4. 识别投资理念的显著变化节点: - 是否有“顿悟时刻”(某次重大亏损/盈利后的思想转变) - 是否有“渐进演变”(慢慢从一种风格转向另一种) - 是否有“回归”(回到早期的投资理念) **典型演变模式**: | 模式 | 特征 | 典型路径 | |------|------|----------| | 激进→稳健 | 早期追求高收益,后期追求稳定 | 短线打板→价值投资 | | 复杂→简单 | 早期研究复杂技术,后期回归简单 | 复杂指标系统→只关注几个核心指标 | | 技术→基本面 | 从技术分析转向基本面分析 | K线图→财务报表 | | 个股→宏观 | 从关注个股转向关注宏观趋势 | 个股分析→行业趋势→宏观解读 | | 独狼→社群 | 从独自投资转向社交化投资 | 闭门研究→开放分享→社群投资 | **时间线输出格式**: | 时期 | 投资理念 | 代表事件/文章 | 关键转变 | |------|---------|-------------|----------| | 早期(年份) | {理念} | {文章/事件} | {转变描述} | | 中期(年份) | {理念} | {文章/事件} | {转变描述} | | 近期(年份) | {理念} | {文章/事件} | {当前状态} | #### 7.3 里程碑事件 里程碑事件是博主人设中的"关键时刻",这些事件往往深刻影响其投资理念。 **常见里程碑类型**: | 类型 | 特征 | 典型表述 | |------|------|----------| | 重大亏损 | 公开提及的重大亏损经历 | "当年腰斩的教训"、"那次回撤让我..." | | 重大盈利 | 公开提及的重大成功 | "翻倍的那次"、"最满意的一笔投资" | | 市场危机 | 亲历的重大市场事件 | "2015年的股灾"、"2020年的疫情" | | 认知突破 | 突然领悟某个投资真理 | "我终于明白了..."、"那一刻我顿悟了" | | 转型时刻 | 投资风格的重大转变 | "从那天起我不再打板"、"开始价值投资" | | 人生转折 | 影响投资的人生事件 | "辞职全职炒股"、"孩子出生后更保守了" | **提取方法**: 1. 扫描文章中带有情感强度的个人经历描述 2. 关注“过去”、“当年”、“那时”、“以前”等时间回溯表述 3. 分析博主反复提及的事件(反复提及=重要里程碑) 4. 关注文章中的转折词(“但是”、“直到”、“从此”)后面的内容 5. 从里程碑事件中提炼博主的核心教训 #### 7.4 师承/影响源 师承/影响源揭示博主的精神导师和知识来源,是理解其投资框架的关键线索。 **师承/影响源识别关键词库**: | 类型 | 关键词 | |------|--------| | 价值投资大师 | 巴菲特、芒格、格雷厄姆、费雪、彼得林奇、段永平、李录 | | 投机/交易大师 | 索罗斯、利弗莫尔、杰西·利弗莫尔、艾迪·塞科塔 | | 宏观/周期 | 达利欧、霍华德马克斯、桥水、美林时钟 | | 书籍 | 《聪明的投资者》《穷查理宝典》《投资最重要的事》《股票大作手回忆录》 | | 思想概念 | 价值投资、护城河、安全边际、能力圈、反身性 | | 国内大V | 具体提及的国内投资博主/大V名称 | | 行业专家 | 具体提及的行业分析师/研究员名称 | **提取方法**: 1. 脚本自动扫描全量内容中的师承关键词 2. 统计各影响源的提及频率 3. 分析影响深度:是简单提及名字还是深入讨论其思想? 4. 识别“直接师承”(明确表示受某人影响)和“间接影响”(思想相似但未明确引用) 5. 分析影响源的组合:是单一师承还是多元融合? **影响源深度评估**: | 深度 | 特征 | 示例 | |------|------|------| | 深度师承 | 反复引用,思想深入融合 | "芒格的多元思维模型是我的核心框架" | | 明确影响 | 多次提及,认可其思想 | "受巴菲特影响,我更关注护城河" | | 浅层引用 | 偶尔提及,作为论据 | "就像格雷厄姆说的..." | | 间接影响 | 未明确提及但思想相似 | 风格类似某大师但未提及 | ### 维度7产出标准 **必须输出**: - 投资经历时间线(含关键节点) - 投资哲学演变分析(含早期/近期对比) - 里程碑事件列表(含事件描述和影响) - 师承/影响源排名(含提及频率和影响深度) **加分项**: - 博主投资哲学的内在逻辑图 - 里程碑事件与哲学转变的关联分析 - 与师承/影响源的思想传承关系图 --- ## 附录:维度间关联关系 七个维度不是孤立的,它们之间存在强关联。蒸馏时应关注以下跨维度一致性: | 关联对 | 一致性要求 | 不一致时的处理 | |---------|---------|----------------| | 交易体系 ↔ 市场判断 | 交易体系应与市场判断框架自洽 | 标注不一致,可能是言行不一 | | 交易体系 ↔ 热点图谱 | 短线应偏好活跃板块,长线应偏好确定性板块 | 标注异常,分析原因 | | 表达风格 ↔ 内容深度 | 表达风格应与内容深度匹配 | 可能是风格转型期 | | 表达风格 ↔ 互动特征 | 权威型语气应有更高战绩展示率 | 标注不一致 | | 人设基因 ↔ 交易体系 | 投资经历应能解释交易体系的选择 | 这是有价值的洞察点 | | 人设基因 ↔ 表达风格 | 师承影响应在表达风格中体现 | 可能是隐性影响 | | 市场判断 ↔ 内容深度 | 预判明确度应与复盘详细度匹配 | 可能是刻意模糊 | --- ## 附录:蒸馏质量准出标准 ### 硬性准出标准(蒸馏准确性校验) ```bash python "$SKILL_PATH/scripts/distill.py" --validate --author "博主名" --sample 15 ``` **三维度评分体系:** | 校验维度 | 说明 | 权重 | |---------|------|------| | A. 个股提及 | 画像声明的常提及个股是否在文章中真实出现 | 40% | | B. 风格特征 | 标志性表达、标题模式、开头/结尾模式、字数范围是否匹配 | 35% | | C. 投资体系 | 核心流派、持仓周期、板块偏好是否与文章一致 | 25% | **准出标准:综合准确率 ≥ 80%** - ≥ 80%:蒸馏通过,画像可用于风格模拟 - < 80%:需补充蒸馏——仔细阅读raw全文,更新画像中不准确的字段后重新校验 - 任一维度低于60%:该维度需要完全重写 ### 软性质量检查 | 检查项 | 通过标准 | 权重 | |--------|---------|------| | 标志性表达命中率 | > 40% | 15% | | 交易体系覆盖度 | > 70% | 15% | | 文章结构匹配度 | > 60% | 10% | | 盘面指标覆盖 | > 50% | 10% | | 语气一致性 | 偏差 < 20% | 10% | | 字数范围 | ±30% | 5% | | 交易术语覆盖 | > 50% | 10% | | 人设一致性 | 背景/哲学/里程碑无矛盾 | 13% | **综合评分 > 70 分准出(软性),< 70 分打回重新蒸馏。** ### 校验执行规则 - **每次画像更新后**必须执行校验 - **每月**全量校验所有博主画像 - 增量同步获取新文章后,如新文章涉及画像未覆盖的个股/板块,需更新画像
-
-
scripts
-
distill.py 60.4 KB
#!/usr/bin/env python3 """ 公众号投资博主蒸馏器 — 主脚本 ================================== 通过公众号文章数据,执行七维DNA蒸馏。 Usage: python distill.py --account "zshbtz" --count 60 python distill.py --account "zshbtz" --author "财躺平" --count 100 python distill.py --validate --author "财躺平" --sample 15 python distill.py --check-env """ import argparse import json import os import re import sys from collections import Counter, defaultdict from datetime import datetime from pathlib import Path # Windows 控制台 UTF-8 编码 if sys.platform == 'win32': sys.stdout.reconfigure(encoding='utf-8', errors='replace') sys.stderr.reconfigure(encoding='utf-8', errors='replace') # ─── 配置 ───────────────────────────────────────────────────────────────────────── SCRIPT_DIR = Path(__file__).parent.parent OUTPUT_DIR = SCRIPT_DIR / "output" # ─── 终端颜色 ────────────────────────────────────────────────────────────────────── GREEN = "\033[92m" YELLOW = "\033[93m" RED = "\033[91m" CYAN = "\033[96m" BOLD = "\033[1m" RESET = "\033[0m" def info(msg): print(f"{GREEN}[✓]{RESET} {msg}") def warn(msg): print(f"{YELLOW}[!]{RESET} {msg}") def error(msg): print(f"{RED}[✗]{RESET} {msg}") def step(msg): print(f"{CYAN}[→]{RESET} {msg}") # ─── 环境检查 ────────────────────────────────────────────────────────────────────── def check_env(): """检查依赖环境""" info("环境检查中...") issues = [] try: import requests info("requests 已就绪") except ImportError: warn("缺少 requests,正在安装...") os.system(f"{sys.executable} -m pip install requests") try: import requests info("requests 安装成功") except ImportError: error("requests 安装失败") issues.append("requests") # 检查 API Key from gzh import get_api_key key = get_api_key() if key: info(f"API Key 已配置({key[:8]}...)") else: error("未找到 API Key,请先配置 REDFOX_API_KEY") error("获取: https://redfox.hk/settings/api-keys?source=github") issues.append("REDFOX_API_KEY") OUTPUT_DIR.mkdir(parents=True, exist_ok=True) info(f"输出目录: {OUTPUT_DIR}") if issues: error(f"仍有依赖缺失: {', '.join(issues)}") return False info("环境检查通过") return True # ─── 文本预处理 ──────────────────────────────────────────────────────────────────── def clean_text(text): """清洗文本""" if not text: return "" text = str(text) text = re.sub(r'<[^>]+>', '', text) text = re.sub(r' ', ' ', text) text = re.sub(r'&', '&', text) text = re.sub(r'<', '<', text) text = re.sub(r'>', '>', text) text = re.sub(r'\n{3,}', '\n\n', text) return text.strip() def split_paragraphs(text): """分段""" if not text: return [] return [p.strip() for p in text.split('\n') if p.strip()] # ─── 核心词典(蒸馏质量关键:必须从raw全文逐篇提取,禁止依赖clean中间层) ────── # 股票/指数词典:标准名 → [别名列表](别名用于宽松匹配,覆盖口语化表达) STOCK_DICT = { # 指数 "上证指数": ["上证", "沪指", "大盘", "A股"], "创业板指": ["创业板", "创业板指"], "中证500": ["中证500"], "沪深300": ["沪深300"], "科创50": ["科创50", "科创板"], "中证1000": ["中证1000"], "纳斯达克": ["纳斯达克", "纳指"], "标普500": ["标普500", "标普"], "恒生指数": ["恒生", "恒指"], "恒生科技": ["恒生科技"], # A股龙头 "贵州茅台": ["茅台", "贵州茅台"], "五粮液": ["五粮液"], "美的": ["美的集团", "美的"], "格力": ["格力", "格力电器"], "中国平安": ["平安", "中国平安"], "宁德时代": ["宁德", "宁德时代"], "比亚迪": ["比亚迪"], "长江电力": ["长江电力", "长电"], "寒武纪": ["寒武纪"], "中芯国际": ["中芯", "中芯国际"], "中际旭创": ["中际旭创", "旭创"], # 港股/美股 "腾讯": ["腾讯"], "阿里巴巴": ["阿里", "阿里巴巴"], "美团": ["美团"], "京东": ["京东"], "小米": ["小米"], "百度": ["百度"], "英伟达": ["英伟达", "NVIDIA"], "苹果": ["苹果", "Apple"], "特斯拉": ["特斯拉", "Tesla"], "谷歌": ["谷歌", "Google"], "微软": ["微软", "Microsoft"], "Meta": ["Meta", "Facebook"], "台积电": ["台积电", "TSMC"], "美光": ["美光", "Micron"], # 其他 "华为": ["华为"], "字节跳动": ["字节", "字节跳动", "抖音"], "拼多多": ["拼多多", "PDD"], } # 投资关键短语(领域专用,比通用句子频次更精准) INVESTMENT_PHRASES = [ # 估值/价值 "估值", "安全边际", "内在价值", "护城河", "价值投资", "基本面", "财报", "分红", "股息率", "ROE", "PE", "PB", "自由现金流", "市盈率", "市净率", # 趋势/技术 "趋势", "钝化", "均线", "支撑", "压力", "突破", "回调", "反弹", "放量", "缩量", "涨停", "跌停", "连板", "龙头", "妖股", # 操作 "仓位", "加仓", "减仓", "止损", "止盈", "建仓", "清仓", "定投", "急涨不追", "急跌不抄底", "追高", "抄底", # 宏观 "美联储", "利率", "关税", "通胀", "降息", "加息", "流动性", "地缘政治", "中美", "制裁", # 产业链 "产业链", "景气", "周期", "拐点", "国产替代", "算力", "AI", "人工智能", "半导体", "芯片", "新能源", "光伏", "储能", "商业航天", "卫星", "光通信", "存储", # 哲学/认知 "认知", "慢慢变富", "道法自然", "逆向", "周期会来的", "长期主义", "复利", "贪婪", "恐惧", "知足常乐", # 市场情绪 "恐慌", "贪婪", "情绪", "人声鼎沸", "共识", "关注度", "量化", "ETF", "指数基金", "散户", "机构", ] # 板块关键词映射(用于文章级别计数) SECTOR_KEYWORDS = { "AI/人工智能": ["AI", "人工智能", "大模型", "GPT", "算力", "Agent", "ChatGPT"], "半导体/芯片": ["半导体", "芯片", "光刻", "中芯", "台积电", "制程", "封装"], "商业航天/卫星": ["航天", "卫星", "火箭", "商业航天", "星链", "太空", "低轨"], "新能源": ["新能源", "光伏", "风电", "储能", "锂电", "充电桩", "碳中和"], "金融/银行": ["银行", "券商", "保险", "金融", "信贷"], "消费/白酒": ["消费", "白酒", "食品", "零售", "茅台", "五粮液", "品牌"], "煤炭/资源": ["煤炭", "资源", "矿业", "铜", "锂", "稀土"], "房地产": ["房地产", "楼市", "房价", "开发商", "物业"], "医药": ["医药", "医疗", "创新药", "生物科技", "CXO"], "光通信": ["光通信", "光模块", "光纤", "CPO", "硅光"], "存储": ["存储", "DRAM", "NAND", "HBM", "闪存"], "军工": ["军工", "国防", "装备", "导弹"], "机器人": ["机器人", "人形机器人", "减速器", "伺服"], "脑机接口": ["脑机", "Neuralink", "脑科学"], "核聚变": ["核聚变", "可控核", "托卡马克"], } # 个股识别正则(中文股票名称模式 — 捕获词典外的个股,补充STOCK_DICT) STOCK_NAME_PATTERN = re.compile( r'(?:中国|中|国|华|南|北|东|西|新|大|上|深|长|广|江|浙|海|天|金|银|龙|凤|' r'安|宝|富|恒|嘉|美|高|万|百|千|红|蓝|绿|紫|星|光|明|达|利|通|信|科|泰|' r'航|发|沈|成|西|赣|鲁|闽|川|渝|鄂|湘|皖|豫|冀|辽|吉|黑)[\u4e00-\u9fff]{1,5}' r'(?:股份|科技|电子|集团|控股|材料|设备|能源|动力|智能|芯片|生物|药业|' r'化工|机械|光电|信息|通信|网络|软件|互联|新材|环保|装备|工业|精密|' r'电气|自动化|仪器|仪表|航空|航天|船舶|重工)' ) # 短线信号词(蒸馏用:情绪周期/辨识度/卡位等短线专有术语) SHORT_SIGNAL_KW = [ "涨停", "连板", "龙头", "资金流入", "主力买入", "封板", "竞价", "炸板", "反包", "首板", "二板", "三板", "妖股", "情绪", "辨识度", "卡位", "补涨", "加速", "打板", "游资", "龙虎榜", "复盘", "盘面", "资金流向", "止损", ] # 长线/基本面指标词(蒸馏用:财务报表和估值分析术语) FINANCIAL_METRICS_KW = [ "护城河", "ROE", "净利润", "毛利率", "自由现金流", "估值", "PE", "PB", "分红", "回购", "业绩增长", "核心竞争力", "市场份额", "研发", "壁垒", "内在价值", "市盈率", "市净率", "股息率", "营收增长", "净利率", "ROA", "资产负债率", ] # 投资格言/金句关键词(用于提取哲理性表达) WISDOM_INDICATORS = [ "道", "禅", "悟", "哲学", "认知", "智慧", "思维", "格局", "长期", "耐心", "时间", "复利", "慢慢", "变富", "恐惧", "贪婪", "纪律", "原则", "底线", ] # ─── 统计分析(基于raw全文逐篇提取) ────────────────────────────────────────────── def analyze_articles(articles: list, author_name: str) -> dict: """ 统计分析文章数据。 核心原则:必须从raw全文逐篇提取,不依赖任何clean/NER中间层。 """ stats = { "author": author_name, "total_articles": len(articles), "analysis_time": datetime.now().isoformat(), } # 1. 基础统计(含精确字数) word_counts = [] publish_dates = [] all_contents = [] for a in articles: content = clean_text(a.get("content", "") or a.get("正文", "")) title = a.get("title", "") or a.get("标题", "") pub_time = a.get("publish_time", "") or a.get("发布时间", "") wc = len(content) word_counts.append(wc) all_contents.append({ "title": title, "content": content, "publish_time": pub_time, "word_count": wc, }) if pub_time: publish_dates.append(str(pub_time)[:10]) sorted_wc = sorted(word_counts) stats["word_count"] = { "avg": round(sum(word_counts) / len(word_counts), 0) if word_counts else 0, "min": min(word_counts) if word_counts else 0, "max": max(word_counts) if word_counts else 0, "median": sorted_wc[len(sorted_wc) // 2] if word_counts else 0, } # 2. 发布频率 if publish_dates: date_counter = Counter(publish_dates) stats["publish_frequency"] = { "total_days": len(date_counter), "avg_per_day": round(len(articles) / max(len(date_counter), 1), 1), "most_active_date": date_counter.most_common(1)[0] if date_counter else None, } # 3. 内容关键词聚合(API 字段: contentKeywords,非 wordCloud) ck_agg = Counter() for a in articles: ck = a.get("content_keywords", []) if isinstance(ck, list): for item in ck: if isinstance(item, dict): ck_agg[item.get("keyword", "")] += item.get("weight", 1.0) stats["top_keywords"] = [{"keyword": k, "weight": round(v, 2)} for k, v in ck_agg.most_common(30)] # 4. 个股/指数频次提取(词典+别名+正则双通道,含上下文和复合评分) stock_counter = Counter() stock_context = defaultdict(list) # 个股 → 相关文章标题列表 for a in all_contents: text = f"{a['title']} {a['content']}" title_short = a['title'][:60] if a['title'] else "" # 通道A:词典+别名匹配(精确,含口语化别名) for stock_name, aliases in STOCK_DICT.items(): if any(alias.lower() in text.lower() for alias in aliases): stock_counter[stock_name] += 1 if title_short: stock_context[stock_name].append(title_short) # 通道B:正则模式匹配(捕获词典外的个股全称) regex_matches = STOCK_NAME_PATTERN.findall(text) for m in regex_matches: if len(m) >= 3: # 排除已被词典覆盖的个股 already_covered = any(m == sn or m in aliases for sn, aliases in STOCK_DICT.items()) if not already_covered: stock_counter[m] += 1 if title_short: stock_context[m].append(title_short) # 复合评分:提及频率 + 短线/长线关键词上下文权重 stock_scores = {} for stock, count in stock_counter.items(): contexts = stock_context.get(stock, []) context_text = " ".join(contexts) # 基础分 = 提及次数 score = count # 短线信号加分(出现短线术语说明该个股有短线关注价值) score += sum(1 for kw in SHORT_SIGNAL_KW if kw in context_text) # 长线指标加分(出现基本面术语说明该个股有长线分析深度) score += sum(2 for kw in FINANCIAL_METRICS_KW if kw in context_text) stock_scores[stock] = score # 输出:按复合评分排序,保留上下文 top_stocks = sorted(stock_scores.items(), key=lambda x: x[1], reverse=True)[:30] stats["stock_mentions"] = [ {"stock": s, "count": stock_counter[s], "score": sc, "ratio": round(stock_counter[s] / max(len(articles), 1), 2), "sample_titles": stock_context.get(s, [])[:3]} for s, sc in top_stocks ] # 正则发现的词典外个股(供AI审查是否有重要遗漏) dict_stocks = set(STOCK_DICT.keys()) regex_discovered = [ {"stock": s, "count": stock_counter[s], "sample_titles": stock_context.get(s, [])[:2]} for s, _ in top_stocks if s not in dict_stocks ][:10] stats["regex_discovered_stocks"] = regex_discovered # 5. 板块文章级计数(每篇只计一次) sector_article_counts = {} for sector, kws in SECTOR_KEYWORDS.items(): count = sum( 1 for a in all_contents if any(kw in f"{a['title']} {a['content']}" for kw in kws) ) if count > 0: sector_article_counts[sector] = count stats["sector_focus"] = dict( sorted(sector_article_counts.items(), key=lambda x: x[1], reverse=True) ) # 6. 投资关键短语提取 phrase_counter = Counter() for a in all_contents: text = f"{a['title']} {a['content']}" for phrase in INVESTMENT_PHRASES: c = text.count(phrase) if c > 0: phrase_counter[phrase] += c stats["investment_phrases"] = [ {"phrase": p, "count": c} for p, c in phrase_counter.most_common(40) ] # 7. 交易类型判定(使用扩充的SHORT_SIGNAL_KW + FINANCIAL_METRICS_KW) long_kw = list(set(FINANCIAL_METRICS_KW + [ "价值投资", "基本面", "财报", "持有", "长期", "安全边际", "定投", "生意", "核心竞争力", "业绩增长", ])) short_kw = list(set(SHORT_SIGNAL_KW + [ "跌停", "封板", "炸板", "反包", "首板", "二板", "三板", "卡位", "补涨", "加速", "辨识度", ])) long_count = sum(a["content"].count(kw) for a in all_contents for kw in long_kw) short_count = sum(a["content"].count(kw) for a in all_contents for kw in short_kw) stats["trader_type"] = { "long_score": long_count, "short_score": short_count, "classified_type": "长线" if long_count > short_count * 1.5 else ("短线" if short_count > long_count * 1.5 else "混合"), } # 8. 标志性表达提取 phrase_counter_sig = Counter() for a in all_contents: sentences = re.split(r'[。!?\n]', a["content"]) for s in sentences: s = s.strip() if 4 <= len(s) <= 30: phrase_counter_sig[s] += 1 stats["signature_phrases"] = [ {"phrase": p, "count": c} for p, c in phrase_counter_sig.most_common(50) if c >= 2 ][:20] # 8b. 投资格言/金句提取 wisdom_phrases = [] for p, c in phrase_counter_sig.most_common(100): if any(ind in p for ind in WISDOM_INDICATORS) and c >= 2: wisdom_phrases.append({"phrase": p, "count": c}) stats["investment_wisdom"] = wisdom_phrases[:15] # 9. 文章结构分析 + 开头/结尾/标题模式检测 structures = [] opening_patterns = Counter() closing_patterns = Counter() for a in all_contents: paragraphs = split_paragraphs(a["content"]) if not paragraphs: continue opening = paragraphs[0][:100] closing = paragraphs[-1][:100] if len(paragraphs) > 1 else "" if "免责" in opening: opening_patterns["免责声明开头"] += 1 if "今天" in opening[:10]: opening_patterns["今日盘面开头"] += 1 if "免责" in closing or "风险" in closing or "投资需谨慎" in closing: closing_patterns["风险/免责结尾"] += 1 if "链接" in closing or "星标" in closing or "关注" in closing: closing_patterns["引导关注结尾"] += 1 structures.append({ "title": a["title"], "para_count": len(paragraphs), "opening": opening, "closing": closing, "word_count": a["word_count"], "publish_time": a["publish_time"], }) stats["article_structures"] = structures[:20] stats["opening_patterns"] = dict(opening_patterns.most_common(5)) stats["closing_patterns"] = dict(closing_patterns.most_common(5)) # 10. 标题模式分析 title_patterns = {"疑问句": 0, "感叹句": 0, "陈述句": 0, "数字开头": 0} title_format_counter = Counter() for a in all_contents: t = a.get("title", "") if t: if "?" in t or "?" in t: title_patterns["疑问句"] += 1 elif "!" in t or "!" in t: title_patterns["感叹句"] += 1 else: title_patterns["陈述句"] += 1 if t[0].isdigit(): title_patterns["数字开头"] += 1 if len(t) > 6: prefix = re.sub(r'[((].+?[))]', '', t)[:8] title_format_counter[prefix] += 1 stats["title_patterns"] = title_patterns stats["title_format_templates"] = [ {"prefix": p, "count": c} for p, c in title_format_counter.most_common(5) if c >= 3 ] # 11. 交易术语统计(整合SHORT_SIGNAL_KW + FINANCIAL_METRICS_KW + 操作术语) trading_terms = list(set( SHORT_SIGNAL_KW + FINANCIAL_METRICS_KW + [ "情绪周期", "止盈", "仓位", "满仓", "清仓", "减仓", "加仓", "建仓", "空仓", "做多", "做空", "牛市", "熊市", "震荡", "放量", "缩量", "突破", "回调", "反弹", "趋势", "支撑", "压力", "均线", "K线", "MACD", "量价", "换手率", "成交额", "市值", "基本面", "技术面", "资金面", "消息面", "板块轮动", ] )) term_counter = Counter() for a in all_contents: for term in trading_terms: c = a["content"].count(term) if c > 0: term_counter[term] += c stats["trading_terms"] = [{"term": t, "count": c} for t, c in term_counter.most_common(30)] # 12. 免责声明检测 disclaimer_kw = ["免责声明", "不构成", "投资建议", "个人日记", "个人笔记", "理财需谨慎", "投资有风险"] dc = sum(1 for a in all_contents if any(kw in a["content"] for kw in disclaimer_kw)) stats["has_disclaimer"] = {"count": dc, "ratio": round(dc / max(len(articles), 1), 2)} # 13. 师承/影响源扫描 mentor_kw = { "巴菲特": ["巴菲特", "伯克希尔"], "芒格": ["芒格", "穷查理"], "段永平": ["段永平"], "李录": ["李录"], "格雷厄姆": ["格雷厄姆", "聪明的投资者"], "彼得林奇": ["彼得林奇", "林奇"], "索罗斯": ["索罗斯", "反身性"], "达利欧": ["达利欧", "原则"], "霍华德马克斯": ["霍华德", "马克斯", "投资最重要的事"], } mentor_scores = {} for mentor, kws in mentor_kw.items(): score = sum(a["content"].count(kw) for a in all_contents for kw in kws) if score > 0: mentor_scores[mentor] = score stats["mentor_influence"] = dict(sorted(mentor_scores.items(), key=lambda x: x[1], reverse=True)) # 14. 语气量化分析(感叹句/疑问句/第一人称/口语化 四类标记) tone_markers = { "感叹句": 0, "疑问句": 0, "第一人称": 0, "口语化": 0, } for a in all_contents: c = a["content"] tone_markers["感叹句"] += len(re.findall(r'[!!]', c)) tone_markers["疑问句"] += len(re.findall(r'[??]', c)) tone_markers["第一人称"] += len(re.findall(r'我[们]?', c)) tone_markers["口语化"] += len(re.findall(r'[吧呢啊嘛哦哈嘿哟啦哇]', c)) # 归一化为每篇平均 n = max(len(articles), 1) tone_avg = {k: round(v / n, 1) for k, v in tone_markers.items()} total_tone = sum(tone_markers.values()) if total_tone > n * 10: tone_style = "强语气型" elif total_tone > n * 3: tone_style = "中等语气型" else: tone_style = "冷静克制型" stats["tone_analysis"] = { "markers_total": tone_markers, "per_article_avg": tone_avg, "tone_style": tone_style, } # 15. 论证链模式提取(检测博主特有的分析推理路径) # 常见论证模式标记词 arg_patterns = { "事件驱动型": ["消息", "事件", "突发", "利好", "利空", "催化", "政策", "发布"], "数据驱动型": ["数据", "财报", "营收", "利润", "增长率", "同比", "环比", "出货量"], "逻辑推演型": ["因此", "所以", "导致", "意味着", "由此可见", "逻辑是", "推导"], "类比推理型": ["类似", "参照", "对比", "历史", "上一轮", "复盘", "如同"], "产业链分析型": ["产业链", "上下游", "景气度", "传导", "供需", "产能", "订单"], "逆向思维型": ["反过来", "逆向", "反直觉", "大多数人", "相反", "市场错了"], } arg_scores = {} for pattern_name, kws in arg_patterns.items(): score = sum(a["content"].count(kw) for a in all_contents for kw in kws) if score > 0: arg_scores[pattern_name] = score stats["argumentation_style"] = dict( sorted(arg_scores.items(), key=lambda x: x[1], reverse=True) ) # 16. 核心分析工具识别(博主用什么思维框架分析市场) thinking_tools = { "宏观经济分析": ["GDP", "PMI", "CPI", "PPI", "利率", "美联储", "货币政策", "财政政策"], "产业链研究": ["产业链", "上下游", "景气度", "产能", "供需格局", "行业格局"], "财务报表分析": ["财报", "营收", "净利润", "毛利率", "现金流", "ROE", "负债"], "技术面分析": ["K线", "MACD", "均线", "支撑", "压力", "趋势", "量价", "突破"], "资金面分析": ["北向资金", "主力资金", "融资余额", "资金流向", "龙虎榜", "机构"], "情绪周期分析": ["情绪", "周期", "高潮", "冰点", "退潮", "修复", "分歧", "一致"], "全球对标分析": ["美股", "纳斯达克", "标普", "英伟达", "台积电", "全球", "海外"], "政策面分析": ["政策", "监管", "制裁", "关税", "补贴", "规划", "纲要"], } tool_scores = {} for tool_name, kws in thinking_tools.items(): score = sum(a["content"].count(kw) for a in all_contents for kw in kws) if score > 0: tool_scores[tool_name] = score stats["thinking_tools"] = dict( sorted(tool_scores.items(), key=lambda x: x[1], reverse=True) ) # 17. 数据引用密度(区分"数据驱动型"和"主观判断型"博主) data_ref_kws = [ "数据", "财报", "同比", "环比", "增长", "下降", "%", "营收", "利润", "出货量", "产能", "利用率", "订单", "库存", "价格指数", "成交额", "万亿", "千亿", "百亿", "亿元", ] data_ref_count = sum( a["content"].count(kw) for a in all_contents for kw in data_ref_kws ) total_chars = sum(a["word_count"] for a in all_contents) data_density = round(data_ref_count / max(total_chars, 1) * 1000, 2) # 每千字数据引用次数 if data_density > 5: data_style = "高密度数据驱动型" elif data_density > 2: data_style = "中等数据引用型" else: data_style = "主观判断型" stats["data_citation"] = { "total_refs": data_ref_count, "density_per_1k": data_density, "data_style": data_style, } # 18. 跨市场视角检测(是否关注全球市场联动) cross_market_kws = { "美股": ["美股", "纳斯达克", "标普", "道琼斯", "美联储", "英伟达", "苹果", "特斯拉", "谷歌", "微软"], "港股": ["港股", "恒生", "恒指", "恒生科技", "南向资金"], "A股": ["A股", "上证", "深证", "创业板", "科创板"], "商品/汇率": ["黄金", "原油", "美元", "人民币", "汇率", "铜", "锂"], } cross_market = {} for market, kws in cross_market_kws.items(): count = sum(a["content"].count(kw) for a in all_contents for kw in kws) if count > 0: cross_market[market] = count # 跨市场广度:涉及几个市场 cross_breadth = len(cross_market) stats["cross_market"] = { "markets": dict(sorted(cross_market.items(), key=lambda x: x[1], reverse=True)), "breadth": cross_breadth, "perspective": "全球视角" if cross_breadth >= 3 else ("多市场" if cross_breadth >= 2 else "单一市场"), } # 19. 信息密度评估(投资分析内容占比,区分干货型和水文型) investment_content_kws = list(set( SHORT_SIGNAL_KW + FINANCIAL_METRICS_KW + [ "估值", "仓位", "板块", "赛道", "龙头", "趋势", "基本面", "技术面", "资金面", "消息面", "产业链", "景气", "周期", ] )) inv_content_count = sum( a["content"].count(kw) for a in all_contents for kw in investment_content_kws ) info_density = round(inv_content_count / max(total_chars, 1) * 1000, 2) # 每千字投资内容密度 if info_density > 10: info_level = "高信息密度(投资分析占比80%+)" elif info_density > 5: info_level = "中等信息密度(投资分析占比50-80%)" else: info_level = "低信息密度(生活/闲聊/引流内容较多)" stats["information_density"] = { "investment_refs": inv_content_count, "density_per_1k": info_density, "level": info_level, } # 20. 互动数据统计(API 直接返回,非正文推断) engagement = { "read_avg": 0, "read_max": 0, "read_total": 0, "like_avg": 0, "like_max": 0, "like_total": 0, "comment_avg": 0, "comment_total": 0, "share_avg": 0, "share_total": 0, "collect_avg": 0, "collect_total": 0, "reward_total": 0, "engagement_rate": 0, # 互动率 = (点赞+评论+转发) / 阅读 } if all_contents: reads = [a.get("read_count", 0) or 0 for a in articles] likes = [a.get("like_count", 0) or 0 for a in articles] comments = [a.get("comment_count", 0) or 0 for a in articles] shares = [a.get("share_count", 0) or 0 for a in articles] collects = [a.get("collect_count", 0) or 0 for a in articles] rewards = [a.get("reward_count", 0) or 0 for a in articles] n = len(articles) engagement["read_avg"] = round(sum(reads) / n, 0) engagement["read_max"] = max(reads) engagement["read_total"] = sum(reads) engagement["like_avg"] = round(sum(likes) / n, 0) engagement["like_max"] = max(likes) engagement["like_total"] = sum(likes) engagement["comment_avg"] = round(sum(comments) / n, 0) engagement["comment_total"] = sum(comments) engagement["share_avg"] = round(sum(shares) / n, 0) engagement["share_total"] = sum(shares) engagement["collect_avg"] = round(sum(collects) / n, 0) engagement["collect_total"] = sum(collects) engagement["reward_total"] = sum(rewards) total_reads = engagement["read_total"] or 1 engagement["engagement_rate"] = round( (engagement["like_total"] + engagement["comment_total"] + engagement["share_total"]) / total_reads * 100, 2 ) # 互动层级判定 er = engagement["engagement_rate"] if er > 5: engagement["level"] = "极高互动(粉丝粘性极强)" elif er > 2: engagement["level"] = "高互动(活跃粉丝群体)" elif er > 1: engagement["level"] = "中等互动" else: engagement["level"] = "低互动(阅读量大但互动少)" stats["engagement"] = engagement return stats # ─── 生成数据底稿和蒸馏任务 ────────────────────────────────────────────────────────── def generate_brief(stats, author_name): """生成数据底稿""" lines = [] lines.append(f"# {author_name} 蒸馏数据底稿") lines.append(f"\n> 生成时间:{stats.get('analysis_time', '')}") lines.append(f"> 内容总数:{stats['total_articles']} 篇\n") lines.append("## 1. 基础统计\n") wc = stats.get("word_count", {}) lines.append(f"- 平均字数:{wc.get('avg', 0)}") lines.append(f"- 最短/最长:{wc.get('min', 0)} / {wc.get('max', 0)}") lines.append(f"- 中位数:{wc.get('median', 0)}\n") pf = stats.get("publish_frequency", {}) lines.append("## 2. 发布频率\n") lines.append(f"- 发布天数:{pf.get('total_days', 0)}") lines.append(f"- 日均发文:{pf.get('avg_per_day', 0)} 篇\n") tt = stats.get("trader_type", {}) lines.append("## 3. 交易类型判定\n") lines.append(f"- 长线关键词得分:{tt.get('long_score', 0)}") lines.append(f"- 短线关键词得分:{tt.get('short_score', 0)}") lines.append(f"- 判定结果:**{tt.get('classified_type', '未知')}**\n") lines.append("## 4. 个股/指数提及排行 TOP20(复合评分 = 提及频率 + 上下文关键词权重)\n") lines.append("| 个股 | 提及次数 | 综合评分 | 占比 | 相关文章 |") lines.append("|------|---------|---------|------|---------|") for s in stats.get("stock_mentions", [])[:20]: titles = "、".join(s.get("sample_titles", [])[:2]) lines.append(f"| {s['stock']} | {s['count']} | {s['score']} | {s['ratio']:.0%} | {titles} |") lines.append("") # 正则发现的词典外个股(重要补充信息) regex_stocks = stats.get("regex_discovered_stocks", []) if regex_stocks: lines.append("### 正则发现的词典外个股(AI审查是否有重要遗漏)\n") for s in regex_stocks: titles = "、".join(s.get("sample_titles", [])[:2]) lines.append(f"- **{s['stock']}**({s['count']}次)相关文章:{titles}") lines.append("") lines.append("## 5. 板块关注度(文章级计数)\n") for sector, count in stats.get("sector_focus", {}).items(): ratio = count / max(stats['total_articles'], 1) lines.append(f"- {sector}:{count}篇({ratio:.0%})") lines.append("") lines.append("## 6. 投资关键短语 TOP30\n") for p in stats.get("investment_phrases", [])[:30]: lines.append(f"- {p['phrase']}({p['count']}次)") lines.append("") lines.append("## 7. 标志性表达 TOP15\n") for p in stats.get("signature_phrases", [])[:15]: lines.append(f"- 「{p['phrase']}」出现 {p['count']} 次") lines.append("") lines.append("## 8. 投资格言/金句\n") wisdom = stats.get("investment_wisdom", []) if wisdom: for p in wisdom[:10]: lines.append(f"- 「{p['phrase']}」出现 {p['count']} 次") else: lines.append("- 未检测到高频投资格言") lines.append("") lines.append("## 9. 交易术语使用频率 TOP20\n") for t in stats.get("trading_terms", [])[:20]: lines.append(f"- {t['term']}({t['count']}次)") lines.append("") lines.append("## 10. 标题模式分析\n") for k, v in stats.get("title_patterns", {}).items(): lines.append(f"- {k}:{v}") templates = stats.get("title_format_templates", []) if templates: lines.append("\n**固定格式模板:**") for t in templates: lines.append(f"- 「{t['prefix']}...」({t['count']}次)") lines.append("") lines.append("## 11. 开头/结尾模式\n") op = stats.get("opening_patterns", {}) if op: lines.append("**开头模式:**") for k, v in op.items(): lines.append(f"- {k}:{v}篇") cp = stats.get("closing_patterns", {}) if cp: lines.append("\n**结尾模式:**") for k, v in cp.items(): lines.append(f"- {k}:{v}篇") lines.append("") hd = stats.get("has_disclaimer", {}) lines.append(f"## 12. 免责声明\n") lines.append(f"- 含免责声明:{hd.get('count', 0)}/{stats['total_articles']}({hd.get('ratio', 0):.0%})\n") mi = stats.get("mentor_influence", {}) lines.append("## 13. 师承/影响源\n") if mi: for mentor, score in mi.items(): lines.append(f"- {mentor}(提及{score}次)") else: lines.append("- 未检测到明显师承影响") lines.append("") lines.append("## 14. 高频关键词 TOP20\n") for kw in stats.get("top_keywords", [])[:20]: lines.append(f"- {kw['keyword']}(权重:{kw['weight']})") lines.append("") lines.append("## 15. 内容结构样本(前5篇)\n") for s in stats.get("article_structures", [])[:5]: lines.append(f"### {s['title']}") lines.append(f"- 段落数:{s['para_count']}") lines.append(f"- 字数:{s['word_count']}") lines.append(f"- 开头:{s['opening'][:80]}...") lines.append(f"- 结尾:{s['closing'][:80]}...") lines.append("") # ── 互动数据(API数值,非正文推断)── eg = stats.get("engagement", {}) if eg: lines.append("## 互动数据统计\n") lines.append(f"- 篇均阅读:{eg.get('read_avg', 0):.0f}(最高 {eg.get('read_max', 0)})") lines.append(f"- 篇均点赞:{eg.get('like_avg', 0):.0f}(最高 {eg.get('like_max', 0)})") lines.append(f"- 篇均评论:{eg.get('comment_avg', 0):.0f}") lines.append(f"- 篇均转发:{eg.get('share_avg', 0):.0f}") lines.append(f"- 篇均收藏:{eg.get('collect_avg', 0):.0f}") lines.append(f"- 互动率:{eg.get('engagement_rate', 0)}%") lines.append(f"- 互动层级:**{eg.get('level', '未知')}**") lines.append("") # ── 思维层分析维度(16-21)── lines.append("---\n") lines.append("## 16. 语气量化分析\n") tone = stats.get("tone_analysis", {}) markers = tone.get("markers_total", {}) avg = tone.get("per_article_avg", {}) if markers: lines.append(f"- 风格分类:**{tone.get('tone_style', '未知')}**") lines.append(f"- 感叹句:{markers.get('感叹句', 0)}(篇均{avg.get('感叹句', 0)})") lines.append(f"- 疑问句:{markers.get('疑问句', 0)}(篇均{avg.get('疑问句', 0)})") lines.append(f"- 第一人称:{markers.get('第一人称', 0)}(篇均{avg.get('第一人称', 0)})") lines.append(f"- 口语化:{markers.get('口语化', 0)}(篇均{avg.get('口语化', 0)})") lines.append("") lines.append("## 17. 论证链模式(博主特有推理路径)\n") arg = stats.get("argumentation_style", {}) if arg: for pattern, score in arg.items(): lines.append(f"- **{pattern}**:{score}分") else: lines.append("- 未检测到明显论证模式偏好") lines.append("") lines.append("## 18. 核心分析工具(思维框架)\n") tools = stats.get("thinking_tools", {}) if tools: for tool, score in tools.items(): lines.append(f"- **{tool}**:{score}分") else: lines.append("- 未检测到明确思维框架") lines.append("") lines.append("## 19. 数据引用密度\n") dc = stats.get("data_citation", {}) if dc: lines.append(f"- 风格分类:**{dc.get('data_style', '未知')}**") lines.append(f"- 总引用次数:{dc.get('total_refs', 0)}") lines.append(f"- 每千字数据引用:{dc.get('density_per_1k', 0)}次") lines.append("") lines.append("## 20. 跨市场视角\n") cm = stats.get("cross_market", {}) if cm: lines.append(f"- 视角分类:**{cm.get('perspective', '未知')}**(涉及{cm.get('breadth', 0)}个市场)") for market, count in cm.get("markets", {}).items(): lines.append(f"- {market}:{count}次提及") lines.append("") lines.append("## 21. 信息密度评估\n") info = stats.get("information_density", {}) if info: lines.append(f"- 密度等级:**{info.get('level', '未知')}**") lines.append(f"- 投资关键词总量:{info.get('investment_refs', 0)}") lines.append(f"- 每千字投资密度:{info.get('density_per_1k', 0)}") lines.append("") return "\n".join(lines) def generate_task(stats, author_name): """生成AI蒸馏任务清单(七维DNA)""" tt = stats.get("trader_type", {}) trader_type = tt.get("classified_type", "未知") lines = [] lines.append(f"# {author_name} AI蒸馏任务清单\n") lines.append(f"> 交易类型:{trader_type}") lines.append(f"> 内容数:{stats['total_articles']} 篇") lines.append("") lines.append("## 蒸馏任务\n") lines.append("请基于数据底稿,按七维DNA框架生成风格画像。\n") # 构建思维层参考数据 thinking_tools_ref = ', '.join(list(stats.get("thinking_tools", {}).keys())[:5]) or '待分析' arg_ref = ', '.join(list(stats.get("argumentation_style", {}).keys())[:3]) or '待分析' tone_ref = stats.get("tone_analysis", {}).get("tone_style", "待分析") data_ref = stats.get("data_citation", {}).get("data_style", "待分析") cross_ref = stats.get("cross_market", {}).get("perspective", "待分析") info_ref = stats.get("information_density", {}).get("level", "待分析") dims = [ ("维度1:交易体系DNA", [ "提取核心交易模式", "提取选股逻辑", "提取买入信号", "提取卖出/止损信号", "提取仓位管理策略", f"提取核心分析工具/思维框架(脚本参考:{thinking_tools_ref})", "每个要点需引用至少2条原文证据", ]), ("维度2:市场判断DNA", [ "判定交易流派", "提取板块偏好", "提取持仓周期特征", "提取多空判断条件", "追踪历史预判与实际走势对比", f"分析跨市场视角(脚本检测:{cross_ref})", ]), ("维度3:表达风格DNA", [ "分析文章结构", "提取TOP10标志性表达", "分析标题模式", "提取开头模板", "提取结尾模式", f"分析语气和人称特征(脚本量化:{tone_ref})", f"提取论证链模式(脚本检测:{arg_ref})", f"评估数据引用风格(脚本检测:{data_ref})", ]), ("维度4:内容深度DNA", [ f"统计平均字数:{stats.get('word_count', {}).get('avg', 0)}字", f"评估信息密度(脚本检测:{info_ref})", "评估复盘详细度", "评估预判明确度", ]), ("维度5:互动特征DNA", [ "分析读者互动方式", "分析战绩展示方式", "分析争议处理方式", f"免责声明使用率:{stats.get('has_disclaimer', {}).get('ratio', 0):.0%}", ]), ("维度6:热点图谱DNA", [ f"核心赛道排序(参考:{', '.join(list(stats.get('sector_focus', {}).keys())[:5])})", "提取龙头记忆", "提取常用盘面指标", "提取资金面关注点", ]), ("维度7:人设基因DNA", [ "提取投资经历和入市背景", "分析投资哲学演变(对比早期 vs 近期内容)", "提取里程碑事件(重大盈亏/转折点)", f"分析师承/影响源(参考:{', '.join(list(stats.get('mentor_influence', {}).keys())[:5]) or '未检测到'})", ]), ] for title, items in dims: lines.append(f"### {title}") for item in items: lines.append(f"- {item}") lines.append("") lines.append("## 输出格式\n") lines.append("按照 `assets/profile_template.md` 模板输出,保存为:") lines.append(f"`output/{author_name}_风格画像.md`\n") lines.append("## 质量要求\n") lines.append("- 每个维度至少3个具体特征") lines.append("- 每个特征至少1条原文证据") lines.append("- 标注蒸馏置信度(高/中/低)") lines.append("- 禁止编造未在原文中出现的数据") return "\n".join(lines) # ─── 主流程 ────────────────────────────────────────────────────────────────────────── def distill(account, author_name, count=None, api_key=None, force_refresh=False): """蒸馏指定博主""" step(f"开始蒸馏:{author_name}(微信号: {account},目标: {count}篇)") # 采集文章 from gzh import fetch_articles articles = fetch_articles( account=account, author_name=author_name, count=count, api_key=api_key, force_refresh=force_refresh, ) if not articles: error(f"未获取到「{author_name}」的文章数据,请检查微信号是否正确") return False info(f"「{author_name}」共 {len(articles)} 条内容") # 保存完整文章到磁盘(供后续校验/AI精读使用) articles_file = OUTPUT_DIR / f"{author_name}_完整文章.json" articles_file.write_text(json.dumps(articles, ensure_ascii=False, indent=2), encoding="utf-8") info(f"完整文章已保存:{articles_file}") # Phase 2: 统计分析 step("统计分析中...") stats = analyze_articles(articles, author_name) # 保存统计数据 OUTPUT_DIR.mkdir(parents=True, exist_ok=True) stats_file = OUTPUT_DIR / f"{author_name}_统计数据.json" stats_file.write_text(json.dumps(stats, ensure_ascii=False, indent=2), encoding="utf-8") info(f"统计数据已保存:{stats_file}") # Phase 3: 生成数据底稿和蒸馏任务 step("生成数据底稿和蒸馏任务...") brief = generate_brief(stats, author_name) task = generate_task(stats, author_name) brief_file = OUTPUT_DIR / f"{author_name}_数据底稿.md" task_file = OUTPUT_DIR / f"{author_name}_蒸馏任务.md" brief_file.write_text(brief, encoding="utf-8") task_file.write_text(task, encoding="utf-8") info(f"数据底稿已保存:{brief_file}") info(f"蒸馏任务已保存:{task_file}") # Phase 3.5: 生成结构化JSON画像 step("生成结构化JSON画像...") json_profile = generate_json_profile(stats, author_name) profile_file = OUTPUT_DIR / f"{author_name}_画像.json" profile_file.write_text(json.dumps(json_profile, ensure_ascii=False, indent=2), encoding="utf-8") info(f"JSON画像已保存:{profile_file}") info(f"JSON画像为基础框架,AI需基于蒸馏任务深入阅读原文后补充完善") print() print(f"{BOLD}{'='*60}{RESET}") print(f"{BOLD} 数据底稿和蒸馏任务已生成{RESET}") print(f"{BOLD} 请AI读取以下文件并生成七维DNA风格画像:{RESET}") print(f" 1. {brief_file}") print(f" 2. {task_file}") print(f" 3. {profile_file}(JSON画像基础框架)") print(f" 4. 参考模板:{SCRIPT_DIR}/assets/profile_template.md") print(f" 输出到:{OUTPUT_DIR}/{author_name}_风格画像.md") print(f"{BOLD} 蒸馏完成后请执行校验:{RESET}") print(f" python distill.py --validate --author \"{author_name}\"") print(f"{BOLD}{'='*60}{RESET}") print() return True # ─── JSON结构化画像生成 ───────────────────────────────────────────────────────────── def generate_json_profile(stats, author_name): """基于统计数据生成结构化JSON画像(七维DNA)。""" wc = stats.get("word_count", {}) tt = stats.get("trader_type", {}) stock_mentions = [ {"name": s["stock"], "count": s["count"], "score": s["score"]} for s in stats.get("stock_mentions", [])[:20] ] stock_names = [s["name"] for s in stock_mentions] regex_discovered = [s["stock"] for s in stats.get("regex_discovered_stocks", [])[:5]] sectors = [f"{s}({c}篇)" for s, c in list(stats.get("sector_focus", {}).items())[:8]] sig_phrases = [p["phrase"] for p in stats.get("signature_phrases", [])[:10]] inv_phrases = [p["phrase"] for p in stats.get("investment_phrases", [])[:15]] wisdom = [p["phrase"] for p in stats.get("investment_wisdom", [])[:8]] templates = stats.get("title_format_templates", []) title_style = f"固定格式:'{templates[0]['prefix']}...'" if templates else "自由格式" op = stats.get("opening_patterns", {}) cp = stats.get("closing_patterns", {}) opening = max(op, key=op.get) if op else "自由开头" closing = max(cp, key=cp.get) if cp else "自由结尾" # 提取思维层数据 thinking_tools = list(stats.get("thinking_tools", {}).keys())[:5] arg_styles = list(stats.get("argumentation_style", {}).keys())[:3] tone_data = stats.get("tone_analysis", {}) tone_style = tone_data.get("tone_style", "") data_cite = stats.get("data_citation", {}) data_style = data_cite.get("data_style", "") cross_data = stats.get("cross_market", {}) cross_perspective = cross_data.get("perspective", "") cross_markets = list(cross_data.get("markets", {}).keys()) info_density = stats.get("information_density", {}) profile = { "大V名称": author_name, "蒸馏日期": datetime.now().strftime("%Y-%m-%d"), "样本文章数": stats["total_articles"], "蒸馏置信度": "高" if stats["total_articles"] >= 60 else "中", "风格类型": f"{tt.get('classified_type', '未知')}型投资者", "投资体系": { "核心流派": f"{tt.get('classified_type', '未知')}投资,{'基本面,估值' if tt.get('long_score', 0) > tt.get('short_score', 0) else '技术,趋势'}为核心", "选股逻辑": inv_phrases[:3] if inv_phrases else [], "买入决策": [], "卖出决策": [], "止损纪律": "", "仓位管理": "", "持仓周期": "", "核心分析工具": thinking_tools, }, "市场判断": { "研判方式": "", "板块偏好": sectors, "风险偏好": "", "典型看多条件": [], "典型看空条件": [], "大盘依赖度": "", "周期判断": "", "逆向思维": "逆向思维型" in arg_styles, }, "表达风格": { "文章结构": "", "段落长度": "", "语气": tone_style, "标志性表达": sig_phrases, "投资格言": wisdom, "数据引用": data_style, "论证方式": arg_styles, "标题风格": title_style, "开头模式": opening, "结尾模式": closing, "文风温度": tone_style, "免责声明": f"使用率{stats.get('has_disclaimer', {}).get('ratio', 0):.0%}", }, "内容深度": { "平均字数": int(wc.get("avg", 0)), "中位数字数": int(wc.get("median", 0)), "信息密度": info_density.get("level", ""), "时效性": "", "分析深度": "", "预判明确度": "", "更新频率": f"{stats.get('publish_frequency', {}).get('avg_per_day', 0)}篇/天", }, "互动特征": { "读者互动": "", "争议处理": "", "战绩展示": "", "粉丝运营": "", "生活分享": "", "互动数据": { "篇均阅读": int(stats.get("engagement", {}).get("read_avg", 0)), "篇均点赞": int(stats.get("engagement", {}).get("like_avg", 0)), "篇均评论": int(stats.get("engagement", {}).get("comment_avg", 0)), "篇均转发": int(stats.get("engagement", {}).get("share_avg", 0)), "互动率": f"{stats.get('engagement', {}).get('engagement_rate', 0)}%", "互动层级": stats.get("engagement", {}).get("level", ""), }, }, "关注图谱": { "核心赛道": [s.split("(")[0] for s in sectors[:6]], "常提及个股": stock_mentions, "正则发现补充": regex_discovered, "宏观关注": cross_markets, "常用指标": [], "投资格言": wisdom, "跨市场": cross_perspective, }, } return profile # ─── 准确性校验 ───────────────────────────────────────────────────────────────────── def validate_profile(author_name, sample_n=10, **kwargs): """校验画像准确性:随机抽样文章,比对画像声明与实际内容。""" import random random.seed(42) step(f"开始校验:{author_name}") # 加载画像 profile_file = OUTPUT_DIR / f"{author_name}_画像.json" if not profile_file.exists(): stats_file = OUTPUT_DIR / f"{author_name}_统计数据.json" if stats_file.exists(): stats_data = json.loads(stats_file.read_text(encoding="utf-8")) profile = generate_json_profile(stats_data, author_name) else: error(f"未找到 {author_name} 的画像或统计数据") return None else: profile = json.loads(profile_file.read_text(encoding="utf-8")) # 从完整文章文件获取样本(优先),回退到统计数据截断文本 articles = [] full_file = OUTPUT_DIR / f"{author_name}_完整文章.json" if full_file.exists(): try: full_data = json.loads(full_file.read_text(encoding="utf-8")) articles = [ {"title": a.get("title", ""), "content": a.get("content", ""), "publish_time": a.get("publish_time", "")} for a in full_data ] info(f"从完整文章文件读取 {len(articles)} 篇(含完整正文)") except (json.JSONDecodeError, OSError): warn("完整文章文件损坏,回退到统计数据截断文本") if not articles: stats_file = OUTPUT_DIR / f"{author_name}_统计数据.json" if stats_file.exists(): stats_data = json.loads(stats_file.read_text(encoding="utf-8")) structures = stats_data.get("article_structures", []) articles = [ {"title": s.get("title", ""), "content": s.get("opening", "") + s.get("closing", ""), "publish_time": s.get("publish_time", "")} for s in structures ] warn(f"回退到截断文本模式(仅开头+结尾各100字,准确率偏低)") if not articles: error(f"无法获取 {author_name} 的文章用于校验") return None sampled = random.sample(articles, min(sample_n, len(articles))) # 获取画像声明 focus = profile.get("关注图谱", {}) stocks = focus.get("常提及个股", []) stock_names = [s.get("name", "") for s in stocks if isinstance(s, dict)] sig_phrases = profile.get("表达风格", {}).get("标志性表达", []) # A. 个股提及校验 stock_hits = 0 for art in sampled: text = f"{art.get('title', '')} {art.get('content', '')}" if any(sn.lower() in text.lower() for sn in stock_names if sn): stock_hits += 1 stock_acc = stock_hits / len(sampled) * 100 if sampled else 0 # B. 风格特征校验 style_hits = 0 style_total = 3 if any(any(p in f"{a.get('title', '')} {a.get('content', '')}" for p in sig_phrases[:3]) for a in sampled): style_hits += 1 avg_claimed = profile.get("内容深度", {}).get("平均字数", 0) if avg_claimed > 0: actual_avg = sum(len(a.get("content", "")) for a in sampled) / len(sampled) if abs(actual_avg - avg_claimed) / avg_claimed < 0.5: style_hits += 1 else: style_hits += 1 # 标题风格:检查样本标题是否与画像声称的模式一致 title_style = profile.get("表达风格", {}).get("标题风格", "") sampled_titles = [a.get("title", "") for a in sampled] title_exclaim = sum(1 for t in sampled_titles if "!" in t or "!" in t) title_ratio = title_exclaim / max(len(sampled_titles), 1) if title_ratio >= 0.3: # 至少30%标题含感叹号即为语气型标题 style_hits += 1 style_acc = style_hits / style_total * 100 # C. 投资体系校验 system_hits = 1 system_total = 3 core = profile.get("投资体系", {}).get("核心流派", "") full_text = " ".join([a.get("content", "") for a in sampled]) # 流派关键词拆分为两字以上独立词(处理中文逗号连接的情况) core_kws = [w.strip() for w in re.split(r'[\s,,+、/]+', core) if len(w.strip()) >= 2] if any(kw in full_text for kw in core_kws): system_hits += 1 sectors = focus.get("核心赛道", []) # 赛道名去掉篇数后缀(如 "AI/人工智能(17篇)" → ["AI", "人工智能"]) sector_kws_all = set() for s in sectors[:3]: s_clean = re.sub(r'[((]\d+篇[))]', '', s).strip() for part in re.split(r'[/、]', s_clean): if len(part.strip()) >= 2: sector_kws_all.add(part.strip()) if any(kw in full_text for kw in sector_kws_all): system_hits += 1 system_acc = system_hits / system_total * 100 # 综合 total_hits = stock_hits + style_hits + system_hits total_items = len(sampled) + style_total + system_total overall_acc = total_hits / total_items * 100 result = { "author": author_name, "stock_acc": round(stock_acc, 0), "style_acc": round(style_acc, 0), "system_acc": round(system_acc, 0), "overall_acc": round(overall_acc, 0), "passed": overall_acc >= 80, "sampled": len(sampled), } print(f"\n | 校验维度 | 总题数 | 命中数 | 准确率 |") print(f" |---------|--------|--------|--------|") print(f" | A. 个股提及 | {len(sampled)} | {stock_hits} | {stock_acc:.0f}% |") print(f" | B. 风格特征 | {style_total} | {style_hits} | {style_acc:.0f}% |") print(f" | C. 投资体系 | {system_total} | {system_hits} | {system_acc:.0f}% |") print(f" | **综合** | {total_items} | {total_hits} | **{overall_acc:.0f}%** |") print(f"\n 准出标准:综合准确率 >= 80%") print(f" 结果:{'通过' if result['passed'] else '需补充蒸馏'}") if not result["passed"]: warn(f"准确率 {overall_acc:.0f}% < 80%,建议:") warn("1. 增加采集数量(--count 100)") warn("2. 仔细阅读raw全文补充蒸馏") warn("3. 更新画像中不准确的字段后重新校验") report_file = OUTPUT_DIR / f"{author_name}_校验报告_{datetime.now().strftime('%Y%m%d')}.json" report_file.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8") info(f"校验报告已保存:{report_file}") return result # ─── CLI ──────────────────────────────────────────────────────────────────────────── def main(): parser = argparse.ArgumentParser( description="公众号投资博主蒸馏器", formatter_class=argparse.RawDescriptionHelpFormatter, epilog="""\ 示例: python distill.py --account "zshbtz" --count 60 python distill.py --account "zshbtz" --author "� -
gzh.py 13.1 KB
#!/usr/bin/env python3 """ 公众号文章数据采集 ================== 两步 API 流程: 1. queryWorkList — 分页获取文章 UUID 列表(每页20条,offset 步进20) 2. workDetail — 按 UUID 获取单篇完整数据(正文/摘要/词云等) UUID 缓存:首次获取后自动保存到 output/{account}_uuids.json, 后续运行直接读取缓存,避免重复消耗积分。 认证:REDFOX_API_KEY(CLI 参数 > 环境变量 > 配置文件) """ import json import os import sys import time from pathlib import Path # Windows 控制台 UTF-8 编码 if sys.platform == 'win32': sys.stdout.reconfigure(encoding='utf-8', errors='replace') sys.stderr.reconfigure(encoding='utf-8', errors='replace') try: import requests HAS_REQUESTS = True except ImportError: HAS_REQUESTS = False # ─── 配置 ───────────────────────────────────────────────────────────────────────── WORK_LIST_URL = "https://redfox.hk/story/api/gzh/data/queryWorkList" WORK_DETAIL_URL = "https://redfox.hk/story/api/gzh/data/workDetail" CONFIG_DIR = Path.home() / ".qoder" / "apis" CONFIG_FILE = CONFIG_DIR / "redfox.json" ENV_KEY = "REDFOX_API_KEY" SOURCE = "公众号投资博主蒸馏-GitHub" PAGE_SIZE = 20 # queryWorkList offset 步进为20,非10 # UUID 缓存目录(与 distill.py 的 OUTPUT_DIR 保持一致) SCRIPT_DIR = Path(__file__).parent.parent CACHE_DIR = SCRIPT_DIR / "output" # ─── 终端颜色 ────────────────────────────────────────────────────────────────────── GREEN = "\033[92m" YELLOW = "\033[93m" RED = "\033[91m" CYAN = "\033[96m" RESET = "\033[0m" def info(msg): print(f"{GREEN}[✓]{RESET} {msg}") def warn(msg): print(f"{YELLOW}[!]{RESET} {msg}") def error(msg): print(f"{RED}[✗]{RESET} {msg}") def step(msg): print(f"{CYAN}[→]{RESET} {msg}") # ─── API Key 管理 ────────────────────────────────────────────────────────────────── def get_api_key(cli_key=None): """获取 API Key:CLI参数 > 环境变量 > 配置文件。未配置返回空字符串。""" if cli_key: return cli_key env_key = os.environ.get(ENV_KEY) if env_key: return env_key if CONFIG_FILE.exists(): try: data = json.loads(CONFIG_FILE.read_text(encoding="utf-8")) key = data.get("api_key") or data.get("REDFOX_API_KEY") if key: return key except (json.JSONDecodeError, OSError): pass return "" # ─── Step 1: 获取文章UUID列表 ────────────────────────────────────────────────────── def fetch_work_list(session, account, count, force_refresh=False): """ 调用 queryWorkList 分页获取文章 UUID 列表。 offset 从0开始,每页+20,循环分页直到达到目标数量。 首次获取后自动缓存到 output/{account}_uuids.json,后续运行直接读取。 Args: session: requests.Session(已设置 headers) account: 公众号微信号(如 zshbtz) count: 目标获取文章数量 force_refresh: 是否强制刷新缓存(忽略已有缓存重新请求API) Returns: list[dict] — 每个 dict 包含 workUuid 等基础字段 """ # 检查 UUID 缓存 CACHE_DIR.mkdir(parents=True, exist_ok=True) cache_file = CACHE_DIR / f"{account}_uuids.json" if not force_refresh and cache_file.exists(): try: cached = json.loads(cache_file.read_text(encoding="utf-8")) cached_items = cached.get("items", []) if len(cached_items) >= count: info(f"使用 UUID 缓存({len(cached_items)}条,跳过API请求)") return cached_items[:count] else: info(f"缓存仅 {len(cached_items)} 条,不足目标 {count} 条,重新请求...") except (json.JSONDecodeError, OSError): warn("缓存文件损坏,重新请求...") all_items = [] offset = 0 while len(all_items) < count: payload = { "source": SOURCE, "account": account, "sortType": "2", "offset": offset, } try: resp = session.post(WORK_LIST_URL, json=payload, timeout=30) result = resp.json() except Exception as e: error(f"queryWorkList 请求失败: {e}") break code = result.get("code") if code not in (200, 2000): if code == 3108: warn("触发限流,等待5秒...") time.sleep(5) continue error(f"queryWorkList 返回错误码 {code}:{result.get('msg') or result.get('message') or '(无详细信息)'}") break data_raw = result.get("data", {}) if isinstance(data_raw, list): items = data_raw elif isinstance(data_raw, dict): items = data_raw.get("list") or data_raw.get("records") or data_raw.get("data") or [] else: items = [] if not items: break # 按需截断:避免 API 返回超量数据浪费积分 needed = count - len(all_items) all_items.extend(items[:needed]) offset += PAGE_SIZE if len(items) < PAGE_SIZE or len(all_items) >= count: break # 已无更多数据 # 进度提示 if len(all_items) % 20 == 0: step(f" 已获取 {len(all_items)} 条UUID...") time.sleep(0.5) # 请求间隔 info(f"queryWorkList 共获取 {len(all_items)} 条文章UUID") # 保存 UUID 缓存 try: cache_data = { "account": account, "fetched_at": time.strftime("%Y-%m-%dT%H:%M:%S"), "count": len(all_items), "items": all_items, } cache_file.write_text(json.dumps(cache_data, ensure_ascii=False, indent=2), encoding="utf-8") info(f"UUID 缓存已保存:{cache_file}") except OSError as e: warn(f"缓存写入失败: {e}") return all_items[:count] # ─── Step 2: 逐篇获取完整数据 ────────────────────────────────────────────────────── def fetch_work_detail(session, uuid): """ 调用 workDetail 获取单篇文章完整数据。 Args: session: requests.Session(已设置 headers) uuid: 文章UUID Returns: dict — 包含 title/content/summary/wordCloud 等完整字段,失败返回 None """ payload = { "source": SOURCE, "workUuid": uuid, } try: resp = session.post(WORK_DETAIL_URL, json=payload, timeout=30) result = resp.json() except Exception as e: warn(f"workDetail({uuid[:8]}...) 请求失败: {e}") return None code = result.get("code") if code not in (200, 2000): if code == 3108: time.sleep(5) return fetch_work_detail(session, uuid) # 重试一次 warn(f"workDetail({uuid[:8]}...) 返回错误码 {code}:{result.get('msg') or result.get('message') or '(无详细信息)'}") return None data = result.get("data", {}) if isinstance(data, list) and data: data = data[0] return data if isinstance(data, dict) else None def fetch_work_details(session, uuid_items, batch_delay=0.3): """ 批量获取文章详情。 Args: session: requests.Session uuid_items: UUID列表(从 fetch_work_list 返回) batch_delay: 每篇请求间隔(秒) Returns: list[dict] — 完整文章数据列表 """ articles = [] total = len(uuid_items) for i, item in enumerate(uuid_items): uuid = item.get("workUuid") or item.get("uuid") or item.get("id") or (item if isinstance(item, str) else "") if not uuid: continue detail = fetch_work_detail(session, uuid) if detail: articles.append(detail) # 进度提示 done = i + 1 if done % 10 == 0 or done == total: step(f" 已获取 {done}/{total} 篇正文...") time.sleep(batch_delay) info(f"workDetail 共获取 {len(articles)} 篇完整文章") return articles # ─── 主采集函数 ────────────────────────────────────────────────────────────────────── def fetch_articles(account, author_name="", count=None, api_key=None, force_refresh=False): """ 两步流程采集公众号文章: 1. queryWorkList 获取UUID列表(优先读缓存) 2. workDetail 逐篇获取完整数据 Args: account: 公众号微信号(如 zshbtz) author_name: 博主显示名称(用于日志) count: 目标文章数量(20/60/100) api_key: API Key(可选) force_refresh: 是否强制刷新UUID缓存 Returns: list[dict] — 标准化文章数据列表,每个 dict 包含: - title: 标题 - content: 正文 - summary: 摘要 - publish_time: 发布时间 - url: 链接 - content_keywords: 内容关键词(list[dict],含 keyword/weight) - read_count/like_count/comment_count/share_count/collect_count/reward_count: 互动数据 - author: 作者名 - uuid: 文章UUID """ if not HAS_REQUESTS: error("缺少 requests 库,请执行: pip install requests") return [] key = get_api_key(api_key) if not key: error("未配置 API Key,请设置环境变量 REDFOX_API_KEY=ak_xxxxxxxx") error("获取 Key: https://redfox.hk/settings/api-keys?source=github") return [] session = requests.Session() session.headers.update({ "Content-Type": "application/json", "X-API-Key": key, }) display = author_name or account step(f"开始采集公众号 [{display}](微信号: {account})的文章...") # Step 1: 获取UUID列表 step("Step 1: 获取文章UUID列表...") uuid_items = fetch_work_list(session, account, count=count, force_refresh=force_refresh) if not uuid_items: error(f"未获取到 [{display}] 的文章列表,请检查微信号是否正确") return [] # Step 2: 逐篇获取完整数据 step("Step 2: 逐篇获取文章正文...") raw_articles = fetch_work_details(session, uuid_items) if not raw_articles: error(f"获取到UUID但无法获取正文数据") return [] # 标准化输出 articles = [] for raw in raw_articles: # 内容关键词(API 字段名: contentKeywords,非 wordCloud) ck_raw = raw.get("contentKeywords") or raw.get("wordCloud") or raw.get("contentWordCloud") or [] if isinstance(ck_raw, str): try: ck_raw = json.loads(ck_raw) except (json.JSONDecodeError, ValueError): ck_raw = [] content_keywords = ck_raw if isinstance(ck_raw, list) else [] articles.append({ "title": raw.get("title") or raw.get("workName") or "", "content": raw.get("content") or raw.get("workContent") or raw.get("workText") or "", "summary": raw.get("summary") or raw.get("workSummary") or "", "publish_time": raw.get("publishTime") or raw.get("publicTime") or "", "url": raw.get("workUrl") or raw.get("url") or "", "content_keywords": content_keywords, # 互动数据(直接来自 API) "read_count": raw.get("readCount", 0), "like_count": raw.get("likeCount", 0), "comment_count": raw.get("commentCount", 0), "share_count": raw.get("shareCount", 0), "collect_count": raw.get("collectCount", 0) if raw.get("collectCount") is not None else 0, "reward_count": raw.get("rewardCount", 0) if raw.get("rewardCount") is not None else 0, "author": raw.get("author") or raw.get("accountName") or raw.get("accountNickName") or author_name or account, "uuid": raw.get("workUuid") or raw.get("uuid") or raw.get("id") or "", "platform": "gzh", }) info(f"[{display}] 共采集到 {len(articles)} 篇完整文章") return articles
-
-
README.en.md 5.1 KB
# WeChat Investment Blogger Distiller / investor-distiller --- ## Overview Enter a WeChat public account ID and it automatically collects articles and distills a seven-dimensional DNA style profile — from trading systems to expression style, you get a complete analysis of the blogger. Unlike generic summaries, every conclusion is backed by original text evidence, and the profile's accuracy is automatically scored and validated, so you know exactly how reliable it is. **Core Value** - **Plug and Analyze**: Enter a WeChat ID to automatically collect articles and generate a complete profile, with three tiers (20/60/100) — no manual browsing required - **Seven-Dimensional DNA**: Trading systems, stock selection logic, expression style, interaction patterns… dissect the blogger's investment DNA across seven dimensions, not just word frequency stats - **Auto-Validated Accuracy**: Automatic three-dimensional scoring after each distillation, checking stocks/style/system item by item — you can see at a glance how accurate it is - **Ready to Use**: Generate style-consistent stock analysis based on the profile, ready to use as reference material, each with data source annotations and disclaimers **Target Users** - 🧑💼 Investors — Quickly understand an influencer's investment style and core logic to support decision-making - ✍️ Content Creators — Learn from influencers' expression styles and argumentation patterns to improve content quality - 🔬 Researchers — Systematically analyze investment blogger style characteristics, supporting multi-blogger comparisons --- ## Features ### Core Capabilities - **Plug and Analyze**: Enter a WeChat ID to automatically collect articles and generate a complete profile, with flexible 20/60/100 article tiers - **Newest-First Collection**: The blogger's latest content comes first, so the profile reflects their current views and state - **Complete Per-Article Data**: Each article's body text, summary, publish time, and read/like/share/collect/comment metrics are all collected, giving richer original-text evidence - **Seven-Dimensional DNA**: From trading systems to persona DNA, dissect the blogger's investment DNA across seven dimensions — not just word frequency stats - **Auto-Validated Quality**: Automatic scoring after each distillation, checking stocks/style/system item by item, with prompts for supplementary distillation when accuracy falls short - **Ready to Use**: Generate style-consistent stock analysis based on the profile, ready to use as reference, each with data source annotations --- ## API Key Acquisition & Security - This skill requires the environment variable: `REDFOX_API_KEY`. - `REDFOX_API_KEY` is provided by [RedFoxHub](https://redfox.hk/settings/api-keys?source=github) (`https://redfox.hk`). - Please visit [RedFoxHub](https://redfox.hk?source=github) to register an account and obtain your `REDFOX_API_KEY`. - Configure the environment variable `REDFOX_API_KEY` on your device before using this skill. - Before providing your key, please verify the key source, available scope, validity period, and whether reset/revocation is supported. - Never hardcode or expose your key in plaintext within code, prompts, logs, or output files. --- ## Usage Guide Simply describe your needs in natural language — no commands to memorize. ### Quick Reference | Intent | Example | Result | | ------ | ------- | ------ | | Distill a blogger profile | `Distill the WeChat account zshbtz` | Automatically collects articles and generates a 7D DNA style profile | | Specify article count | `Distill zshbtz with 100 articles` | High-precision distillation for more stable profile characteristics | | Validate profile quality | `Validate the distilled profile for 财躺平` | Three-dimensional scoring to confirm profile accuracy | | Style-based analysis | `Analyze CATL using 猫笔刀's style` | Generate style-consistent stock analysis based on the distilled profile | ### Output Example After distillation, the following files are generated in the `output/` directory: - `{blogger_name}_风格画像.md` — Complete 7D DNA style profile with original text evidence and confidence annotations - `{blogger_name}_统计数据.json` — Structured statistical data for validation and comparison - `{blogger_name}_校验报告_YYYYMMDD.json` — Accuracy validation report with three-dimensional scoring --- ## Use Cases | Scenario | Role | Example Query | Benefit | | -------- | ---- | ------------- | ------- | | Understanding an influencer | Investor | `Distill the WeChat account 猫笔刀` | Quickly grasp the blogger's trading system and market perspective | | Multi-blogger comparison | Researcher | `Distill 财躺平 and 投资明见, compare their styles` | Cross-reference different bloggers' investment approaches and expression styles | | Style-based market review | Content Creator | `Write today's A-share recap in 格兰投研's style` | Generate style-consistent market commentary | | Stock selection support | Investor | `Analyze the new energy sector from 猫笔刀's perspective` | Evaluate stocks/sectors through the blogger's analytical framework | -
README.md 4.2 KB
# 公众号投资博主蒸馏器 / investor-distiller --- ## 简介 输入公众号微信号就能自动获取文章、提取七维DNA风格画像,从交易体系到表达风格给你一份完整的大V分析报告。不像网上泛泛的介绍,每一条结论都有原文证据支撑,画像准不准还会自动打分校验,不会凭空编造风格特征。 **核心价值** - **输入即分析**:输入微信号就能自动获取文章、生成完整画像,支持 20/60/100 篇三档,不用自己一篇篇翻 - **七维全面还原**:交易体系、选股逻辑、表达风格、互动特征……从七个维度拆解博主的投资DNA,不只是统计词频 - **自动打分校验**:每次蒸馏后自动三维度评分,个股/风格/体系逐项检查,准不准一眼就能看出来 - **拿来就能用**:基于画像生成风格一致的个股分析,直接当参考资料用,每份分析都标注数据来源和免责说明 **适用对象** - 🧑💼 投资者 — 快速了解大V投资风格与核心逻辑,辅助投资决策参考 - ✍️ 内容创作者 — 借鉴大V表达风格与论证模式,提升内容质量 - 🔬 研究者 — 系统性分析投资博主风格特征,支持多博主对比研究 --- ## 功能特性 ### 核心功能 - **输入即分析**:输入微信号就能自动获取文章、生成完整画像,支持 20/60/100 篇三档,灵活选 - **按时间由近到远采集**:优先拿到博主最新的内容,画像更贴近当下的观点与状态 - **单篇数据取全**:每篇文章的正文、摘要、发布时间与阅读、点赞、分享、收藏、评论数据一并获取,原文证据更充分 - **七维全面还原**:从交易体系到人设基因,七大维度拆解博主投资DNA,不是简单统计词频 - **自动校验质量**:每次蒸馏后自动评分,个股/风格/体系逐项检查,准确率不够会提示补充 - **拿来就能用**:基于画像生成风格一致的个股分析,直接当参考资料用,每份都标注数据来源 --- ## 密钥获取与安全说明 - 本技能需要使用环境变量:`REDFOX_API_KEY`。 - `REDFOX_API_KEY` 由 [红狐 hub](https://redfox.hk/settings/api-keys?source=github) (`https://redfox.hk`)提供。 - 请前往 [红狐 hub](https://redfox.hk?source=github) 注册账号,获取 `REDFOX_API_KEY`。 - 配置设备环境变量 `REDFOX_API_KEY` 后使用本技能。 - 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。 - 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。 --- ## 使用指南 直接用自然语言描述需求,无需记忆命令。 ### 常用说法速查 | 意图 | 示例话术 | 效果 | | -------- | ---------------------------- | -------- | | 蒸馏博主画像 | `蒸馏公众号 zshbtz` | 自动采集文章并生成七维DNA风格画像 | | 指定文章数量 | `蒸馏公众号 zshbtz,采集 100 篇` | 高精度蒸馏,画像特征更稳定 | | 校验画像质量 | `校验财躺平的蒸馏画像` | 三维度评分,确认画像准确率 | | 风格化分析 | `用猫笔刀的风格分析一下宁德时代` | 基于蒸馏画像生成风格一致的个股分析 | ### 输出示例 蒸馏完成后,在 `output/` 目录下得到: - `{博主名}_风格画像.md` — 七维DNA完整风格画像,含原文证据引用与置信度标注 - `{博主名}_统计数据.json` — 结构化统计数据,用于校验与对比 - `{博主名}_校验报告_YYYYMMDD.json` — 准确性校验报告,含三维度评分 --- ## 使用场景 | 场景 | 角色 | 示例问法 | 收益 | | -------- | -------- | -------- | -------- | | 了解大V风格 | 投资者 | `蒸馏公众号猫笔刀` | 快速掌握博主交易体系与市场判断逻辑 | | 多V对比研究 | 研究者 | `蒸馏财躺平和投资明见,对比他们的风格` | 横向对比不同博主的投资流派与表达特点 | | 风格化复盘 | 内容创作者 | `用格兰投研的风格写今天的A股复盘` | 生成风格一致的复盘内容 | | 选股辅助 | 投资者 | `用猫笔刀的视角分析一下新能源板块` | 以博主分析框架审视个股/板块 | -
SKILL.md 16.6 KB
--- name: investor-distiller description: > 公众号投资博主蒸馏器。通过公众号文章数据,自动提取交易体系、市场判断、表达风格、内容深度、互动特征、热点图谱、 人设基因七维DNA,输出结构化风格画像 profile。 触发词:蒸馏投资博主、蒸馏大V、蒸馏公众号大V、分析投资博主风格、 提取交易体系、风格画像、投资博主蒸馏。 --- # 公众号投资博主蒸馏器 > **免责声明**:本工具仅供学习研究使用,蒸馏产物为风格模拟参考,不构成任何投资建议。 > 所有生成内容必须标注「AI 风格模拟,不构成投资建议」。 ## 📝 简介 自动化的公众号投资博主风格蒸馏工具。输入公众号微信号和文章数量,自动采集文章并提取七维DNA投资风格画像,输出结构化的交易体系、市场判断、表达风格等完整分析报告。 ## ✨ 功能特性 | 功能模块 | 能力描述 | 核心价值 | |---------|---------|----------| | 文章自动采集 | 通过微信号批量拉取公众号历史文章,支持 20/60/100 篇三档 | 无需手动整理,一键获取完整素材 | | 七维DNA蒸馏 | 提取交易体系、市场判断、表达风格、内容深度、互动特征、热点图谱、人设基因 | 结构化画像,可复用可对比 | | 双层特征提取 | 表层(术语/个股频次)+ 思维层(分析工具/论证模式/语气量化) | 不仅像博主说的话,更像博主的思考 | | 质量校验闭环 | 三维度评分(个股/风格/体系),≥80% 准出,双层审计 | 画像准确性有保障 | | 风格化模拟 | 基于画像生成风格一致的个股/市场分析,含数据来源标注与免责声明 | 可复现博主风格的分析输出 | ## ⚠️ 蒸馏质量铁律 > **必须从raw全文逐篇提取,禁止依赖任何clean/NER中间层。** 蒸馏准确性直接决定画像质量。经验表明,clean阶段的个股NER提取管线会遗漏大量信息(如一篇提及6只股票的文章可能只提取0-2只),导致画像基于不完整数据构建。因此: 1. **raw全文原则**:所有提取(个股/短语/板块/风格)必须直接遍历raw文章正文,不经过任何预处理过滤 2. **词典+别名匹配**:个股提取使用完整词典(含口语化别名,如"上证指数"→"上证/大盘/沪指/A股"),确保宽松但准确 3. **文章级板块计数**:板块关注度按文章级别计数(每篇只计一次),比词频更准确反映博主真实关注方向 4. **领域专用短语**:使用投资领域专用关键词列表提取关键短语,比通用句子频次统计更精准 5. **校验闭环**:蒸馏完成后必须执行准确性校验(`--validate`),≥80%方可准出 --- ## 七维DNA蒸馏结构 | # | 维度 | 回答什么 | 关键字段 | |---|------|---------|---------| | 1 | 交易体系 | TA怎么交易? | 核心模式、选股逻辑、买卖信号、仓位管理 | | 2 | 市场判断 | TA怎么看市场? | 交易流派、板块偏好、持仓周期、多空条件 | | 3 | 表达风格 | TA怎么写/说? | 文章结构、标志性表达、标题/开头/结尾模式、语气 | | 4 | 内容深度 | TA写多少? | 平均字数、信息密度、复盘详细度、预判明确度 | | 5 | 互动特征 | TA怎么互动? | 读者互动、战绩展示、争议处理、免责声明 | | 6 | 热点图谱 | TA关注什么? | 核心赛道、龙头记忆、常用指标、资金面关注 | | 7 | 人设基因 | TA是谁? | 投资经历、哲学演变、里程碑事件、师承/影响源 | ### 蒸馏维度分支 蒸馏前需先判断博主属于长线还是短线交易者,再按对应维度侧重提取: | 维度 | 长线 | 短线 | |------|------|------| | 投资哲学 | 价值投资/波段交易 | 龙头战法/情绪周期/题材驱动 | | 核心能力 | 生意本质 + 估值 + 护城河 | 热点捕捉 + 情绪周期 + 量价关系 + 板块轮动 | | 分析周期 | 年级别(10年持有视角) | 日级别(隔日~2周) | | 数据驱动 | 财务报表 + 行业数据 | 盘面数据 + 资金流向 + 消息面 | --- ## 双层提取框架 蒸馏不仅提取「用了什么词」(表层),更要提取「怎么思考」(思维层)。二者缺一不可: **表层特征**(自动量化,脚本产出): - 个股/板块/术语/短语 频次统计 - 标题/开头/结尾 模式识别 - 字数/发布频率/免责声明 基础统计 **思维层特征**(脚本检测+AI深度分析): | 分析维度 | 脚本检测内容 | AI深度补充 | |---------|-------------|-----------| | 核心分析工具 | 宏观经济/产业链/财报/技术面/资金面/情绪/政策 8类思维框架评分 | 提炼博主独有的分析链条(如"事件→产业拆解→A股影响") | | 论证链模式 | 事件驱动/数据驱动/逻辑推演/类比推理/产业链分析/逆向思维 6类模式 | 还原博主典型论证步骤和推导逻辑 | | 语气量化 | 感叹句/疑问句/第一人称/口语化 四类标记篇均数值,自动分类 | 判断文风温度(高/中/低),提炼情感表达策略 | | 数据引用密度 | 每千字数据引用次数,自动分类(数据驱动型/主观判断型) | 分析数据引用场景和方式 | | 跨市场视角 | 美股/港股/A股/商品 四大市场引用检测 | 判断是否全球视角、多市场联动还是单一市场 | | 信息密度 | 投资内容占比评估(干货型 vs 水文型) | 区分深度分析和浅层评论 | --- ## 多维资料采集(超越文章本身) | 资料类型 | 来源 | 丰富哪个维度 | |---------|------|------------| | 人设背景 | 简介/置顶帖/自我介绍 | 人设基因DNA | | 投资哲学演变 | 按时间线分析早期vs近期内容 | 人设基因DNA + 交易体系DNA | | 里程碑事件 | 公开提及的重大盈亏/转折点 | 人设基因DNA | | 师承/影响源 | 提及的大师/书籍/引用频率 | 人设基因DNA | | 社交互动画像 | 评论/回复/争论/社区关系 | 互动特征DNA | | 历史预判追踪 | 过去预判与实际走势对比 | 市场判断DNA | | 观点一致性 | 同一主题不同时间观点演变 | 市场判断DNA | --- ## 🔑 鉴权 前往 [红狐 hub](https://redfox.hk/settings/api-keys?source=github) 获取 API Key,通过以下方式配置: ```bash # 方式一:配置文件(如 OpenClaw 的 ~/.openclaw/openclaw.json) { "env": { "REDFOX_API_KEY": "ak_xxxx..." } } # 方式二:终端环境变量 export REDFOX_API_KEY="ak_xxxx..." ``` 注册地址:[redfox.hk/login](https://www.redfox.hk/login) 积分消耗参考: | 文章数量 | 约消耗积分 | 精度评估 | |---------|-----------|---------| | 20篇 | ~8积分 | 基础了解,画像粗糙 | | 60篇 | ~25积分 | 推荐档位,画像较完整 | | 100篇 | ~50积分 | 高精度画像,特征稳定 | ## 前置要求 - Python 3.9+ - 依赖:`pip install requests` --- ## 执行流程 ### Phase 0: 环境准备 ```bash python "$SKILL_PATH/scripts/distill.py" --check-env ``` 自动检查并提示安装缺失依赖(requests 等)。 ### Phase 0.5: 前置交互 触发蒸馏前,必须由用户明确以下信息: 1. **公众号微信号**(如 `zxgbtz`) - 获取方式:打开公众号 → 点右上角 `···` → 更多信息 → 微信号 - 注意:微信号不是公众号名称,是唯一的字母/数字ID 2. **文章数量档位**(20 / 60 / 100) - 提示:数量越多积分消耗越多,但蒸馏精度越准。推荐60篇,100篇精度最佳(约50积分) > **自动补充**:博主背景资料(投资经历、师承、里程碑事件等)由 AI 通过 WebSearch 自动采集,无需用户提供。 ### Phase 1: 公众号文章采集 两步 API 流程: **Step 1:获取文章UUID列表** 调用 `POST https://redfox.hk/story/api/gzh/data/queryWorkList`,每页返回20条,offset 步进为20,循环分页直到达到目标数量。 参数:`account`(微信号)、`sortType: "2"`、`offset`(从0开始,每页+20)。 **Step 2:逐篇获取完整数据** 对每个 UUID,调用 `POST https://redfox.hk/story/api/gzh/data/workDetail` 获取正文、摘要、词云等完整数据。 ```bash # 采集60篇文章 python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 60 # 采集100篇(高精度) python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 100 ``` 输出标准化数据到 `output/{博主名}/`。 ### Phase 2: 多维资料整合分析 脚本自动完成基础统计分析(21项),AI 在此基础上执行多维资料整合: **信息丰富度分级**(脚本自动评估): | 等级 | 特征 | 应对策略 | |------|------|---------| | **A 级**(信息充裕) | ≥60篇、高信息密度、多维度数据充分 | **反面检验**:博主看多时,聪明人为什么看空? | | **B 级**(信息适中) | 20-59篇、部分维度数据不足 | 每个推算结论标注置信度 | | **C 级**(信息稀缺) | <20篇、低信息密度 | **第一性原理提问**,不拼凑"看起来完整"的画像 | **分析维度并行执行:** 1. **表层内容分析** — 统计 + 词云 + 结构分析 + 交易术语 + 个股/板块频次 2. **思维层分析** — 核心分析工具 + 论证链模式 + 语气量化 + 数据引用密度 + 跨市场视角 + 信息密度 3. **社交互动分析** — 评论/回复/争论风格/社区关系 4. **人设背景分析** — 简介/里程碑/师承/投资哲学演变/推荐书籍 5. **投资观点追踪** — 历史预判/准确率/观点一致性/认错修正方式 ### Phase 3: 七维DNA蒸馏 #### Step A:生成数据底稿 脚本产出: - `output/{博主名}_统计数据.json` — 结构化统计分析结果 - `output/{博主名}_数据底稿.md` — 结构化统计数据 - `output/{博主名}_蒸馏任务.md` — AI蒸馏任务清单 - `output/{博主名}_画像.json` — 结构化JSON画像(校验用) #### Step B:AI生成风格画像 AI 读取蒸馏任务,按七维DNA框架生成最终产物: **风格画像文件**:`output/{博主名}_风格画像.md` 包含7大章节,每个章节必须包含: - 具体特征描述(非空话) - 原文证据引用(至少2条) - 可复用的规则/模板 - 蒸馏置信度标注(高/中/低) #### Step C:风格化分析输出规范 当使用蒸馏画像生成风格化的个股/市场分析时,输出必须包含以下两部分: **1. 数据来源与局限表格** | 数据项 | 来源 | 说明 | |--------|------|------| | (示例)股价 XX 元、涨跌 ±XX% | 东方财富/雪球(日期) | 收盘价,非实时盘中数据;不同平台可能有分钟级延迟 | | (示例)PE XX 倍 / EPS XX | 中财网/财报(季度) | 基于最新可获取财报数据,可能因业绩变动而失真 | | (示例)定增 XX 亿 | 公司公告(日期) | 尚处预案阶段,存在审批不确定性 | | (示例)负债 XX 亿 | 财报时点数据 | 当前负债状况可能已变化 | 并附加局限声明: > 以上行情数据为公开平台聚合数据,非交易所直连实时数据;基本面数据基于最新可获取财报,可能与当前实际经营状况存在差异。 **2. ⚠️ AI 风格模拟免责段落** > ⚠️ **AI 风格模拟,不构成投资建议。** 本文为 AI 基于对「{博主名}」公众号的七维DNA蒸馏画像生成的风格模拟内容,与原大V本人无关。文中所有观点、判断、推荐均不代表{博主名}本人立场,亦不构成任何买入/卖出/持有建议。股市有风险,投资需谨慎。 ### Phase 4: 质量校验 #### 蒸馏准确性校验(硬性准出标准) ```bash python "$SKILL_PATH/scripts/distill.py" --validate --author "博主名" --sample 10 ``` **三维度评分体系:** | 校验维度 | 说明 | 权重 | |---------|------|------| | A. 个股提及 | 画像声明的常提及个股是否在文章中真实出现 | 40% | | B. 风格特征 | 标志性表达、标题模式、开头/结尾模式、字数范围是否匹配 | 35% | | C. 投资体系 | 核心流派、持仓周期、板块偏好是否与文章一致 | 25% | **准出标准:综合准确率 ≥ 80%** - ≥ 80%:蒸馏通过,画像可用于风格模拟 - < 80%:需补充蒸馏——仔细阅读raw全文,更新画像中不准确的字段后重新校验 - 任一维度低于60%:该维度需要完全重写 #### 蒸馏质量软性检查(双层审计) 审计分两层:**表层特征**权重 60%,**思维层特征**权重 40%。二者缺一不可——表层保证「像博主说的话」,思维层保证「像博主的思考」。 **表层检查(60%):** | 检查项 | 通过标准 | 权重 | 层级 | |--------|---------|------|------| | 标志性表达命中率 | > 40% | 10% | 表层 | | 交易体系覆盖度 | > 70% | 10% | 表层 | | 文章结构匹配度 | > 60% | 10% | 表层 | | 盘面指标覆盖 | > 50% | 10% | 表层 | | 语气一致性 | 偏差 < 20% | 10% | 表层 | | 交易术语覆盖 | > 50% | 10% | 表层 | **思维层检查(40%):** | 检查项 | 通过标准 | 权重 | 层级 | |--------|---------|------|------| | 核心思维匹配度 | > 60%(核心分析工具关键词覆盖) | 15% | 思维层 | | 论证方式匹配 | > 60%(论证链关键词覆盖) | 15% | 思维层 | | 哲学价值观体现 | > 50%(投资格言自然融入分析逻辑) | 10% | 思维层 | **综合评分 > 70 分准出(软性),< 70 分打回重新蒸馏。** #### 校验执行规则 - **每次画像更新后**必须执行校验 - **每月**全量校验所有博主画像 - 增量同步获取新文章后,如新文章涉及画像未覆盖的个股/板块,需更新画像 --- ## 使用方式 ### 自然语言触发(推荐) 直接对 AI 说: ``` 蒸馏公众号 zshbtz ``` AI 会自动执行 Phase 0 → 4 完整流程。 ### 命令行 ```bash # 蒸馏(60篇文章,推荐档位) python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 60 # 高精度蒸馏(100篇) python "$SKILL_PATH/scripts/distill.py" --account "zshbtz" --count 100 # 蒸馏后校验画像准确性(≥80%准出) python "$SKILL_PATH/scripts/distill.py" --validate --author "财躺平" --sample 10 # 环境检查 python "$SKILL_PATH/scripts/distill.py" --check-env ``` --- ## 数据与合规原则 - **禁止LLM编造**交易记录、持仓数据、交割单等未公开信息 - 严格区分**原文/原帖**与**AI蒸馏结论** - 交叉验证文章描述与实际市场数据(如有) - 所有蒸馏产物标注蒸馏置信度 - 盘面数据必须实时采集,**禁止 LLM 编造涨跌停、资金流向等数据** - **所有面向用户的 AI 生成投资分析输出,必须包含两段固定声明**: 1. **[数据来源与局限]** 表格 — 逐项标注引用的股价、PE、定增、负债等关键数据的来源平台及具体局限(详见 Phase 3 Step C) 2. **[AI 风格模拟,不构成投资建议]** 段落 — 明确标注为 AI 基于蒸馏画像的风格模拟,与原大V本人无关,不构成任何买入/卖出/持有建议(详见 Phase 3 Step C 固定模板) --- ## 文件结构 ```text investor-distiller/ ├── SKILL.md # 本文件 ├── scripts/ │ ├── distill.py # 主蒸馏脚本(调度+统计+校验) │ └── gzh.py # 公众号数据采集(queryWorkList + workDetail) ├── assets/ │ └── profile_template.md # 七维DNA风格画像输出模板 ├── references/ │ └── 蒸馏维度规范.md # 七维DNA详细规范 └── output/ # 蒸馏产物输出目录 ├── {博主名}_uuids.json # UUID 缓存(避免重复扣积分) ├── {博主名}_统计数据.json # 脚本统计分析结果 ├── {博主名}_完整文章.json # 完整正文落盘(供校验/AI精读) ├── {博主名}_数据底稿.md # 结构化数据底稿 ├── {博主名}_蒸馏任务.md # AI蒸馏任务清单 ├── {博主名}_画像.json # 结构化JSON画像(校验用) ├── {博主名}_风格画像.md # AI生成的七维DNA画像 └── {博主名}_校验报告_YYYYMMDD.json # 准确性校验报告 ``` --- ## 依赖 ```bash pip install requests ```
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.