Skip to main content

消息结构

花卷智能体 API 支持两种消息格式,服务端会自动将简化格式转换为 AI SDK 标准格式。

1. 简化格式(推荐用于简单场景)

适合纯文本对话,无需手动管理消息 ID:
简化格式示例
{
  "role": "user",
  "content": "你好,请介绍一下你自己"
}
使用简化格式时,服务端会自动:
  • 生成唯一的消息 ID(使用 crypto.randomUUID()
  • content 转换为 parts: [{ type: "text", text: content }]

2. AI SDK 格式(推荐用于复杂场景)

完整的 AI SDK UIMessage 结构,支持多种消息部分类型:
AI SDK 格式示例
{
  "id": "msg_abc123",
  "role": "user",
  "parts": [
    {
      "type": "text",
      "text": "你好,请介绍一下你自己"
    }
  ]
}
使用 AI SDK 格式时,必须提供 id 字段id 应该是唯一标识符,建议使用 UUID。

UIMessage 完整结构

根据 AI SDK v5 规范,UIMessage 的完整类型定义为:
UIMessage 类型定义
interface UIMessage {
  id: string; // 必需:消息的唯一标识符
  role: "user" | "assistant" | "system"; // 必需:消息角色
  parts: UIMessagePart[]; // 必需:消息内容部分数组
  metadata?: unknown; // 可选:自定义元数据
  status?: "submitted" | "streaming" | "ready" | "error"; // 可选:消息状态
}

必需字段

字段类型说明
idstring消息的唯一标识符。使用简化格式时自动生成,使用 AI SDK 格式时必须手动提供
role'user' | 'assistant' | 'system'消息的角色类型
partsUIMessagePart[]消息内容数组,至少包含一个 part

可选字段

字段类型说明
metadataunknown自定义元数据,可用于存储业务相关信息
status'submitted' | 'streaming' | 'ready' | 'error'消息状态,通常由客户端管理

角色类型

角色说明使用场景
user用户消息用户的问题或指令
assistantAI 助手消息AI 的回复内容
system系统消息系统级指令(通常通过 systemPrompt 参数传递,而非 messages 数组)
虽然 system role 在类型定义中存在,但建议使用 systemPrompt 参数设置系统提示词,而不是在 messages 数组中包含 system 消息。

多轮对话

通过 messages 数组传递完整的对话历史:
多轮对话示例
{
  "model": "anthropic/claude-3-7-sonnet-20250219",
  "messages": [
    {
      "role": "user",
      "content": "1+1等于几?"
    },
    {
      "role": "assistant",
      "content": "1+1等于2"
    },
    {
      "role": "user",
      "content": "那再加3呢?"
    }
  ]
}
数组中的消息会按顺序处理,AI 能够理解完整的对话上下文。

Parts 类型详解

parts 数组支持多种类型的消息部分(UIMessagePart):
最常用的消息类型,包含纯文本:
text part 示例
{
  "type": "text",
  "text": "这是文本内容"
}
包含文件信息(如图片、文档等):
file part 示例
{
  "type": "file",
  "data": "base64_encoded_data",
  "mimeType": "image/png"
}
由服务端自动生成,包含工具调用的输入和输出:
dynamic-tool part 示例
{
  "type": "dynamic-tool",
  "toolName": "zhipin_reply_generator",
  "toolCallId": "call_abc123",
  "state": "output-available",
  "input": {
    "candidate_message": "你们公司地址在哪?",
    "brand": "蜀地源冒菜"
  },
  "output": {
    "reply": "您好!我们位于上海市..."
  }
}
字段说明
  • type:固定值 "dynamic-tool"
  • toolName:工具名称
  • toolCallId:AI 生成的唯一调用 ID
  • state:工具状态("output-available" 表示已完成,"input-available" 表示仅输入)
  • input:工具输入参数(使用 snake_case 命名
  • output:工具输出结果(仅当 state: "output-available" 时存在)
重要:工具调用和结果包含在同一个 dynamic-tool part 中。服务端自动执行工具并生成输入输出,客户端无需手动创建。

混合消息示例

一个消息可以包含多个 parts:
混合类型消息
{
  "id": "msg_mixed_123",
  "role": "assistant",
  "parts": [
    {
      "type": "dynamic-tool",
      "toolName": "zhipin_reply_generator",
      "toolCallId": "call_001",
      "state": "output-available",
      "input": {
        "candidate_message": "你们薪资待遇怎么样?",
        "brand": "蜀地源冒菜"
      },
      "output": {
        "reply": "您好!我们的薪资范围是4000-6000元..."
      }
    }
  ]
}
一个消息可以包含多个 parts,如文本 + 工具调用、多个工具调用等。

格式验证

简化格式要求

简化格式验证规则
{
  "role": "user" | "assistant",  // 必需
  "content": "string"             // 必需,必须是字符串
}

AI SDK 格式要求

AI SDK 格式验证规则
{
  "id": "string",                 // 必需,唯一标识符
  "role": "user" | "assistant" | "system",  // 必需
  "parts": [                      // 必需,至少一个元素
    {
      "type": "text",
      "text": "string"
    }
  ],
  "metadata": {},                 // 可选
  "status": "ready"               // 可选
}

常见错误

问题:使用 AI SDK 格式但未提供 id
错误示例
{
  "role": "user",
  "parts": [{ "type": "text", "text": "hello" }]
}
解决方案:添加唯一的 id 字段
正确示例
{
  "id": "msg_abc123",
  "role": "user",
  "parts": [{ "type": "text", "text": "hello" }]
}
或者使用简化格式(会自动生成 id):
简化格式(推荐)
{
  "role": "user",
  "content": "hello"
}
问题parts 数组不能为空
错误示例
{
  "id": "msg_001",
  "role": "user",
  "parts": []
}
解决方案:至少包含一个 part
正确示例
{
  "id": "msg_001",
  "role": "user",
  "parts": [
    { "type": "text", "text": "hello" }
  ]
}
说明:启用工具调用时,非流式响应或流式响应完成后,API 返回的 data.messages 数组中会包含 dynamic-tool 类型的 parts
流式 vs 非流式的区别
  • 流式响应:工具调用以独立的 SSE 事件返回(tool-input-availabletool-output-available
  • 非流式响应:工具调用包含在 messages 数组的 dynamic-tool part 中
  • 详见工具调用功能文档的流式响应部分
{
  "success": true,
  "data": {
    "messages": [
      {
        "id": "msg_001",
        "role": "assistant",
        "parts": [
          {
            "type": "dynamic-tool",
            "toolName": "zhipin_reply_generator",
            "toolCallId": "call_abc123",
            "state": "output-available",
            "input": {
              "candidate_message": "你们薪资待遇怎么样?",
              "brand": "蜀地源冒菜"
            },
            "output": {
              "reply": "您好!我们的薪资范围是4000-6000元,另有全勤奖、绩效奖等。"
            }
          }
        ]
      },
      {
        "id": "msg_002",
        "role": "assistant",
        "parts": [
          {
            "type": "text",
            "text": "已为您生成专业的招聘回复",
            "state": "done"
          }
        ]
      }
    ],
    "usage": {
      "inputTokens": 150,
      "outputTokens": 80,
      "totalTokens": 230
    },
    "tools": {
      "used": ["zhipin_reply_generator"],
      "skipped": []
    }
  }
}
关键点
  • 工具调用和结果包含在同一个 dynamic-tool part 中
  • 服务端自动执行工具并管理 toolCallId
  • 客户端从 data.messages 数组中提取消息
  • 详见工具调用功能文档

完整请求示例

简单文本对话
{
  "model": "anthropic/claude-3-7-sonnet-20250219",
  "messages": [
    {
      "role": "user",
      "content": "你好"
    }
  ]
}

下一步