diff --git a/industry-deep/SKILL.md b/industry-deep/SKILL.md new file mode 100644 index 0000000..6a76cb2 --- /dev/null +++ b/industry-deep/SKILL.md @@ -0,0 +1,119 @@ +--- +name: industry-deep +description: 查询行业深度研报数据。当用户询问任何行业分析、市场规模、竞争格局、产业链、投资逻辑、政策法规、技术趋势时使用。支持原始Markdown(Part)查询、行业摘要、跨行业排名对比。关键词:行业分析、行业数据、行业报告、景气度、industry analysis。 +--- + +# 行业深度研报查询 (Industry Deep Analysis) + +连接 MySQL 数据库,查询行业深度研报数据。 +覆盖 ~20 个行业,每个行业包含 8 个 Part 深度分析原文(约 8-14K 字/Part)。 + +## 数据架构 + +### 核心数据源:Part 原文(`report_raw_parts` 表) + +Part 是 LLM 按固定 prompt 生成的深度分析 Markdown,**信息最完整、上下文最丰富**,是首选查询目标。 + +每个行业包含 9 个 Part(0-8),子章节结构跨行业基本一致(约 85% 一致性): + +| Part | 主题 | 子章节结构 | 典型字数 | +|------|------|-----------|---------| +| 0 (meta) | 目录 + 执行摘要 | YAML 元数据、目录索引、报告概览表、Part 生成明细 | ~1.4K | +| 1 | 行业定义与边界 | **1.1** GB/T 4754-2017 标准定义(分类层级表)→ **1.2** 与相邻行业的边界划分(多维对比表)→ **1.3** 核心产品/服务清单(市场规模) | ~7K | +| 2 | 市场规模追踪 | **2.1** 十年规模追踪 2015-2024(年度数据表+关键节点分析)→ **2.2** 规模预测 2025-2030(三情景分析+假设条件)→ **2.3** 细分市场结构(按产品/应用/区域)→ **2.4** 增长驱动因素深度分析 | ~9K | +| 3 | 竞争格局 | **3.1** 集中度分析(CR5/CR10/HHI 追踪表+驱动因素)→ **3.2** 龙头企业分层分析(Tier1/2/3 + 财务对标数据)→ **3.3** 竞争壁垒评估 | ~9K | +| 4 | Survival Metrics | 多个**生死指标**,每个含:定义 → 为何是生死线 → 基准值体系 → 龙头企业实测数据 → 改善路径。*指标因行业而异*(如轮胎业=产能利用率/替换配套比;细胞治疗=IND 获批数/临床转化率) | ~10K | +| 5 | 产业链价值分布 | **5.1** 产业链全景图(ASCII 结构图 + 各环节核心企业)→ **5.2** 各环节毛利率与话语权分析(利润分布表)→ **5.3** 成本结构深度拆分(总成本+分产品+头部企业对比) | ~14K | +| 6 | 政策法规监管 | **6.1** 核心政策清单(含文号、发布机构、日期、影响评级的完整表格)→ **6.2** 行业专项政策演进(按重点领域分类)→ **6.3** 审批注册要求 | ~10K | +| 7 | 技术演进创新 | **7.1** 当前主流技术路线(多维对比表 + 市场占比)→ **7.2** 技术发展历程(时间线 + 关键突破)→ **7.3** 技术迭代周期与驱动因素 | ~13K | +| 8 | 投资逻辑风险 | **8.1** 核心增长逻辑重构(3-4 条逻辑链,每条含数据支撑)→ **8.2** 风险清单(概率-影响矩阵 + 详细风险表)→ **8.3** 估值参考(上市公司估值对比表) | ~10K | + +### 辅助数据源:行业摘要(`industry_reports` 表) + +汇总表,存储每个行业的核心指标数值,适合**快速查数字**和**跨行业对比**: +- 景气度星级(1-5)、CAGR、毛利率、净利率、CR5/CR10/HHI、集中度趋势、headline + +### 补充数据源:Module(`report_modules` 表) + +从 Part 提取的结构化 JSON,主要服务前端 UI 展示。LLM 消费场景下一般不需要,Part 原文信息更完整。 + +## 命令接口 + +脚本路径: `~/.claude/skills/industry-deep/scripts/query_industry.py` + +### 1. 查找行业 +```bash +python ~/.claude/skills/industry-deep/scripts/query_industry.py lookup "轮胎" +python ~/.claude/skills/industry-deep/scripts/query_industry.py lookup "C2911" +``` + +### 2. 行业摘要(快速数字) +```bash +python ~/.claude/skills/industry-deep/scripts/query_industry.py summary C2911 +``` + +### 3. Part 原文(深度分析,首选) +```bash +python ~/.claude/skills/industry-deep/scripts/query_industry.py part C2911 2 # Part 2 市场规模 +python ~/.claude/skills/industry-deep/scripts/query_industry.py part C2911 3,5 # 多个 Part +python ~/.claude/skills/industry-deep/scripts/query_industry.py part C2911 all # 全部(慎用,~84K 字) +``` + +### 4. 跨行业排名 +```bash +python ~/.claude/skills/industry-deep/scripts/query_industry.py rank stars --top 5 +python ~/.claude/skills/industry-deep/scripts/query_industry.py rank cagr --top 10 +python ~/.claude/skills/industry-deep/scripts/query_industry.py rank gross_margin --top 5 +``` + +### 5. 列出所有行业 +```bash +python ~/.claude/skills/industry-deep/scripts/query_industry.py list +``` + +### 6. 结构化 Module(可选,通常不需要) +```bash +python ~/.claude/skills/industry-deep/scripts/query_industry.py module C2911 1 +``` + +## 回答策略 + +1. **先 lookup 确认行业代码**(除非用户已给出代码) +2. **Part 原文优先**: 根据问题类型查对应的 Part,信息最完整 +3. **summary 用于快速数字**: 只需要 CAGR、景气度等单个指标时用 summary +4. **rank 用于跨行业对比**: 排名、筛选场景 +5. **按需查询,不要一次查 all**: 根据问题精准选择 1-2 个 Part + +### 场景速查表 + +| 用户问题类型 | 推荐命令 | 关键子章节 | +|-------------|---------|-----------| +| "XXX 行业是什么,包含哪些" | part 1 | 1.1 标准定义、1.2 边界划分、1.3 产品清单 | +| "XXX 市场有多大" | part 2 | 2.1 十年追踪、2.2 预测、2.3 细分市场 | +| "XXX 行业增长驱动因素" | part 2 | 2.4 增长驱动因素 | +| "XXX 行业集中度/龙头" | part 3 | 3.1 集中度(CR5/HHI)、3.2 企业分层 | +| "XXX 行业哪些公司风险高" | part 4 | 各生死指标 + 龙头实测数据 | +| "XXX 产业链结构" | part 5 | 5.1 全景图、5.2 毛利率话语权 | +| "XXX 行业成本结构" | part 5 | 5.3 成本拆分 | +| "XXX 行业有哪些政策" | part 6 | 6.1 政策清单、6.2 专项演进 | +| "XXX 行业技术趋势" | part 7 | 7.1 技术路线、7.2 发展历程 | +| "XXX 值不值得投资" | part 8 | 8.1 增长逻辑、8.2 风险、8.3 估值 | +| "XXX 行业景气度" | summary | 快速查星级+CAGR+毛利率 | +| "哪些行业景气度最高" | rank stars | 跨行业对比 | +| "高成长行业有哪些" | rank cagr | 跨行业对比 | +| 综合分析(多维度) | part 0 + 相关 Parts | 先读 meta 执行摘要,再查具体 Part | + +## 安装 + +```bash +pip install -r ~/.claude/skills/industry-deep/requirements.txt +``` + +唯一第三方依赖为 `pymysql`。 + +## 约束 + +- 数据库: MySQL @ 192.168.1.10:3306 (局域网,需在局域网内访问) +- 数据库连接信息可通过环境变量 `INDUSTRY_DEEP_DB_*` 覆盖(见 `scripts/db_config.py`) +- 当前约 20 个行业,数据来源为 V3 深度研报 LLM 生成 +- Part 原文为 LLM 生成的 Markdown,子章节结构约 85% 跨行业一致,个别行业可能有小幅偏差 diff --git a/industry-deep/requirements.txt b/industry-deep/requirements.txt new file mode 100644 index 0000000..9e9f6b1 --- /dev/null +++ b/industry-deep/requirements.txt @@ -0,0 +1 @@ +pymysql>=1.0.0 diff --git a/industry-deep/scripts/__pycache__/db_config.cpython-310.pyc b/industry-deep/scripts/__pycache__/db_config.cpython-310.pyc new file mode 100644 index 0000000..1e4c5a7 Binary files /dev/null and b/industry-deep/scripts/__pycache__/db_config.cpython-310.pyc differ diff --git a/industry-deep/scripts/db_config.py b/industry-deep/scripts/db_config.py new file mode 100644 index 0000000..140f5a7 --- /dev/null +++ b/industry-deep/scripts/db_config.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +"""数据库连接配置 —— 供 industry-deep Skill 查询脚本使用。 + +优先读取环境变量 INDUSTRY_DEEP_DB_*,否则使用默认值。 +""" +import os + +DB_CONFIG = { + "host": os.environ.get("INDUSTRY_DEEP_DB_HOST", "192.168.1.10"), + "port": int(os.environ.get("INDUSTRY_DEEP_DB_PORT", "3306")), + "user": os.environ.get("INDUSTRY_DEEP_DB_USER", "sunjiewei"), + "password": os.environ.get("INDUSTRY_DEEP_DB_PASS", "sunjiewei@vf"), + "database": os.environ.get("INDUSTRY_DEEP_DB_NAME", "industry_deep"), + "charset": "utf8mb4", +} diff --git a/industry-deep/scripts/query_industry.py b/industry-deep/scripts/query_industry.py new file mode 100644 index 0000000..4dad64f --- /dev/null +++ b/industry-deep/scripts/query_industry.py @@ -0,0 +1,304 @@ +# -*- coding: utf-8 -*- +"""行业深度研报查询脚本 —— 供 Claude Skill 使用。 + +连接 MySQL 数据库,查询行业报告的结构化数据和原始 Markdown 文本。 +依赖: pymysql(项目已安装)。 + +用法: + python query_industry.py [args...] + +子命令: + lookup 按关键词或代码查找行业 + summary 获取行业核心指标摘要 + module 获取结构化 Module JSON + part 获取 Part 原始 Markdown + rank [--top N] 跨行业排名 + list 列出所有行业 +""" +from __future__ import annotations + +import json +import sys +import os + +# Windows 终端 GBK 编码问题 +sys.stdout.reconfigure(encoding="utf-8") +sys.stderr.reconfigure(encoding="utf-8") + +# 数据库配置 +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from db_config import DB_CONFIG + +try: + import pymysql +except ImportError: + import subprocess + print("pymysql 未安装,正在自动安装...", file=sys.stderr) + subprocess.check_call([sys.executable, "-m", "pip", "install", "pymysql", "-q"]) + import pymysql + + +def _get_conn(): + """获取数据库连接。""" + return pymysql.connect(**DB_CONFIG, cursorclass=pymysql.cursors.DictCursor) + + +# --------------------------------------------------------------------------- +# 子命令实现 +# --------------------------------------------------------------------------- + +def cmd_lookup(keyword: str): + """按关键词查找行业,模糊匹配 name 和 code。""" + conn = _get_conn() + try: + with conn.cursor() as cur: + like = f"%{keyword}%" + cur.execute( + """SELECT code, name, stars, stars_label, headline + FROM industry_reports + WHERE name LIKE %s OR code LIKE %s + ORDER BY stars DESC""", + (like, like), + ) + rows = cur.fetchall() + finally: + conn.close() + + if not rows: + print(f"未找到匹配「{keyword}」的行业") + return + + print(f"找到 {len(rows)} 个行业:\n") + for r in rows: + stars_display = "★" * r["stars"] + "☆" * (5 - r["stars"]) + print(f" {r['code']} {r['name']} {stars_display} ({r['stars_label']})") + if r["headline"]: + print(f" {r['headline']}") + print() + + +def cmd_summary(code: str): + """获取行业核心指标摘要。""" + conn = _get_conn() + try: + with conn.cursor() as cur: + cur.execute( + """SELECT code, name, stars, stars_label, cagr, gross_margin, + net_margin, cr5, cr10, hhi, concentration_trend, + headline, total_characters, report_version, generated_at + FROM industry_reports WHERE code = %s""", + (code,), + ) + row = cur.fetchone() + finally: + conn.close() + + if not row: + print(f"未找到行业: {code}") + return + + print(json.dumps(row, ensure_ascii=False, indent=2, default=str)) + + +def cmd_module(code: str, module_num: str): + """获取结构化 Module JSON 数据。""" + conn = _get_conn() + try: + with conn.cursor() as cur: + if module_num == "all": + cur.execute( + """SELECT rm.module_num, rm.module_json + FROM report_modules rm + JOIN industry_reports ir ON ir.id = rm.report_id + WHERE ir.code = %s + ORDER BY rm.module_num""", + (code,), + ) + else: + cur.execute( + """SELECT rm.module_num, rm.module_json + FROM report_modules rm + JOIN industry_reports ir ON ir.id = rm.report_id + WHERE ir.code = %s AND rm.module_num = %s""", + (code, int(module_num)), + ) + rows = cur.fetchall() + finally: + conn.close() + + if not rows: + print(f"未找到行业 {code} 的 Module 数据") + return + + for r in rows: + mj = r["module_json"] + data = json.loads(mj) if isinstance(mj, str) else mj + print(f"=== Module {r['module_num']} ===") + print(json.dumps(data, ensure_ascii=False, indent=2)) + print() + + +def cmd_part(code: str, part_nums: str): + """获取 Part 原始 Markdown 文本。""" + conn = _get_conn() + try: + with conn.cursor() as cur: + if part_nums == "all": + cur.execute( + """SELECT rrp.part_num, rrp.content, rrp.char_count + FROM report_raw_parts rrp + JOIN industry_reports ir ON ir.id = rrp.report_id + WHERE ir.code = %s + ORDER BY rrp.part_num""", + (code,), + ) + else: + nums = [int(x.strip()) for x in part_nums.split(",")] + placeholders = ",".join(["%s"] * len(nums)) + cur.execute( + f"""SELECT rrp.part_num, rrp.content, rrp.char_count + FROM report_raw_parts rrp + JOIN industry_reports ir ON ir.id = rrp.report_id + WHERE ir.code = %s AND rrp.part_num IN ({placeholders}) + ORDER BY rrp.part_num""", + [code] + nums, + ) + rows = cur.fetchall() + finally: + conn.close() + + if not rows: + print(f"未找到行业 {code} 的 Part 数据") + return + + for r in rows: + label = "meta (目录+执行摘要)" if r["part_num"] == 0 else f"Part {r['part_num']}" + print(f"{'=' * 60}") + print(f" {label} ({r['char_count']} 字)") + print(f"{'=' * 60}") + print(r["content"]) + print() + + +def cmd_rank(field: str, top: int = 5): + """跨行业排名,按指定字段降序。""" + field_map = { + "stars": "stars", + "cagr": "cagr_value", + "cagr_value": "cagr_value", + "gross_margin": "gross_margin_value", + "gross_margin_value": "gross_margin_value", + } + column = field_map.get(field) + if not column: + print(f"不支持的排序字段: {field}") + print(f"可用字段: {', '.join(field_map.keys())}") + return + + conn = _get_conn() + try: + with conn.cursor() as cur: + cur.execute( + f"""SELECT code, name, stars, stars_label, cagr, gross_margin, headline + FROM industry_reports + WHERE {column} IS NOT NULL + ORDER BY {column} DESC + LIMIT %s""", + (top,), + ) + rows = cur.fetchall() + finally: + conn.close() + + if not rows: + print("暂无数据") + return + + print(f"Top {top} — 按 {field} 排序:\n") + for i, r in enumerate(rows, 1): + print(f" {i}. {r['code']} {r['name']}") + print(f" 景气度={r['stars']}★ CAGR={r['cagr']} 毛利率={r['gross_margin']}") + if r["headline"]: + print(f" {r['headline']}") + print() + + +def cmd_list(): + """列出所有行业。""" + conn = _get_conn() + try: + with conn.cursor() as cur: + cur.execute( + "SELECT code, name, stars FROM industry_reports ORDER BY code" + ) + rows = cur.fetchall() + finally: + conn.close() + + if not rows: + print("暂无行业数据") + return + + print(f"共 {len(rows)} 个行业:\n") + for r in rows: + print(f" {r['code']} {r['name']} {'★' * r['stars']}") + + +# --------------------------------------------------------------------------- +# 主入口 +# --------------------------------------------------------------------------- + +def main(): + if len(sys.argv) < 2: + print(__doc__) + sys.exit(0) + + cmd = sys.argv[1] + + if cmd == "lookup": + if len(sys.argv) < 3: + print("用法: query_industry.py lookup ") + sys.exit(1) + cmd_lookup(sys.argv[2]) + + elif cmd == "summary": + if len(sys.argv) < 3: + print("用法: query_industry.py summary ") + sys.exit(1) + cmd_summary(sys.argv[2]) + + elif cmd == "module": + if len(sys.argv) < 4: + print("用法: query_industry.py module <1-5|all>") + sys.exit(1) + cmd_module(sys.argv[2], sys.argv[3]) + + elif cmd == "part": + if len(sys.argv) < 4: + print("用法: query_industry.py part <0-8|all>") + sys.exit(1) + cmd_part(sys.argv[2], sys.argv[3]) + + elif cmd == "rank": + if len(sys.argv) < 3: + print("用法: query_industry.py rank [--top N]") + sys.exit(1) + field = sys.argv[2] + top = 5 + if "--top" in sys.argv: + idx = sys.argv.index("--top") + if idx + 1 < len(sys.argv): + top = int(sys.argv[idx + 1]) + cmd_rank(field, top) + + elif cmd == "list": + cmd_list() + + else: + print(f"未知命令: {cmd}") + print(__doc__) + sys.exit(1) + + +if __name__ == "__main__": + main()