# 多轮对话

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

# 基本原理

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

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

# 使用示例

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-preview",
                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 开头加一次:

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

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

# 控制历史长度

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

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