# 多轮对话

多轮对话需要在每次请求中携带完整的历史消息，让模型理解对话上下文。

## 基本原理

大模型本身不记忆历史对话，每次调用都是独立的。要实现多轮对话，需要在 `messages` 中传入之前的对话记录：

```
第 1 轮：messages = [用户问题1]
第 2 轮：messages = [用户问题1, AI回答1, 用户问题2]
第 3 轮：messages = [用户问题1, AI回答1, 用户问题2, AI回答2, 用户问题3]
```

## 使用示例

```js
Page({
    data: {
        chatHistory: [],  // 存储完整对话历史
    },

    async sendMessage(userInput) {
        const {chatHistory} = this.data;

        // 1. 将用户消息加入历史
        chatHistory.push({role: "user", content: userInput});

        const model = wx.cloud.extend.AI.createModel("cloudbase");
        let assistantContent = "";

        // 2. 将完整历史传给模型
        const res = await model.streamText({
            data: {
                model: "hy3",
                messages: chatHistory,
            },
        });

        for await (const text of res.textStream) {
            assistantContent += text;
        }

        // 3. 将 AI 回复也加入历史，供下一轮使用
        chatHistory.push({role: "assistant", content: assistantContent});

        this.setData({chatHistory});
    },
});
```

## 添加系统提示词

通过 `system` 角色设定 AI 的行为，系统提示词只需在 messages 开头加一次：

```js
const chatHistory = [
    {
        role: "system",
        content: "你是一个专业的旅行顾问，回答简洁友好，每次推荐不超过3个选项。",
    },
];

// 后续对话在此基础上追加 user 和 assistant 消息
```

## 控制历史长度

对话轮次过多会导致输入 token 过长，影响响应速度和成本。建议限制历史长度：

```js
function trimHistory(messages, maxRounds = 10) {
    // 保留 system 消息
    const systemMsgs = messages.filter((m) => m.role === "system");
    const chatMsgs = messages.filter((m) => m.role !== "system");

    // 只保留最近 N 轮（每轮 = 1 条 user + 1 条 assistant）
    const trimmed = chatMsgs.slice(-maxRounds * 2);

    return [...systemMsgs, ...trimmed];
}
```

## 注意事项

1. **历史消息顺序必须正确**：`user` 和 `assistant` 交替出现
2. **不要在历史中包含 `reasoning_content`**：深度思考模型的思考过程不应追加到历史中，否则会导致 token 膨胀和回复质量下降
3. **控制历史长度**：建议保留最近 10-20 轮对话，避免超出模型上下文窗口
