Skip to content

Segment 内容模型(SSOT)

破坏性改版(2026):Segment[] 为 IM、Console、agent_messages 与 AI 出站 JSON 的共享消息体契约。Adapter 负责平台互转;Core 负责 schema 与校验;文档为本文件唯一权威表。

规范态形状

typescript
interface Segment {
  type: string;
  data: Record<string, unknown>;
  platform?: Record<string, unknown>; // 与 type 同级;adapter 往返用,Console 一般不渲染
}
  • dataplatform 字段一律 snake_case(如 message_idmime_typeforward_id)。
  • 禁止在规范 data 内混写 url / file / src 表示同一媒体;统一用 MediaRef
  • 编写期可用 MessageComponent(html / keyboard 等);async render 完成后再进入 $content、WebSocket、DB。

MediaRef

typescript
interface MediaRef {
  kind: 'url' | 'path' | 'base64';
  value: string;
  mime_type?: string;
}

用于 image / video / audio / voice / record / file 等媒体类 data.media

数据流

Canonical type 总表

typedata(snake_case)IM 可见说明
text{ text }yes
image{ media: MediaRef, alt? }yes
video{ media: MediaRef }yes
audio / voice / record{ media: MediaRef, duration?, text? }yestext 可为 STT 转写
file{ media: MediaRef, name? }yes
face{ id, name? }yes入站 sticker / emoji normalize 为 face
mention{ target, name? }yes全体:target: 'all';原 at / qq
reply{ message_id }yesmessage.$quote_id 双层同步
forward{ forward_id, title?, messages? }yesmessages 为嵌套 Segment[][]
link{ url, text? }yes
dice / rps{}{ result? }yes非 OneBot 出站降级 text
markdown{ content, width?, background_color?, file_name? }yes存储 SSOT;出站 rich render 见下
html / qrcode / ttsRich Segmentyes存储 SSOT
keyboardInteractive Segmentyes
thinking{ text }noagent_messages / Console agent 面板
tool_call{ id, name, arguments }no仅 agent 持久化
json / xml非规范;入站 normalize

Rich / Interactive 与存储

  • markdown / html / qrcode / tts持久化保留原 typeresolveRichSegments 出站可变为 text / image / audio,但不改写 SSOT 存储。
  • keyboard:同上,policy 见 ADR 0022

非规范:json / xml

QQ 等平台入站常有 { type: 'json' } / { type: 'xml' } 包装。Adapter 入站须 normalize 为 forward / face / text 等规范段;无法识别时降级 text: '[卡片消息]'。原始 payload 放 platform,不进 data

reply 与 $quote_id(双层)

json
{ "type": "reply", "data": { "message_id": "12345" } }
  • 段级$content 内保留 reply,供 Console 展示与 adapter CQ/API 往返。
  • 消息级message.$quote_idSendOptions.quoteId 供框架与 AI quote context。
  • 入站:adapter 从 reply 段或平台 raw 解析 → 写 $contentsyncQuoteId
  • 出站:alignReplySegments 写回 data.message_id(单字段,废弃 id / message_id 双写)。

forward 示例

json
{
  "type": "forward",
  "data": {
    "forward_id": "ABC123",
    "title": "群聊的聊天记录",
    "messages": [[{ "type": "text", "data": { "text": "..." } }]]
  },
  "platform": { "resid": "ABC123" }
}

messages 由 adapter get_forward_msg enrich 后可选填入。

AI 交互层

AgentMessage 信封 vs Segment[]

持久化使用 信封 + 段 双层,不新增 type=tool_result 段:

角色形状segments 内容
user{ role: 'user', segments }多为 text / image / …
assistant{ role: 'assistant', segments, api, model, … }可含 text + thinking + tool_call
toolResult{ role: 'toolResult', tool_call_id, tool_name, segments, is_error }多为 text / image

IM 可见性白名单

segmentsForImDelivery(segments) 过滤 AI-only 段后再进 $reply / 用户 IM:

  • 剔除thinkingtool_call
  • 保留:上表 IM 可见 = yes 的 type

ZhinAiOutboundPayload(ADR 0025)

AI 结构化出站 JSON 的 segments 与 canonical 同形type / data / platform),废弃 { kind, mode, data } DSL。

json
{
  "text": "可选正文",
  "mentions": ["researcher"],
  "segments": [
    { "type": "mention", "data": { "target": "123", "name": "Bot" } },
    { "type": "text", "data": { "text": " 请看一下" } }
  ],
  "extensions": { "onebot.keyboard": { } }
}
  • mentions + text 为便捷字段;resolve 后合并为 canonical mention + text
  • 禁止 AI 直接输出平台原生 CQ 码;extensions → adapter toMessageElements

LLM 序列化

  • 废弃 agent 路径上的 segment XML(segment.from / segment.toString 对模型输入)。
  • LLM 只收 JSON Segment[]纯 text

Legacy 映射(adapter 责任)

入站 legacy规范态
image.url / file / srcdata.media
at.qq / at.idmention.target
face_idface.id
reply.id / message_idreply.message_id
forward.id / residforward.forward_id + platform
json / xml 卡片forward / face / text 或 [卡片消息]
Telegram file_idplatform.file_id

Core 自动 normalize legacy;各 adapter segment-mapper 实现互转。CI:pnpm check:segments

Adapter 互转 checklist

  • [ ] 入站:平台 payload → toCanonicalSegments()message.$content
  • [ ] 出站:fromCanonicalSegments() → 平台 API / CQ
  • [ ] tests/segment-contract.test.ts golden round-trip
  • [ ] 平台专有字段仅放 platform,不进规范 data

Console 双视图

视图数据源展示
endpoint inboxmessage.$content 经 IM-visible 过滤text / image / face / mention / reply / forward / …
agent 面板agent_messages.segments 全量thinking / tool_call

发送示例(endpoint:sendMessage

json
{
  "adapter": "icqq",
  "endpointId": "8596238",
  "id": "634415832",
  "type": "channel",
  "parent": { "type": "guild", "id": "650779094005186335" },
  "content": [
    { "type": "text", "data": { "text": "你好" } },
    { "type": "mention", "data": { "target": "123456", "name": "Alice" } }
  ]
}

相关