> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wolian.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# 消息格式

> 理解对话消息的结构和格式要求

## 消息结构

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

### 1. 简化格式（推荐用于简单场景）

适合纯文本对话，无需手动管理消息 ID：

```json 简化格式示例 icon="message" theme={null}
{
  "role": "user",
  "content": "你好，请介绍一下你自己"
}
```

<Note>
  使用简化格式时，服务端会自动：

  * 生成唯一的消息 ID（使用 `crypto.randomUUID()`）
  * 将 `content` 转换为 `parts: [{ type: "text", text: content }]`
</Note>

### 2. AI SDK 格式（推荐用于复杂场景）

完整的 AI SDK UIMessage 结构，支持多种消息部分类型：

```json AI SDK 格式示例 highlight={2} lines icon="code" theme={null}
{
  "id": "msg_abc123",
  "role": "user",
  "parts": [
    {
      "type": "text",
      "text": "你好，请介绍一下你自己"
    }
  ]
}
```

<Warning>
  使用 AI SDK 格式时，**必须提供 `id` 字段**。`id` 应该是唯一标识符，建议使用
  UUID。
</Warning>

## UIMessage 完整结构

根据 AI SDK v5 规范，UIMessage 的完整类型定义为：

```typescript UIMessage 类型定义 lines icon="file-code" theme={null}
interface UIMessage {
  id: string; // 必需：消息的唯一标识符
  role: "user" | "assistant" | "system"; // 必需：消息角色
  parts: UIMessagePart[]; // 必需：消息内容部分数组
  metadata?: unknown; // 可选：自定义元数据
  status?: "submitted" | "streaming" | "ready" | "error"; // 可选：消息状态
}
```

### 必需字段

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

### 可选字段

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

## 角色类型

| 角色          | 说明      | 使用场景                                             |
| ----------- | ------- | ------------------------------------------------ |
| `user`      | 用户消息    | 用户的问题或指令                                         |
| `assistant` | AI 助手消息 | AI 的回复内容                                         |
| `system`    | 系统消息    | 系统级指令（通常通过 `systemPrompt` 参数传递，而非 `messages` 数组） |

<Tip>
  虽然 `system` role 在类型定义中存在，但建议使用 `systemPrompt`
  参数设置系统提示词，而不是在 `messages` 数组中包含 system 消息。
</Tip>

## 多轮对话

通过 `messages` 数组传递完整的对话历史：

```json 多轮对话示例 lines expandable highlight={5-6,9-10,13-14} icon="comments" theme={null}
{
  "model": "anthropic/claude-3-7-sonnet-20250219",
  "messages": [
    {
      "role": "user",
      "content": "1+1等于几？"
    },
    {
      "role": "assistant",
      "content": "1+1等于2"
    },
    {
      "role": "user",
      "content": "那再加3呢？"
    }
  ]
}
```

<Note>数组中的消息会按顺序处理，AI 能够理解完整的对话上下文。</Note>

## Parts 类型详解

`parts` 数组支持多种类型的消息部分（`UIMessagePart`）：

<AccordionGroup>
  <Accordion title="text - 文本内容" icon="font">
    最常用的消息类型，包含纯文本：

    ```json text part 示例 icon="font" theme={null}
    {
      "type": "text",
      "text": "这是文本内容"
    }
    ```
  </Accordion>

  <Accordion title="file - 文件附件" icon="file">
    包含文件信息（如图片、文档等）：

    ```json file part 示例 highlight={3-4} lines icon="file" theme={null}
    {
      "type": "file",
      "data": "base64_encoded_data",
      "mimeType": "image/png"
    }
    ```
  </Accordion>

  <Accordion title="dynamic-tool - 工具调用" icon="wrench">
    由服务端自动生成，包含工具调用的输入和输出：

    ```json dynamic-tool part 示例 highlight={2-4,6,11} lines icon="wrench" theme={null}
    {
      "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"` 时存在）

    <Warning>
      **重要**：工具调用和结果包含在同一个 `dynamic-tool` part 中。服务端自动执行工具并生成输入输出，客户端无需手动创建。
    </Warning>
  </Accordion>
</AccordionGroup>

### 混合消息示例

一个消息可以包含多个 parts：

```json 混合类型消息 lines expandable highlight={5-18} icon="layer-group" theme={null}
{
  "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元..."
      }
    }
  ]
}
```

<Note>
  一个消息可以包含多个 parts，如文本 + 工具调用、多个工具调用等。
</Note>

## 格式验证

### 简化格式要求

```json 简化格式验证规则 lines icon="circle-check" theme={null}
{
  "role": "user" | "assistant",  // 必需
  "content": "string"             // 必需，必须是字符串
}
```

### AI SDK 格式要求

```json AI SDK 格式验证规则 lines expandable icon="clipboard-check" theme={null}
{
  "id": "string",                 // 必需，唯一标识符
  "role": "user" | "assistant" | "system",  // 必需
  "parts": [                      // 必需，至少一个元素
    {
      "type": "text",
      "text": "string"
    }
  ],
  "metadata": {},                 // 可选
  "status": "ready"               // 可选
}
```

## 常见错误

<AccordionGroup>
  <Accordion title="错误：缺少 id 字段" icon="triangle-exclamation">
    **问题**：使用 AI SDK 格式但未提供 `id`

    ```json 错误示例 icon="xmark" theme={null}
    {
      "role": "user",
      "parts": [{ "type": "text", "text": "hello" }]
    }
    ```

    **解决方案**：添加唯一的 `id` 字段

    ```json 正确示例 highlight={2} icon="check" theme={null}
    {
      "id": "msg_abc123",
      "role": "user",
      "parts": [{ "type": "text", "text": "hello" }]
    }
    ```

    或者使用简化格式（会自动生成 id）：

    ```json 简化格式（推荐） icon="lightbulb" theme={null}
    {
      "role": "user",
      "content": "hello"
    }
    ```
  </Accordion>

  <Accordion title="错误：parts 数组为空" icon="triangle-exclamation">
    **问题**：`parts` 数组不能为空

    ```json 错误示例 highlight={4} icon="xmark" theme={null}
    {
      "id": "msg_001",
      "role": "user",
      "parts": []
    }
    ```

    **解决方案**：至少包含一个 part

    ```json 正确示例 highlight={4-6} lines icon="check" theme={null}
    {
      "id": "msg_001",
      "role": "user",
      "parts": [
        { "type": "text", "text": "hello" }
      ]
    }
    ```
  </Accordion>

  <Accordion title="工具调用响应中的消息结构" icon="info-circle">
    **说明**：启用工具调用时，**非流式**响应或流式响应完成后，API 返回的 `data.messages` 数组中会包含 `dynamic-tool` 类型的 parts

    <Note>
      **流式 vs 非流式的区别**：

      * **流式响应**：工具调用以独立的 SSE 事件返回（`tool-input-available` 和 `tool-output-available`）
      * **非流式响应**：工具调用包含在 messages 数组的 `dynamic-tool` part 中
      * 详见[工具调用功能文档](/features/tool-calling)的流式响应部分
    </Note>

    <CodeGroup>
      ```json 完整 API 响应 lines expandable icon="check" theme={null}
      {
        "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": []
          }
        }
      }
      ```

      ```json 仅 messages 部分 lines icon="list" theme={null}
      [
        {
          "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"
            }
          ]
        }
      ]
      ```
    </CodeGroup>

    <Tip>
      **关键点**：

      * 工具调用和结果包含在同一个 `dynamic-tool` part 中
      * 服务端自动执行工具并管理 `toolCallId`
      * 客户端从 `data.messages` 数组中提取消息
      * 详见[工具调用功能文档](/features/tool-calling)
    </Tip>
  </Accordion>
</AccordionGroup>

## 完整请求示例

<Tabs>
  <Tab title="简单文本对话">
    ```json 简单文本对话 lines icon="message" theme={null}
    {
      "model": "anthropic/claude-3-7-sonnet-20250219",
      "messages": [
        {
          "role": "user",
          "content": "你好"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="多轮对话（AI SDK 格式）">
    ```json 多轮对话（完整格式） lines expandable icon="comments" theme={null}
    {
      "model": "anthropic/claude-3-7-sonnet-20250219",
      "messages": [
        {
          "id": "msg_001",
          "role": "user",
          "parts": [
            {
              "type": "text",
              "text": "今天天气怎么样？"
            }
          ]
        },
        {
          "id": "msg_002",
          "role": "assistant",
          "parts": [
            {
              "type": "text",
              "text": "抱歉，我无法获取实时天气信息。"
            }
          ]
        },
        {
          "id": "msg_003",
          "role": "user",
          "parts": [
            {
              "type": "text",
              "text": "那你能做什么？"
            }
          ]
        }
      ]
    }
    ```
  </Tab>

  <Tab title="混合格式（自动归一化）">
    ```json 混合格式示例 lines expandable icon="shuffle" theme={null}
    {
      "model": "anthropic/claude-3-7-sonnet-20250219",
      "messages": [
        {
          "role": "user",
          "content": "第一条消息（简化格式）"
        },
        {
          "id": "msg_002",
          "role": "assistant",
          "parts": [
            {
              "type": "text",
              "text": "第二条消息（AI SDK 格式）"
            }
          ]
        }
      ]
    }
    ```

    <Note>
      可以在同一个请求中混合使用两种格式，服务端会统一归一化为 AI SDK 格式。
    </Note>
  </Tab>
</Tabs>

## 下一步

<CardGroup cols={2}>
  <Card title="系统提示词" icon="message-lines" href="/concepts/system-prompts">
    了解如何配置系统提示词
  </Card>

  {" "}

  <Card title="消息剪裁" icon="scissors" href="/features/message-pruning">
    优化长对话的 token 使用
  </Card>

  {" "}

  <Card title="工具调用" icon="wrench" href="/features/tool-calling">
    了解如何在消息中使用工具
  </Card>

  <Card title="API 参考" icon="code" href="/api-reference/endpoint/chat">
    查看完整的 API 文档
  </Card>
</CardGroup>
