gRPC over HTTP/2 协议深度解析:报文格式、流语义与 chttp2 传输层实现
本文基于 gRPC 仓库中的协议规范文档 doc/PROTOCOL-HTTP2.md,系统讲解 gRPC 如何承载于 HTTP/2 帧之上:请求与响应的 ABNF 报文文法、grpc-timeout 等核心头字段、Length-Prefixed-Message 分帧格式、trailers 中的错误状态语义,以及 GOAWAY/PING/RST_STREAM 等连接管理帧的处理规则。读完本文,你可以准确理解一次 gRPC 调用在 HTTP/2 线路上的完整字节级流转,并能对照当前仓库的 chttp2 传输层源码验证上述规则的真实落地方式。
协议概述:一次调用的报文原子序列
gRPC 的通信建立在 HTTP/2 分帧(HTTP/2 framing)之上,规范假设读者已熟悉 HTTP/2 协议本身。协议的生产规则(production rules)采用 ABNF 语法(RFC 5234 定义的标准)描述。
一次完整的 gRPC 请求/响应消息流由以下报文原子(message atoms)构成:
Request → Request-Headers *Length-Prefixed-Message EOS
Response → (Response-Headers *Length-Prefixed-Message Trailers) / Trailers-Only
- 请求(客户端 → 服务端):先发送
Request-Headers(HEADERS 帧),随后是零个或多个Length-Prefixed-Message(DATA 帧),最后以EOS(END_STREAM 标志)结束流。 - 响应(服务端 → 客户端):正常路径为
Response-Headers+ 零或多个Length-Prefixed-Message+Trailers;对于立即报错的调用,允许只发送Trailers-Only(单帧)。
在 gRPC 源码中,这套协议由 chttp2 传输层插件实现,其定位在 src/core/ext/transport/chttp2/README.md 中明确写道:"chttp2 transport plugin - implements grpc over http2",即该传输层承担了"把 gRPC 调用翻译成 HTTP/2 帧"的全部职责。
Path 规则与 Content-Type 校验
ABNF 中 :path 的格式为 "/" Service-Name "/" {方法名},例如 /helloworld.Greeter/SayHello。规范特别强调 Path 大小写敏感,且允许部分实现覆盖该 Path 格式的行为——但这种做法被强烈不建议(strongly discouraged)。gRPC 官方不会主动破坏这类自定义行为,但也不提供活跃支持;当 Path 不是标准格式时,某些功能(如 service config 支持)将不生效。
Content-Type 必须以 application/grpc 开头(可附加 +proto / +json / 自定义后缀)。如果请求头中的 Content-Type 不满足该前缀,gRPC 服务端 SHOULD 返回 HTTP 415 (Unsupported Media Type)。这样做的目的,是防止其他 HTTP/2 客户端把 gRPC 的错误响应(其 HTTP 状态恒为 200 OK)误判为成功。
从源码结构看,这一前缀校验在元数据层就被编码为强类型约束:src/core/call/metadata_batch.h#L124-L151 中 ContentTypeMetadata 的取值仅区分三种状态(kApplicationGrpc / kEmpty / kInvalid),注释明确写着 "gRPC says that content-type can be application/grpc[;something]. Core has only ever verified the prefix"——即核心只校验 application/grpc 前缀,与规范描述一致。
请求头(Request-Headers)完整文法
Request-Headers 通过 HTTP/2 的 HEADERS + CONTINUATION 帧块下发,其完整 ABNF 定义如下:
Request-Headers → Call-Definition *Custom-Metadata
Call-Definition → Method Scheme Path [Authority] TE [Timeout]
Content-Type [Message-Type] [Message-Encoding]
[Message-Accept-Encoding] [User-Agent]
Method → ":method" "POST"
Scheme → ":scheme" ("http" / "https")
Path → ":path" "/" Service-Name "/" {方法名}
Service-Name → {IDL 特定的服务名}
Authority → ":authority" {权威虚拟主机名}
TE → "te" "trailers" ; 用于探测不兼容的中间代理
Timeout → "grpc-timeout" TimeoutValue TimeoutUnit
TimeoutValue → {最多 8 位的十进制正整数字符串}
TimeoutUnit → Hour / Minute / Second / Millisecond / Microsecond / Nanosecond
Hour → "H"
Minute → "M"
Second → "S"
Millisecond → "m"
Microsecond → "u"
Nanosecond → "n"
Content-Type → "content-type" "application/grpc" [("+proto" / "+json" / {自定义})]
Content-Coding → "identity" / "gzip" / "deflate" / "snappy" / {自定义}
Message-Encoding → "grpc-encoding" Content-Coding
Message-Accept-Encoding → "grpc-accept-encoding" Content-Coding *( "," Content-Coding )
User-Agent → "user-agent" {结构化 UA 字符串}
Message-Type → "grpc-message-type" {消息 schema 类型名}
Custom-Metadata → Binary-Header / ASCII-Header
Binary-Header → {Header-Name "-bin"} {base64 编码值}
ASCII-Header → Header-Name ASCII-Value
Header-Name → 1*( %x30-39 / %x61-7A / "_" / "-" / "." ) ; 即 0-9 a-z _ - .
ASCII-Value → 1*( %x20-%x7E ) ; 空格与可打印 ASCII
几个关键约束逐一展开:
1. 头字段排序要求
HTTP/2 要求保留头(以 : 开头的伪头,如 :method、:scheme、:path、:authority)必须出现在所有其他头之前。gRPC 规范在此之上补充了两条推荐排序:Timeout 头应紧跟在保留头之后发送;Call-Definition 头应在 Custom-Metadata 之前发送。
2. grpc-timeout 的解析与编码
超时值的单位覆盖了从纳秒到小时的全部粒度,且值部分最多 8 位数字(因此超时上限约 9999 小时)。如果请求省略 Timeout,服务端应视为无限超时;客户端实现可以根据部署需求自由发送一个默认的最小超时。
在源码中,grpc-timeout 被建模为一个独立的元数据 trait:src/core/call/metadata_batch.h#L75-L90 中 GrpcTimeoutMetadata 的 ValueType 是 Timestamp(绝对截止时间戳),注释说明它在传输层发送前会被转换为时长(Duration);kTransferOnTrailersOnly = false 表明该头不会在 Trailers-Only 响应中被透传。这与规范中"Timeout 只在请求头中出现"的语义吻合。
类似地,TE 头在 src/core/call/metadata_batch.h#L93-L121 的 TeMetadata 中只允许 trailers 一个合法值(空表示未设置,非法值会被记录为 kInvalid),印证了规范中 "TE → te trailers ; Used to detect incompatible proxies" 的定位——它本质上是 gRPC 客户端探测链路上代理是否支持 trailers 的探针。
3. 自定义元数据(Custom-Metadata)与二进制头
Custom-Metadata 是应用层自定义的任意 key-value 头集合,有若干必须遵守的规则:
- 以
grpc-开头但未被协议列出的头名,保留给 gRPC 未来使用,应用不应将其用作自定义元数据。 - HTTP/2 不允许头值携带任意八位字节序列,因此二进制头值必须按 RFC 4648 §4 进行 Base64 编码。实现必须同时接受带填充(padded)与不带填充(un-padded)的 Base64 值,且发送时应输出不带填充的形式。应用通过让头名以
-bin结尾来声明这是一个二进制头;运行时库依据该后缀检测并自动施加 Base64 编解码。 - Custom-Metadata 的头顺序不保证被保留,唯一例外是同名重复头的值顺序。同名头可能以
,作为分隔符合并,且应被视为语义等价。实现必须在解码 Base64 之前,先对 Binary-Header 按,切分。 - ASCII-Value 不应带首尾空白;如果带了,可能被剥离。注意 gRPC 定义的 ASCII-Value 字符集比 HTTP 更严格:实现不应因收到一个"对 HTTP 合法的 field-value 但对 gRPC 非法的 ASCII-Value"而报错,其行为未被严格限定——可以丢弃该值,也可以接受。若接受,必须注意允许应用安全地回显(echo)该值:例如请求中作为列表提供的元数据,不应在作为响应元数据回传时触发错误。
4. 请求头大小限制
服务端可以限制 Request-Headers 的总大小,建议默认值为 8 KiB。规范鼓励实现按 HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE 的方式计算总头大小:对所有头字段求和,每个字段贡献为"未压缩头名长度 + 头值长度 + 32",且二进制头的值长度按 Base64 编码之后计算。
Length-Prefixed-Message:消息分帧格式
请求中重复出现的 Length-Prefixed-Message 序列通过 DATA 帧下发,其格式为:
Length-Prefixed-Message → Compressed-Flag Message-Length Message
Compressed-Flag → 0 / 1 ; 1 字节无符号整数
Message-Length → {Message 的长度} ; 4 字节无符号整数(大端序)
Message → *{binary octet}
即每条 gRPC 消息在线路上都是"1 字节压缩标志 + 4 字节大端长度 + 消息体"的封装。关于压缩标志的语义:
Compressed-Flag = 1表示消息体已按Message-Encoding头声明的机制压缩;0表示未做任何编码。- 压缩上下文不跨消息边界维护——实现必须为流中的每条消息创建全新的压缩上下文。
- 如果请求未携带
Message-Encoding头,Compressed-Flag必须为 0。
源码层面,DATA 帧的接收与消息重组由 src/core/ext/transport/chttp2/transport/frame_data.cc 与 src/core/ext/transport/chttp2/transport/message_assembler.h 等文件负责。例如 frame_data.cc#L128-L133 在解析出 Length-Prefixed-Message 的 Message-Length 字段后,会立即检查该长度是否超过调用方通过调用上下文(call context)设定的 max_recv_message_length,超过即报"message larger than maximum"错误——这正是"4 字节长度字段先于消息体被校验"这一分帧设计在实现中的体现。
EOS:请求流的结束语义
对请求而言,EOS(end-of-stream)由最后一个 DATA 帧上的 END_STREAM 标志指示。特殊场景:当请求流需要关闭但已无数据可发送时(例如客户端 unary 调用只发了 HEADERS 就要关闭发送方向),实现必须发送一个空的 DATA 帧并带上 END_STREAM 标志。这一点在消息组装器中有直接对应:src/core/ext/transport/chttp2/transport/message_assembler.h#L160-L175 中的 GenerateNextFrame 负责把消息切分为若干 DATA 帧,而 GenerateEmptyEndFrame 正是为"无数据仍需 END_STREAM"的场景生成的空帧。
响应(Responses):Trailers 与错误状态
响应的完整文法:
Response → (Response-Headers *Length-Prefixed-Message Trailers) / Trailers-Only
Response-Headers → HTTP-Status [Message-Encoding] [Message-Accept-Encoding]
Content-Type *Custom-Metadata
Trailers-Only → HTTP-Status Content-Type Trailers
Trailers → Status [Status-Message] [Status-Details] *Custom-Metadata
HTTP-Status → ":status" "200"
Status → "grpc-status" 1*DIGIT ; 0-9(十进制 ASCII,无前导零)
Status-Message → "grpc-message" Percent-Encoded
Status-Details → "grpc-status-details-bin" {base64 编码值}
Percent-Encoded → 1*(Percent-Byte-Unencoded / Percent-Byte-Encoded)
Percent-Byte-Unencoded → 1*( %x20-%x24 / %x26-%x7E ) ; 空格与 VCHAR(不含 %)
Percent-Byte-Encoded → "%" 2HEXDIGIT
关键语义逐条解析
- 帧块结构:
Response-Headers与Trailers-Only各自在单个 HEADERS 帧块中下发。大多数响应同时携带 headers 与 trailers,但产生立即错误的调用允许只发Trailers-Only。Status 必须始终出现在 Trailers 中,即使状态码是 OK(0)——这是 gRPC 客户端判定调用成功与否的唯一依据,HTTP 层的 200 只说明传输正常。 - EOS:响应的结束由携带 Trailers 的最后一个 HEADERS 帧上的 END_STREAM 标志指示。
- 对破损部署的容错:实现应预期真实网络中存在发送非 200 HTTP 状态、发送非 gRPC content-type、甚至完全省略
Status与Status-Message的"破损部署"(broken deployments)。当出现这些情况时,实现必须合成(synthesize)一个 Status 与 Status-Message 上报给应用层,而不是把错误吞掉或原样暴露 HTTP 细节。 - 响应头/trailers 大小:客户端可以限制
Response-Headers、Trailers与Trailers-Only的大小,建议默认各 8 KiB。 - Status 值格式:十进制 ASCII 整数字符串,不允许前导零。
- Status-Message 的百分号编码:其值在概念上是一段 Unicode 错误描述,物理编码为"先 UTF-8,再 percent-encoding"。percent-encoding 参照 RFC 3986 §2.1,但此处允许未编码的字符集与标准 URL 不同(空格与 VCHAR 除外
%本身,见上文 ABNF)。解码到非法值时,实现不得报错或丢弃消息,最宽松的处理是放弃解码、让用户收到原始的 percent-encoded 形式;也可以解码合法部分、保留损坏的%编码原样、或用替换字符(如?或 Unicode 替换字符)替代。 - Status-Details:仅当 Status 不为 OK 时允许携带,内容是关于该 RPC 错误的附加信息。如果其中包含 status code 字段,不得与 Status 头矛盾,消费方必须验证这一要求。在 Protobuf 场景下(见附录 A),该字段的值就是
google.rpc.Status消息的 Base64 编码。
示例:一次一元调用的完整 HTTP/2 帧序列
以下是规范给出的 unary call 示例,展示了帧级别的报文序列:
请求(Request)
HEADERS (flags = END_HEADERS)
:method = POST
:scheme = http
:path = /google.pubsub.v2.PublisherService/CreateTopic
:authority = pubsub.googleapis.com
grpc-timeout = 1S
content-type = application/grpc+proto
grpc-encoding = gzip
authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v
DATA (flags = END_STREAM)
<Length-Prefixed Message>
响应(Response)
HEADERS (flags = END_HEADERS)
:status = 200
grpc-encoding = gzip
content-type = application/grpc+proto
DATA
<Length-Prefixed Message>
HEADERS (flags = END_STREAM, END_HEADERS)
grpc-status = 0 # OK
trace-proto-bin = jher831yy13JHy3hc
注意示例中请求侧 DATA 帧直接带 END_STREAM(一元请求只有一条消息),响应侧的 Trailers HEADERS 帧同时携带 END_STREAM 与 END_HEADERS,且 grpc-status = 0 表明调用成功——即便成功,trailers 也必须携带 Status,与该帧即流结束帧的语义完全一致。响应中的 trace-proto-bin 则是一个应用层自定义二进制头(-bin 后缀触发 Base64 编解码)。
User-Agent 约定
协议功能上不要求携带 user-agent,但推荐客户端提供结构化的 UA 字符串,描述调用库、版本与平台,以方便在异构环境中定位问题。推荐的构造文法:
User-Agent → "grpc-" Language ?("-" Variant) "/" Version
?( " (" *(AdditionalProperty ";") ")" )
例如:
grpc-java/1.2.3
grpc-ruby/1.2.3
grpc-ruby-jruby/1.3.4
grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile)
幂等性与重试
除非明确定义,gRPC 调用默认不假定为幂等(not idempotent),具体规则:
- 无法证明已经开始(cannot be proven to have started)的调用,不会被重试;
- 不存在重复抑制(duplicate suppression)机制——因为不需要;
- 被标记为幂等的调用,可能被发送多次。
这条语义是 gRPC 上层重试策略(retry)与负载均衡失败转移设计的底线:传输层只有在能确信"对端从未开始处理"(如 REFUSED_STREAM)时,才允许透明重试。
HTTP/2 传输映射
流标识(Stream Identification)
所有 gRPC 调用需要一个内部 ID,该方案直接复用 HTTP/2 stream-id 作为调用标识。注意:这些 id 只在单个 HTTP/2 会话(session)上下文内有意义,在处理多个 HTTP/2 会话的进程中不具有全局唯一性,也不能当作 GUID 使用。
DATA 帧与消息边界
DATA 帧的边界与 Length-Prefixed-Message 的边界没有任何对应关系,实现不得假设两者对齐。一条消息可能被切分进多个 DATA 帧,一个 DATA 帧也可能包含多条消息的片段——这正是需要 4 字节长度字段做帧内重组的原因。
错误处理与 RST_STREAM 映射
当 RPC 过程中发生应用或运行时错误时,Status 与 Status-Message 通过 Trailers 下发。但在某些情况下,消息流的帧格式可能已经损坏,此时 RPC 运行时会选择用 RST_STREAM 帧告知对端。gRPC 运行时实现应把 RST_STREAM 解释为流的立即完全关闭,并把错误向上传播到调用方应用层。
规范定义了 RST_STREAM 错误码到 gRPC 错误码的映射表:
| HTTP/2 Code | gRPC Code |
|---|---|
| NO_ERROR (0) | INTERNAL —— 本应显式发送 OK 状态;此情形也可能用于某些场景下激进的 lameduck(摘除慢节点) |
| PROTOCOL_ERROR (1) | INTERNAL |
| INTERNAL_ERROR (2) | INTERNAL |
| FLOW_CONTROL_ERROR (3) | INTERNAL |
| SETTINGS_TIMEOUT (4) | INTERNAL |
| STREAM_CLOSED | 无映射——此时已无打开的流可供传播。实现应记录日志 |
| FRAME_SIZE_ERROR | INTERNAL |
| REFUSED_STREAM | UNAVAILABLE —— 表示未发生任何处理,该请求可以被重试,甚至可在其他节点重试 |
| CANCEL (8) | 客户端发出时映射为"调用被取消";服务端发出时映射为 CANCELLED。注意:服务端只应在"需要取消调用但消息字节序列不完整"的场景使用此机制 |
| COMPRESSION_ERROR | INTERNAL |
| CONNECT_ERROR | INTERNAL |
| ENHANCE_YOUR_CALM | RESOURCE_EXHAUSTED —— 由运行时附加错误详情,指明耗尽的资源是带宽 |
| INADEQUATE_SECURITY | PERMISSION_DENIED —— 附加详情说明权限被拒绝,原因是所用协议的安全性不足以支撑该调用 |
这套映射在当前仓库源码中有精确对应。src/core/ext/transport/chttp2/transport/http2_status.h 定义了与 RFC 9113 一致的 Http2ErrorCode 枚举(kNoError=0x0 至 kInadequateSecurity=0xc 等),而 ErrorCodeToAbslStatusCode(http2_status.h#L58-L77)实现了从 HTTP/2 错误码到 gRPC 状态码的转换:
kEnhanceYourCalm→kResourceExhausted(对应表中 ENHANCE_YOUR_CALM → RESOURCE_EXHAUSTED)kInadequateSecurity→kPermissionDenied(对应 INADEQUATE_SECURITY → PERMISSION_DENIED)kRefusedStream→kUnavailable(对应 REFUSED_STREAM → UNAVAILABLE,即"可重试"状态)kCancel→ 以当前时间是否已超过 deadline 区分kDeadlineExceeded/kCancelled- 其余错误码默认落到
kInternal,与表中 NO_ERROR/PROTOCOL_ERROR/INTERNAL_ERROR/FLOW_CONTROL_ERROR/SETTINGS_TIMEOUT/COMPRESSION_ERROR/CONNECT_ERROR 均映射为 INTERNAL 的规定一致
反向转换 AbslStatusCodeToErrorCode(http2_status.h#L83-L100)则用于本地 gRPC 状态需要编码进 RST_STREAM/GOAWAY 帧时的选型。此外该文件中的 Http2Status 类明确区分 kConnectionError(用于 GOAWAY 帧的错误码)与 kStreamError(用于 RST_STREAM 帧的错误码)两种错误类型,与规范中"流错误 vs 连接错误"的边界划分相呼应。
安全(Security)
HTTP/2 规范强制:使用 TLS 时必须为 TLS 1.2 或更高版本;同时规范对允许的密码套件施加了额外约束以规避已知问题,并要求支持 SNI。此外可以预期 HTTP/2 会与私有传输安全机制配合使用,对此规范不做具体建议。对应地,上文 INADEQUATE_SECURITY → PERMISSION_DENIED 的映射正是当协议安全性不足以支撑调用时的拒绝路径。
连接管理
GOAWAY 帧
GOAWAY 由服务端发给客户端,表示该连接不再接受新的流,帧中携带服务端最后成功接受的流 id。客户端应把在"最后成功接受的流"之后发起的所有流视为 UNAVAILABLE,并将调用重试到别处;对于已被接受的流,客户端可以继续使用直到其完成或连接终止。规范建议:服务端在终止连接之前应先发送 GOAWAY,以便可靠告知客户端哪些工作已被接受并正在执行。
源码中 GOAWAY 帧的收发由 src/core/ext/transport/chttp2/transport/frame_goaway.cc 与 src/core/ext/transport/chttp2/transport/goaway.cc 等文件实现,http2_status.h 中 GetConnectionErrorCode 的注释也明确写道:其用途之一就是"确定应写入 HTTP2 GOAWAY 帧的错误码"。
PING 帧
客户端与服务端都可以发送 PING 帧,对端必须精确回显收到的内容。用途有二:断言连接仍然存活(liveness),以及提供估算端到端延迟的手段。超时语义如下:
- 服务端发起的 PING 若在运行时预期的期限之内未收到响应,该服务端上所有未决调用将以 CANCELLED 状态关闭;
- 客户端发起的 PING 超期,会导致所有调用以 UNAVAILABLE 状态关闭。
PING 的频率高度依赖网络环境,实现可以自由地依据网络与应用需求调整 PING 频率。仓库中相关的实现文件包括 src/core/ext/transport/chttp2/transport/keepalive.cc、src/core/ext/transport/chttp2/transport/frame_ping.cc,以及防止对端被 PING 洪泛的 ping_abuse_policy.cc 与 ping_rate_policy.cc——从文件结构可以推断,传输层对 PING 的发送频率与滥用防护做了独立策略化管理。
连接失败(Connection failure)
如果客户端检测到可识别的连接失败,所有调用以 UNAVAILABLE 状态关闭;对服务端而言,未决调用以 CANCELLED 状态关闭。这与 PING 超时路径的语义(客户端侧 UNAVAILABLE / 服务端侧 CANCELLED)保持一致:客户端视角把"连接死了"解释为"服务暂不可用,可换路重试",服务端视角把"流没了"解释为"取消"。
附录 A:GRPC for Protobuf
由 protobuf 声明的服务接口,可以通过 protoc 的代码生成扩展轻松映射到 gRPC。规范定义的映射关系:
Service-Name → ?( {proto 包名} "." ) {服务名}
Message-Type → {完全限定的 proto 消息名}
Content-Type → "application/grpc+proto"
Status-Details → {google.rpc.Status proto 消息}
即::path 中的 Service-Name 采用"proto 包名(可选)+ 点号 + 服务名";grpc-message-type 头携带完全限定的消息类型名;content-type 固定为 application/grpc+proto;而错误详情头 grpc-status-details-bin 中 Base64 编码的正是 google.rpc.Status 消息本体,其内部 status code 字段不得与 grpc-status 头矛盾(消费方必须校验)。仓库中 src/compiler/ 目录下的 cpp_generator.cc、python_generator.cc 等各语言代码生成器,以及 examples/protos/helloworld.proto 等示例 proto,就是这套"proto → 各语言 gRPC stub"映射关系的具体落地。
小结:从规范到实现的验证路径
本文沿 doc/PROTOCOL-HTTP2.md 的完整脉络,梳理了 gRPC over HTTP/2 的三层要点:
- 报文层:Request-Headers / Length-Prefixed-Message / Trailers 三段式结构,以及
grpc-timeout(最多 8 位数字 + H/M/S/m/u/n 单位)、te: trailers代理探测、application/grpc前缀校验(否则 415)、-bin二进制头的 Base64 编解码与,切分规则、8 KiB 头大小建议; - 语义层:Status 必须恒在 Trailers 中出现、
grpc-message的 UTF-8 + percent-encoding 容错解码、grpc-status-details-bin仅对非 OK 状态携带且 status code 不得矛盾、UNAVAILABLE vs CANCELLED 在客户端/服务端视角的对称性; - 传输层:stream-id 作为调用 id、DATA 帧与消息边界解耦、RST_STREAM 到 gRPC 错误码的 12 项映射(在 src/core/ext/transport/chttp2/transport/http2_status.h 中可逐条核对)、GOAWAY 与 PING 的连接管理职责。
读者可以按"规范 ABNF → 元数据 trait(src/core/call/metadata_batch.h)→ chttp2 帧处理(src/core/ext/transport/chttp2/transport/)"的路径在当前仓库中自行验证上述每一条规则,测试侧 test/core/transport/ 下还有大量 .headers 帧级测试数据与端到端用例可供进一步深入。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00