NPS-Release

English Version 中文版

NPS-1: Neural Communication Protocol (NCP)

Spec Number: NPS-1
Status: Proposed
Version: 0.7 Date: 2026-04-25
Port: 17433(默认,全协议族共用)
Authors: Ori Lynn / INNO LOTUS PTY LTD

本文档为 NCP 详细规范。套件总览见 NPS-0-Overview.cn.md


1. Terminology(术语)

本文档中的关键字 “MUST”、”MUST NOT”、”REQUIRED”、”SHOULD”、”SHOULD NOT”、”MAY” 按照 RFC 2119 解释。


2. 协议概述

NCP 是 NPS 的帧格式与通信基础层,定义 AI 节点间的帧结构、编码层级和语义压缩机制。所有上层协议(NWP/NIP/NDP/NOP)均以 NCP 帧为载体传输。

2.1 角色

2.2 传输模式

NCP 支持两种传输模式,帧格式完全一致,仅承载方式不同:

模式 承载 适用场景 推荐阶段
HTTP 模式 NCP 帧序列化在 HTTP Body 中,配合 X-NWP-* 请求头 Overlay 部署、与现有 Web 基础设施兼容、防火墙友好 Phase 1 推荐
原生模式 直接 TCP/QUIC 连接,NCP 帧为线上格式,无 HTTP 开销 高性能 Agent-to-Agent、低延迟场景 Phase 2+

HTTP 模式

POST /nwp/products/query HTTP/1.1
Host: api.example.com:17433
Content-Type: application/nwp-frame
X-NWP-Agent: urn:nps:agent:ca.innolotus.com:550e8400

[NCP Frame bytes / JSON]

原生模式

TCP connect → api.example.com:17433
→ HelloFrame (握手,0x06)
← CapsFrame (能力协商,0x04)
→ QueryFrame (0x10)
← CapsFrame (响应,0x04)

两种模式的帧 Payload 完全相同。原生模式下,错误通过 ErrorFrame (0xFE) 返回;HTTP 模式下,同时返回 HTTP 状态码(映射见 status-codes.cn.md)。

2.3 统一端口

NPS 全协议族默认共用 端口 17433。不同协议帧通过帧类型码(Frame Type)路由:

帧类型范围 协议
0x01–0x0F NCP
0x10–0x1F NWP
0x20–0x2F NIP
0x30–0x3F NDP
0x40–0x4F NOP
0xF0–0xFF Reserved(含 ErrorFrame 0xFE)

实现 MAY 为各协议分配独立端口用于隔离部署,但默认行为 MUST 支持单端口复用。

2.4 帧交换模式

模式 描述 典型帧序列
请求-响应 单次查询或操作 QueryFrame → CapsFrame
流式推送 大数据集或实时数据 QueryFrame → StreamFrame × N → StreamFrame(is_last=true)
增量订阅 变更通知 订阅请求 → DiffFrame × N
多 Agent 同步 任务状态对齐 AlignStream × N(见 NPS-5)

2.5 连接状态机

┌──────────┐  connect()  ┌──────────────────┐  anchor_ok  ┌─────────────┐
│  CLOSED  │ ──────────→ │ ANCHOR_NEGOTIATE  │ ──────────→ │ ESTABLISHED │
└──────────┘             └──────────────────┘             └─────────────┘
                                │ timeout/error                  │ close()
                                ↓                                ↓
                          ┌──────────┐                   ┌──────────────┐
                          │  FAILED  │                   │   CLOSING    │
                          └──────────┘                   └──────────────┘
                                                                 │
                                                                 ↓
                                                           ┌──────────┐
                                                           │  CLOSED  │
                                                           └──────────┘

2.6 连接握手序列(原生模式)

原生模式下,连接建立 MUST 遵循以下握手流程:

Client (Agent)                        Server (Node)
      │                                     │
      │── TCP/QUIC connect ──────────────→  │
      │── 8 字节 "NPS/1.0\n"(前导)─────→  │  校验;不匹配则静默关闭(不发 ErrorFrame)
      │── HelloFrame (0x06) ─────────────→  │  声明客户端版本与能力
      │                                     │  版本协商 & 能力交集计算
      │  ←──────────────── CapsFrame (0x04) │  返回协商后的服务端能力
      │                                     │  (若不兼容则返回 ErrorFrame + 断开)
      │  [可选] 预加载 AnchorFrame            │
      │── GET /.schema ──────────────────→  │
      │  ←──────────────── AnchorFrame(s)   │
      │                                     │
      │  ── ESTABLISHED ───────────────── ESTABLISHED

版本协商规则

错误处理

若握手失败(版本不兼容、能力集为空等),Server MUST 返回:

{
  "frame": "0xFE",
  "status": "NPS-PROTO-VERSION-INCOMPATIBLE",
  "error": "NCP-VERSION-INCOMPATIBLE",
  "message": "No compatible NPS version",
  "details": { "server_version": "0.4", "client_min_version": "0.5" }
}

2.6.1 连接前导(原生模式)

状态:必选(NCP v0.7 起,由 NPS-RFC-0001 引入)。

原生模式下,每条 NCP 连接 MUST 在传输层(TCP / QUIC)握手完成之后、首个 HelloFrame 发出之前,由客户端发出一段 8 字节常量前导。HTTP 模式不受影响(Content-Type: application/nwp-frame 头部承担同样的识别职责)。

线上格式

偏移   0   1   2   3   4   5   6   7
       ┌───┬───┬───┬───┬───┬───┬───┬───┐
       │ N │ P │ S │ / │ 1 │ . │ 0 │\n │
       └───┴───┴───┴───┴───┴───┴───┴───┘
       0x4E 50  53  2F  31  2E  30  0A

十六进制:4E 50 53 2F 31 2E 30 0A。前导不是帧 —— 没有头部、没有 Flags、没有长度字段。帧类型字节 0x4E 已保留(见 frame-registry.yaml reservations: 段),MUST NOT 分配给任何 NCP 帧。

客户端行为

服务端行为

  1. 接受原生模式连接后,服务端读取恰好 8 字节。
  2. 若与 b"NPS/1.0\n" 完全匹配,进入帧解析流程。
  3. 若不匹配:
    • 服务端 MUST 在 500 ms 内关闭连接。
    • 服务端 MUST NOT 发送 ErrorFrame —— 对端尚未确认是否说 NCP,发出帧字节会向扫描器泄露协议细节。
    • 服务端 MAY 记录前 32 字节用于运维诊断。
  4. 若 10 秒内收到的字节少于 8 字节,按超时处理,静默关闭。

主版本语义

错误

错误码 触发条件
NCP-PREAMBLE-INVALIDNPS-PROTO-PREAMBLE-INVALID 首 8 字节不匹配常量;500 ms 内静默关闭。
(超时) 10 秒内字节不足 8;静默关闭。线上不发任何编码。

服务端状态机(原生模式)

[LISTEN] ──accept──→ [PREAMBLE-WAIT] ──8 字节匹配──→ [FRAMING] ──HelloFrame──→ [HANDSHAKE] ──CapsFrame──→ [ESTABLISHED]
                          │
                          ├──不匹配──→ [CLOSING](≤ 500 ms)
                          └──10 秒超时──→ [CLOSING](静默)

完整设计动机、备选方案、SDK 推进 phase,参见 NPS-RFC-0001


3. 帧格式

3.1 固定头(4 字节,默认) / 扩展头(8 字节,大帧模式)

默认帧头(4 字节)

 Byte 0          Byte 1          Byte 2–3
┌───────────────┬───────────────┬───────────────────────────┐
│  Frame Type   │     Flags     │      Payload Length       │
│   (1 byte)    │   (1 byte)    │        (2 bytes, BE)      │
└───────────────┴───────────────┴───────────────────────────┘

扩展帧头(8 字节,EXT=1 时)

 Byte 0          Byte 1          Byte 2–5               Byte 6–7
┌───────────────┬───────────────┬───────────────────────┬──────────────┐
│  Frame Type   │     Flags     │   Payload Length      │   Reserved   │
│   (1 byte)    │   (1 byte)    │   (4 bytes, BE)       │  (2 bytes)   │
└───────────────┴───────────────┴───────────────────────┴──────────────┘

3.2 Flags 字段(逐位定义)

Bit 7   Bit 6   Bit 5   Bit 4   Bit 3   Bit 2   Bit 1   Bit 0
┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐
│  EXT  │  RSV  │  RSV  │  RSV  │  ENC  │ FINAL │  T1   │  T0  │
└───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┘
名称 描述
0–1 T0, T1 编码 Tier:00=Tier-1 JSON,01=Tier-2 MsgPack,10=Reserved(原 Tier-3 位),11=Reserved
2 FINAL 流式帧最终块标志(StreamFrame 专用,其他帧固定为 1)
3 ENC Payload 使用应用层 E2E 加密(见 §7.4);TLS 传输层加密独立,开发模式可为 0
4–6 RSV 保留,MUST 为 0,接收方 MUST 忽略
7 EXT 扩展帧头标志:0=默认 4 字节帧头(Payload ≤ 64KB),1=扩展 8 字节帧头(Payload ≤ 4GB)

3.3 帧大小配置

配置项 默认值 最大值 说明
max_frame_payload 65,535 (64KB) 4,294,967,295 (4GB) 单帧最大 Payload 字节数

分片规则


4. 帧类型

4.1 AnchorFrame (0x01)

Schema 锚点帧,由 Node 发布,用于建立全局 Schema 引用,消除后续重复传输。

字段定义

字段 类型 必填 描述
frame uint8 必填 固定值 0x01
anchor_id string 必填 Schema 的 SHA-256 摘要,格式:sha256:{64位hex}
schema object 必填 Schema 定义对象
schema.fields array 必填 字段描述数组,见下
ttl uint32 可选 缓存有效期(秒),默认 3600,0 表示不缓存
supersedes string 可选 本帧替代的旧 AnchorFrame 的 anchor_id。生产端 MAY 设置;当新旧两帧都在缓存中时,消费端 SHOULD 优先使用新帧(见 §5.5)
valid_from string 可选 ISO-8601 UTC 时间戳,标记时序有效性窗口起点(如 2026-05-10T00:00:00Z)。在该时刻之前,锚点 MUST 视为无效(见 §5.5)
valid_until string 可选 ISO-8601 UTC 时间戳,标记时序有效性窗口终点。在该时刻之后,锚点 MUST 视为无效(见 §5.5)

schema.fields 元素

字段 类型 必填 描述
name string 必填 字段名
type string 必填 数据类型:string/uint64/int64/decimal/bool/timestamp/bytes/object/array
semantic string 可选 语义标注,格式:{domain}.{concept}(见语义类型系统)
nullable bool 可选 是否可为 null,默认 false

anchor_id 计算规则

  1. schema 字段按 RFC 8785(JSON Canonicalization Scheme, JCS) 序列化为规范化 JSON
    — JCS 保证:所有 Unicode 字符规范化、对象 key 按 UTF-16 排序、无多余空白
    — 实现 MUST 使用 JCS 标准库(不得自行实现),以确保跨语言 SDK(.NET/Python/TS)一致
  2. 计算 JCS 输出的 UTF-8 字节流的 SHA-256 摘要
  3. 格式化为 sha256:{lowercase hex}

:JCS 参考实现列表见 https://www.rfc-editor.org/rfc/rfc8785#appendix-A

示例

{
  "frame": "0x01",
  "anchor_id": "sha256:a3f9b2c1d4e5f6789012345678901234567890abcdef1234567890abcdef12",
  "schema": {
    "fields": [
      { "name": "id",    "type": "uint64",  "semantic": "entity.id" },
      { "name": "name",  "type": "string",  "semantic": "entity.label" },
      { "name": "price", "type": "decimal", "semantic": "commerce.price.usd" },
      { "name": "stock", "type": "uint64",  "semantic": "commerce.inventory.count" }
    ]
  },
  "ttl": 3600
}

语义类型系统(部分)

Semantic 含义
entity.id 实体唯一标识符
entity.label 实体人类可读名称
entity.description 实体描述文本
entity.timestamp.created 创建时间
entity.timestamp.updated 更新时间
commerce.price.usd 美元价格
commerce.price.cny 人民币价格
commerce.inventory.count 库存数量
geo.latitude 纬度
geo.longitude 经度

4.2 DiffFrame (0x02)

增量数据帧,仅传输变更字段的 patch,适用于订阅或轮询场景。

字段定义

字段 类型 必填 描述
frame uint8 必填 固定值 0x02
anchor_ref string 必填 基准 Schema 的 anchor_id
base_seq uint64 必填 本 Diff 基于的版本序号
patch_format string 可选 补丁格式:json_patch(默认)或 binary_bitset(Tier-2 推荐)
patch array | bytes 必填 补丁数据(格式由 patch_format 决定,见下)
entity_id string 可选 被更新实体的 ID

patch_format: json_patch(默认,Tier-1 JSON 场景)

patch 为 JSON Patch 操作数组(RFC 6902),每个元素含 oppathvalue

patch_format: binary_bitset(Tier-2 MsgPack 场景,减少 15–20% 体积)

patch 为二进制字节流(MsgPack bin 类型),结构如下:

┌──────────────────────────────────────────────────────┐
│  Changed Fields Bitset(ceil(N/8) bytes,N=Schema字段数)│
│  Bit i=1 表示第 i 个字段有变更(按 schema.fields 顺序)  │
├──────────────────────────────────────────────────────┤
│  Values(仅包含变更字段的新值,按字段顺序,MsgPack 编码)  │
└──────────────────────────────────────────────────────┘

规则:

示例(json_patch)

{
  "frame": "0x02",
  "anchor_ref": "sha256:a3f9b2c1...",
  "base_seq": 42,
  "patch_format": "json_patch",
  "entity_id": "product:1001",
  "patch": [
    { "op": "replace", "path": "/price", "value": 299.00 },
    { "op": "replace", "path": "/stock", "value": 48 }
  ]
}

---

### 4.3 StreamFrame (0x03)

流式数据块帧,用于大数据集、实时推送或超帧大小的 Payload 分片。

**字段定义**

| 字段 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `frame` | uint8 | 必填 | 固定值 `0x03` |
| `stream_id` | string | 必填 | 流的唯一标识符(UUID v4 |
| `seq` | uint32 | 必填 | 块序号,从 0 递增,接收方按 seq 重组 |
| `is_last` | bool | 必填 | true 表示此为最后一块 |
| `anchor_ref` | string | 可选 | Schema anchor_id(首块携带,后续块可省略) |
| `data` | array | 必填 | 本块数据,符合 anchor_ref 所指 Schema |
| `window_size` | uint32 | 可选 | 接收方可缓冲的剩余帧数(见流量控制语义)|
| `error_code` | string | 可选 | 非空时表示流异常终止,is_last 强制为 true |

**流量控制语义**

NCP 提供应用层语义背压,补充 TCP/QUIC 传输层流量控制:

- **初始窗口**:发送方在首帧(seq=0)携带 `window_size`,声明接收方剩余可接受帧数
- **窗口消耗**:每发送一帧,接收方逻辑窗口减 1
- **窗口更新**:接收方准备好接收更多数据时,发送一个反向 StreamFrame(`data=[]`, `is_last=false`),携带新的 `window_size` 以刷新窗口
- **背压暂停**:接收方发送 `window_size=0` 的更新帧,发送方 MUST 暂停,直到收到非零 `window_size`
- **省略语义**:`window_size` 未设置时,表示不启用应用层流量控制(依赖底层传输)
- 发送方在窗口耗尽后继续发送,接收方 SHOULD 返回 `NCP-STREAM-WINDOW-OVERFLOW` 并可终止流

---

### 4.4 CapsFrame (0x04)

封装完整响应体,最常见的响应帧类型。也用于连接建立时的能力协商。

**字段定义**

| 字段 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `frame` | uint8 | 必填 | 固定值 `0x04` |
| `anchor_ref` | string | 必填 | Schema anchor_id |
| `count` | uint32 | 必填 | `data` 数组长度,MUST 等于 `len(data)` |
| `data` | array | 必填 | 数据记录数组,每条记录符合 anchor_ref Schema |
| `next_cursor` | string | 可选 | 下一页游标,Base64-URL 编码,null 表示最后一页 |
| `token_est` | uint32 | 可选 | 本响应预估 CGN 消耗(见 [token-budget.cn.md](/spec/token-budget.cn.html))|
| `tokenizer_used` | string | 可选 | 实际使用的 tokenizer 标识 |
| `cached` | bool | 可选 | true 表示本响应来自服务端缓存 |
| `inline_anchor` | object | 可选 | Schema 已更新时内联返回最新 AnchorFrame,避免额外 RTT(见 §5.4)|

**连接协商 CapsFrame**

在原生模式连接建立时,Node 通过 CapsFrame 返回协商后的能力声明:

```json
{
  "frame": "0x04",
  "anchor_ref": "nps:system:caps",
  "count": 1,
  "data": [{
    "nps_version": "0.4",
    "session_version": "0.4",
    "max_frame_payload": 65535,
    "negotiated_encoding": "msgpack",
    "supported_protocols": ["ncp", "nwp", "nip"],
    "ext_support": true,
    "max_concurrent_streams": 32,
    "e2e_enc_algorithms": ["aes-256-gcm", "chacha20-poly1305"]
  }]
}

数据响应示例

{
  "frame": "0x04",
  "anchor_ref": "sha256:a3f9b2c1...",
  "count": 2,
  "data": [
    { "id": 1001, "name": "iPhone 15 Pro", "price": 999.00, "stock": 42 },
    { "id": 1002, "name": "MacBook Air M3", "price": 1299.00, "stock": 15 }
  ],
  "next_cursor": "eyJpZCI6MTAwM30",
  "token_est": 180
}

4.5 AlignFrame (0x05) — Deprecated

⚠️ AlignFrame 已在 NCP v0.7 中标记为 Deprecated。 请使用 NOP AlignStream (0x43),见 NPS-5-NOP.cn.md。 AlignFrame 将在 NPS v1.0 中移除。


4.6 HelloFrame (0x06)

原生模式客户端握手帧,由 Agent(客户端)在连接建立后首先发送,声明自身协议版本与能力。Server 以 CapsFrame 响应(见 §2.6)。

命名说明:NIP 层已定义 IdentFrame (0x20) 用于身份证书交换。NCP HelloFrame 仅负责版本与能力协商,不携带身份信息,两者职责明确分离。

字段定义

字段 类型 必填 描述
frame uint8 必填 固定值 0x06
nps_version string 必填 客户端支持的最高 NPS 版本,格式 "major.minor"
min_version string 可选 客户端支持的最低 NPS 版本,默认与 nps_version 相同
supported_encodings array[string] 必填 支持的编码格式列表,如 ["json", "msgpack"],按优先级降序
supported_protocols array[string] 必填 支持的上层协议列表,如 ["ncp", "nwp", "nip"]
agent_id string 可选 Agent 的 NID(NIP 身份标识符),格式 urn:nps:agent:{domain}:{id}
max_frame_payload uint32 可选 客户端可接受的最大帧 Payload 字节数,默认 65535
ext_support bool 可选 是否支持扩展帧头(EXT=1),默认 false
max_concurrent_streams uint32 可选 客户端可处理的最大并发流数,默认 32
e2e_enc_algorithms array[string] 可选 客户端支持的 E2E 加密算法列表(见 §7.4),如 ["aes-256-gcm"]

规则

HelloFrame 示例

{
  "frame": "0x06",
  "nps_version": "0.4",
  "min_version": "0.3",
  "supported_encodings": ["msgpack", "json"],
  "supported_protocols": ["ncp", "nwp"],
  "agent_id": "urn:nps:agent:ca.innolotus.com:550e8400",
  "max_frame_payload": 65535,
  "ext_support": false,
  "max_concurrent_streams": 16,
  "e2e_enc_algorithms": ["aes-256-gcm", "chacha20-poly1305"]
}

4.7 ErrorFrame (0xFE)

NPS 统一错误帧,所有协议层共用。在原生模式下承载错误响应。

字段定义

字段 类型 必填 描述
frame uint8 必填 固定值 0xFE
status string 必填 NPS 状态码(见 status-codes.cn.md
error string 必填 协议级错误码(如 NCP-ANCHOR-NOT-FOUND
message string 可选 人类可读错误描述
details object 可选 错误相关的结构化数据(如 anchor_refstream_id

示例

{
  "frame": "0xFE",
  "status": "NPS-CLIENT-NOT-FOUND",
  "error": "NCP-ANCHOR-NOT-FOUND",
  "message": "Schema anchor not found in cache, please resend AnchorFrame",
  "details": { "anchor_ref": "sha256:a3f9b2c1..." }
}

5. Schema 锚定机制

5.1 Schema 所有权

AnchorFrame 由 Node(数据模型拥有者) 发布。Agent 通过读取 Node 清单或 Schema 端点获取 AnchorFrame,本地缓存后在后续请求中引用。

5.2 标准流程

Agent                              Node
  │                                  │
  │── GET /.nwm ─────────────────→│  读取节点清单,获取 schema_anchors
  │←── NWM(schema_anchors) ───────│
  │                                  │
  │── GET /.schema ──────────────→│  获取完整 AnchorFrame(可选,按需)
  │←── AnchorFrame(schema) ───────│  Agent 本地缓存 anchor_id → schema
  │                                  │
  │── QueryFrame(anchor_ref) ────→│  请求只携带 anchor_ref
  │←── CapsFrame(anchor_ref) ─────│  响应也只引用 anchor_ref
  │                                  │
  │── QueryFrame(anchor_ref) ────→│  后续请求无需重传 Schema
  │←── CapsFrame(anchor_ref) ─────│

5.3 缓存语义

5.4 缓存未命中处理

5.4.1 Schema 已更新(过期 anchor_ref)

若 Agent 引用了已过期的 anchor_ref,Node 发现该 Schema 版本已更新时,处理行为取决于请求端 auto_anchor 标志(在 NWP QueryFrame 中定义):

{
  "frame": "0x04",
  "anchor_ref": "sha256:new_anchor...",
  "count": 2,
  "data": [ ... ],
  "inline_anchor": {
    "frame": "0x01",
    "anchor_id": "sha256:new_anchor...",
    "schema": { "fields": [ ... ] },
    "ttl": 3600
  }
}

Agent 收到含 inline_anchor 的响应后,MUST 更新本地缓存(替换旧 anchor_id 对应的 Schema)。

5.4.2 未知 anchor_ref

若 Agent 引用了 Node 完全不认识的 anchor_ref(如手工构造、跨节点误引用),Node MUST 返回:

{
  "frame": "0xFE",
  "status": "NPS-CLIENT-NOT-FOUND",
  "error": "NCP-ANCHOR-NOT-FOUND",
  "details": { "anchor_ref": "sha256:..." }
}

NCP-ANCHOR-STALE 表示 anchor 存在但已更新;NCP-ANCHOR-NOT-FOUND 表示 anchor 从未被此 Node 注册。

5.5 Schema 演进

Schema 会随时间演进。NCP 定义了一套兼容性分类法,并规定了 AnchorFrame 跨版本生命周期内生产端与消费端的义务。§4.1 中的可选字段 supersedesvalid_fromvalid_until 承载本节使用的版本血缘和时序有效性元数据。

5.5.1 兼容性分类

任何 Schema 变更 MUST 归入下列兼容性分类之一。生产端 SHOULD 在发布说明中记录类别;消费端 MAY 据此判断是否必须重新拉取锚点。

分类 描述 向后兼容
additive_optional schema.fields 中新增可选字段(即 nullable=true 或带文档化默认值)
additive_required schema.fields 中新增必填字段(无默认值)
type_widening 在不丢失既有合法值的前提下,扩大已有字段的类型(如 uint32uint64string 枚举 → 开放 string
type_narrowing 收窄已有字段的类型或取值域(如 string → 枚举、int64uint32
semantic_change 线格式不变但已有字段的含义发生变化(如单位、币种、所指对象) 视情况
field_remove schema.fields 中移除已有字段

任何归类为 additive_requiredtype_narrowingfield_remove 的变更都属于破坏性变更,MUST 产生新的 anchor_id。生产端 MUST 在新 AnchorFrame 上将 supersedes 设置为旧的 anchor_id,以便消费端追溯版本血缘。

对于 semantic_change,除非生产端能通过外带文档证明无消费端依赖原有含义,否则 MUST 视同破坏性变更处理。

5.5.2 时序有效性

当设置了 valid_from 和/或 valid_until 时,AnchorFrame 仅在半开区间 [valid_from, valid_until) 内有效。窗口之外:

若设置了 valid_until,生产端 MUST 在响应时间落在过期 60 秒内(即 now ≥ valid_until − 60s)的所有 CapsFrame 中携带 inline_anchor(包含后继 AnchorFrame)。这一约束界定了消费端仍在使用即将过期锚点的最坏窗口,确保后继锚点在当前锚点失效前抵达消费端。

5.5.3 生产端 / 消费端义务


6. 状态码与错误码

NPS 采用两级错误体系:

  1. NPS 状态码:传输层状态分类,见 status-codes.cn.md
  2. 协议错误码:具体错误标识,前缀标识所属协议

NCP 错误码

错误码 NPS 状态码 描述
NCP-ANCHOR-NOT-FOUND NPS-CLIENT-NOT-FOUND anchor_ref 引用的 Schema 不存在
NCP-ANCHOR-SCHEMA-INVALID NPS-CLIENT-BAD-FRAME AnchorFrame 中 Schema 格式不合法
NCP-ANCHOR-ID-MISMATCH NPS-CLIENT-CONFLICT 相同 anchor_id 收到不同 Schema(锚点污染攻击防御)
NCP-FRAME-UNKNOWN-TYPE NPS-CLIENT-BAD-FRAME 未知帧类型码
NCP-FRAME-PAYLOAD-TOO-LARGE NPS-LIMIT-PAYLOAD Payload 超过协商的 max_frame_payload
NCP-FRAME-FLAGS-INVALID NPS-CLIENT-BAD-FRAME Flags 字段中保留位非零
NCP-STREAM-SEQ-GAP NPS-STREAM-SEQ-GAP StreamFrame 序号不连续
NCP-STREAM-NOT-FOUND NPS-STREAM-NOT-FOUND stream_id 引用的流不存在
NCP-STREAM-LIMIT-EXCEEDED NPS-STREAM-LIMIT 超出单连接最大并发流数
NCP-ENCODING-UNSUPPORTED NPS-SERVER-ENCODING-UNSUPPORTED 请求的编码 Tier 不被支持
NCP-ANCHOR-STALE NPS-CLIENT-CONFLICT anchor_ref 存在但 Schema 已更新(配合 inline_anchor 使用)
NCP-DIFF-FORMAT-UNSUPPORTED NPS-CLIENT-BAD-FRAME DiffFrame 使用了接收方不支持的 patch_format
NCP-VERSION-INCOMPATIBLE NPS-PROTO-VERSION-INCOMPATIBLE 客户端 min_version 高于 Server 支持版本
NCP-STREAM-WINDOW-OVERFLOW NPS-STREAM-LIMIT 发送方在窗口耗尽后继续发送
NCP-PREAMBLE-INVALID NPS-PROTO-PREAMBLE-INVALID 原生模式连接首 8 字节非 b"NPS/1.0\n";服务端 500 ms 内静默关闭(不发 ErrorFrame)—— 见 §2.6.1

HTTP 模式下的状态码映射见 status-codes.cn.md


7. 安全考量

7.1 重放攻击防御

CapsFrame 和 QueryFrame 应在 TLS 层由传输协议防御重放。若在非 TLS 场景(开发模式)下,Agent SHOULD 在请求中携带 nonce 字段。

7.2 锚点污染(Anchor Poisoning)

Schema 由 Node 发布,Agent 只读引用。Node MUST 对 anchor_id 做幂等校验——相同 anchor_id 对应的 Schema MUST 始终一致。Agent 若检测到同一 anchor_id 返回了不同 Schema,SHOULD 断开连接并报告安全事件。

7.3 流式洪泛(Stream Flooding)

Node SHOULD 限制单连接最大并发流数(推荐默认值:32,通过 CapsFrame max_concurrent_streams 协商)。超出限制时返回 NCP-STREAM-LIMIT-EXCEEDED

7.4 E2E 加密(ENC 标志正式定义)

当帧头 Flags ENC=1 时,帧 Payload 使用应用层端到端加密。E2E 加密独立于 TLS 传输层,适用于多跳 Relay 场景中 Relay 不可信的情况。

算法选择

通过握手 CapsFrame 的 e2e_enc_algorithms 字段协商,优先级从高到低:

算法 标识符 密钥长度 Nonce Tag
AES-256-GCM aes-256-gcm 256-bit 12 bytes 16 bytes
ChaCha20-Poly1305 chacha20-poly1305 256-bit 12 bytes 16 bytes

ENC=1 时 Payload 布局

┌────────────────┬──────────────────────────────────────┬─────────────┐
│   Nonce        │   Encrypted Payload                  │  Auth Tag   │
│  (12 bytes)    │   (原始 Payload 密文)                 │  (16 bytes) │
└────────────────┴──────────────────────────────────────┴─────────────┘

实现要求

新增错误码

错误码 NPS 状态码 描述
NCP-ENC-NOT-NEGOTIATED NPS-CLIENT-BAD-FRAME ENC=1 但会话未协商 E2E 加密算法
NCP-ENC-AUTH-FAILED NPS-CLIENT-BAD-FRAME E2E 加密 Auth Tag 验证失败(可能被篡改)

8. 编码层级

所有帧类型支持以下编码层级,通过帧头 Flags T0/T1 位标识:

Tier 格式 Flag 适用场景
Tier-1 JSON 00 开发调试、兼容模式
Tier-2 MsgPack(Binary) 01 生产环境,~60% 体积压缩
Reserved 10 保留,供未来高性能编码格式使用
Reserved 11 保留

默认:生产环境使用 Tier-2,开发环境使用 Tier-1。

:原 Tier-3 MatrixTensor 概念已从编码层级中移除,10 位标记为 Reserved。若未来定义高性能编码格式(如向量/张量专用编码),将通过正式 RFC 流程分配。


9. 实现注意事项


10. 变更历史

版本 日期 变更
0.6 2026-04-25 新增 §2.6.1 原生模式连接前导(8 字节常量 b"NPS/1.0\n");在 frame-registry.yaml 中保留帧类型字节 0x4E;新增错误码 NCP-PREAMBLE-INVALID 和状态码 NPS-PROTO-PREAMBLE-INVALID。详见 NPS-RFC-0001
0.4 2026-04-14 新增 IdentFrame (0x06) 握手帧;新增 §2.6 连接握手序列及版本协商规则;anchor_id 计算明确引用 RFC 8785 JCS;DiffFrame 新增 patch_format 字段(json_patch / binary_bitset);CapsFrame 新增 inline_anchor;StreamFrame 流量控制语义正式化(window_size 协议);§7.4 E2E 加密节(ENC 标志、AES-256-GCM / ChaCha20-Poly1305、Payload 布局);§5.4 auto-anchor 协议(NCP-ANCHOR-STALE + inline_anchor);新增错误码 NCP-ANCHOR-STALE、NCP-DIFF-FORMAT-UNSUPPORTED、NCP-VERSION-INCOMPATIBLE、NCP-STREAM-WINDOW-OVERFLOW、NCP-ENC-NOT-NEGOTIATED、NCP-ENC-AUTH-FAILED
0.3 2026-04-12 传输双模(HTTP/原生);统一端口 17433;可配置帧大小(EXT 位);ErrorFrame (0xFE);NPS 状态码体系;Tier-3 标记 Reserved;AnchorFrame 所有权明确为 Node 发布;Token 估算改用 CGN
0.2 2026-04-10 AnchorFrame/DiffFrame/StreamFrame/CapsFrame/AlignFrame 定义;Flags 字段逐位定义;AlignFrame 标记 Deprecated
0.1 2026-03-01 初始帧格式与编码层级定义

归属:LabAcacia / INNO LOTUS PTY LTD · Apache 2.0