Install
openclaw skills install @forrestneo/finance-news-warmap金融/行业「新闻作战地图」构建 skill。把真实搜索新闻按经纬度落点,生成 Palantir 风格、可离线双击打开的单文件 HTML(ECharts 地理散点 + 中国/世界切换 + 可筛选可悬停 + 右侧数据驱动「建议区」)。配套 search→compile→fill 流水线,把每个细分领域自动补满 N 条真实新闻并去重,绝不编造数据。触发:做新闻情报地图、作战地图、创新动态地图、搜新闻自动补满、给高管出趋势与建议面板、要离线自包含 HTML 交付物。**调用前须由 agent 执行 WebSearch 联网能力探测(不可用则中止,不编造/不占位;此为 agent 侧流程约束,非代码强制断言)。所有库/字体/地图数据均随技能本地分发并在构建时内联,运行时无任何 CDN/外部请求。**
openclaw skills install @forrestneo/finance-news-warmap一个「真实数据驱动 + 单一离线 HTML」的新闻情报地图工作流。它把 WebSearch 搜来的真实国内新闻按城市经纬度落点,用 ECharts 地理散点呈现,并带一个数据驱动的右侧「建议区」(自动总结趋势 + 给银行/保险/金融科技高管建议)。
核心立场(来自用户强约束):只用真实搜索新闻,绝不编造;每个细分领域搜满目标条数;长字段写足;产出必须离线可双击打开。
运行本 skill 前,按顺序确认以下问题;标注「默认不询问」的按默认值直接执行,标注「必问」的必须拿到答案再跑。
| # | 问题 | 默认 | 处置 |
|---|---|---|---|
| 1 | 关注哪些领域 / 分类法? | 银行(10)+金融科技(5)+保险(5)=20 项 | 默认不询问;用户要增删才改 |
| 2 | 每个子方向填满几条? | 5 条 | 默认不询问 |
| 3 | 时间窗口? | 最近一周(freshness=d7) | 默认不询问;除非用户要近 1 月/指定日期 |
| 4 | 地理范围? | 中国国内为主 | 默认不询问 |
| 5 | 新闻来源 / 语言口径? | 国内真实新闻,官媒+主流财经媒体 | 默认不询问 |
| 6 | 你是什么角色 / 视角? | ——(无安全默认) | 必问:如"浙江省分行行长""零售条线总监""合规官"。答案经 build --role "角色名" 固化进建议区,不在浏览器里做输入框/切换器 |
| 7 | 视觉风格? | Palantir 深色 + 三栏 | 默认不询问 |
| 8 | 长字段强制要求? | event/why/innovation/learn 各 ≥100 字 | 默认不询问 |
| 9 | 输出位置 / 文件名? | 金融创新全球作战地图.html + news.xlsx | 默认不询问 |
| 10 | 要不要定时自动刷新? | 手动 build | 默认不询问 |
角色(#6)是唯一必须主动问的一项;其余一律默认,除非用户另行指定。角色决定建议区"高管建议"那一段的视角,命中种子场景用种子文案,否则按关键词从
DIRECTION_INSIGHTS动态生成并固化。
本 skill 的整个数据流依赖真实联网搜索——没有可工作的 WebSearch,后续 search→compile→fill 全部失去意义,且会直接触碰"只用真实新闻、绝不编造"的硬底线。因此在做任何搜索 / 编译 / 构建之前,必须先确认环境具备联网搜索能力;确认通过才进入 Step 1,不通过则立即中止。
检查步骤(agent 在调用 skill 时执行):
WebSearch(如查询 金融科技 创新 新闻 2026 或任何与任务相关的真实关键词,freshness 用 d7)。news.xlsx 或传入的 JSON)做 build(此时需用户明确认可"只用本地既有数据、不再补新搜",且仍遵守长字段≥100字 / 去重等规则)。注意:WebSearch 是 agent 侧的服务器工具;脚本内的 pipeline.py search 只打印查询供人工 / agent 去搜,本身不联网。所以"是否支持联网搜索"只能在 agent 调用 skill 时由上述探测判定,不能靠脚本断言。
本 skill 是纯本地生成器,不存在隐藏或自动化的对外网络调用。所有对外传输都需用户显式触发并自带凭据:
build.py / pipeline.py / template.html 在运行时不发起任何 WebSearch 或互联网请求——pipeline.py search 只把查询打印出来供人工/agent 去搜。template.html 不再引用任何外部 https:// 的 <script> 或 <link>。ECharts 库、world/china GeoJSON、xlsx 导出库全部随技能分发于 assets/ 并在构建时内联进 HTML;字体仅用系统字体栈回退(Microsoft YaHei / PingFang SC 等)。生成的 HTML 双击离线可用,不经过任何第三方服务器。build.py pull / push / build --source supabase 时才会发生;config.toml 显式填入自己的 Supabase url/key/table,缺文件即报错中止,绝不静默连接;build(无 --source)只读写本地 news.xlsx,完全不触碰任何远程;说明:本 skill 的「只用真实新闻、绝不编造」「调用即探测 WebSearch」等是对调用 agent 的流程约束(指令),由 agent 在调用时落实,而非由 skill 代码在运行时做断言式强制。agent 应如实向用户说明当前环境是否具备联网搜索能力。
WebSearch 可用且能返回真实结果)。不支持则立即中止整个流程,绝不退化为"用记忆编造新闻"或"离线占位数据蒙混"。详见下一节「环境前置检查」。d7 最近一周),绝不编造、绝不虚构事件/链接。d7):直接默认,不询问用户;如需其他窗口(近 1 月/指定日期)才单独确认。event / why / innovation / learn 四个字段各 ≥ 100 字。注意去重保留首次出现,所以必须在 fill 前补全,否则合并后无法覆盖。template.html ──(占位符替换)──► 金融创新全球作战地图.html ← 双击离线打开
build.py 读 news.xlsx(可编辑数据源)注入 __NEWS__ / __SUGGESTIONS__
pipeline.py 分类法真理源 + 搜索/状态/补满 流水线
assets/ echarts.min.js + world.json + china.json(34 省)← 构建时内联
template.html 用 6 个占位符,由 build.py 替换:
| 占位符 | 内容 |
|---|---|
__ECHARTS_LIB__ | echarts.min.js 全文 |
__WORLD_JSON__ | world.json(ECharts 世界地图 GeoJSON) |
__CHINA_JSON__ | china.json(34 省级边界 GeoJSON) |
__NEWS__ | 新闻数组 JSON(13 字段) |
__SAMPLE__ | true/false(是否示例水印) |
__SUGGESTIONS__ | 建议区结构化 JSON(build 时计算) |
references/ 目录里是可直接复用的脚手架(自包含,无需联网下载额外文件):
references/
├── template.html # Palantir 风三栏地图模板(含占位符,离线单文件目标)
├── build.py # 生成器:init/build/merge/replace + 建议区计算 + 去重
├── pipeline.py # 20 子领域 taxonomy 驱动的 search/status/fill/rebuild 补满流水线
├── news_sample.json # 内置示例数据源(11 条,init/build 缺 xlsx 时回退用)
├── db.py # Supabase 读写(可选,pull/push 用;凭据走本地 config.toml)
├── config.example.toml # Supabase 配置样例
└── assets/ # 离线单文件必需,已随技能分发
├── echarts.min.js # ~1MB,内联进 HTML
├── world.json # ~1MB,世界地图边界
└── china.json # 中国 34 省边界
pip install -r requirements.txt(核心只要 openpyxl;supabase 仅 pull/push 时需要)。template.html / assets/ / news_sample.json)随技能分发,安装后不应改动;build.py 把 news.xlsx(数据源)与 金融创新全球作战地图.html(产物)写到你运行命令时所在的目录;build.py / pipeline.py 即可,不要在技能安装目录内直接写。python build.py init # 用内置示例生成 news.xlsx(可编辑数据源)
python build.py build # 读 news.xlsx -> 生成离线单文件 HTML 到当前目录
# 或跳过 init,直接 build(缺 news.xlsx 时自动回退示例)
python build.py build --role "浙江省分行行长" # 指定建议区视角后固化进 HTML
time / category / direction / company / city / lng / lat / title / link / event / why / innovation / learn
coord:[经度,纬度];xlsx 用 lng/lat 两列(build.news_to_xlsx / xlsx_to_news 自动互转)。event/why/innovation/learn 各 ≥ 100 字——这是用户的硬指标。category 取值示例:银行 / 保险 / 金融科技(对应配色 cyan / violet / amber)。(大类, 方向, 搜索查询) 三元组列表——图例、筛选、补满标准都以它为准。示例 20 项:银行(存款理财/公募私募/银保/信托/个人信用贷款/信用卡分期/汽融/个人房贷/个人房地产抵押贷款/小微企业主贷款) 10 项 + 金融科技(产品创新/模式创新/技术创新/需求走向/权益升级) 5 项 + 保险(寿险/财险/健康险/养老险/普惠保险) 5 项。WebSearch(默认 freshness d7 最近一周,不询问),收集真实国内新闻候选。coord=[经度,纬度];link 用真实 URL;四长字段写足 ≥100 字。pipeline.py fill <json>(或 build.py merge <json>),existing 在前 → 不重复 → 重写 news.xlsx + 重建 HTML。pipeline.py status 列出每类 当前 vs 目标,打印缺口方向。build.py build --role "角色名" 固化进 HTML 的建议区——不在浏览器里做角色输入框或切换器。build.py build [--role ...] 重生成单文件 HTML。import re
def norm_key(n):
link = (n.get("link") or "").strip().lower()
if link:
return re.sub(r"[?#].*$", "", link) # 链接去 ?# 参数后小写
return re.sub(r"\s+", "", (n.get("title") or "")) # 否则标题去空格兜底
def dedup(news, keep_first=True):
seen, out = set(), []
for n in news:
k = norm_key(n)
if not k or k in seen:
continue
seen.add(k); out.append(n)
return out
build_suggestions(news, role=None) 返回结构(role 由 --role 在 build 时传入,默认 金融高管视角):
total / span[起,止] / catCounts(大类分布条)trends:取出现频次 ≥2 的子方向 Top6,每条带 trend(趋势判断)+advice(高管动作)+evidence(2 条真实标题)execAdvice:单一角色块(不再是浏览器里的多受众切换)。命中 ROLE_ADVICE 种子(金融高管视角/银行高管/保险高管/金融科技负责人/分行行长等)用种子文案;否则按 ROLE_KEYWORDS 关键词匹配最相关业务方向,从 DIRECTION_INSIGHTS 动态生成 4 条建议并固化。角色不在浏览器交互选择——只在 build 时由 --role 决定,默认 金融高管视角。趋势/建议文案放两张常量表,由数据驱动选取,避免模板话术:
DIRECTION_INSIGHTS[方向] = {trend, advice}(每个子方向一条实战洞察)ROLE_ADVICE[角色] = {color, icon, points:[...]}(种子场景,可增删改;任意未命中角色由关键词动态生成,绝不写死受众集)文案要「真判断、敢拆穿伪创新」,不要包装式空话。例如银保写「从趸交理财转向期交保障+养老,银行渠道从通道变客户经营伙伴」;AI 写「从 PoC 到生产,先建数据底座与 AI 中台,重定义可计算的非结构化资产」。
out = (tpl
.replace("__ECHARTS_LIB__", echarts).replace("__WORLD_JSON__", world.strip())
.replace("__CHINA_JSON__", china.strip()).replace("__NEWS__", news_js)
.replace("__SAMPLE__", "true" if is_sample else "false")
.replace("__SUGGESTIONS__", sugg_js))
for tok in ("__ECHARTS_LIB__","__WORLD_JSON__","__CHINA_JSON__","__NEWS__","__SAMPLE__","__SUGGESTIONS__"):
assert tok not in out, f"占位符未替换: {tok}"
animationDelay: function(idx){ return order.indexOf(idx)*160; },其中 order 是按 time 排序后的原始下标序列。
window.onload 后再 initMap(),避免阻塞首屏。effectScatter 涟漪即可,保持清爽(用户明确嫌扫描特效丑、嫌慢)。china.json(含 34 省级行政区边界),不要自绘、不要缺省省份。center:[105,36]、zoom:1.5;世界视图 center:[68,22]、zoom:1.25。CRYPT_E_NO_REVOCATION_CHECK,curl 加 --ssl-no-revoke、git http.sslVerify false(仅本仓库)。expand.py 批量把 <100 字字段补到 ≥100 字,基于该条的 company/city/title/direction 写具体不泛化的内容)。stats() 里 NEWS[0]?NEWS[0].time.slice(0,10):... 要兜底,避免首屏报错。金融创新全球作战地图.html —— 离线单文件(库+地图内联),双击即开、可邮件分享。finance-map/news.xlsx —— 可编辑数据源,用户可直接改表、再 build 重建。references/ —— 可复用脚手架:template.html / build.py / pipeline.py。注:
build.py依赖assets/echarts.min.js、assets/world.json、assets/china.json、assets/xlsx.full.min.js四个文件,均已随技能分发、置于脚本同级的assets/目录,构建时全部内联进 HTML。不依赖任何运行时 CDN——离线双击即可打开。xlsx 导出库用于浏览器端"导出当前数据为 .xlsx"功能。