背景
2026年8月13日,DeepSeek 正式开源了 Harness 开发者预览版。项目在 GitHub 上线一个多小时便突破两万 Star,引发了广泛关注。
从5月份组建 Harness 团队,到7月开启内测,再到8月以 MIT 协议完全开源,前后不到三个月。这个节奏表明,DeepSeek 此次并非只是发布一个新工具,而是在产品战略上进行了一次方向性调整。
2026 年 7 月 10 日,OpenAI 发布了 GPT-5.6。
这次发布的信息量很大,但如果只抓一个核心变化,那就是:大模型正在从聊天机器人变成能干活的智能体。过去你问它问题,它给你答案;现在你给它目标,它能自己规划步骤、调用工具、协调多个 Agent 并行工作,最终把任务完成。
方向对了还得看数字。GPT-5.6 在效率上也交出了非常亮眼的成绩单:以更少的 Token、更低的成本,在编程、知识型工作、网络安全和科学领域均取得了行业前沿水平。用官方的话说:树立了智能与效率的新标杆。
这篇文章基于 OpenAI 官方发布文档,从核心定位、多智能体架构、编程能力、设计能力、安全机制和开发者影响几个维度展开分析。
过去几年,大模型的发展路径很清晰:GPT-3 解决语言生成问题,GPT-4 解决复杂推理问题,GPT-5.6 开始解决任务执行问题。
| 阶段 | 代表模型 | 核心能力 | 关注点 |
|---|---|---|---|
| 语言生成 | GPT-3 | 给定上下文,预测最合理的后续内容 | 文本质量 |
| 复杂推理 | GPT-4 | 在复杂信息中建立逻辑关系,找到可靠答案 | 推理准确性 |
| 任务执行 | GPT-5.6 | 理解目标,在真实环境中持续采取行动,完成目标 | 任务完成率 |
这三种能力不是替代关系,而是叠加关系。GPT-5.6 依然具备强大的语言生成和推理能力,但它更进一步——正如官方文档所说,它能够理解目标、规划步骤、调用工具并完成复杂任务。
用一个具体例子来理解。假设你在线上遇到一个接口变慢的问题:
传统模型会给你一套排查建议:查慢 SQL、检查 Redis 命中率、分析 JVM GC、看链路追踪……建议完全正确,但给建议不等于解决问题——你还是得自己去连监控、查日志、改代码、验证效果。
GPT-5.6 代表的方向是:模型自己去连监控系统、查日志、分析 SQL、定位问题、修改代码、跑测试、验证效果。用官方的描述,它能够编写并运行轻量级程序,在工作开展过程中协调工具、处理中间结果、监控进度并自主选择下一步操作。当然,这是一个理想化的场景,实际效果取决于工具集成的完整度和权限配置。
用一个类比来说:传统模型像一个百科全书式的顾问——你问什么它都知道,但不动手;GPT-5.6 更像一个能干的同事——你给它一个任务,它会自己想办法完成。
这不是概念层面的畅想,具体数据已经在多个 Benchmark 上得到了验证。
Agents’ Last Exam——覆盖 55 个专业领域的长周期 Agent 工作流评估。GPT-5.6 Sol 在该评测中领先 Claude Fable 5(自适应推理)13.1 分,即便在中等推理强度下,也以约 1/4 的成本领先 Fable 5 达 11.4 分。
OSWorld 2.0——衡量模型在真实计算机环境中的操作能力。Sol 得分 62.6%,超越 Claude Opus 4.8,同时输出 Token 用量减少 85%。
BrowseComp——智能体网页浏览评估。Sol 得分 90.4%,ultra 模式下达到 92.2%。
这些数据的共同指向是:GPT-5.6 不只是更聪明了,而是能独立完成更长周期、更复杂的任务了。
需要说明的是,GPT-5.6 本身并不等同于 Agent。更准确地说,它提供了更强的 Agent 核心模型能力,而一个真正可靠的智能体系统仍然需要开发者构建工具层、状态管理层和执行框架——也就是 Agent = LLM + Tools + Memory + Runtime + Verification。GPT-5.6 解决的是其中 LLM 这一环的能力跃升,其余部分仍然是工程问题。
GPT-5.6 最值得关注的新能力之一是 ultra 模式下的多智能体并行。官方文档的描述是:
ultra 是我们最高性能的设置,能够跨多个并行工作流协调多个智能体,更快地完成复杂任务。
ultra 模式默认并行 4 个智能体,在 BrowseComp 和 SEC-Bench Pro 的测试中还展示了 16 个智能体的配置。
官方给出的数据结论是:增加并行智能体会将得分-延迟前沿向左上方推移——在更短时间内取得更优的结果。
用一个类比来理解:过去的模型像一个超级聪明的实习生——能力很强,但一次只能干一件事,你得等它做完 A 才能让它做 B。多智能体模式更像是一个小型团队——一个项目经理负责协调,几个执行者分头干活,最后汇总结果。
对于复杂任务(比如分析最近一个月销售下降原因并生成优化方案),多个 Agent 可以分头查销售数据、查用户画像、分析市场趋势、查库存情况——然后汇总分析,生成报告。任务完成时间大幅缩短。
不过需要澄清一点:多智能体的核心价值不在于简单堆叠 Agent 数量——4 个 Agent 重复犯同样的错误并不会比 1 个 Agent 更好。真正的价值在于任务分解和角色分工:不同 Agent 负责不同子任务(比如 Research Agent 负责数据收集、Coding Agent 负责实现、Testing Agent 负责验证),配合共享记忆和验证机制,才能发挥协同效应。ultra 模式的意义也应该从这个角度理解。
开发者可以通过 Responses API 的 multi-agent 功能(测试阶段)实现类似 ultra 的体验:在单个请求中并行运行多个子智能体,并整合它们的工作成果。
GPT-5.6 提供了三个模型层级:
| 模型 | 定位 | 输入价格(每百万 Token) | 输出价格(每百万 Token) | 一句话说明 |
|---|---|---|---|---|
| Sol | 旗舰 | $5 | $30 | 最强能力,复杂任务首选 |
| Terra | 中端 | $2.50 | $15 | 性能≈GPT-5.5,成本更低 |
| Luna | 轻量 | $1 | $6 | 速度最快,性价比最高 |
值得注意的是命名策略:数字标注代系(5.6),Sol/Terra/Luna 是持久的能力层级,可以按各自节奏独立演进(据官方文档描述)。从产品设计来看,OpenAI 正尝试建立一套长期的能力分层体系——如果这套策略持续下去,未来的 GPT-5.7 大概率仍然是 Sol/Terra/Luna 三档。
不同任务对模型能力的要求差异巨大。所有任务都用最强模型,成本直接爆炸;都用轻量模型,复杂任务又搞不定。GPT-5.6 的效率数据很有说服力:
不只是同样的钱做同样的事,而是同样的钱做更多的事。
软件工程天然具备几个适合 Agent 发挥的特点:
软件工程是那种做对了就是对了,做错了立刻能发现的领域——这恰好是 Agent 最需要的环境特征。
从技术角度拆解,一个能参与软件工程的 Agent 需要具备三层能力:
第一层:Repository Understanding(代码库理解)。不是把整个项目塞进上下文,而是能像工程师一样探索代码——Code Search 定位关键符号、Symbol Graph 分析调用关系、Dependency Analysis 理解模块依赖。GPT-5.6 在可编程工具调用上的突破(前文已述)正是为这一层提供了基础:模型可以自己写程序来检索和分析代码,而不需要每一步都依赖外部系统。
第二层:Execution Feedback(执行反馈)。修改完代码后,Agent 需要能运行测试、查看编译结果、分析日志,根据真实反馈调整策略。Terminal Agent 的能力直接决定了这一层的上限——这也是 Terminal-Bench 成为重要评测的原因。
第三层:Change Management(变更管理)。一次软件变更不只是改代码,还需要 Diff Review 确认修改范围、Rollback 机制应对失败、Human Approval 把控关键决策。这层能力目前更多依赖工程框架而非模型本身,但模型需要能理解和配合这些流程。
GPT-5.6 在这三层上都有提升,但提升幅度不同——第一层和第二层进步最明显(可编程工具调用 + Terminal Agent),第三层仍然需要开发者在框架层面解决。
| 评测 | GPT-5.6 Sol | Claude Fable 5 | GPT-5.5 |
|---|---|---|---|
| Coding Agent Index v1.1 | 80(新 SOTA) | 77.2 | 76.4 |
| Terminal-Bench 2.1 | 88.8%(Ultra 91.9%) | 83.1% | 85.6% |
| DeepSWE v1.1 | 72.7% | 69.7% | 67% |
| SWE-Bench Pro | 64.6% | 80% | 59.4% |
值得注意:在 SWE-Bench Pro 上,Fable 5 仍然领先(80% vs 64.6%),说明不同 Benchmark 上各家模型互有胜负。但在 Coding Agent Index、Terminal-Bench、DeepSWE 这三项更侧重完整工程能力的评测上,GPT-5.6 Sol 都拿到了第一。
更重要的是效率:在 Coding Agent Index 上,Sol 以 80 分创下新 SOTA,同时实现了前文所述的效率提升——Token、耗时、成本均大幅下降。不只是更强,还更便宜更快。
GPT-5.6 在编程场景下的一个重要变化是:模型能够编写并运行轻量级程序,在工作过程中协调工具、处理中间结果、监控进度并自主选择下一步操作。
传统的 Tool Calling 模式是调工具 → 拿结果 → 再调工具 → 再拿结果,每一步都需要模型参与决策,消耗大量 Token 和交互次数。而 GPT-5.6 可以直接在内存中写程序来处理中间数据、过滤噪音、只保留关键信息,然后在运行过程中动态调整工作流。
官方文档的表述是:开发人员无需编写每一个步骤的脚本,也不必将工具的每个响应都回传给模型。Responses API 中的可编程工具调用功能让重度依赖工具的任务能够以更少的 Token、更少的模型交互次数顺利推进。
过去代码助手主要工作在 IDE 内,模型无法观察代码运行后的真实结果。而软件开发是一个高度依赖反馈的过程——模型生成了代码,但只有运行之后才知道对不对。
通过 Terminal,模型可以执行 git status、mvn test、npm run build、docker logs 等命令,观察编译错误、测试失败、运行异常。这让 AI 从代码生成器变成了开发环境中的参与者。前文 Terminal-Bench 2.1 的成绩也直接反映了这方面的能力。
Benchmark 是实验室数据,真实用户的反馈更值得关注:
GPT-5.6 帮助用户以比前代模型减少约 25% 的步骤和 35-48% 的工具调用量完成任务,同时将项目成功率提升了 15%,并减少了运行卡顿的情况。
—— Fabian Hedin,Lovable 联合创始人
GPT-5.6 是我们在 CursorBench 上测试过的能力最强的模型之一,在早期评估中表现稳健。在任务持久性、智能水平及整体效率方面的提升,对开发者而言是令人振奋的一步。
—— Oskar Schulz,Cursor 总裁
官方文档专门用了一个章节介绍 GPT-5.6 在设计方面的进步:
仅凭高层次指导,GPT-5.6 就能创建美观、符合人体工学且功能完善的界面。凭借更强的计算机使用能力,它不再仅仅局限于生成底层代码或内容,而是能够检查并优化渲染后的结果——从而在交付最终作品前,主动捕获视觉与功能问题,并进行细节修饰。
这个能力转变值得关注——模型从生成完就结束变成了能自己看渲染结果、发现问题、自己修复。官方展示了多个 demo,包括 3D 航海游戏、博物馆网站、室内设计演示文稿、交互式万花尺等,均是仅凭自然语言描述生成。
在 ChatGPT Work 中,GPT-5.6 还能将自然语言请求转化为精美的、具有互动性的解释与可视化呈现——这对前端开发和教育场景有直接价值。
GPT-5.6 在知识型工作方面也有显著提升。据官方文档描述,它能从用户的文档以及 Slack、Notion、Microsoft 365 和 Google Drive 等日常工作流中提取信息,将其转化为专家级、可共享的成果。
具体能力包括:
传统模型的安全问题相对简单——输入危险内容,模型拒绝回答,核心是内容过滤。但 Agent 的安全问题本质上变了:模型不再只是回答问题,而是拥有了执行动作的能力。
这意味着安全的焦点从内容安全转向了权限控制。一个 Agent 可能拥有文件读写权限、数据库操作权限、代码执行权限、企业系统访问权限——真正需要防范的不是模型回答错误,而是模型在错误的时间、对错误的资源、执行了错误的操作。
所以 Agent Security 更接近传统软件安全中的 Identity + Authorization + Audit + Sandbox,而不只是输入输出过滤。理解了这个背景,再看 GPT-5.6 的安全设计就更有针对性。
随着 Agent 能力增强(能自主执行任务、操作文件、运行代码),安全问题变得更加突出。据官方文档,GPT-5.6 采用了分层保护架构:
官方文档提到了一个有意思的观点:过度拦截本身也有安全风险。如果防护机制太严,防御者无法测试系统和部署补丁,而攻击者却在继续使用其他模型和现有黑客工具。官方的表述是:
有效的防护机制应充分考量请求的具体语境与可能产生的后果;在保护合规防御工作的同时,当有证据表明存在严重危害风险时,则应实施更严格的控制。
OpenAI 在官方文档中披露了内部使用数据:
官方也坦言:这些使用情况指标本身并不能衡量研究进展,但它们表明 AI 辅助在研究以及销售、营销、用户运营、财务等其他团队中的应用正在快速增长。
从行业趋势来看,一个明显的变化是:开发者对怎么写 Prompt 的关注正在让位于怎么组织 Agent 的上下文和工具链。GPT-5.6 的产品设计也体现了这一点——可编程工具调用、multi-agent API、显式缓存断点、30 分钟缓存 TTL——这些都是在帮开发者解决工程层面的问题,而不只是提示词层面的问题。
(注:业界将这一趋势概括为从 Prompt Engineering 到 Context Engineering 的转变。这并非 OpenAI 官方术语,而是一个被广泛接受的行业观察。)
早期 AI 应用可能只需要一个前端加一个 LLM API 调用。未来需要 Agent 层、Workflow 编排、Memory 管理、Tools 集成、监控体系……AI 应用开发会越来越接近后端系统开发。
RAG 不会消失,但定位会变化——从独立的 AI 应用范式变成 Agent 系统中的一个知识组件。MCP(Model Context Protocol)等协议的重要性也在提升——Agent 需要连接大量外部系统,统一工具协议是降本增效的关键。
虽然 GPT-5.6 代表了 Agent 方向的重要进展,但距离完全自主工作的 AI 还有明显差距:
可靠性:模型仍可能理解错误目标、做出错误决策、产生幻觉。在 SWE-Bench Pro 上,Fable 5 仍然以 80% 领先 Sol 的 64.6%——说明在纯代码理解和修复能力上,还有提升空间。
成本:Sol 的输出价格 $30/M tokens 并不算便宜。复杂 Agent 需要多次模型调用,综合成本仍然不低。对于高频调用场景,Terra 和 Luna 是更务实的选择。
抽象推理:Sol 在 ARC-AGI-3 上只拿到 7.78%(据官方数据)——距离通用人工智能还有很长的路。
安全最佳实践缺失:让 Agent 自主执行任务、操作生产系统,安全边界如何划定?OpenAI 的分层防护方案是一个起点,但行业整体还没有成熟的标准。
GPT-5.6 的意义不在于它是不是每个 Benchmark 上的第一名,而在于它代表了大模型应用方向的一次根本转变:
对于开发者来说,未来竞争的重点不会只是调用更强的模型,而是如何围绕模型构建可靠、高效、可维护的 AI 系统。GPT-5.6 是这个趋势中的一个重要节点,但真正决定 AI 应用价值的,仍然是系统工程能力。
GPT-5.6 的真正意义,不是让模型替代软件工程,而是让软件工程开始具备智能执行层。未来的软件系统,将不再只是由代码定义行为,而是由代码、模型和环境反馈共同驱动。
JetCache 是阿里巴巴开源的通用缓存访问框架(开源地址),它做了一件事:用统一的 Cache<K, V>接口,把本地内存缓存和远程 Redis 缓存无缝组合起来,再通过注解、API 两种方式定义出标准的缓存协议接入层,让业务代码以最简洁的方式使用缓存。
和 Spring Cache 比,JetCache 的核心优势:
| 能力 | Spring Cache | JetCache |
|---|---|---|
| TTL(超时时间) | 不原生支持,需自定义 | 原生支持,注解上直接写 expire |
| 两级缓存 | 不支持 | 原生支持 CacheType.BOTH(本地 + 远程) |
| 缓存自动刷新 | 不支持 | 支持 @CacheRefresh,分布式全局唯一刷新 |
| 穿透保护 | 不支持 | 支持 @CachePenetrationProtect |
| 分布式锁 | 不支持 | 内置 tryLock / tryLockAndRun |
| 异步 API | 不支持 | 支持(Lettuce 客户端下真正非阻塞) |
| 统计监控 | 需第三方 | 内置 命中率、加载次数等统计 |
| 更新/删除缓存注解 | 有但功能弱 | @CacheUpdate / @CacheInvalidate 支持 SpEL |

不管你底层用的是 Caffeine(本地内存)、Redis(远程)还是两级缓存组合,业务代码面对的都是同一个接口:
1 | public interface Cache<K, V> { |
用起来就像一个 Map,非常直观。
| 类型 | 含义 | 适用场景 | 备注 |
|---|---|---|---|
CacheType.LOCAL |
纯本地内存缓存 (Caffeine 或 LinkedHashMap) |
字典数据、配置项等变化少的数据 | 目前没有使用本地缓存的诉求 |
CacheType.REMOTE |
纯远程缓存(Redis) | 一般业务场景,数据统一存 Redis | 我们目前的使用场景 |
CacheType.BOTH |
两级缓存:本地 + 远程 | 高频读取,本地扛量 + Redis 兜底 | 目前没有使用多级缓存的诉求 |
最终在 Redis 里存的 key 格式是:
1 | Redis key = keyPrefix + keyConvertor(K); |
keyPrefix:来自 @Cached(name = "toc:user:info:") 中的 name,或 QuickConfig.newBuilder("toc:user:info:") 中的参数。它的作用就是给不同业务的缓存加个”门牌号”,避免 key 冲突。
keyConvertor:把 Java 对象转成 String。默认用 fastjson2,对 String 类型的 key 直接透传,对复杂对象做 JSON 序列化。
举个例子:@Cached(name = "toc:user:info:", key = "#userId") ,userId = 12345,最终 Redis 里的 key 就是 toc:user:info:12345。
Area 是 JetCache 的多租户机制。默认有一个 "default" area,对应配置里的 jetcache.local.default 和 jetcache.remote.default。如果你的项目需要连多个 Redis 实例,可以配多个 area,然后在注解里通过 area = "otherArea" 指定。大多数场景用默认的就行。
根据业务应用的 Redis 客户端,选择对应的 starter(三选一):
1 | <!-- 方式一:Lettuce(推荐,支持异步 API) --> |
版本说明:JetCache 2.8+ 需要 JDK 17+、Spring Boot 3.x+、Spring Framework 6.x+。如果你的项目还在 JDK 8,请用 2.7.x 版本。
1 | jetcache: |
1 | @SpringBootApplication |
@EnableMethodCache(basePackages = "..."):告诉 JetCache 去扫描哪些包下的 Spring Bean,对其中的 @Cached、@CacheUpdate、@CacheInvalidate 等注解做 AOP 代理。basePackages 要覆盖你所有用了缓存注解的包。
@EnableCreateCacheAnnotation:激活 @CreateCache 注解支持,用于在字段上直接注入 Cache 实例,源码标记 Deprecated 了,可以不加。
至此,接入完成。下面开始介绍怎么用。
这是最常用的方式。在 Service 接口(或实现类)的方法上加注解,JetCache 通过 Spring AOP 代理自动处理缓存的读、写、删。
注意:注解可以加在接口方法上,也可以加在类方法上,但被注解的类必须是 Spring Bean。
1 | public interface UserService { |
| 属性 | 默认值 | 说明 |
|---|---|---|
area |
"default" |
缓存区域,一般不用改 |
name |
自动生成(类名.方法名) | 缓存唯一名称,会作为 Redis key 的前缀 |
key |
自动生成(根据所有参数) | SpEL 表达式指定 key,如 "#userId" 或 "args[0]" |
expire |
跟随全局配置 | 超时时间 |
timeUnit |
TimeUnit.SECONDS |
expire 的时间单位 |
cacheType |
CacheType.REMOTE |
LOCAL / REMOTE / BOTH |
localLimit |
100 | 本地缓存最大元素数(LOCAL/BOTH 时生效) |
localExpire |
同 expire | 本地缓存单独的超时时间(仅 BOTH 时生效) |
syncLocal |
false | 更新时广播失效其他 JVM 的本地缓存(仅 BOTH 时生效) |
serialPolicy |
java |
序列化方式:SerialPolicy.JAVA 或 SerialPolicy.KRYO |
keyConvertor |
fastjson2 |
key 转换方式 |
enabled |
true | 是否启用缓存,false 时不走缓存,可通过 CacheContext.enableCache 临时激活 |
cacheNullValue |
false | 方法返回 null 时是否缓存 |
condition |
无 | SpEL 表达式,返回 true 才查缓存(方法执行前评估) |
postCondition |
无 | SpEL 表达式,返回 true 才更新缓存(方法执行后评估,可用 #result) |
当数据被修改时,用这个注解直接更新缓存,避免等 TTL 过期:
1 | public interface UserService { |
数据被删除时,从缓存中也移除:
1 | @CacheInvalidate(name = "toc:user:info:", key = "#uuid") |
@CacheUpdate 和 @CacheInvalidate 的共同注意点:它们的 name 和 area 必须和对应的 @Cached 完全一致,这样 JetCache 才知道操作的是哪个缓存。
这是 JetCache 的特色功能之一。对于加载开销大、实时性要求不高的数据(比如报表汇总),配置自动刷新,防止缓存过期瞬间的并发请求打爆数据库(缓存雪崩):
1 | public interface SummaryService { |
| 属性 | 默认值 | 说明 |
|---|---|---|
refresh |
无 | 刷新间隔 |
timeUnit |
TimeUnit.SECONDS |
时间单位 |
stopRefreshAfterLastAccess |
无(一直刷新) | 该 key 多久没访问就停止刷新 |
refreshLockTimeout |
60 秒 | 刷新时在 Redis 放的分布式锁超时时间 |
关键特性:当 cacheType 为 REMOTE 或 BOTH 时,刷新行为是集群全局唯一的——不管有多少台服务器,同时只有一个节点在刷新某个 key,通过分布式锁实现。
1 | @Cached(expire = 3600, cacheType = CacheType.REMOTE) |
当缓存未命中时,同一个 JVM 内同一个 key 只有一个线程去加载,其他线程等待结果。防止高并发场景下大量请求同时穿透到数据库。
当前实现是 单机的保护,不是分布式级别的。如果多个节点同时遇到同一个 key 的缓存未命中,各节点会各自加载一次。
我们可以这样组合:自动刷新 + 穿透保护
1 | @Cached(name = "toc:user:info:", key = "#uuid", expire = 3600) |
每 30 分钟自动刷新(集群唯一),30 分钟没人访问就停止刷新,万一缓存未命中还有穿透保护。
注解方式虽然简洁,但灵活性有限——比如你需要在运行时动态决定 key,或者想在非 Spring 管理的类中使用缓存。这时候就用 Cache API。
1 | @Component |
QuickConfig 支持的配置项:
| 方法 | 说明 |
|---|---|
expire(Duration) |
超时时间 |
localExpire(Duration) |
本地缓存单独超时(BOTH 时) |
localLimit(Integer) |
本地缓存最大元素数 |
cacheType(CacheType) |
LOCAL / REMOTE / BOTH |
syncLocal(Boolean) |
是否跨节点同步失效本地缓存 |
keyConvertor(Function) |
key 转换器 |
valueEncoder / valueDecoder |
序列化/反序列化 |
cacheNullValue(Boolean) |
是否缓存 null |
penetrationProtect(Boolean) |
是否开启穿透保护 |
penetrationProtectTimeout(Duration) |
穿透保护超时时间 |
refreshPolicy(RefreshPolicy) |
自动刷新策略 |
loader(CacheLoader) |
缓存未命中时的加载函数 |
1 | // 读取 |
这个方法非常实用,相当于 get + put 的原子操作:
1 | // 缓存命中直接返回,未命中则调用 loader 加载并写入缓存 |
也可以在创建缓存时就设置好 loader,这样每次 get 都会自动加载:
1 | // 创建时设置 loader |
小写的 get() 返回 null 时,你分不清是”缓存中没有”还是”缓存出错了”。大写 API 返回 CacheGetResult,提供了完整的状态信息:
1 | CacheGetResult<UserDO> r = userCache.GET("toc:user:info:12345"); |
其他大写 API:GET_ALL、PUT、PUT_ALL、REMOVE、REMOVE_ALL、PUT_IF_ABSENT。
当使用 Lettuce 客户端时,大写 API 支持真正的异步非阻塞:
1 | CacheGetResult<UserDO> r = userCache.GET("toc:user:info:12345"); |
注意:小写的 put() 和 removeAll() 没有返回值,在 Lettuce 下会被自动优化为异步调用,减少 RT。但 get() 需要等待结果,所以仍然会阻塞。
JetCache 的 key 是怎么生成和处理的,搞清楚这个才能在 Redis 里看到符合预期的 key。
1 | Redis 中的 key = keyPrefix + keyConvertor(Java Key 对象) |
举个例子:
@Cached(name = "``toc:user:info:``", key = "#``userId``") + userId= 12345(long 类型)
keyConvertor 把 long 转成 "Long12345"
最终 Redis key = toc:user:info:Long12345
如果 key 是 String 类型:
@Cached(name = "``toc:user:info:``", key = "#uuid") + uuid = "``X123456``"
keyConvertor 对 String 直接透传
最终 Redis key = toc:user:info:X123456
从 ExternalKeyUtil.buildKeyAfterConvert 源码可知,JetCache 支持以下 key 类型:
| Java 类型 | 转换规则 | 示例 |
|---|---|---|
String |
直接使用,不转换 | "abc" → abc |
Number(Long、Integer 等) |
类名 + 值 | 12345L → Long12345 |
Date |
类名 + yyyyMMddHHmmss,SSS | new Date() → Date20260617100000,000 |
Boolean |
toString | true → true |
byte[] |
直接使用 | — |
其他 Serializable 对象 |
Java 序列化 | 复杂对象 → 序列化字节 |
实践建议:推荐使用 String 类型的 key。如果你用 Long/Integer 类型的 key,最终 Redis 里会带个 Long/Integer 前缀,虽然不影响功能,但看起来不直观。在 SpEL 里做一下转换就行:key = "'' + #userId" 或 key = "#userId.toString()"。
keyConvertor 负责把 Java 对象转成 Redis 能存的 String:
| 值 | 说明 |
|---|---|
fastjson2 |
默认推荐。String 直接透传,其他对象用 JSON.toJSONString() 转 |
jackson |
用 Jackson 转 JSON |
jackson3 |
Jackson 3.x 版本 |
none |
不转换,直接 equals 比较。仅用于 @CreateCache 且 cacheType = LOCAL 的场景 |
@Cached 的 key 属性支持 Spring 的 SpEL 表达式:
1 | // 直接用参数名(需 javac -parameters 编译) |
注意:使用参数名(如 #userId)需要编译时加 -parameters 参数,否则只能用 args[0] 按下标访问。
Maven 配置:
1 | <plugin> |
IntelliJ IDEA 配置:Settings → Build → Compiler → Java Compiler → Additional command-line parameters,填入 -parameters。
JetCache 是纯 KV 模型(底层用 Redis STRING 类型),不支持 Redis HASH 的子字段操作(HGET/HSET)。如果你之前用 Redisson 的 RMap 做过 Hash 缓存,迁移到 JetCache 时需要调整思路。
场景:**toc:user:archives:{uuid} 一个用户对应多条 KYC 记录**
Redisson 的做法(Hash 粒度操作):
1 | // Redisson:可以按 kycType 单独读写 |
JetCache 的做法(整体缓存):
1 | // 方案一:整个 List 作为 value |
JetCache 无法做 Hash 字段级操作,需要把「uuid 对应的全部数据」作为一个完整的 value 来缓存。如果业务对子字段粒度读写要求很高,建议保留 Redisson RMap;如果整体读写为主,JetCache 的两级缓存、自动刷新等能力更有价值。
两级缓存是 JetCache 的一大亮点,虽然我们暂时用不到。简单来说就是:本地内存缓存(L1)+ Redis(L2)组合使用,读的时候先查 L1 再查 L2,写的时候两级都写。
1 | 读取流程: |
1 | @Cached(name = "toc:user:info:", key = "#uuid", expire = 3600, |
1 | QuickConfig qc = QuickConfig.newBuilder("userCache") |
这是两级缓存的关键配置。加入你有 3 台服务器,每台都有本地缓存。如果节点 A 更新了某个用户数据,节点 B 和 C 的本地缓存还是旧值,这就出现了不一致。
syncLocal = true 的解决方式:
节点 A 更新缓存时,向 Redis 的 broadcastChannel 发一条失效消息
节点 B 和 C 订阅了这个 channel,收到消息后清除本地对应的缓存
下次读取时,B 和 C 会从 Redis 拉取最新数据
前提条件:yml 中必须配置了 broadcastChannel。
1 | jetcache: |
注意:多个服务共用同一个 Redis 时,不同服务请使用不同的 broadcastChannel,否则一个服务的缓存更新会触发其他服务的本地缓存全部失效,造成广播风暴。
两级缓存场景下,本地缓存的过期时间通常应该 小于 远程缓存。比如远程设 1 小时,本地设 1 分钟,这样即使广播消息丢失,本地最多 1 分钟后也会自动过期重新从 Redis 拉取。
| 场景 | 推荐 CacheType | 理由 |
|---|---|---|
| 字典数据、配置项 | LOCAL |
变化少,本地内存就够了 |
| 一般业务数据 | REMOTE |
统一存 Redis,简单可靠 |
| 高频读 + 可接受秒级不一致 | BOTH + syncLocal = true |
本地扛读压力,Redis 兜底 |
| 高频读 + 数据量特别大 | BOTH + localLimit 控制大小 |
避免本地内存撑爆 |
远程缓存(Redis)里的数据是字节流,存入时需要 序列化(encode),取出时需要 反序列化(decode)。JetCache 提供了三种序列化方式:
| 方式 | 优点 | 缺点 |
|---|---|---|
java(默认) |
兼容性最好,Java 原生 | 性能最差,字节数最大 |
kryo / kryo5 |
性能好,字节数小 | 需要注册类,升级时注意兼容 |
1 | jetcache: |
这里不建议自定义编解码实现,存在造成多级缓存不一致的风险。因为编解码器不一致,会导致 jetcache 广播 start 异常。
JetCache 2.8.x 默认开启了反序列化安全过滤器,只允许白名单中的类被反序列化。这是为了防止反序列化漏洞攻击。默认白名单包含:java.lang、java.util.、java.time.、java.math、com.alicp.jetcache.。
如果你的缓存值包含自定义类(比如 UserDO、OrderDO),必须添加白名单,否则反序列化会报错:
1 | jetcache: |
模式匹配规则:
| 模式 | 匹配方式 | 示例 |
|---|---|---|
com.``remotecarter``. |
前缀匹配(以 . 结尾) |
匹配 com.remotecarter.Foo、com.remotecarter.sub.Bar |
com.``remotecarter |
包名匹配(不以 . 结尾) |
仅匹配 com.remotecarter.Foo,不含子包 |
com.``remotecarter``.``User``Dto |
精确匹配(完整类名) | 仅匹配 com.remotecarter.UserDto |
拒绝列表(内置)包含已知反序列化攻击 gadget chain(Commons Collections、Spring AOP、Hibernate 等),以及 Runtime、ProcessBuilder 等危险类。拒绝列表不可被允许列表覆盖。
也可以通过编程方式配置:
1 | DecodeFilter.getDefault().addAllowPatterns("com.yourcompany."); |
最常见的场景——按 ID 查用户,缓存到 Redis。
1 | public interface UserService { |
Redis 里的 key 长这样:toc:user:info:X12345。
一个用户对应多条 KYC 记录,之前在 Redisson 中用 RMap(Hash)实现,迁移到 JetCache 后用 整体缓存 替代:
1 | // 整个 List 作为一条缓存 |
1 | public interface ReportService { |
缓存 2 小时,每 30 分钟自动刷新一次(集群唯一),30 分钟没人访问就停止刷新。本地 + Redis 两级缓存,万一未命中还有穿透保护。
普通场景下需要根据条件决定是否使用缓存:
1 | // 只有 type 为 1 的时候才走缓存 |
如果需要通过配置热部署开启 / 关闭缓存:
1 | package com.remotecarter.appuser.config; |
@CacheUpdate 和 @CacheInvalidate 可能因为网络波动失败。如果没有设置 TTL,失败的删除/更新操作就会导致缓存永远不一致。一定要设置合理的 expire 作为最终一致性的兜底。
开发阶段 / 不确定选啥:用 java,兼容性最好;
追求性能:用 kryo,体积小、速度快,但需要注册类;
JSON 序列化:不推荐。JSON 不是专门的 Java 序列化工具,反射无法识别类型时会反序列化为 JSONObject,兼容性差;
多个服务共用同一个 Redis 实例时,不同服务一定要用不同的 broadcastChannel。否则 A 服务更新了缓存,广播消息会触发 B 服务的本地缓存失效——虽然看起来没啥问题,但当广播量大的时候就是灾难。
JetCache 的注解通过 Spring AOP 代理实现。同一个类内部的方法调用不经过代理,缓存不会生效:
1 | @Service |
解决办法:通过 @Autowired 注入自己,用注入的实例调用:
1 | @Service |
如果想在 SpEL 中用参数名(如 #uuid),编译时必须加 -parameters 参数。否则只能用 args[0] 按下标访问。
name 会作为 Redis key 的前缀,建议:
用业务含义明确的名称,如 "toc:user:info:";
末尾加 - 或 : 作为分隔符,如 "userCache-12345"
不要给不同的 @Cached 注解分配相同的 name + area
localLimit 是每个缓存实例的限制,不是全部。如果有 10 个 @CreateCache 创建的缓存实例,每个 limit 100,那本地总共可能有 1000 个元素。大对象场景下要注意控制。
Spring AOP 基于代理实现,同类内部的方法调用不经过代理。解决方案见上面”最佳实践”第 4 条。
检查是否配置了 -parameters 编译参数。没有配置的话改用 args[0] 按下标访问。
2.8+ 默认开启了反序列化安全过滤器。需要在 yml 中配置 decodeFilterAllowPatterns 添加你的自定义类所在的包。
配置多个 area:
1 | jetcache: |
然后在注解中指定 area:@Cached(area = "second", ...)。
这两个操作可能因网络问题失败。JetCache 不会抛异常,只是静默失败。所以 设置合理的 TTL 是必须的——即使更新/删除失败,缓存也会在 TTL 后自动过期,从数据库重新加载。
确保配置了 syncLocal = true 和 broadcastChannel。另外设置一个比 Redis expire 更小的 localExpire,作为兜底——即使广播消息丢失,本地缓存也会在 localExpire 后自动过期。
JetCache 的锁是基于 Redis SETNX + TTL 实现的非严格分布式锁,适用于”防止重复执行”的场景。可以用。但目前了解到各域都有自己的分布式锁,建议还是用自己的吧,毕竟 JetCache 核心职责是定义缓存框架协议。
1 | jetcache: |
JD-HotKey 是京东开源的实时热点 key 探测与缓存中间件(开源地址),它做了一件事:在高并发场景下,自动发现热点 key,毫秒级推送到所有应用节点的 JVM 内存中,让热点请求直接在本地内存响应,不再打到 Redis 和数据库。
经典场景:某明星突然官宣,相关商品瞬间涌入海量请求。你事先根本不知道这个商品 ID 会变热,Redis 某个节点被这些请求打得 CPU 飙升——这就是典型的不可预知突发热点。
这时候你就需要 JD-HotKey:它能自动发现这类热点,把数据”镜像”到每台应用服务器的本地内存里,后续请求直接从内存读,RT 从几十毫秒降到 < 1ms。
和直接用本地缓存(比如 Caffeine)比,JD-HotKey 的核心优势:
| 能力 | Caffeine 本地缓存 | JD-HotKey |
|---|---|---|
| 热点发现 | 手动配置,你得提前知道哪些 key 要缓存 | 自动探测,根据访问量实时判定 |
| 动态性 | 静态的,配了就一直在 | 自动加入 / 退出热点,冷了自动释放内存 |
| 多节点一致性 | 各节点独立,互不知情 | 全局统一判定,所有节点同步感知 |
| 适用场景 | 已知高频数据(如字典、配置) | 不可预知的突发热点(如秒杀、热搜) |
| 部署复杂度 | 低(纯 SDK) | 中等(需要 etcd + worker) |
| 热用户 / 热接口探测 | 不支持 | 支持(不只限 key,接口、用户也能探) |
简单总结:已知的热点用本地缓存就够了,不可预知的热点用 JD-HotKey。


系统由四个核心组件构成:
| 组件 | 职责 | 说明 |
|---|---|---|
| etcd 集群 | 配置中心 + 注册中心 | 存储热点规则、worker 节点注册、热点 key 的推送中转 |
| worker | 聚合计算节点 | 接收所有客户端的访问统计,执行热点判定,推送热点通知 |
| client SDK | 嵌入业务应用的客户端 | 收集访问数据、上报统计、接收热点通知、本地缓存热点数据 |
| dashboard | 可视化管理控制台 | 配置规则、查看热点、管理应用 |
整个热点探测的过程就像一条流水线:
1 | 1. 业务请求打到 app,client SDK 对 key 做访问计数 |
关键设计:集中计算。你可能会想,为什么不直接在每个客户端本地判断热点?因为分布式场景下,单机请求是分散的——一个 key 在 100 台机器上每台只被访问了 5 次,单看任何一台都不算热,但汇总起来有 500 次。必须由 worker 集中汇总计算,才能准确识别全局热点。
Worker 内部处理流程:worker 收到 client 上报的数据后,经过一条责任链处理:
1 | Netty 收到消息 |
Worker 内部还有一个 hotCache(Caffeine 实现,5 秒 TTL),用来防抖——同一个 key 在 5 秒内不会重复推送,避免热点持续触发时产生大量无效推送。
etcd 在这个系统里承担了三个职责:
规则存储:你在 dashboard 配置的热点规则(哪个 key 前缀、阈值多少、窗口多大),都持久化在 etcd 中。worker 和 client 通过 watch etcd 来感知规则变化。
worker 注册:每个 worker 启动时把自己的 IP 注册到 etcd,client 通过读 etcd 知道该连哪些 worker。
热点推送中转:worker 判定出热点 key 后,写入 etcd 并设置 TTL 过期时间;客户端 watch 对应的 etcd 路径,收到变更事件后立即更新本地缓存。
一个巧妙的设计:etcd 原生支持 key 的 TTL 自动过期删除。热点 key 写入 etcd 时设一个过期时间(比如 60 秒),过期后 etcd 自动删除,删除事件通过 watch 回调通知所有 client 清除本地缓存。这样就实现了热点 key 的自动淘汰,不需要额外的清理逻辑。
为什么选 etcd 而不是 ZooKeeper? etcd 原生支持 key TTL 自动删除(ZooKeeper 不支持),性能更高,资源占用更少,API 风格也更现代(基于 gRPC)。
etcd 版本要求:3.4.x 及以上。
这是热点判定的核心算法。JD-HotKey 用的是双缓冲 Map实现滑动窗口:
1 | Worker 内部的双 Map 机制: |
AtomicLong 取模 2 切换读写对象,完全无锁设计LinkedBlockingQueue + 读写分离锁的方案,性能反而更稳定Key 的 Hash 分发:client 上报数据时,会对 key 做 Hash 计算(hash(key) % workerCount),同一个 key 始终路由到同一个 worker。这样保证了某个 key 的所有统计数据集中在一个 worker 上,不需要跨 worker 聚合。worker 之间也互不通信,各自独立计算。
JdHotKeyStore 是 client SDK 提供的核心操作类,只有 4 个静态方法:
| 方法 | 作用 | 使用场景 |
|---|---|---|
isHotKey(key) |
判断 key 是否热点,同时上报该 key 的访问 | 最常用,适用于只需拦截或限流的场景 |
get(key) |
从本地内存读取热点 key 缓存的值 | 配合 smartSet 使用 |
smartSet(key, value) |
为热点 key 设置本地缓存值 | key 已被判定为热点时,存入真实数据 |
getValue(key) |
综合查询:本地有值返回值,无值返回 null 并自动上报 | 一步到位的查询方式 |
注意区分这几个方法的行为差异,很多人刚接触时会搞混:
1 | isHotKey(key) → 返回 true/false,同时上报 key 的访问量(计数 +1) |
一个内部细节:当 worker 推送热点通知到 client 时,client 会先在 Caffeine 中存入一个魔术值(0x12fcf76)作为占位标记,表示”这个 key 已经是热点了,但还没填入实际业务数据”。所以 get(key) 可能返回这个魔术值或者 null——说明热点标记已生效,但数据还没被 smartSet 填进去,你需要自己加载数据并写入。
Caffeine 分桶设计:client 内部不是用一个 Caffeine 实例存所有热点 key,而是按过期时间(duration)分桶——相同过期时间的 key 共享同一个 Caffeine 实例。这样不同规则下的热点 key 可以有不同的 TTL,互不干扰。
JD-HotKey 依赖 etcd,部署前需要先准备好 etcd 集群。
1 | # Docker 方式(快速启动单节点) |
worker 是独立部署的 Java 进程,负责聚合计算。
1 | # 从源码编译 |
| 参数 | 说明 |
|---|---|
etcd |
etcd 集群地址 |
threads |
工作线程数,建议根据 CPU 核数调整 |
workerPath |
worker 在 etcd 中的注册路径 |
dashboard 是 Web 管理控制台,需要连接 MySQL 和 etcd。
1 | # 1. 创建数据库,执行 db.sql 初始化脚本 |
1 | <dependency> |
依赖冲突注意:
在 Spring Boot 启动时初始化 client,连接到 etcd 并启动数据管道:
1 | @Component |
ClientStarter.Builder 支持的配置项:
| 方法 | 默认值 | 说明 |
|---|---|---|
setAppName |
无(必填) | 应用名称,用于匹配 dashboard 中的规则 |
setEtcdServer |
无(必填) | etcd 集群地址,多个用逗号分隔 |
setCaffeineSize |
200000 | 本地 Caffeine 缓存最大容量 |
setPushPeriod |
500ms | 批量上报统计数据的时间间隔(最小 50ms) |
在 dashboard 中配置你的热点规则。规则以 JSON 格式存储,支持以下参数:
1 | { |
| 字段 | 类型 | 说明 |
|---|---|---|
key |
String | key 匹配规则。prefix = true 时作为前缀匹配 |
prefix |
boolean | 是否前缀匹配。true 表示匹配 key 开头的所有 key |
threshold |
int | 热点阈值——时间窗口内总访问次数超过此值判定为热点 |
duration |
int | 滑动窗口大小(秒) |
interval |
int | 窗口滑动步长(秒) |
desc |
String | 规则描述,方便管理 |
上面的配置含义:以 goods: 开头的 key,在 5 秒内被访问超过 100 次,判定为热点。
最简单的用法——判断是否热点,是的话做特殊处理(降级、限流或直接返回):
1 | @RestController |
更实用的方式——检测到热点后,把数据缓存到本地内存,后续请求直接从内存读:
1 | @Service |
这里的 smartSet 很巧妙:它只在 key 已被判定为热点时才写入本地缓存。如果 key 不是热点,写入会被忽略——不用担心内存被非热点数据撑爆。
getValue 把”查本地缓存 + 上报”合并成了一步,代码更简洁:
1 | public GoodsDetail getGoodsDetail(String goodsId) { |
JD-HotKey 不只局限于数据 key,也能探测热用户和热接口:
1 | // 热用户探测(防爬虫 / 防刷子) |
在 dashboard 中配置对应的规则就行:key = "hot:user:" 和 key = "hot:api:"。
JD-HotKey 的性能不是一蹴而就的,从初版到最终版经历了 17 倍 的提升:
| 版本 | QPS | CPU | 关键优化 |
|---|---|---|---|
| V1(初版) | ~2 万 | >20% | Disruptor + Fastjson,遇到 JDK 线程 bug 导致大量线程创建 |
| V2 | ~10 万 | 7-10% | 换掉 Disruptor,改用 LinkedBlockingQueue |
| V3 | ~16 万 | ~40% | 8 核单机调优 |
| V4 | 25-30 万 | ~70% | 8 生产 + 8 消费线程 |
| V5(最终版) | 稳定 30 万,极限 37 万 | ~50% | 序列化从 Fastjson 换为 Protobuf,16 核 |
最大的性能跃升来自序列化方案的切换:从 Fastjson 换为 Protobuf 后,序列化效率显著提升,CPU 使用率反而下降了。
| 推送速率 | 延迟表现 |
|---|---|
| 10-12 万/秒 | 即时送达,无延迟 |
| 20 万/秒 | 约 1 秒延迟 |
| 40-60 万/秒(8 IO 线程) | 稳定推送 |
| 70 万/秒(16 IO 线程) | 稳定推送 |
| 80 万/秒(极限) | 频繁 GC,最终 OOM |
| 指标 | 数据 |
|---|---|
| 大促期间集群总吞吐 | 1500 万/秒 |
| 本地缓存命中占总流量 | >50% |
| 日探测 Key 数量 | 数十亿 |
| 1 台 Worker(16 核)可支撑 | ~1000 台业务服务 |
| 扛住百万级热 key 所需 Worker | ~30 台 |
对比一下:普通请求访问 Redis 的 RT 通常在 1-5ms,访问数据库 5-50ms。JD-HotKey 让热点请求直接从 JVM 内存读取,RT 降到纳秒级。
| 维度 | JD-HotKey | Caffeine 本地缓存 | Redis 热点 key 探测 | JetCache BOTH |
|---|---|---|---|---|
| 热点发现 | 自动探测 | 手动配置 | redis-cli --hotkeys(采样) |
手动配置 |
| 实时性 | 秒级自动感知 | 静态,需手动更新 | 实时但精度受限 | 广播通知 |
| 动态性 | 自动加入 / 退出 | 不变化,配了就一直有 | 需手动清理 | 广播失效 |
| 多节点一致性 | 全局统一判定 | 各节点独立 | Redis 层面 | 广播通知 |
| 探测范围 | key / 用户 / 接口 | 仅配置的 key | 仅 Redis key | 仅配置的 key |
| 部署复杂度 | 中等(etcd + worker) | 低(纯 SDK) | 低(Redis 自带) | 低(纯 SDK) |
| 运维成本 | 中(etcd 集群维护) | 无 | 无 | 无 |
| 适用场景 | 不可预知的突发热点 | 已知高频数据 | Redis 热点节点排查 | 已知高频读数据 |
阈值设太低 → 太多 key 被判定为热点 → 本地内存撑爆;阈值设太高 → 热点漏判 → Redis 被打。
建议:
smartSet 存入的热点数据占用的是应用 JVM 内存。注意:
CaffeineSize 默认 200000,根据单机内存和数据大小调整etcd 是核心依赖,但 client 有容灾设计:
这是接入时最常踩的坑:
| 冲突依赖 | 解决方案 |
|---|---|
| guava | 升级到 28.2-jre 以上 |
| fastjson | 降到 1.2.70(hotkey-client 内部使用的版本) |
| protobuf | 注意版本兼容,参考 hotkey-client 的 pom |
| Netty | 确保不与业务中的 Netty 版本冲突 |
| JDK 版本 | 建议使用 JDK 1.8.0_191+(早期版本在容器环境下 availableProcessors() 返回宿主机核数而非容器限制核数,导致线程配置异常) |
建议:引入依赖后先跑一遍单元测试,确认没有类冲突。特别注意 guava 和 fastjson 版本,这两个最容易出问题。
热点探测不是万能的,建议配合降级策略:
1 | public GoodsDetail getGoodsDetail(String goodsId) { |
建议监控以下指标:
JD-HotKey 中,worker 就是实际干活的服务节点。有些文章叫它”server”,其实是一个东西。worker 接收 client 上报的数据,执行热点判定,推送结果。它独立部署,不依赖 Spring Boot,是个纯 Java 进程。
理论上不限,但建议按业务域隔离。不同应用用不同的 appName,规则互不影响。大规模场景下建议 etcd 独立集群部署。
是的,isHotKey 每次调用都会在 client 本地的双 Map 中计数 +1。client 每隔 pushPeriod(默认 500ms)将聚合后的数据批量上报给 worker。所以不是每次调用都发网络请求,是批量聚合后上报,开销很小。
worker 内部用 LinkedBlockingQueue(容量 200 万)做消息缓冲,多线程消费。经验数据:1 台 16 核 worker 可以支撑约 1000 台业务服务。大促期间如果需要扛百万级热 key,大约需要 30 台 worker。
smartSet 内部用的也是 Caffeine,但它有个关键区别:只有 key 被判定为热点时才会写入成功。如果你直接用 Caffeine,所有 key 都会缓存,内存可能被非热点数据占满。smartSet 帮你做了这个过滤。
另外还有个 forceSet 方法可以强制设置缓存值(不管 key 是否热点),一般用不到。
JD-HotKey 只负责告诉你”这个 key 是热点”和”管理本地缓存的存取”,不负责帮你从数据库加载数据。你需要在代码中自己实现数据加载逻辑(见场景二的示例代码)。
完整流程是这样的:
0x12fcf76)作为占位isHotKey(key) 返回 trueget(key) → 返回 null(因为是魔术值占位,还没填实际数据)smartSet(key, value) 写入本地缓存Redis Cluster 的热点 key 问题是:某个 key 的访问量集中到一个分片节点,导致该节点 CPU / 带宽打满。JD-HotKey 的解决思路是在应用层就把热点请求拦截掉——数据缓存在 JVM 内存中,根本不会打到 Redis。两者是不同层面的解决方案。
推荐架构:
它们不冲突,可以一起用:
配合方式:JetCache 负责常规缓存,JD-HotKey 负责突发热点保护。当 JD-HotKey 判定某 key 为热点时,数据直接走 JVM 内存,连 JetCache 的 L2(Redis)都不需要访问。
JD-HotKey 的核心价值在于自动发现热点——这是它区别于其他缓存方案的最大优势。你不需要提前知道哪些 key 会变热,系统会根据实际访问量自动判定、自动推送、自动过期释放。
| 场景 | 推荐方案 |
|---|---|
| 已知的固定高频数据 | Caffeine 或 JetCache BOTH |
| 不可预知的突发热点 | JD-HotKey |
| Redis 热点节点保护 | JD-HotKey(应用层拦截)或 Redis 热点分片 |
| 热用户 / 热接口探测 | JD-HotKey |
如果你的业务中存在”不知道什么时候会突然变热”的场景(电商秒杀、热搜话题、突发新闻),JD-HotKey 能帮你自动识别并保护这些热点 key,将请求拦截在 JVM 内存中,避免打垮 Redis 和数据库。
但它也不是万能的——etcd 的部署运维、依赖冲突的处理、阈值的调优,都需要一定的投入。建议先在非核心业务上试水,验证效果后再推广到核心链路。
当系统从单个 Agent 进化到多个 Agent 协作时,一个核心问题就会浮出水面:Agent 之间怎么通信?
通信设计直接决定了你的 Multi-Agent 系统是高效协作还是混乱互怼。
打个比方:单个 Agent 像一个独立工作的程序员,能力再强也有天花板。Multi-Agent 就像一个开发团队——你需要设计好团队的沟通机制:谁向谁汇报?用什么格式交流?出了问题怎么兜底?这些决策决定了团队是 1+1>2 还是 1+1<0。
这篇文章会系统性地拆解 Multi-Agent 通信的三个核心维度:拓扑(谁跟谁聊)、机制(数据怎么流)、协议(聊什么格式)**,并深入分析工程落地中的失败模式和成本控制。
Multi-Agent 的通信,本质上不是”数据包交换”,而是”认知语义的传递”与”任务状态的对齐”。
传统分布式系统里,通信关心的是:HTTP 还是 gRPC?JSON 还是 Protobuf?超时时间设多少?这些当然重要,但在 Multi-Agent 系统里,它们只是基础设施层面的问题。
真正让 Multi-Agent 通信变得独特且困难的,是以下三个问题:
| 层次 | 传统分布式系统 | Multi-Agent 系统 |
|---|---|---|
| 语义层 | 结构化数据,格式固定 | 自然语言 + 推理链,语义模糊 |
| 状态层 | 无状态或简单状态机 | 复杂的认知状态(信念、意图、置信度) |
| 容错层 | 重试 + 降级 | 语义漂移检测 + 认知纠偏 |
比如:当 Agent A 告诉 Agent B “这个 Bug 很严重”时,B 需要理解的不只是”严重”这两个字,还包括 A 判断严重的依据、影响的范围、以及 A 对修复难度的预判。这种心智模型的传递,是传统 RPC 调用里不存在的。
基于这一点,我们再来看具体的通信设计。
拓扑设计是架构的第一个决策。它决定了系统的耦合度、容错性和扩展上限。
这是最常见的模式,也最容易理解和实现。
1 | ┌─────────────────┐ |
核心逻辑:一个 Supervisor 负责接收任务、拆解子任务、分配给 Worker Agent、收集结果并汇总。Worker 之间不直接通信,所有信息流都经过 Supervisor 中转。
生活类比:这就像一个项目经理带团队。需求先交给 PM,PM 拆分任务分给开发、测试、设计,最后由 PM 汇总交付。开发人员不需要直接跟测试沟通——PM 是信息枢纽。
优势:
致命缺陷:
适用场景:任务流程明确、Agent 数量较少(3-5 个)的场景。比如”搜索 → 分析 → 生成报告”这种线性流水线。
所有 Agent 地位平等,直接互相通信,没有中心节点。
1 | ┌────────────┐ ┌────────────┐ |
核心逻辑:每个 Agent 都能发起对话、响应请求、推荐下一个处理者。没有谁是”老板”,大家通过协商决定谁来干活。
生活类比:这像一个开源项目的维护者社区。每个人都能提 Issue、Review PR、Merge 代码,没有绝对的上下级关系。
优势:
致命缺陷:
防循环的工程手段:
1 | # 1. 设置最大轮次 |
适用场景:头脑风暴、多角色辩论、代码审查等需要多视角碰撞的场景。
现实中的大型系统,往往是两者的结合——分层。
1 | ┌───────────────┐ |
核心逻辑:顶层 Agent 做任务拆解和战略规划,中层 Agent 做子任务协调,底层 Agent 执行具体操作。每层只跟相邻层直接通信。
生活类比:这就是公司的组织架构。CEO 定方向,VP 拆目标,一线执行。你不会希望 CEO 直接管到实习生——层级是管理复杂度的利器。
关键设计原则:
| 原则 | 说明 |
|---|---|
| 信息压缩 | 每层向上汇报时,要压缩信息。底层报”3 个 API 报错”,中层报”接口层有 3 个异常”,顶层只需要知道”系统存在稳定性风险” |
| 上下文隔离 | 每层只维护自己需要的上下文,避免全局状态膨胀 |
| 委托边界 | 明确每层的决策权限。底层不需要请示中层就能做的小事,就不要上报 |
适用场景:大型企业级系统,如金融风控(合规层 → 策略层 → 执行层)、智能客服(路由层 → 业务层 → 工具层)。
| 维度 | 中心化编排 | 去中心化协作 | 层次化混合 |
|---|---|---|---|
| 耦合度 | 高(Worker 依赖 Supervisor) | 低(Agent 独立) | 中(层级内紧耦合,层级间松耦合) |
| 容错性 | 差(单点故障) | 好(无单点) | 中(某层故障可降级) |
| 可观测性 | 好(中心节点全局可见) | 差(信息分散) | 中(分层可见) |
| 扩展性 | 差(中心节点是瓶颈) | 好(动态加入) | 好(横向+纵向扩展) |
| 实现复杂度 | 低 | 高 | 中 |
| 适用 Agent 数 | 3-5 个 | 5-10 个 | 10+ 个 |
拓扑解决的是”谁跟谁聊”,机制解决的是”数据怎么从 A 到 B”。
这是 LangGraph 的核心设计哲学,也是目前最流行的方案。
核心思想:Agent 之间不直接发送消息,而是共同读写一个全局状态对象。前一个 Agent 更新状态,后一个 Agent 读取状态变化,间接完成通信。
1 | ┌──────────┐ ┌──────────────┐ ┌──────────┐ |
生活类比:想象一个共享的 Google Docs。团队成员不需要开会讨论,直接打开文档看最新内容,需要修改就直接编辑。文档本身就是通信媒介。
优势:
| 优势 | 说明 |
|---|---|
| 天然支持断点续传 | 状态持久化到数据库,崩溃后可以从上次状态恢复 |
| Human-in-the-loop 友好 | 人类可以查看和修改中间状态,再让 Agent 继续 |
| 可观测性强 | 每次状态变更都有记录,方便调试和审计 |
| 避免消息丢失 | 状态是幂等更新的,不存在”消息丢了”的问题 |
注意事项:
当你的 Agent 系统需要跨语言、跨进程、跨机器通信时,共享状态就不够用了。这时候需要引入消息中间件。
1 | ┌───────────┐ ┌───────────┐ |
生活类比:这像公司的邮件系统 + 公告板。你需要别的团队配合时,发邮件(发布消息)到对方的收件箱(Topic),对方在自己方便的时候查看并处理(异步消费)。不需要面对面沟通。
与共享状态的核心区别:
| 维度 | 共享状态 | 消息队列 |
|---|---|---|
| 通信模式 | 隐式(通过读写状态) | 显式(发送/接收消息) |
| 耦合方式 | 数据耦合(共享同一份状态) | 消息耦合(约定消息格式) |
| 时效性 | 最终一致 | 可精确控制(同步/异步) |
| 跨语言 | 困难(需要共享运行时) | 天然支持(消息是通用格式) |
| 失败恢复 | 状态快照恢复 | 消息重发(ACK 机制) |
| 适用场景 | 单进程、强一致性 | 多进程/多语言、异步解耦 |
这是一种隐式通信方式:Agent 之间不直接交换数据,而是通过一个共享的向量知识库来间接协作。
1 | ┌──────────┐ ┌──────────┐ |
核心逻辑:Agent A 将中间推理结果、观察到的事实、学到的经验向量化后存入向量库。Agent B 在需要时,通过语义检索主动”拉取”相关信息。
生活类比:这像公司的知识库(Confluence / Notion)。前人在项目结束后把经验写成文档,后来的人遇到类似问题时去搜索,找到相关文档后借鉴。写文档的人和读文档的人不需要直接沟通。
适用场景:
关键设计点:
| 设计点 | 建议 |
|---|---|
| 元数据过滤 | 一定要给向量加元数据(来源 Agent、时间戳、类型),否则检索结果会混入无关信息 |
| 遗忘机制 | 不能只增不减,需要定期清理过期或低相关度的记忆 |
| 冲突检测 | 不同 Agent 可能写入矛盾的信息,需要版本控制或置信度排序 |
拓扑和机制解决的是”通道”问题,协议解决的是”内容”问题——Agent 之间传什么格式的消息,才能确保对方准确理解?
1 | # Agent A 发给 Agent B 的消息 |
问题:
这是目前业界的主流做法。把 Agent 之间的通信标准化为函数调用格式,充分利用 LLM 原生的 Function Calling 能力。
1 | { |
核心优势:
name 字段直接说明要做什么tool_call_id 让每次调用都可溯源这是进阶玩法。不只要传递”结果”,还要传递”推理过程”和”置信度”。
1 | { |
为什么这很重要?
因为下游 Agent 需要根据置信度来决定下一步行动:
1 | def decision_agent(received_message): |
生活类比:这像医生会诊。一个医生不能只说”我觉得是肺炎”,他需要说”基于 X 光片和血常规结果(推理依据),我有 80% 的把握是肺炎(置信度),但也考虑了支气管炎的可能性(备选方案),建议再做 CT 确认(下一步建议)”。
目前最重要的行业趋势之一:Agent 通信协议的标准化。
两个值得关注的协议:
| 协议 | 提出者 | 定位 | 核心概念 |
|---|---|---|---|
| MCP(Model Context Protocol) | Anthropic | Agent ↔ 工具/数据源 | Resource、Tool、Prompt |
| A2A(Agent-to-Agent) | Agent ↔ Agent | Task、Artifact、Message、StatusUpdate |
MCP 解决的是:Agent 怎么调用外部工具和数据源。它定义了一套标准接口,让不同的 LLM 应用能以统一方式访问工具,类似于 USB-C 之于外设。
A2A 解决的是:不同平台、不同供应商的 Agent 之间怎么互通。它定义了 Agent Card(能力描述)、Task(任务生命周期)、Artifact(产出物)等标准对象。
1 | A2A 协议核心对象: |
为什么标准化很重要?
想象一下这个场景:你的公司用 LangChain 写了 5 个 Agent,合作伙伴用 AutoGen 写了 3 个 Agent,供应商用自研框架写了 2 个 Agent。如果没有标准协议,每两个 Agent 之间都需要写一个”翻译层”——N 个 Agent 需要 N×(N-1)/2 个适配器。有了标准协议,所有 Agent 只需要实现协议接口,N 个 Agent 只需要 N 个适配器。
这是工程落地中最关键、也最容易被忽视的部分。你的系统在 Demo 里跑得很好,一上生产就炸,大概率就是通信失败处理没做好。
问题:Agent A 的意图在传递过程中被曲解,Agent B 理解的意思和 A 想表达的不一样。
1 | Agent A: "优化这个函数的性能"(意图:降低时间复杂度) |
解决方案:
1 | # 结构化的任务描述,避免语义漂移 |
问题:多轮通信导致消息列表越来越长,超出 LLM 的上下文窗口限制。
1 | Round 1: 2,000 tokens |
解决方案:
| 策略 | 做法 | 优缺点 |
|---|---|---|
| 滑动窗口 | 只保留最近 N 轮消息 | 简单,但会丢失早期重要信息 |
| 摘要压缩 | 定期将历史消息压缩成摘要 | 保留关键信息,但摘要本身消耗 Token |
| 分层记忆 | 短期记忆(最近消息)+ 长期记忆(向量化存储) | 效果最好,但实现复杂 |
1 | def compress_context(messages: list, max_tokens: int = 4000): |
死锁:Agent A 等待 Agent B 的结果,Agent B 等待 Agent C 的结果,Agent C 等待 Agent A 的结果 → 三个都卡住。
活锁:Agent A 和 B 互相传递任务,谁都不处理,一直踢皮球 → 系统一直在”忙”但没有进展。
1 | 死锁示例: |
解决方案:
1 | # 1. 全局超时机制 |
问题:一个 Agent 的输出错误,会导致下游所有 Agent 基于错误信息做出错误决策。
1 | Agent A(数据收集): 错误地认为 API 限额是 1000 次/小时(实际是 10000 次) |
解决方案:
每次 Agent 间的通信都不是免费的。架构师需要在”充分通信”和”成本控制”之间找平衡。
| 成本项 | 说明 | 量级 |
|---|---|---|
| Token 消耗 | 每次通信的输入 + 输出 Token | 主要成本 |
| API 延迟 | 每次 LLM 调用的网络延迟 | 0.5-5 秒/次 |
| 错误代价 | 一次错误通信导致的重做成本 | 可能数倍于正常成本 |
策略一:按需通信,不要全程直播
1 | ❌ 差的做法:Agent A 的每一步都实时通知 Agent B |
策略二:通信分级
| 级别 | 方式 | 适用场景 | Token 消耗 |
|---|---|---|---|
| L1 轻量 | 结构化信号(状态码/枚举值) | “任务完成”、”需要帮助” | 极少 |
| L2 标准 | 结果摘要 + 关键数据 | 阶段性汇报 | 中等 |
| L3 完整 | 完整推理链 + 原始数据 | 关键决策、任务交接 | 高 |
不是所有通信都需要完整的推理链。简单的状态同步,一个枚举值就够了。
策略三:缓存复用
1 | # 缓存其他 Agent 的历史输出,避免重复请求 |
1 | 你的 Agent 系统是什么场景? |
1 | 你的 Agent 在哪里运行? |
1 | 你的项目处于什么阶段? |
Multi-Agent 通信设计,核心就是回答三个问题:
没有银弹,只有权衡。选择取决于你的Agent 数量、任务复杂度、性能要求和成本预算。
但有几个通用原则:
Multi-Agent 系统还处于快速发展期,A2A 和 MCP 等标准协议正在逐步成熟。现在投入精力把通信架构设计好,未来接入更广泛的 Agent 生态时,就会觉得打地基阶段都是值得的。
过去 50 年,人机交互经历了 CLI → GUI → Web 的演进。今天,一个名为 Flipbook 的实验性产品正在悄悄开启第四个时代——AI 生成界面(AGI,AI-Generated Interface)。每”页”都是一张 AI 实时生成的图片,没有 HTML,没有 CSS,没有 JavaScript。你看到的一切,都是像素。
最近刷到 Shopify CEO Tobi Lütke 转发了一条动态,引起了我的注意。一个叫 flipbook.page 的平台,被描述为:
“An infinite visual browser generated entirely on demand in real time.”
(一个完全按需实时生成的无限视觉浏览器)
用一句话概括:
你在 Flipbook 里看到的每一”页”,都是一张 AI 实时生成的图片。点击图中的任何元素,就会生成一张新图片,带你深入探索那个方向。
听起来有点科幻?但它已经上线了。
传统浏览器的渲染链路是这样的:
1 | 用户点击链接 → 服务器返回 HTML → 浏览器解析 DOM → CSS 渲染 → JS 执行 → 显示页面 |
Flipbook 的链路则完全不同:
1 | 用户点击图片某处 → AI 理解意图 → 实时生成一张新图片 → 显示为"下一页" |
具体来说:
这就像在探索一张无限展开的知识地图,而不是在浏览一个个独立的网页。
Flipbook 背后有两套 AI 系统在协作:
| 系统 | 职责 | 类比 |
|---|---|---|
| 图像生成模型 | 根据用户意图,实时绘制每一页 | “画家” |
| 自定义视频模型 | 在页面之间生成平滑过渡动画 | “导演” |
用户开启”视频流”模式后,两系统合并为连续 1080p 视频流,页面切换不再是跳变,而是平滑的镜头运动。
这不是一个”纯幻觉”的生成器。Flipbook 的内容来源有两个:
官方自己也说:“事实准确性大致等同于 ChatGPT/Gemini/Claude 的水平。”
有一个细节很有意思:官方专门解释了文字渲染问题。
“All text on the screen is rendered as pixels by the image model. There are no text overlays applied to the images.”
这意味着图中的每一个字、每一行标题、每一个数字标注,都是图像模型”画”出来的。偶尔会出现文字不够清晰、位置偏移的问题——但这会随着模型迭代而改善。
换句话说,文字在这个系统中不再是可复制的文本节点,而是视觉元素的一部分。
Flipbook 的创始团队背景很有意思:
| 创始人 | 背景 |
|---|---|
| Zain Shah | 前 OpenAI 研究员 |
| Eddie Jiao | 前 Humane、Slack |
| Drew Carr | 前 Apple |
算力由 Modal 赞助,投资方是 South Park Commons(这家机构还投了 Notion、Figma 等知名产品)。
一个前 OpenAI 研究员 + 两个顶尖产品设计师的组合,解释了为什么这个项目既有技术深度,又有极强的交互直觉。
过去 30 年,我们默认了一个前提:人机交互的界面是由工程师编写代码构建的。
无论是早期的 HTML 页面、Flash 动画,还是现在的 React 组件,本质上都是:工程师定义结构 → 浏览器渲染 → 用户交互。
Flipbook 打破了这个假设:
界面不再是”建造”出来的,而是”生成”出来的。
就像从”手工绘制每一帧动画”进化到”实时渲染引擎”——只不过这里的渲染引擎不是 GPU,而是大模型。
官方有一段话很打动我:
“一张图片价值千言万语,但我们的屏幕上却大多只是文字和彩色方块。”
在传统 Web 上,如果你想解释一个复杂概念,你只有几种选择:
在 Flipbook 里,如果最有效的表达方式是一个词,你会看到一个词;如果是一幅插图,你会看到一幅插图;如果是一个数据可视化,你会看到一个数据可视化——AI 会自动选择最适合当前语境的形式。
这不是在”展示信息”,而是在”选择最佳的信息传达方式”。
Flipbook 被描述为 “AI 完全实现的 HyperCard”。
HyperCard 是 Apple 在 1987 年推出的一个软件,允许用户以卡片式的方式组织知识和导航。它的核心理念是:知识应该以空间方式探索,而不是线性搜索。
这个理念在当时太超前了,最终被万维网(WWW)取代。但 37 年后,AI 让”空间化知识探索”重新有了可能——而且这次不再需要用户手动制作卡片。
官方明确表示,Flipbook 目前是一个实验。但它规划的演进方向,每一条都足够让人兴奋。
官方原话举例:
“现在你用 Flipbook 研究旅行计划,但预订要去别的地方。未来整个过程都可以在 Flipbook 内完成。”
想象一下:
从”信息探索”到”行动执行”的闭环。
当前页面是”快照式”的图片。但未来可能实现:
官方提到了 “more interactive” 和 “take actions and store their own data”:
这意味着交互能力将内嵌到像素生成的过程中,不再是 HTML 元素的专利。
这是最大胆的方向。官方说:
“我们想象一个世界,你使用的所有工具都像我们生活的世界一样丰富和可视化。”
翻译成大白话:Flipbook 可能成为所有 App 的”元界面”。
| 场景 | 现在 | 未来(Flipbook) |
|---|---|---|
| 打车 | 打开 Uber App → 输入地址 → 确认 | 在 Flipbook 里说”叫车去机场” → 生成选择图 → 点击确认 |
| 发邮件 | 打开 Gmail → 写邮件 → 发送 | 在 Flipbook 里说”给 Alice 发项目更新” → 生成预览图 → 点击发送 |
| 点外卖 | 打开外卖 App → 选餐厅 → 下单 | 在 Flipbook 里说”点份泰餐” → 生成推荐图 → 点击下单 |
所有功能都通过自然语言 + 视觉界面调度,不需要打开任何独立 App。
这不就是 AI 一直在说的”无 App 的未来”吗?
当前生成的是通用信息图。未来结合个人数据后:
每个人看到的内容完全不同,而且是当下即时生成的。
当然,Flipbook 要走的路还很长。以下是当前的核心瓶颈:
| 挑战 | 当前状态 | 突破方向 |
|---|---|---|
| 算力成本 | 每页实时 AI 生成,极其昂贵 | 模型压缩、缓存热点页面、边缘计算 |
| 文字渲染精度 | 官方承认”偶尔不完美” | 下一代图像模型的文本能力 |
| 事实准确性 | 类似 ChatGPT 水平,可能有幻觉 | RAG + 实时搜索 + 引用溯源 |
| 交互延迟 | 生成需要等待时间 | 流式生成、预判意图提前生成 |
| 商业化模式 | 目前靠赞助算力 | 订阅制、按页面消耗计费、B2B |
说实话,第一次看到 Flipbook 的演示时,我的第一反应是:这东西真的能用吗?
但仔细思考后,我发现它触及了一个本质问题——我们为什么需要浏览器?
浏览器的核心功能是”获取信息并交互”。传统 Web 用 HTML/CSS/JS 实现了这个功能,但这只是一种实现方式,不是唯一的方式。
Flipbook 用 AI 重新定义了”获取信息”的界面形态:不再是工程师预先写好的页面,而是根据你的意图即时生成的视觉表达。
这就像从”预先录制的电视节目”进化到”实时互动的直播”——内容不再是固定的,而是随观众需求变化的。
Flipbook 目前可能只是一个实验性产品,但它代表了一个可能改变行业走向的信号:
界面,正在从”被构建”走向”被生成”。
如果说 HTML 定义了 Web 1.0 的界面范式,React 定义了 Web 2.0 的界面范式,那么 Flipbook 可能正在定义 Web 3.0 的界面范式——AI 生成的实时视觉界面。
这不是在取代 Web,而是在 Web 之上叠加了一层新的交互维度。
正如官方所说:
“We wanted a computing experience full of rich beautiful visuals made just for us, generated just in time.”
之前研究 Chrome DevTools MCP 的时候,解决的核心问题是让 AI 能操控浏览器。但那个方案有天然的局限性:必须配置 MCP Server、依赖 Chrome 调试端口、每个平台要单独写适配器。
OpenCLI 把这件事重新做了一遍,而且做得更彻底——它不只是让 AI 能操控浏览器,而是把任何网站变成标准化的命令行工具。GitHub 上 22K+ Stars,不是偶然。
这篇文章的目标很明确:讲清楚 OpenCLI 是什么、架构怎么设计的、以及最核心的部分——如何在 Claude Code 等 Code Agent 里用它。
一句话定义:OpenCLI 是一个 AI 原生的 CLI 运行时框架,把任意网站、浏览器会话、Electron 应用统一变成标准化的命令行接口。
打个比方理解它的定位:
| 场景 | 传统做法 | OpenCLI 做法 |
|---|---|---|
| 发一篇小红书 | 打开浏览器 → 登录 → 上传图片 → 写文案 → 发布 | opencli xiaohongshu publish --title "xxx" --content "xxx" |
| 看 B站播放量 | 打开 B站创作者中心 → 刷新 → 看数据 | opencli bilibili stats |
| 给 Claude Code 说”帮我发篇文章” | Claude Code 做不到 | Claude Code 通过 OpenCLI 直接完成 |
核心区别在于:传统做法每次都要手动操作网页,OpenCLI 把这些操作封装成确定性 CLI 命令,而且零 LLM 运行成本。
1 | ┌──────────────────────────────────────────────────────┐ |
这个架构有几个关键设计点,值得拆开细说。
这是 OpenCLI 架构里最重要的一个设计选择。
运行期智能的意思是:每次执行命令时都让 LLM 实时理解页面结构、决定操作步骤。这种方式灵活,但每次都要消耗 token,而且结果不稳定。
编译期智能是 OpenCLI 的选择:Adapter 在生成阶段只解析一次页面结构,产出一个确定性的 YAML 定义。后续所有 CLI 调用都走这个 YAML,零 LLM 成本,结果可预测。
1 | # 一个 Adapter 示例:获取 B站视频播放量 |
这段 YAML 定义好之后,每次执行都是确定的 DOM 选择器匹配,不需要 LLM 参与。只有在 Adapter 开发阶段才需要一次智能解析。
OpenCLI 选择基于 Chrome DevTools Protocol (CDP) 而不是传统的 Selenium 或 Playwright,原因很实际:
| 维度 | Selenium/Playwright | CDP + Chrome 实例 |
|---|---|---|
| 登录态 | 需要单独维护 cookies | 直接复用你正在用的 Chrome |
| 安全 | 需要存储账号密码 | 零凭证存储 |
| 真实性 | 无头浏览器可能被检测 | 真实浏览器实例 |
| 开发成本 | 要写完整的自动化脚本 | YAML 声明式定义 |
关键点在于复用登录态。你在浏览器里已经登录了知乎、B站、小红书,OpenCLI 直接通过 CDP 连上这个正在运行的实例,不需要重新登录、不需要 API Key、不需要存密码。
CDP 本身只能从外部控制 Chrome,但 OpenCLI 需要双向通信——既要控制页面,也要把页面结构回传给 CLI。这个桥梁由一个 Chrome 扩展承担:
Playwright MCP Bridge 扩展负责:
这个扩展是轻量级的 micro-daemon 模式,启动 OpenCLI 时自动加载。
Session 是 OpenCLI 连接 CLI 命令和具体浏览器标签页的桥梁:
1 | # 把当前浏览器某个已登录的标签页绑定到 session |
绑定之后,所有针对该平台的 CLI 命令都会在这个已登录的标签页里执行。
1 | # 全局安装 OpenCLI |
opencli setup 会做这几件事:
~/.opencli 配置目录1 | # 查看内置适配器列表 |
这部分是整篇文章的核心。OpenCLI 的真正威力不在于手动敲命令,而在于让 AI Code Agent 通过它操控任意网站。
Claude Code、Cursor 这类 Code Agent 原生能力很强:能写代码、能读文件、能跑测试、能用 git。但有一个明确的边界——它们不能操作网页。
这个边界在实际工作中很要命。举个例子:
你要把一篇技术博客同步到知乎、公众号、小红书三个平台。用 Claude Code 写文章很快,但发布环节只能手动操作三个平台的后台。OpenCLI 把这个边界打通了。
Claude Code 本身就能执行 shell 命令,最直接的方式就是在对话中让它执行 opencli 命令:
1 | 你: 帮我查看 B站最近的视频数据 |
这种方式不需要额外配置,只要本机装了 OpenCLI 就行。
OpenCLI 提供了适配 AI Agent 的 Skill 定义,安装后 Agent 能更准确地理解和使用 OpenCLI:
1 | # 在 Claude Code 中安装 OpenCLI skill |
安装之后,Claude Code 会在执行浏览器相关任务时自动识别 OpenCLI 的可用命令,而不是每次都让你手动指定。
结合 Claude Code 的自定义命令系统,可以把常用的 OpenCLI 操作封装成斜杠命令:
1 | # .claude/commands/publish-blog.md |
之后在 Claude Code 中只需输入 /publish-blog 就能一键发布。
1 | 你: 把 source/_posts/opencli-deep-analysis.md 这篇文章发到知乎、小红书、B站 |
整个过程不需要你打开任何一个浏览器页面。
1 | 你: 帮我看看各平台最近一周的数据 |
对于数字游民社区的运营工作,OpenCLI 能大幅减少重复劳动:
1 | 你: 检查一下社区后台有没有待审核的帖子 |
理解 Claude Code 通过 OpenCLI 操作浏览器的底层流程,有助于你排查问题和编写自定义插件。
完整的调用链路:
1 | Claude Code 发起对话 |
结构化 DOM 快照 是理解这一切的关键。OpenCLI 不是截图给 AI 看,而是把页面转成一个带语义的结构化文本:
1 | [button] "发布文章" (clickable, enabled) |
这种格式对 LLM 极其友好:token 消耗远低于截图,信息密度更高,而且可以直接定位到可交互元素。
内置适配器覆盖了主流平台,但你自己的网站或者小众平台需要写自定义插件。
1 | ~/.opencli/plugins/ |
以”从某个网站后台提取文章列表”为例:
1 | # plugin.yaml |
1 | # adapters/list.yaml |
1 | # adapters/publish.yaml |
写好之后,通过 symlink 链接到 OpenCLI 插件目录:
1 | # Linux/Mac |
之后就能直接使用:
1 | # 列出文章 |
自定义插件写好后,Claude Code 同样能调用。你可以在 Claude 的对话中直接说:
1 | 你: 用 my-blog-admin 插件列出所有已发布的文章 |
市面上让 AI 操作网页的方案不少,简单对比一下:
| 方案 | 登录态 | LLM 成本 | 开发门槛 | 稳定性 |
|---|---|---|---|---|
| OpenCLI | 复用 Chrome | 零运行成本 | YAML 声明式 | 确定性执行 |
| Chrome DevTools MCP | 复用 Chrome | 每次消耗 token | 需 MCP 配置 | LLM 实时判断 |
| Playwright 脚本 | 需要维护 cookies | 无 | 完整编程 | 最高但开发成本大 |
| Browser Use 框架 | 需要单独登录 | 每次消耗 token | Python 代码 | 依赖 LLM 判断 |
OpenCLI 的 sweet spot 很明确:当你需要一个确定性的、零运行成本的、能复用浏览器登录态的网站操作方案时,它是最优选择。
任何工具都有边界,OpenCLI 也不例外。
OpenCLI 复用浏览器登录态,意味着它能操作你已登录的任何网站。建议:
部分平台会检测自动化行为。OpenCLI 走的是真实浏览器实例,比无头浏览器好一些,但如果操作频率过高仍可能触发风控。控制节奏、避免短时间大量操作。
OpenCLI 把”让 AI 操作网页”这件事从实验阶段拉到了生产可用阶段。它的核心价值可以概括为三点:
对于写博客、运营社区、管理多平台的创作者来说,配合 Claude Code 这样的 Code Agent,OpenCLI 能省掉大量重复的浏览器操作。对于开发者来说,YAML 声明式的插件开发门槛远低于写完整的自动化脚本。
每天打开手机,十几个 APP 轮番刷一遍,微博热搜、知乎热榜、抖音热点、今日头条……刷完一圈下来,两个小时过去了,真正有用的信息可能就三五条。剩下的是什么?震惊体标题党、营销软文、明星八卦、各种算法硬塞给你的”你可能感兴趣”。
更气人的是,明明只想看看科技圈今天发生了什么,却被”某明星离婚”霸占了热搜第一。平台算法绑架了我们的注意力,想看的内容找不到,不想看的铺天盖地。
有没有一种工具,能帮你从”被动接收”变成”主动获取”?TrendRadar 就是这么一个开源项目——聚合全网热点,按你的关键词筛选,定时推送到你的手机。更重要的是,它还能让 AI 帮你分析这些热点背后的趋势和情绪。
一句话概括:TrendRadar 是一个开源的热点新闻聚合分析工具。
它的核心思路很简单——把全网 50+ 个平台的热榜抓过来,按你设定的关键词过滤,把真正关心的内容推给你。推送渠道也很丰富:飞书、钉钉、企业微信、Telegram、邮件、Bark(iOS)、Slack,甚至自定义 Webhook。
更厉害的是,它内置了 AI 分析功能。不仅是聚合热点,还能让 AI 帮你:
这就像雇了一个私人新闻助理,每天帮你从海量信息中提炼出真正有价值的干货。
TrendRadar 的数据来源是另一个开源项目 NewsNow。这个项目聚合了全网 50+ 个平台的热榜数据,包括:
| 国内综合 | 科技平台 | 金融平台 | 国际媒体 |
|---|---|---|---|
| 知乎、微博 | IT之家、36氪 | 华尔街见闻 | Hacker News |
| 百度热搜 | 稀土掘金 | 财联社 | GitHub Trending |
| 抖音、今日头条 | V2EX | 雪球 | Product Hunt |
| 澎湃新闻、凤凰网 | 酷安 | 金十数据 | 联合早报 |
| 虎扑、贴吧 | 少数派 | 格隆汇 | 卫星通讯社 |
NewsNow 通过调用各平台的官方 API 或爬取页面来获取热榜数据,然后统一输出成标准格式。TrendRadar 直接调用 NewsNow 的公开 API:
1 | https://newsnow.busiyi.world/api/s?id=zhihu&latest |
返回的数据格式是这样的:
1 | { |
所以 TrendRadar 不需要自己去啃各平台的反爬机制,数据源维护这个苦活儿由 NewsNow 项目负责。万一某个平台接口变了,NewsNow 更一下就行,TrendRadar 用户完全不用操心。
默认支持 11 个主流平台:知乎、微博、百度热搜、抖音、今日头条、B站热搜、华尔街见闻、财联社、澎湃新闻、凤凰网、贴吧。想加更多平台?直接在配置文件里加就行。
这是核心功能。你在 frequency_words.txt 里写上关心的关键词,系统就只推送包含这些词的新闻。语法很灵活:
1 | # 最简单的:直接写关键词 |
如果你不想自己写关键词,可以用 自然语言描述 你关注的方向。在 ai_interests.txt 里写:
1 | 下面是我要关注的内容: |
AI 会自动理解你的兴趣,给每条新闻打分,只推送高相关度的内容。这个功能需要配置 AI API(支持 DeepSeek、OpenAI、Gemini 等)。
| 模式 | 说明 | 适用人群 |
|---|---|---|
| daily(当日汇总) | 每天定时推送当天所有匹配新闻 | 企业管理者、普通用户 |
| current(当前榜单) | 每次推送当前榜单匹配新闻 | 自媒体人、内容创作者 |
| incremental(增量监控) | 只推送新出现的内容,零重复 | 投资者、交易员 |
举个例子:你监控”特斯拉”,每小时执行一次。如果选择 incremental 模式,只有第一次出现的新闻才会推送给你,后续重复出现的就不打扰了。适合高频监控场景。
你可以精细控制”什么时间做什么事”。比如:
预设了 5 种模板:always_on(全天候)、morning_evening(早晚汇总)、office_hours(办公时间)、night_owl(夜猫子)、custom(完全自定义)。
开启后,每次推送都会附带一份 AI 生成的洞察报告,包含:
AI 还能分析每条新闻的排名变化轨迹、热度持续时间、跨平台表现。比如某条新闻在微博排第3,知乎排第5,抖音排第8——AI 能告诉你这个话题的”全网热度分布”。
如果你订阅了海外 RSS(如 Hacker News),AI 可以帮你把英文标题翻译成中文。反过来,如果你想用英文读国内热点,也可以翻译成英文。
这是给深度用户准备的。TrendRadar 实现了 MCP (Model Context Protocol) 协议,可以接入 Claude Desktop、Cherry Studio、Cursor 等 AI 客户端。
你可以用自然语言跟新闻数据”对话”:
1 | "分析过去一周 DeepSeek 的热度变化" |
AI 会自动调用 TrendRadar 的 21 个分析工具,帮你做深度数据挖掘。
适合没有服务器的用户。流程是:
缺点是每次运行完环境就销毁,数据没法本地存。需要配置云存储(如 Cloudflare R2)来持久化数据。
适合有服务器、NAS 或长期运行电脑的用户。数据本地存储,更稳定。
1 | # 克隆项目 |
Docker 部署还有个好处:可以同时跑两个容器——一个做新闻推送,一个做 MCP AI 分析服务。
Windows/Mac/Linux 直接跑:
1 | # Windows |
这是核心配置文件,结构如下:
1 | app: |
前面已经介绍过语法,这里补充几个实用技巧:
技巧1:从宽到严,逐步调整
刚开始可以写宽泛的关键词,观察几天后再加过滤词:
1 | # 第一版:先测试 |
技巧2:正则表达式精确匹配英文
英文容易误匹配,比如 ai 会匹配到 training 里的 ai。用正则解决:
1 | # 精确匹配独立单词 |
不会写正则?直接问 ChatGPT:”帮我写一个正则表达式,精确匹配英文单词 AI,不匹配 training 里的 ai,格式是 /正则/ => 别名”
技巧3:全局过滤不想看的
有些内容不管什么关键词都不想看,用 [GLOBAL_FILTER]:
1 | [GLOBAL_FILTER] |
企业微信(最简单):
飞书:
1 | { |
Telegram:
需要两个配置:bot_token 和 chat_id。
/newbot 创建机器人https://api.telegram.org/bot<Token>/getUpdateschat.id邮件:
支持 Gmail、QQ邮箱、163、Outlook 等。QQ邮箱需要用授权码(不是密码),在邮箱设置里开启 SMTP 服务后生成。
我部署了一套配置,关键词设为:AI、DeepSeek、华为、特斯拉、芯片、大模型。推送模式选 incremental,调度选 morning_evening。
效果是这样的:
早上 9 点:收到推送,包含昨晚到今早新出现的 15 条相关热点。AI 分析报告附在最后,告诉我”AI 领域今天舆论偏正面,DeepSeek 新模型发布引发热议,华为鸿蒙讨论度上升”。
晚上 8 点:收到当日汇总,包含全天所有匹配新闻(去重后约 30 条)。AI 给了一份更完整的趋势分析,包括”哪些话题持续在榜”、”哪些是新爆发点”。
好处:
注意点:
max_news_for_analysis 从 150 降到 50。如果你想深度挖掘新闻数据,MCP 功能很有价值。
以 Cherry Studio 为例(推荐,有 GUI):
运行 TrendRadar 的 MCP 服务:
1 | # Windows |
在 Cherry Studio 设置里添加 MCP 服务器:
streamableHttphttp://127.0.0.1:3333/mcp开始对话。
趋势分析:
1 | "分析最近 7 天 DeepSeek 的热度变化" |
AI 会调用 analyze_topic_trend 工具,返回:
平台对比:
1 | "对比知乎和微博今天关于 AI 的讨论差异" |
AI 会对比两个平台的热点分布、情绪倾向、讨论角度差异。
情感分析:
1 | "分析特斯拉最近新闻的情感倾向" |
返回正面/负面/中性分布,以及典型情感关键词。
生成报告并推送:
1 | "写一份今天的科技热点摘要,推送到飞书" |
AI 会调用 generate_summary_report 生成报告,然后调用 send_notification 推送。自动处理格式转换(Markdown → 飞书格式)。
| 分类 | 工具 | 功能 |
|---|---|---|
| 基础 | get_latest_news |
获取最新新闻 |
get_news_by_date |
按日期查询 | |
get_trending_topics |
热点统计 | |
| RSS | get_latest_rss |
RSS 内容 |
search_rss |
RSS 搜索 | |
| 搜索 | search_news |
统一搜索 |
find_related_news |
相似新闻 | |
| 分析 | analyze_topic_trend |
趋势分析 |
analyze_sentiment |
情感分析 | |
aggregate_news |
跨平台聚合 | |
compare_periods |
时期对比 | |
generate_summary_report |
生成报告 | |
| 通知 | send_notification |
推送消息 |
| 文章 | read_article |
读取正文 |
总共 21 个工具,覆盖了从查询到分析到推送的全流程。
TrendRadar 的数据存储在 SQLite 数据库,按日期分库:
1 | output/ |
数据库表结构设计得很好:
news_items:存储新闻条目(标题、URL、排名)rank_history:记录排名变化历史(每次抓取的排名)crawl_records:记录抓取时间和数量这样设计的好处是可以追踪热度变化轨迹。比如某条新闻早上排第 5,中午排第 3,晚上掉到第 10——这些变化都会被记录下来,供 AI 分析。
| 工具 | TrendRadar | RSS 阅读器 | 热榜网站 |
|---|---|---|---|
| 数据源 | 50+ 平台热榜 | RSS订阅源 | 单一或少量平台 |
| 筛选方式 | 关键词+AI | 手动订阅 | 无筛选 |
| 推送 | 多渠道 | 需额外工具 | 无推送 |
| AI 分析 | 内置 | 无 | 无 |
| 趋势追踪 | 有 | 无 | 无 |
| 部署复杂度 | 中 | 低 | 无需部署 |
TrendRadar 的优势在于:聚合 + 筛选 + 分析 + 推送 一条龙。RSS 阅读器适合订阅特定博客,热榜网站适合快速浏览,但都没有 AI 分析和自动推送。
项目维护得很活跃,版本迭代快(从 v1.0 到 v6.7),文档也很详细。有问题可以去 GitHub Issues 提,作者回复很及时。
TrendRadar 解决的问题是:如何从信息洪流中高效获取有价值的内容。
它不是简单的热榜聚合,而是:
如果你每天花大量时间刷 APP 看热点,却总觉得信息过载、抓不住重点——试试 TrendRadar。部署一次,配置好关键词,之后就等着推送敲门,看完推送就完事。
从”被动接收算法推荐”变成”主动获取关心内容”,这才是高效的信息消费方式。
2026年,AI浪潮席卷全球,最近都被这些新闻刷频了:
“三星市值突破新高,HBM订单排到明年”
“海力士股价暴涨,成英伟达最大HBM供应商”
“美光宣布HBM3e量产,AI存储竞争白热化”
“长鑫存储融资成功,中国DRAM再获突破”
作为科技爱好者,你可能会有很多困惑:
这篇文章,用两个视角帮你彻底理清:DRAM和NAND Flash——存储芯片世界的两大支柱。
DRAM = Dynamic Random Access Memory,中文叫”动态随机存取存储器”。
通俗理解:DRAM就是你电脑上的”临时工作台”。
1 | 你在用Word写文档: |
忘记保存就断电?文件没了。因为DRAM里的数据瞬间清空。
这是DRAM与其他内存技术最大的区别:数据需要不断”刷新”才能保持。
1 | DRAM的存储单元 = 1个电容 + 1个晶体管 |
这就是”动态”的含义:数据不是静态保存的,需要动态、持续地刷新。
对比一下SRAM(静态随机存取存储器):
| 特性 | DRAM | SRAM |
|---|---|---|
| 存储单元 | 1电容+1晶体管 | 6个晶体管 |
| 需要刷新 | ✅ 必须周期刷新 | ❌ 不需要 |
| 密度 | 高(结构简单) | 低(结构复杂) |
| 容量 | 大(单芯片可达16GB) | 小(通常几KB到几MB) |
| 成本 | 便宜 | 贵 |
| 应用 | 内存条、手机内存 | CPU缓存(L1/L2/L3) |
一句话:DRAM性价比高,适合做大容量内存;SRAM性能好但贵,只做CPU内部的小缓存。
| 特点 | 说明 |
|---|---|
| 易失性 | 断电后数据立即丢失 |
| 需要刷新 | 每隔几毫秒必须刷新,否则数据消失 |
| 速度快 | 读写速度远快于硬盘 |
| 密度高 | 单芯片可存储大量数据 |
| 成本低 | 每GB价格相对便宜 |
都属于DRAM技术,但针对不同场景优化:
| 产品 | 特点 | 用途 | 带宽 | 代表厂商 |
|---|---|---|---|---|
| DDR4/DDR5 | 标准内存条 | PC、服务器 | ~25GB/s | 三星/海力士/美光/长鑫 |
| LPDDR4/LPDDR5 | 低功耗版 | 手机、平板 | ~60GB/s | 三星/海力士/美光/长鑫 |
| HBM/HBM3e | 堆叠高带宽 | AI训练GPU | ~1TB/s+ | 三星/海力士/美光 |
| GDDR6/GDDR7 | 显卡显存 | 游戏显卡 | ~160GB/s | 三星/海力士/美光 |
| Server DRAM | 服务器专用 | 数据中心 | ~50GB/s | 三星/海力士/美光/长鑫 |
| Mobile DRAM | 移动端定制 | 智能穿戴、IoT | ~10GB/s | 各厂商均有 |
普通内存条有个致命瓶颈:带宽不够。
1 | 普通内存条:单通道带宽约 25GB/s(DDR5-6400) |
GPU(如英伟达H100)算力极强,但数据喂不进去——传统内存条成了瓶颈。
HBM的解决方案:垂直堆叠
1 | 传统内存条: |
核心技术:
| 技术 | 作用 |
|---|---|
| TSV(硅通孔) | 在芯片上打微孔,垂直导通 |
| 3D堆叠 | 8层、12层DRAM芯片叠在一起 |
| CoWoS封装 | 把HBM和GPU封装在同一块硅中介层上 |
性能对比:
| 类型 | 带宽 | 应用 |
|---|---|---|
| DDR5内存条 | ~25GB/s | 电脑、服务器 |
| HBM3 | ~1TB/s | AI训练GPU |
| HBM3e | ~1.5TB/s+ | 最先进AI芯片 |
这就是为什么英伟达H100价格3万美元起步——HBM成本占了很大比例。
全球市场份额(2025年Q1):
| 排名 | 厂商 | 国家 | 份额 | 趋势 | 技术水平 |
|---|---|---|---|---|---|
| 1 | 三星电子 | 韩国 | ~40-41% | ↓略降 | 最领先 |
| 2 | SK海力士 | 韩国 | ~28-29% | ↑上升 | HBM领先 |
| 3 | 美光科技 | 美国 | ~23-24% | 稳定 | 一流 |
| 4 | 长鑫存储 | 中国 | ~5-6% | ↑上升 | 追赶中 |
| 5 | 南亚科技 | 中国台湾 | ~2% | 稳定 | 中端 |
| 6 | 华邦电子 | 中国台湾 | ~1% | 稳定 | 中低端 |
| 7 | 力积电 | 中国台湾 | <1% | 稳定 | 代工 |
三巨头控制93%+市场
2025年关键变化:
技术能力矩阵:
| 厂商 | DDR5 | LPDDR5X | HBM3e | GDDR7 | 制程 |
|---|---|---|---|---|---|
| 三星 | ✅ | ✅ | ✅ | ✅ | 12nm |
| 海力士 | ✅ | ✅ | ✅领先 | ✅ | 12nm |
| 美光 | ✅ | ✅ | ✅ | ✅ | 12nm |
| 长鑫 | ✅ | ✅ | ❌ | ❌ | 17nm |
| 南亚科 | ✅ | ❌ | ❌ | ❌ | 20nm |
| 华邦 | ❌ | ❌ | ❌ | ❌ | 25nm |
中国现状:长鑫存储是中国大陆唯一的DRAM厂商,2016年成立,填补了国内空白。目前主攻DDR4/DDR5、LPDDR4/LPDDR5,HBM仍在研发阶段。
日本现状:日本已无DRAM厂商。曾经的霸主尔必达2012年破产被海力士收购,日本DRAM产业终结。
NAND Flash,中文叫”NAND闪存”,是一种非易失性存储器。
通俗理解:NAND Flash就是你电脑的”永久仓库”。
1 | 你的手机: |
核心特点:断电后数据不会丢失,可以长期保存。
NAND是逻辑门电路的名字(Not AND),用这种结构的晶体管阵列存储数据,所以叫NAND Flash。
“闪存”的由来:
1 | 传统EEPROM:擦除需要几秒 |
1 | NAND存储单元 = 浮栅晶体管 |
关键点:电子被困在浮栅里,没有电源也能长期保存——这就是”非易失性”的原因。
| 特点 | 说明 |
|---|---|
| 非易失性 | 断电后数据保留 |
| 不需要刷新 | 与DRAM不同,写入后自然保持 |
| 密度高 | 单芯片容量远超DRAM |
| 有擦写寿命 | 每个单元可擦写几千到几万次 |
| 速度较慢 | 比DRAM慢,但比机械硬盘快很多 |
| 类型 | 全称 | 每单元存储 | 特点 | 寿命 | 应用 |
|---|---|---|---|---|---|
| SLC | Single-Level Cell | 1 bit | 最快、最耐用、最贵 | 10万次 | 企业/军工 |
| MLC | Multi-Level Cell | 2 bit | 平衡性能与成本 | 3000-1万次 | 高端消费 |
| TLC | Triple-Level Cell | 3 bit | 主流选择,性价比高 | 500-3000次 | 消费级SSD |
| QLC | Quad-Level Cell | 4 bit | 便宜但慢 | 100-1000次 | 大容量存储 |
1 | 简单理解: |
传统NAND是平铺的,容量有限。现代技术把存储单元垂直堆叠:
1 | 传统2D NAND: |
主流3D NAND层数:
| 厂商 | 最高层数 |
|---|---|
| 三星 | 236层 |
| 海力士 | 238层 |
| 美光 | 232层 |
| 长江存储 | 232层(Xtacking技术) |
1 | 传统3D NAND: |
优势:存储密度更高、I/O速度更快、制造效率更高。
| 产品 | 特点 | 用途 | 速度 |
|---|---|---|---|
| SSD固态硬盘 | 大容量高速存储 | 电脑硬盘 | 3-7GB/s |
| UFS | 高速嵌入式存储 | 中高端手机 | ~4GB/s |
| eMMC | 集成控制器,成本低 | 低端手机/IoT | ~400MB/s |
| SD卡/TF卡 | 可插拔便携 | 相机/无人机 | ~100MB/s |
| USB闪存盘 | 便携通用 | 数据传输 | ~100MB/s |
全球市场份额(2025年):
| 排名 | 厂商 | 国家 | 份额 | 趋势 | 技术水平 |
|---|---|---|---|---|---|
| 1 | 三星电子 | 韩国 | ~35-38% | 稳定 | 最领先 |
| 2 | 凯侠 | 日本 | ~15-18% | 稳定 | 一流(2024年IPO) |
| 3 | 西部数据 | 美国 | ~12-15% | 稳定 | 一流(与凯侠合资) |
| 4 | SK海力士 | 韩国 | ~12-15% | ↑上升 | 一流(含Solidigm) |
| 5 | 美光科技 | 美国 | ~10-12% | 稳定 | 一流 |
| 6 | 长江存储 | 中国 | ~5-8% | 受限 | 接近一流 |
三星+凯侠+西数+海力士控制80%+市场
2025年关键变化:
中国现状:长江存储是中国最大的NAND Flash厂商,技术水平与国际差距较小,232层Xtacking技术已接近第一梯队。
日本现状:凯侠(原东芝存储)专注NAND Flash,是日本唯一的存储芯片厂商。日本已无DRAM厂商。
| 维度 | DRAM | NAND Flash |
|---|---|---|
| 断电后 | ❌ 数据丢失 | ✅ 数据保留 |
| 需要刷新 | ✅ 必须周期刷新 | ❌ 不需要 |
| 速度 | 很快(几十GB/s) | 较慢(几GB/s) |
| 容量 | 小(8-16GB/芯片) | 大(256GB-4TB/芯片) |
| 擦写寿命 | 无限(理论上) | 有(几千到几万次) |
| 成本/GB | 较贵 | 便宜 |
| 典型产品 | 内存条、HBM | 固态硬盘、手机存储 |
| 生活比喻 | “临时工作台” | “永久仓库” |
1 | 你打开一个大型游戏: |
| 企业 | 技术领域 | 定位 | 国际差距 |
|---|---|---|---|
| 长鑫存储 | DRAM | 中国唯一内存厂商 | 差距较大(落后约2代) |
| 长江存储 | NAND Flash | 中国最大闪存厂商 | 差距较小(接近第一梯队) |
DRAM差距较大:
NAND差距较小:
| 新闻里提到的 | 属于哪个领域 | 哪家厂商在做 |
|---|---|---|
| 内存条涨价 | DRAM | 三星/海力士/美光/长鑫 |
| HBM供不应求 | DRAM(高端) | 三星/海力士/美光 |
| 固态硬盘新品 | NAND Flash | 三星/凯侠/西部数据/长江存储 |
| 长鑫融资成功 | DRAM | 中国唯一DRAM厂商 |
| 长江存储突破 | NAND Flash | 中国NAND厂商 |
DRAM:三巨头(三星+海力士+美光)控制90%市场,长鑫是中国唯一希望,日本已无厂商。
NAND Flash:六强格局(三星/海力士/凯侠/西数/美光/长江存储),长江存储技术水平接近一流。