#新 SOLO 初体验
【实战项目】股票新闻热点分析系统(Bloomberg 风格)
【体验心得】MTC 写方案, Code 模式落地, 一把梭哈到能跑的框架
先打个招呼, 大家好呀我来交作业了. 这次拿到 SOLO 内测资格, 我就寻思别光写两句夸夸, 得整点真东西出来, 不然对不住这资格. 我平时爱看新闻和行情, 但市面上很多终端要么贵, 要么信息一坨糊, 所以我拿这个机会, 直接做了个对标 Bloomberg 终端信息呈现方式的股票新闻热点分析系统, 先把框架和可用免费实时新闻接口方案跑通.
截图我先占个位, 发帖的时候我会把 SOLO 的对话过程, 还有它帮我生成的页面原型, 接口定义, 以及我自己跑起来的 Demo 截图一并贴上来.
截图 1
截图 2
下面是正文, 按我自己的逻辑来, 我会尽量写得更像真实记录和复盘, 读起来别太较真哈, 主要是想让大家能直接照着上手.
0. 为啥选这个题, 我先说在前头
我参加活动, 不是为了堆一堆漂亮词, 主要想验证一件事, SOLO 这套东西到底能不能把一个比较复杂的产品, 从想法, 到架构, 到接口, 到 UI, 再到可运行原型, 连起来.
这个股票新闻热点分析系统, 看起来是个资讯产品, 实际上里面坑挺多, 合规, 数据源, 去重, 限频, 事件合并, 个股映射, 热度模型, 实时推送, 以及 UI 终端味儿的交互. 以前我自己做, 光写 PRD 和技术方案就得磨一阵子, 还容易写着写着跑偏. 这次我就想试试, 让 SOLO 一路跟着我掰扯, 我负责把方向掐住, 它负责把细节补齐, 还有帮我把那些重复劳动一口气干掉.
说实话, 这事挺带劲, 但也挺考验人, 因为你只要一松手, 它就容易写得像模板. 所以我一路上就盯着两个点, 一个是我得不断给边界和约束, 二个是我得要求它把工程上可落地的东西写出来, 不要光喊口号.
1. 先立规矩, 合规原则不定, 后面全是瞎忙
这块我吃过亏, 以前做聚合类产品, 最怕一开始图省事, 去抓一些付费墙内容, 或者抓登录态页面, 你以为能跑, 结果不是被封就是被投诉. 所以这次我第一步就让 SOLO 帮我把合规原则写死, 并且让它在后续所有模块里都默认遵守.
合规原则我就按下面来, 不整花的, 就几个硬要求.
1, 不接入也不抓取彭博社付费内容. 我们只对标 Bloomberg 的产品形态与工作流, 数据只来自公开,免费,可授权渠道, API,RSS,公告源,公开新闻聚合都行. 这句话我在方案里反复写, 免得以后有人拿来问, 你这是不是彭博搬运.
2, 只用官方 API, 开放 API, RSS 或明确允许的公开数据. 避免抓取付费墙, 登录态内容, 或条款里写明禁止爬取的网站. 我宁愿少一点源, 也别给自己埋雷.
3, 尊重条款与版权. 只保留来源链接, 标题, 发布时间, 媒体名, 以及必要的元信息. 正文不存全文也可以, 最多做摘要和要点提炼, 用户想看详情就跳转原文. 这个设计对合规特别友好, 也能降低存储压力.
4, 速率限制与缓存. 免费接口限频普遍很紧, 不做缓存就是作死. 这块我要求必须本地缓存 + 增量拉取, 同时对每个源做限频桶, 失败熔断, 自动切换.
5, 投资免责声明. 页面上要明确, 信息服务不构成投资建议. 这个不是装样子, 真要写上.
规矩不先立, 后面很容易越做越乱, 这句我是真心的.
2. 产品长啥样, 先把终端味儿定下来
我想做的是那种你一打开就能扫全局的终端风格, 三栏, 左边热点榜, 中间新闻流, 右边个股面板. 颜色对比强一点, 暗黑模式默认, 热度用灰到橙到红的渐变, 再配个小 sparkline, 看上去就像在用信息终端.
我在 SOLO 里是这么拆的.
2.1 一套前端, 多端发布
Web 用 Next.js/React + Tailwind + shadcn ui, 这套组合做高颜值很省心, 暗黑模式也容易.
桌面端我倾向 Tauri, 因为轻, 但你要生态丰富也可以 Electron. 核心是, 桌面端就是把同一套 Web 打包, 不要重复造轮子.
移动端先用 PWA, 省事, 有推送需求再看 Capacitor.
2.2 交互统一能力
响应式布局, 同一 URL 在桌面和手机自适应. 桌面端加个终端模式, 允许快捷键, 多面板布局.
实时推送, SSE 或 WebSocket. 我自己更喜欢 SSE, 简单, 断线重连也好处理.
我自己的想法是, 别整太花, 先让它跑起来再说.
3. 总体架构, 分层加可插拔, 不然你后面扩市场会哭
我让 SOLO 给我画了一版分层架构, 我看完觉得对, 就按这个走.
3.1 采集层 Ingestion
这里就是多个免费新闻源 Connector 并行拉取, 每个源都要做.
鉴权, token 管理
限频, token bucket
增量游标, since 或 max published_at
去重, hash(source + url + title + published_at)
失败熔断, 连续失败就降权, 冷却后半开恢复
健康度评分, 成功率, 延迟, 429, 5xx, 近 10 分钟有效条目数
这层不稳, 上面基本都白搭.
3.2 标准化层 Normalization
不同来源字段都不一样, 你得映射成统一模型 NewsItem.
统一时区, 全转 UTC.
统一语言字段, zh,en,ja 等.
保留 source_url 用于跳转.
摘要字段可选, 但要注意合规, 摘要最好是模型生成的短摘要, 不要抄全文.
3.3 分析层 Intelligence
这层才是产品灵魂, 主要几个事.
NER 实体识别, 抽公司名,ticker,主题.
个股映射, 把实体匹配到股票主数据 Instrument Master.
主题聚类, 同一事件跨媒体合并成 Story.
热度评分, 输出 0 到 100 百分比, 再映射成 0,25,50,75,100 五档.
事件影响可选, 情绪, 波动异常, 成交量异常.
3.4 服务层 API
REST 查询新闻, 热点, 个股, 配置.
SSE 推送增量新闻与热度变更.
3.5 展示层 UI
三栏终端式, 颜色编码热度徽章, 趋势小图, 主题标签, 来源可信度.
这套分层我个人感觉很适合用 SOLO, 因为你每一层都能单独问它, 让它把接口, 数据模型, 失败策略写清楚, 然后你把它们拼起来就行.
4. 免费新闻获取, 多源并行, 自动切换, 才像个终端
我做这种东西, 最怕单一数据源, 你一限频, 全站没新闻. 所以我从一开始就按多源策略设计.
4.1 数据源策略, 并行 + 轮询 + 熔断
并行拉取, 作为首选. 多个源同时跑, 统一去重合并, 这才实时.
轮询旋转, 用户可配. 比如每 60 秒切换一次源, 或每 N 分钟轮询一轮.
自动切换必备. 某源超时, 限频, 失败率升高, 就降权熔断, 自动换源.
我在方案里引入一个 SourceManager.
health_score, 成功率, 延迟, 429, 5xx, 近 10 分钟有效条目数
circuit_breaker, 连续失败阈值触发, 冷却, 半开
rate_limiter, 按源维度 token bucket
priority, 用户可配置偏好
这块你不搞, 大概率就等着被限频折腾, 真的挺烦.
4.2 推荐免费接口清单, 我用的是底座加拼图
我不装懂, 免费接口就那几类, 你想覆盖全市场就得组合. 我这版方案是底座一个全球聚合, 再加公告和少量垂直源.
底座.
GDELT 2.1, 免费, 全球, 多语言, 近实时. 用 Doc API 拉文章, 用 Events 做事件维度. 优点覆盖广, 缺点金融垂直一般, 但你做实体映射后就够用.
补充.
RSS 或 Atom, 特别适合交易所公告, 公司新闻室, 监管公告, 还有一些财经媒体公开 RSS. 优点合规可控, 缺点字段不统一, 需要解析和去重.
美股示例.
Finnhub, 有免费额度, 提供 Market News 和 Company News. 注意免费额度有限, 必须缓存限频.
SEC EDGAR, 免费, 8-K,10-Q,10-K 这些公告是影响事件的源头, 很值得接. 记得 EDGAR 对 User Agent 有要求, 必须设置联系信息, 别瞎写.
中港股和其他市场.
我建议优先公告 + 全球聚合 + RSS. 中文财经媒体覆盖你想做强, 得逐一确认条款, 最稳妥还是只存元数据加跳转, 不存全文.
4.3 统一新闻数据模型 NewsItem, 这个是全系统的骨架
我给它定义成这样, 这块是工程里最关键的约定.
id, hash(source + url + title + published_at)
source, gdelt,rss,finnhub,sec
source_url, 原文链接
title, 标题
summary, 可选短摘要
content_snippet, 可选短片段, 不存全文也行
language, zh,en 等
published_at, UTC
fetched_at, UTC
entities, 抽取实体
mapped_instruments, 映射到股票
topics, 主题
sentiment, 情绪可选
heat, 热度 score_pct 和 label
模型你不统一, 后面代码就很难写齐, 也很难维护.
5. Connector 怎么写, 这块我让 SOLO 给我拆成工程接口
我最喜欢 SOLO 的点之一, 是你可以直接让它按工程交付物写, 不要写成 PPT, 它就能输出一个个 Connector 的输入输出, 轮询策略, 去重策略, 失败策略.
我这里按每个源一个 Connector, 统一输出 NewsItem 数组.
5.1 GDELT Connector
输入, 关键词, 市场, 语言, 时间窗, 最近 15 分钟这种, 还可以站点过滤.
输出, 文章列表, 标题, 链接, 时间, 来源域名, 摘要字段如果有.
轮询间隔, 30 秒到 3 分钟, 可配.
增量, 用 max published_at 做游标, 再加 hash 去重.
失败, 限频超时就降权熔断.
5.2 RSS Connector
输入, RSS 列表, 每个 RSS 带权重和市场标签, 这个最好做成后台配置.
输出, 统一文章列表.
工程要点.
ETag 和 Last Modified 能用就用, 能省不少流量.
解析要兼容 RSS 和 Atom, HTML 清洗只做最小化, 保留链接.
去重用 url + title + 时间 + 来源 hash.
5.3 Finnhub Connector
输入, market news, 或按 ticker 拉公司新闻.
策略.
结合用户关注列表按 ticker 拉更省额度.
公共新闻流轮询周期更长, 别浪费额度.
5.4 SEC EDGAR Connector
输入, 表单类型过滤, 8-K,10-Q 等, 关注公司 CIK 映射.
输出, 公告条目, 标题, 链接, 时间, 公司.
工程要点.
User Agent 必须写联系信息, 合规.
公告事件对热度权重更大, 这个在热度模型里体现.
这个 connector 写好了, 系统就更有终端味儿了, 因为公告一出来就能抓到, 不用等媒体二手传播.
6. 股票主数据 Instrument Master, 新闻到个股映射, 真正的难点在这儿
我以前做过实体识别, 说实话最难的是消歧, 不是识别. 你识别出 Apple 很简单, 你要把它映射成 AAPL, 还得避免把 Apple 映射到别的乱七八糟的东西, 这就要一套主数据和打分.
6.1 Instrument Master 必备字段, 我建议至少要有这些
market, US,CN,HK,JP 等
ticker, 代码
name, 公司名
aliases, 别名库, 中文名, 英文名, 简称, 品牌名
exchange, 交易所
country, 国家地区
sector, 行业
identifiers, CIK, ISIN 等可选
updated_at, 同步时间
6.2 免费主数据来源思路, 做成插件化同步任务
美股, SEC 公司 CIK 映射是公开数据, 再结合交易所公开列表, 基本够用.
A 股, 港股, 其他市场, 优先找官方披露的公开列表或公开下载, 必要时用有免费额度且合规授权的数据服务, token 让用户自己申请.
关键点, 主数据同步必须独立任务, 每天或每周跑, 和新闻实时链路解耦. 不然你一边拉新闻一边补主数据, 系统要乱套.
6.3 新闻实体识别与消歧流程, 我这版是规则优先再模型
流程我按下面走.
第一步, 规则优先.
先识别显式代码, 例如 $AAPL,(AAPL),00700.HK,600519.SH. 这一步准确率高, 成本低.
第二步, NER 模型识别公司名,品牌名,机构名.
中文可以考虑 HanLP 或 PaddleNLP, 英文 spaCy 加 transformer 都行.
第三步, 候选召回.
用别名表 + 模糊匹配, BM25 或向量都行.
第四步, 消歧打分.
同篇是否出现行业词,交易所后缀,国家城市
用户关注列表加权, 可选
来源语言与市场匹配度
输出 confidence, 低于阈值不强行绑定, 宁可漏, 别乱标.
误标一次, 用户就很难再信你了.
7. 热点与热度模型, 0 到 100 怎么算得像那么回事
我一开始就定了展示规则, 因为产品上需要固定档位, 你不能一会儿 63.2 一会儿 64.7, 用户看不懂.
7.1 展示规则, 5 档加连续值
内部先算 heat_raw, 0 到 100 连续值, 用于排序和趋势.
展示时映射成 0,25,50,75,100.
映射示例.
heat_raw >= 90, 展示 100
70 到 89, 展示 75
40 到 69, 展示 50
15 到 39, 展示 25
小于 15, 展示 0
这块我让 SOLO 给我一个可调参数的建议, 因为不同市场新闻密度不同, 你固定阈值可能不合适. 后面可以用分位数归一化, 或按滑动窗口做动态阈值.
7.2 热度计算, 我用 Story 维度, 不用单条新闻
对同一事件聚合成 Story 再算热度, 这个比单条新闻靠谱太多. 不然一条爆料转发 100 次, 你就以为有 100 个事件.
特征我选这些.
mentions_1h, 近 1 小时去重后的提及数
sources_1h, 近 1 小时独立来源数, 按域名或媒体
velocity, 提及增长速度, 近 10 分钟对比 1 小时均值
recency, 最新一条距现在的分钟数, 指数衰减
authority, 来源权重, 公告监管大于主流媒体大于博客
market_reaction 可选, 价格振幅,成交量异常, 需要行情源
示例公式我就用一个工程上好实现的.
heat_raw = 100 * sigmoid(
0.8 * log1p(mentions_1h)
-
0.6 * log1p(sources_1h)
-
0.7 * velocity
-
0.9 * authority
-
0.4 * market_reaction
-
0.05 * age_minutes
)
然后做分位数或滑动窗口归一化, 避免某天新闻特别多导致全都低分.
这个公式不一定最牛, 但很实用, 你调一调就能用.
8. MVP 功能清单, 先别贪, 但也不能太寒碜
我把第一阶段必须要有的功能列清楚, 这个清单是我用 MTC 模式和 SOLO 一起磨出来的. SOLO 的好处是, 你列了功能它会反问你哪些是必须, 哪些是增强, 还能提醒你少掉的配置项.
8.1 MVP 必备
新闻流, 按时间排序, 去重, 来源标识, 语言标识
热点榜, 按热度排序的 Story 列表, 支持市场筛选
个股标注, 新闻卡片显示关联股票,ticker,名称,置信度
热度, 0,25,50,75,100 加文案
主题标签, AI,财报,并购,宏观,监管
搜索与过滤, 市场,行业,来源,主题,热度区间,时间窗
自选股, 只推送关注股票相关新闻
实时推送, SSE 或 WebSocket
数据源管理, 源列表,优先级,轮询周期,自动切换开关
8.2 第二阶段增强
Story 聚类和时间线
多语言情绪分析
短摘要与要点, 合规优先
提醒系统, 热度上升, 某股被提及, 某主题爆发
影响面板, 新闻后 5,15,60 分钟的价格成交量反应
MVP 先做完, 再谈增强会更稳.
9. 后端接口设计, REST 加 SSE, 一眼能看懂的那种
这块我让 SOLO 按接口文档写, 结果它给得还挺完整, 我就直接拿来当初版 API spec 了.
9.1 REST 示例
GET /api/news?market=US&since=…&heat_min=50&limit=50
GET /api/stories?market=US&window=1h&sort=heat_desc
GET /api/instruments/search?q=apple&market=US
GET /api/instruments/{ticker}/news?window=24h
POST /api/watchlist
DELETE /api/watchlist/{ticker}
GET /api/config/sources
POST /api/config/polling
9.2 SSE 推送, 我建议两条流
GET /api/stream/news, 推送新新闻
GET /api/stream/stories, 推送热点榜变更
推送内容用增量加变更类型 add 或 update.
SSE 这玩意确实好用, 你前端一接上, 新消息就能持续进来, 体验很直观.
10. UI 颜值与交互, 终端三栏怎么做才不丑
我个人对 UI 颜值要求还行, 不用花里胡哨, 但不能土. 我用 Next.js 加 Tailwind 加 shadcn ui, 这套真的省事. SOLO 在 Code 模式里, 给我做组件拆分和布局建议, 还帮我列了快捷键交互, 这块我觉得挺值.
10.1 推荐布局
左, Hot Stories 热点榜, 热度 + 上升下降箭头 + 主题
中, News Feed 新闻流, 卡片显示标题,来源,时间,关联股票 chips,热度
右, Instrument 面板, 选中股票的相关新闻, 价格图, 事件时间线
10.2 视觉要点
暗黑模式默认, 高对比强调色
热度渐变, 灰到橙到红
微动效, 热度上升闪一下 300ms, 新消息入场动画
快捷键, / 搜索, j,k 上下, enter 打开详情
终端味儿做出来了, 用户才愿意多看两眼.
11. 运行与部署, 先用 Docker Compose, 观测别忘了
我这类项目, 部署我一般先 Docker Compose, 省得一开始就上 K8s 把自己绕晕.
Postgres, 主库
Redis, 热数据缓存, 去重集合, 限频桶
OpenSearch 或 Elasticsearch, 新闻检索和聚合
API 服务, FastAPI 或 NestJS
Worker, 拉取与分析任务
观测建议上 Prometheus + Grafana.
拉取延迟, 失败率, 限频次数, 每分钟入库量, 这几个指标一看, 你就知道哪里出问题.
你不监控, 就基本是在摸黑走路, 出事了都不太好定位.
12. 我是怎么用 SOLO 的, MTC 和 Code 两种模式各干了么斯
这个部分我觉得对想参加活动的朋友可能更有参考, 因为大家不一定都做这个项目, 但用法思路可以搬.
12.1 MTC 模式, 先把方案写扎实
我在 MTC 里主要干了这些.
把需求从一句话拆成产品形态, 用户动作, 信息流, 合规边界.
把架构按分层画出来, 并且要求每层都有清晰输入输出.
把数据源策略写成可运行的工程策略, 并明确缓存, 限频, 熔断, 轮询.
把 NewsItem 模型写成统一结构, 并且明确哪些字段必须, 哪些可选.
把热度模型写成可以落地的公式, 再写展示档位映射.
把 MVP 和增强功能分开, 避免一开始就写成大而全.
最后把交付物拆成任务清单, 方便直接开工.
这里我有个小技巧, 我会反复用一句话去卡住它.
别给我讲理念, 给我写工程上怎么做.
别只列名词, 把失败策略也写出来.
别只说用某某模型, 把阈值和回退策略说清楚.
约束你给够了, 它写出来才更像个能执行的方案.
12.2 Code 模式, 把方案变成能跑的骨架
Code 模式我用得更像一个高级队友. 我让它.
把 Next.js 项目路由和页面拆分好, 三栏布局先上.
给我生成一些 UI 组件骨架, HotStoryList, NewsFeed, InstrumentPanel.
写一个简单的 SSE 客户端, 验证推送链路.
后端先用 FastAPI 写几个 stub 接口, 返回假数据, 让前端先跑.
然后再一点点把 Connector 和入库逻辑接进去.
这里最爽的点是, 你不用从零敲 boilerplate. 但我也踩了坑, 就是它有时候会默认一些我没说的东西, 比如把数据源写成抓全文, 或者把某些接口写成不考虑限频. 这时候你就要立刻提醒它, 我们只存元信息, 只做摘要, 限频必须有, 不然它就会顺手写成一个不合规的抓取器.
你要盯紧点, 不然它写嗨了就容易跑偏, 返工也挺亏.
13. 这套系统如果真要做成产品, 我建议的迭代路线
我把它按三步走, 这样比较稳.
第一步, 做出可用的资讯终端雏形.
多源拉取, 去重入库, 新闻流, 热点榜, 个股映射先用规则, 热度模型先用基础特征, SSE 推送打通.
第二步, 做事件聚类和更稳的映射.
Story 聚类更准确, alias 库更丰富, 消歧更聪明, 热度模型做归一化, 加一个简单调参面板.
第三步, 做用户价值更强的东西.
提醒系统, 影响面板, 多语言情绪, 自选股策略, 以及更细的来源可信度和媒体权重.
迭代路线定好了, 团队才好协作推进.
14. 给想上手 SOLO 的几条小建议, 我觉得蛮实在
1, 先用 MTC 把边界和交付物写清楚, 再去 Code 模式写代码. 你一上来就 Code, 很容易写着写着发现需求没定.
2, 让它输出结构化东西, 比如数据模型, 接口表, 任务拆分. 你越结构化, 越不容易写成口号文.
3, 合规这种硬约束, 要放在最前面反复强调. 不然它默认会给你写一堆抓取和存全文的方案.
4, 你别指望它一次就对, 你要像带实习生一样带它, 多给样例, 多给反例.
5, 写 UI 的时候, 你就直接告诉它你要哪个终端布局, 哪些颜色, 哪些快捷键. 你不说, 它就给你搞成普通资讯站, 那味儿就没了.
你把话说清楚, 它做事就更利索, 也更省心.
15. 收个尾, 这次内测我觉得值不值
我个人感觉值, 因为它最适合干那种跨度大的活, 从方案到落地, 把你脑子里那坨东西梳顺.
惊喜点, 方案拆解和工程化细节, 只要你问法对, 它真的能给到不少能用的东西.
踩坑点, 你不盯合规和限频, 它可能顺手写成爬虫, 还给你存全文, 这就要你自己掐住.
玩法点, 我觉得最爽的是把 MTC 输出的接口和模型, 直接喂给 Code 模式, 让它按同一份约定生成骨架, 这种前后衔接很丝滑.
最后再提醒一下, 我发帖会带上 #新 SOLO 初体验, 也会把截图补全, 让大家更好对照着学. 有同样想做资讯终端或者做多数据源聚合的朋友, 你可以直接照这个结构抄作业, 先把 NewsItem 模型和 SourceManager 搭出来, 你就赢一半了.
16. 再往下细一点, 数据库表我怎么设计才不乱
这块我也让 SOLO 帮我从 NewsItem 模型推表结构, 我再自己改一改. 先说清楚, 这只是 MVP 版本的建议, 不是唯一答案.
16.1 Postgres 表建议
instruments, 主数据表
id, market, ticker, name, exchange, country, sector, aliases jsonb, identifiers jsonb, updated_at
news_items, 新闻原子表
id, source, source_url, title, summary, language, published_at, fetched_at, raw jsonb
注意这里 raw 我会存一份原始字段, 方便回溯和调试, 但别存正文全文.
news_entities, 新闻实体表
news_id, type, text, start,end 可选, confidence
news_instrument_map, 新闻到个股映射
news_id, instrument_id, confidence, method, created_at
stories, 事件聚合表
story_id, canonical_title, first_seen_at, last_seen_at, topics jsonb, heat_raw, heat_bucket, updated_at
story_news_map, story 和 news 对应
story_id, news_id
source_status, 数据源状态
source_name, health_score, last_success_at, last_error_at, error_streak, avg_latency_ms, last_429_at, updated_at
watchlists, 用户自选股, 如果你做账号体系就加 user_id
user_id, instrument_id, created_at
表你先定好, 后面索引和查询才好加.
16.2 OpenSearch 索引, 主要服务检索和聚合
我一般会把新闻和 story 都建索引, 但 MVP 先建 news 也够.
news index 里放.
title, summary, source, published_at, language, topics, mapped tickers, source_url
然后做几个常用 query.
按时间范围过滤
按 market 或 ticker 过滤
按 topic 过滤
按 heat_raw 排序
你要是连搜索都没, 这个终端用起来会很难受, 信息一多就找不到.
17. 去重, 限频, 缓存, 这三件事怎么落到代码上
我写这种采集系统, 最常见的 bug 不是算法, 是去重没做好导致重复刷屏, 限频没做好导致源全挂, 缓存没做好导致你自己把自己打爆.
17.1 去重策略, hash 要稳定
我建议 id 就按 hash(source + normalized_url + normalized_title + published_at_minute) 来, 为啥要 minute, 因为有些源时间精度不同, 你直接秒级会导致同一条不同秒重复.
normalized_url, 去掉 utm 参数, 去掉可选跟踪参数.
normalized_title, trim 空格, 多个空格合一, 全角半角处理一下.
17.2 Redis 做短期去重集合
我会在 Redis 里搞一个 set 或 bloom filter, 保存最近 24 小时的 news_id, 入库前先查一下, 这样能挡住大部分重复.
17.3 token bucket 限频, 每个源一套
每个 source 都有自己的 bucket, 你把每分钟允许请求数换算成 tokens, 每次请求拿一个 token, 没 token 就 sleep 或跳过.
如果你要更稳, 还可以按 endpoint 粒度限频, 因为同一个源不同接口限频不一样.
17.4 熔断, 连续失败就先别碰它
熔断我通常这么写.
连续失败 N 次, 进入 open 状态, 冷却 T 秒
冷却后进入 half open, 允许少量探测请求
探测成功, 恢复 closed
探测失败, 回到 open
这个逻辑写上, 系统就不那么娇气了, 稳定性会明显好很多.
18. Story 聚类我怎么做, 先粗后细, 别一上来就上大模型
Story 聚类是热点榜的基础, 但别一上来就追求完美.
18.1 MVP 版聚类, 标题相似度加实体重合
简单做法.
先按时间窗分桶, 例如最近 2 小时的新闻.
对每条新闻抽取关键词, 也可以用 TF IDF 或简单分词.
计算标题相似度, 同时看 mapped tickers 是否有交集.
相似度超过阈值就归到同一个 story.
这版能跑, 但会有误合并, 特别是宏观新闻.
18.2 进阶版聚类, 向量检索加规则兜底
你可以用 pgvector 或 OpenSearch knn, 把 title + summary 的向量存起来, 新来一条就找最近邻, 再结合实体和 topic 做打分.
规则兜底也要有, 比如公告类和监管类, 很多时候你可以直接按 company + form type 聚成 story, 不用靠语义.
先把能用的版本上起来, 精准度和效果后面再补.
19. 前端路由与组件拆分, 我怎么让 SOLO 写得更听话
我在 Code 模式里给它的约束通常很具体, 不然它就写成一个普通资讯列表页.
我会说.
页面就一个主路由, /terminal
里面三栏, 左 25%, 中 45%, 右 30%
左边只显示 story 列表, 点一下选中 story
中间显示 news feed, 支持按 story 过滤, 支持热度 badge
右边显示当前选中 ticker 的面板, 没选 ticker 就显示空状态
组件我拆成.
HotStoryList, HotStoryItem
NewsFeed, NewsCard
InstrumentPanel, InstrumentHeader, InstrumentNewsList, MiniChart
SourceStatusPopover, WatchlistDrawer
快捷键我也会明确.
/, 聚焦搜索
j,k, 上下移动选中
enter, 打开详情或跳转原文
你把这些说清楚, 它写出来就会像那么回事, 不会变成花里胡哨的门户站.
20. 我在 SOLO 里用过的几个提示词套路, 你可以直接抄
我把几个我觉得好用的问法写出来, 大家别笑, 这些问法真的能把输出质量拉起来.
20.1 让它写工程可落地方案
请把这个系统按采集层, 标准化层, 分析层, API 层, UI 层拆解. 每层都要写清楚输入输出, 失败策略, 缓存策略. 不要写成概念介绍, 要写成工程说明.
20.2 让它列 Connector 的边界
为每个数据源设计一个 Connector 接口, 输出统一 NewsItem. 写清楚轮询间隔建议, 增量游标做法, 去重 hash 规则, 429 限频与熔断处理, 以及需要保留的元数据字段.
20.3 让它把热度模型写成可调参
给我一个 heat_raw 计算公式, 特征包含 mentions_1h,sources_1h,velocity,recency,authority,market_reaction. 同时给出默认参数和阈值映射 0,25,50,75,100. 说明如何用分位数或滑动窗口归一化.
20.4 让它写 UI 原型而不是空描述
用 Next.js, Tailwind, shadcn ui 写一个 Bloomberg 风格三栏终端页骨架. 要求暗黑模式默认, 热度 badge 渐变配色, 列表支持虚拟滚动, 支持快捷键 j,k,/ ,enter. 先用 mock 数据跑通.


