Protobuf 实战:为何比 JSON 更高效?原理、场景与选型建议

做后端这几年,我一直在反复观测同一类问题:接口联调、日志落盘、消息入队、客户端同步,不同系统之间交换数据到底用什么格式最顺手。早期我默认 JSON,后来发现只要流量一大、字段一多,文本格式的浪费就开始变得刺眼。于是我去翻了 Protobuf,把它用于几个真实的线上模块,才发现它为什么被那么多团队当成“默认答案”。这篇就聊一聊:Protobuf 到底强在哪、什么时候该用它、什么时候别硬上。

Protobuf 全称是 Protocol Buffers,由某大型互联网公司内部设计并开源的一种结构化数据序列化格式。它和 JSON、XML 一样,本质都是把内存里的结构体变成“能跨进程传输的一串字节”;但它的存在方式完全不同——它不是让人类直接手写一串文本,而是先定义一份 schema,再生成各种语言的代码,最终产生的是一段紧凑的二进制。这套设计让它天然在性能、体积和类型安全上占了便宜,但也带来了一些使用门槛。这篇文章就是给你把门槛拆掉:先讲原理,再给实操,最后给选型建议。

1. 先搞清楚:Protobuf 到底解决什么问题

1.1 序列化这件事,为什么值得单独聊

任何两个进程要通信,都会面临“怎么把对象变成字节”和“怎么把字节变回对象”的问题。最简单的做法是手写拼接字符串,但很快你会遇到几个尴尬:字段顺序错了怎么办、字符串里出现分隔符怎么办、嵌套结构怎么表达。于是才有了标准化的序列化格式。

XML 的做法是把数据包进标签,通过开始标签和结束标签表达层级关系;JSON 的做法更轻,用键值对和数组表达结构。这俩都是文本格式,人都能直接看懂,也方便调试。可文本格式有一个绕不开的代价:为了让人看懂,额外写入了大量语法字符,比如引号、冒号、标签名、转义符。数据量小的时候这点开销无所谓,但当你每秒要传输几千条、几万条消息时,这些“人可读”的字符就全部变成了带宽和 CPU 的消耗。

Protobuf 走的路线正好相反:它完全不心疼“人是否看得懂”。发送方和接收方都遵守一份共同定义的 schema,消息里只写字段编号和实际值,不再重复写字段名。这一下就省掉了文本格式里的大半冗余。

1.2 Protobuf 和 JSON/XML 不在一个层面

很多人把 JSON、XML、Protobuf 放在同一条赛道上比,其实它们的使用方式差别很大。JSON 和 XML 是“约定好的文本语法”,任何语言自带解析器,拿到文本直接就能读。Protobuf 则是“先定义 schema,再生成代码”的开发流程,你需要提前在一份.proto文件里描述数据结构,然后通过编译器生成对应语言的类或结构体,最后在代码里直接操作生成的对象完成序列化。

这意味着 Protobuf 不是“拿来即用”的库,而是一套“带编译期检查”的工程体系。它比 JSON 多了一个前置步骤,但也正因为这个步骤,让数据在传输前就已经被严格校验过了。实践里最常见的组合是:.proto文件里既定义消息结构,也定义服务接口,再配套生成 gRPC 代码,一条链路下来,从结构到接口全部有类型约束,几乎不给手误留空间。

用一句大白话总结:JSON/XML 让你写的是“给人看的文本”,Protobuf 让你写的是“给机器高效解析的字节”。人看文本确实舒服,但机器跑起来,效率差得不是一点半点。

2. 为什么我最终放弃了 JSON/XML——三个最扎心的理由

2.1 体积差距不是一点半点

先看一个非常典型的用户信息消息。

{ "id": 10086, "name": "小王", "email": "xiaowang@example.com", "status": 1, "tags": ["vip", "new"] }

这段 JSON 如果转成 UTF-8 文本,大概是 100 多个字节。同样的内容,用下面这个.proto定义:

syntax = "proto3"; package userv1; message User { uint64 id = 1; string name = 2; string email = 3; repeated string tags = 4; int32 status = 5; }

生成的代码序列化出来,实际二进制只有几十个字节。原因不难理解:文本格式里"name":"小王"这 10 来个字符中,真正有价值的数据只有“小王”两个字;引号、冒号、字段名全是描述信息。Protobuf 里字段名在二进制里根本不存在,取而代之的是 1 个字节的字段编号和类型标记。字段编号越靠前,标记字节越小,整体体积自然就下去了。

有人会杠:数据量小,多个几十字节也不痛不痒。但放到真实场景里,一条消息可能包含几十个嵌套字段、数组、浮点数,多加的字节会翻好几倍;如果这批数据还要经过移动网络传输,每一千个用户就得多出几十 MB 的流量费用。这种体量差异在低频接口上无感,在高频链路里是实打实的成本。

2.2 解析速度差距,在高频下是数量级的

JSON 解析慢不只是因为字符多,更核心的原因在于它的解析过程依赖“查找字段名”。一段 JSON 文本摆在那里,解析器必须逐字符扫描、匹配键名、处理字符串转义、动态创建对象。字段名越复杂、嵌套越深,内存分配和 CPU 指令就越多。

Protobuf 的解析机制和它完全不同。发送端按照固定规则,把字段编号和值紧凑地写入二进制;接收端每读到一个字节,就能立刻知道“哦,这是 4 号字段,是一个字符串”,然后直接按偏移量取值。整个过程几乎没有文本扫描和动态字符串操作,对 CPU 和内存都友好得多。

我在一个实际服务里做过粗略统计:同样的消息结构,JSON 反序列化一次平均耗时在几十微秒到上百微秒之间,而 Protobuf 反序列化基本能控制在几微秒到十几微妙之间。单看一次没啥感觉,但压测到每秒上万请求时,CPU 使用率的差距会非常明显。早期用 JSON 扛 3 万 QPS 时,进程 CPU 经常飙到 70% 以上,换成 Protobuf 后掉到 30% 左右,同样的机器能扛的流量几乎翻倍。

2.3 类型约束和版本演进,JSON 给不了的“安全感”

JSON 和 XML 都是弱类型文本:字段名拼错不报错,数字写成字符串也能解析,结构里多嵌套一层不检查。这种自由在写脚本、做快速原型时很爽,但在多人协作的正式工程里就是隐患。A 服务返回的id一直是数字,突然某天变成了字符串,B 服务可能要在运行时报错才能发现。

Protobuf 因为有.proto这个“合同”,从源头上把字段类型锁死了。定义成uint64的字段,生成的代码就只会接受整数;数组、枚举、嵌套消息全都由编译器保障。一旦某个字段的语义要变,不是改一个字符串就行,你得先改.proto,再重新生成两端的代码,这对团队来说反而是一种“强制评审”。

更关键的是版本演进。JSON 在接口上加字段,老客户端如果没做兼容处理,很容易因为不认识新字段直接报错;而 Protobuf 的字段编号机制天然支持向前向后兼容。新加字段只要换个新编号,老版本程序读到未知编号时直接跳过,不会崩;删字段时只要不重复使用旧编号,老客户端还能继续容错。就冲这一点,我在维护长期接口时再也不愿意回到手搓 JSON 的老路。

3. 手写一个 .proto 并跑通:从定义到序列化

3.1 一个最小可用的 .proto 文件长什么样

用实操来验证上面这些理论。我准备了一套示例:一个用户查询服务。先建一个user.proto文件,内容大致是这样:

syntax = "proto3"; package userdemo; service UserService { rpc GetUser (UserRequest) returns (UserResponse); } message UserRequest { uint64 user_id = 1; } message UserResponse { uint64 user_id = 1; string name = 2; string email = 3; int32 status = 4; repeated string tags = 5; Address address = 6; } message Address { string city = 1; string street = 2; }

几个值得注意的点:

  • 第一行syntax = "proto3";声明使用 proto3 语法,这是当前主流版本,比 proto2 少了required/optional修饰符,所有字段默认可选。
  • package userdemo;相当于命名空间,避免不同模块之间的消息重名。
  • service UserService定义 RPC 接口,后面可以配套 gRPC 使用;如果你只想要普通的消息序列化,不写 service 也没问题。
  • 每个字段后面的= 1不是默认值,而是字段在二进制编码中的唯一编号。这是整个 Protobuf 兼容体系的基石,后面我会专门说。

3.2 用代码生成和序列化验证(以 Python 为例)

.proto文件写好后,需要用protoc编译器生成目标语言的代码。我习惯用 Python 做实验,生成命令是:

protoc --python_out=. user.proto

执行成功后,目录下会出现一个user_pb2.py文件,里面就是编译好的消息类。接下来写一段脚本,创建用户对象、填充字段、再序列化成二进制:

import user_pb2 user = user_pb2.UserResponse() user.user_id = 10086 user.name = "小王" user.email = "xiaowang@example.com" user.status = 1 user.tags.append("vip") user.tags.append("new") user.address.city = "杭州" user.address.street = "文一西路" data = user.SerializeToString() print("序列化后字节数:", len(data)) print("二进制内容:", data)

运行后你会看到这段二进制可能只有几十个字节,而且里面能看到 “小王” 这类的原始字符串值,但看不到name、email这些字段名。接收端拿到data后,只要调用ParseFromString,就能恢复成一个结构完整的对象:

new_user = user_pb2.UserResponse() new_user.ParseFromString(data) print(new_user)

输出的对象和原来的完全一致,嵌套的address、重复的tags也都还原了。整个流程没有手动拼接字符串,没有键名匹配,所有操作都在内存对象上完成,这就是 Protobuf 最典型的使用姿势。

3.3 看看序列化后的二进制到底长什么样

了解原理的人可能会好奇:为什么这么短的二进制能装下这么多信息?我们挑一段来说。user_id = 10086这个字段,二进制里会被编码成类似这样的一段:先是 1 个字节表示“这是 1 号字段,类型是变长整数”,然后紧跟一个 varint 编码的数值。varint 是一种紧凑的数字表示法,数字小就用 1 个字节,数字大才多占字节,不像文本格式里永远固定用完整字节数。

字符串字段则采用“长度前缀 + 字节内容”的方式:先写入字段编号和类型标记,再写入字符串的长度,最后写入字符串本体。接收端解析时,能精确知道从哪里到哪里是一个完整字段,不需要像 JSON 那样做引号匹配和嵌套扫描。

这种编码逻辑虽然细节多,但核心思想就是两个字:紧凑。所有的字段名都不传,所有的数字都按实际大小动态占位,数组直接连续排列。于我而言,理解到这个层面就够了,真正写业务代码时,你几乎不需要手碰编码细节,编译器已经帮你处理完了。

4. 理清几个容易踩坑的细节

4.1 字段编号和兼容性:加字段随便加,删字段要谨慎

Proto 文件里的编号不是摆设,而是长周期接口的生命线。我的经验是,给字段编号时,一开始就要留出余量,比如新设计的消息从 1 开始,但相邻字段之间可以留空,不要排得太密。这样以后加字段时,你仍然能保持逻辑分组,而不必频繁引入带来兼容风险的新编号。

删字段时更要注意:假设旧代码有int32 temp_flag = 3;,后来你删掉了它,又在同一文件里新加了string remark = 3;。老客户端发过来的数据里,3 号字段本来是一个整数,新服务端会按字符串去解析,轻则类型错乱,重则直接解析失败。这就是我最想强调的“删字段别复用编号”原则。正确的做法是把废弃字段留一个reserved 3;声明,让编译器明确告诉你这个编号已经被占用了。

4.2 可读性和调试:二进制数据出问题了怎么办

很多人初次用 Protobuf,最不适应的就是日志不好排查:一条消息打出来全是乱码,没法像 JSON 那样一眼看出问题。应对方案有几个。

第一,利用文本格式调试。Protobuf 的官方库通常把消息的文本表示和二进制分开,你可以把消息print成类似 JSON 的文本格式来看。Python 里直接print(user)输出就是可读的多行文本,能快速确认字段值对不对。

第二,用工具命令解析线上二进制。protoc自带一个--decode能力,指定.proto文件后,可以把二进制内容反解成可读文本。排查消息队列里积压的脏数据时,这个命令几乎是救命稻草。

第三,在日志里保留必要的原始入参。我习惯在关键链路的入口和出口分别记录 Protobuf 的十六进制摘要,配合--decode_raw做初步判断。等真正定位到是哪个字段出错,再用完整 schema 做精确解析,速度比全量打印快很多。

4.3 别拿小数据做结论:性能对比的参考基准

网上经常有人做“Benchmark:JSON vs Protobuf”,然后得出一个看似科学的标准答案。但这类对比在数据体量很小、字段浅层、序列化次数只有几千次时,结果往往看不出明显差距,甚至 JSON 有时表现得也不差。

我自己的实测范围是:单条消息从 200 字节到 2KB 之间,嵌套 2 到 3 层,数组包含若干个元素,连续跑 10 万次。这个时候 Protobuf 的体积优势稳定在 30% 到 50% 之间,耗时优势更是能拉开 5 倍到 10 倍的差距。如果你的消息只有{"code":0,"msg":"ok"}这种两字段小对象,或者一年只调几百次接口,那 JSON 完全够用,没必要引入额外工具链。性能优化永远要跟随压力和收益走,不要为了“理论上更快”而盲目复杂化。

5. 场景选型:什么时候用 Protobuf,什么时候还是老老实实用 JSON

5.1 闭门造车:内部服务与微服务链路

如果你的服务只在公司内部互相调用,两端都由自己团队维护,那 Protobuf 几乎是首选。这里有两个理由:一是内部调用往往有更高的 QPS 和更低的容忍度,二是指标全链路可追踪,出问题可以用同一套.proto快速定位,不需要“面向浏览器打日志”。

在这种场景里,我会建议配合 gRPC 一起用。gRPC 直接把.proto里的 service 映射成远程调用接口,传输层默认就是 Protobuf 编码,流式传输、超时控制、健康检查都直接内置。用熟了以后,你会发现自己几乎不用再关注“接口文档”这种东西,.proto本身就是最权威的契约。

当然,内部链路也有例外。如果有的系统是老项目,已经用 JSON 跑了好几年、团队没人熟悉 Protobuf 工具链,那是否值得折腾就要算收益了。我见过不少系统为了“潮流”引入 Protobuf,结果部署和排障成本比省下的那点带宽还高,最后又退回 JSON。技术选型要尊重存量。

5.2 对外输出:OpenAPI 和浏览器端

浏览器端的情况完全不同。前端 JavaScript 解析二进制并不方便,更重要的是,公开 API 的调用方五花八门,有移动端、有脚本、有合作伙伴的后端,让人家先下载.proto再生成代码,往往是不现实的。公开 API 几乎就应该用 JSON。

另外,凡是需要人直接阅读的接口,比如管理后台、跑批任务、运维脚本,JSON 的“可读即所用”就是最大的优点。你随手curl一个接口就能看见完整响应,不用依赖任何工具。这种场景下,强行上 Protobuf 纯粹是给自己和调用方添堵。

5.3 混合场景:移动端、消息队列、大数据流

还有些场景介于内部和外部之间,需要具体情况具体判断。移动端 App 请求服务端接口,体量通常有硬性限制,流量越省用户体验越好,所以客户端到服务端的核心传输用 Protobuf 很常见;但 App 要方便联调,服务端最好同时提供 JSON 的调试模式,或者在网关层做协议转换。

消息队列里存放的数据我几乎一律建议用 Protobuf。队列里的消息消费者往往不只一个,不同消费者对字段的需求不同;使用 Protobuf 后,加字段不会打断老消费者,而且序列化体积小,能显著降低存储和带宽压力。大数据流的场景同理,海量日志数据入湖、进数仓,用文本格式会放大好几倍的存储成本,Protobuf 的紧凑性和预定义 schema 反而更有利于数据质量管理。

6. 我的几个固执建议(也就是踩坑后的总结)

6.1 版本升级前,先想好老客户端

无论你多小心,线上服务升级.proto时都可能踩到“编号冲突”或“类型变更”的坑。我的强制流程是:改字段前先grep一遍现有代码,确认没有其他地方引用了旧编号;新增字段一律追加编号,绝不插入到中间;删除字段必须写reserved。

如果是语义型变更,比如“把状态码从 1 改为 2”,千万不要直接改字段值,而是新增一个状态枚举新值,老逻辑继续兜底处理。我在一个支付对账模块里犯过这个错:为了“优化枚举”,把某个中间态删了,结果所有处理到一半的订单全部走错分支,排查了一个通宵才定位到问题。从那以后,我对枚举和字段编号的态度就是:宁可多留几种不再使用的状态,也不轻易动既有语义。

6.2 必要的时候上 gRPC,别硬配 REST

很多人接触 Protobuf 时,只把.proto拿来做个序列化工具,RPC 框架还是继续用 RESTful 风格。这没问题,但你会失去很多红利,比如流式通信、双向流、内置的负载均衡策略、错误码定义。现代微服务内部链路里,我几乎默认用 gRPC,只有面对浏览器或第三方时才单独开一个 JSON 网关。

需要提醒的是,gRPC 虽然好用,但调试体验确实比 REST 差一些。你没法直接用浏览器访问一个 gRPC 接口,必须依赖类似于grpcurl的工具。团队里如果新人多、工具链不熟,我会建议先在一个非核心模块试点,跑顺了再推广,不要一开始就全量迁移。

6.3 别过度设计:小项目用 JSON 很快乐

最后说句公道话。Protobuf 的强项在“长期演进 + 高频传输 + 强类型约束”,但它带来的额外成本也非常明确:要多维护.proto文件、要接入代码生成、要处理二进制排障。对于一个独立小工具、内部一次性脚本、前端展示后端的简单 API,这些成本完全没必要掏。

我现在的选型习惯是:判断这个接口的生命周期会不会超过一年、调用量会不会到每秒千次以上、是否有多团队同时消费。如果三个条件都不满足,我直接用 JSON 写接口,完事;如果命中至少两个条件,我才会认真考虑引入 Protobuf。不盲目跟风,带着场景做取舍,这才是它真正“牛”起来的方式。

相关新闻

基于深度强化学习的无人机TSP路径规划:从建模到实战部署

基于深度强化学习的无人机TSP路径规划:从建模到实战部署

我最早做这个课题,是因为手里接了一个无人机配送的仿真验证任务:一架四旋翼要在尽量短的时间内访问完若干个任务点,最后回到起降点。乍一看就是经典的旅行商问题(TSP),但把“车”换成“无人机”&#xff0c…

2026/10/20 10:03:45 阅读更多 →
大模型与航空科技融合:应用场景、落地挑战与工程师应对策略

大模型与航空科技融合:应用场景、落地挑战与工程师应对策略

最近翻到一份关于大模型与航空科技融合的展望长文,内容来自一个在气动与智能计算方向深耕多年的研究团队。说实话,看标题前我以为又是一篇"AI赋能一切"的务虚畅想,读完之后却发现里面不少判断值得拿出来掰开揉碎聊一聊。航空工业链…

2026/10/20 10:03:45 阅读更多 →
Agent框架插件化设计拆解:从生命周期钩子到上下文协作

Agent框架插件化设计拆解:从生命周期钩子到上下文协作

1. 先说结论再拆代码:这个框架的插件化到底强在哪最近花了一整个周末,把一个开源 Agent 框架从头到尾拆了一遍,重点就看它的插件化设计。这里不强调具体项目名,就叫它 DK-Agent 好了,因为真正值得记录的不是某个项目本…

2026/10/20 10:03:45 阅读更多 →

最新新闻

为什么一降重AI率就升高?手动降重越改越像AI,降重降AI一起做才是正解!

为什么一降重AI率就升高?手动降重越改越像AI,降重降AI一起做才是正解!

为什么一降重AI率就升高?手动降重越改越像AI,降重降AI一起做才是正解! 为什么一降重AI率就升高?不少同学都碰到过:查重报告上的红色总算改少了,再送去做AIGC检测,AI率反而比改之前还高。明明每…

2026/10/20 10:44:37 阅读更多 →
基于Springboot大学生就业服务平台【附源码+文档】

基于Springboot大学生就业服务平台【附源码+文档】

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:44:37 阅读更多 →
Node.js部署实战:从环境配置、PM2进程守护到日志排错的完整指南

Node.js部署实战:从环境配置、PM2进程守护到日志排错的完整指南

开头:真香的是开发,想砸电脑的是部署我当初也是冲着 Node.js 那套开发体验去的,写接口、做工具脚本、甚至给团队搭个内部面板,简直行云流水。直到第一次正儿八经把服务部署到服务器上,才发现前端的爽和后端的痛之间&am…

2026/10/20 10:44:37 阅读更多 →
论文AI率和重复率怎么一起降下来?降重降AI几分钟就能一起完成!

论文AI率和重复率怎么一起降下来?降重降AI几分钟就能一起完成!

论文AI率和重复率怎么一起降下来?降重降AI几分钟就能一起完成! 论文AI率和重复率怎么一起降下来,是很多同学交稿前最头疼的事。论文AI率和重复率两个数字同时摆在报告上,先压哪个都不对:刚把AI率压下去,查…

2026/10/20 10:44:37 阅读更多 →
AgentScope实践:用标准化Msg协议搭建多智能体协作系统

AgentScope实践:用标准化Msg协议搭建多智能体协作系统

上周我在重构一个内部客服项目的时候,终于体会到“多智能体”和“多个会说话的模块”之间那条天堑。单机脚本里我写了三百多行状态机,让一个主管Agent给三个执行Agent派活,结果一个Agent因为提示词里写了句“你继续分析”,就带着上…

2026/10/20 10:44:37 阅读更多 →
如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南

如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南

如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南 【免费下载链接】antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. 项目地址: https://gitcode.com/Gi…

2026/10/20 10:43:36 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →