4.2 消息模型(Message)

模型: claude-opus-4-6 (anthropic/claude-opus-4-6) 生成日期: 2025-02-17


消息(Message)是会话中信息交换的最小单位。OpenCode 的消息模型设计精巧,通过 Part(部件)系统支持丰富的内容类型。

4.2.1 MessageV2 命名空间详解

消息系统定义在 session/message-v2.ts 中。消息分为两种角色:

User 消息

export const User = Base.extend({
  role: z.literal("user"),
  time: z.object({ created: z.number() }),
  summary: z.object({           // 变更摘要(可选)
    title: z.string().optional(),
    body: z.string().optional(),
    diffs: Snapshot.FileDiff.array(),
  }).optional(),
  agent: z.string(),             // 使用的 Agent 名称
  model: z.object({              // 使用的模型
    providerID: z.string(),
    modelID: z.string(),
  }),
  system: z.string().optional(), // 额外的系统指令
  tools: z.record(z.string(), z.boolean()).optional(), // 工具开关(已废弃)
  variant: z.string().optional(), // 变体标识
})

Assistant 消息

Token 统计字段解析

tokens 对象记录了本次 LLM 调用的 token 消耗:

  • input:发送给模型的输入 token 数(包含 system prompt、历史消息、工具结果等)

  • output:模型生成的输出 token 数

  • reasoning:模型的思考链 token 数(仅支持思考链的模型,如 Claude 的 extended thinking)

  • cache.read:从提示词缓存(Prompt Cache)读取的 token 数

  • cache.write:写入提示词缓存的 token 数

  • total:总 token 数(有些 Provider 直接返回总数)

衍生概念:Prompt Cache(提示词缓存)

在多轮对话中,每次请求都会发送完整的消息历史。系统提示(System Prompt)和早期消息在每次请求中都是相同的。Prompt Cache 是 LLM Provider 的一项优化——将这些重复部分缓存在服务端,避免重复计算。

cache.write 表示本次请求首次缓存了多少 token;cache.read 表示本次请求命中缓存的 token 数。缓存命中的 token 计费远低于正常 token,可以显著降低成本。

4.2.2 多模态 Part 类型系统

消息的实际内容不是直接存储在 Message 上,而是通过 Part(部件) 系统组织。每条消息可以包含多个不同类型的 Part。所有 Part 共享一个基础结构:

完整的 Part 类型(12 种):

Part 类型
用途
关键字段

TextPart

文本内容

text, time, synthetic(是否合成), ignored

ReasoningPart

思考链

text, time.start, time.end, metadata

ToolPart

工具调用

tool, callID, state(四种状态)

FilePart

文件附件

mime, filename, url, source

AgentPart

Agent 引用

name, source

SubtaskPart

子任务

prompt, description, agent, model

CompactionPart

压缩标记

auto(是否自动触发)

StepStartPart

步骤开始

snapshot

StepFinishPart

步骤结束

reason, snapshot, cost, tokens

SnapshotPart

快照

snapshot

PatchPart

补丁

hash, files

RetryPart

重试标记

attempt, error, time

ToolPart 的四种状态

ToolPart 是最复杂的 Part 类型,通过 state 字段追踪工具调用的完整生命周期:

4.2.3 消息版本迁移策略

文件名中的 v2 暗示这不是第一版消息模型。message.ts(旧版)和 message-v2.ts(新版)共存,说明 OpenCode 经历了一次消息模型的重大重构。

新版的主要改进:

  1. Part 系统:旧版将所有内容直接放在消息上,新版通过 Part 实现内容的模块化

  2. 更细的状态追踪:ToolPart 的四状态模型、StepStart/StepFinish 标记

  3. 成本追踪:每条 Assistant 消息记录精确的 token 消耗和费用

这种渐进式迁移策略(保留旧版、引入新版、逐步切换)是大型项目中常见的做法——确保不会一次性破坏所有现有数据。

Last updated