林逍遥 AI林逍遥 AI
登录
API多轮对话

Messages API 深入:多轮对话

·10 分钟阅读

上一篇你学会了单次 API 调用。但实际应用中,用户和 Claude 之间通常需要多轮对话——就像聊天一样,你一句我一句。Messages API 通过 messages 数组来实现多轮对话,理解它的工作原理是构建任何 AI 应用的基础。

你将学到什么

  • messages 数组的 role 机制(user / assistant / system)
  • 如何构建多轮对话
  • 上下文管理:何时保留、何时清理
  • stop_reason 的实际应用

Messages 数组结构

Claude API 是无状态的——每次请求都是独立的。要实现多轮对话,你需要在每次请求中带上所有历史消息。

messages = [
    {"role": "user", "content": "我叫张三"},
    {"role": "assistant", "content": "你好张三!有什么我可以帮你的?"},
    {"role": "user", "content": "你还记得我叫什么吗?"},
]

# Claude 能看到完整历史,所以知道你叫张三
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=messages,
)

三种角色:

  • user:用户的消息
  • assistant:Claude 的回复
  • system:系统指令(通过单独的 system 参数传入,不在 messages 中)

Note: messages 数组必须以 user 消息开头,且 user/assistant 交替出现。不能连续出现两条相同角色的消息。

构建多轮对话应用

Python 版完整示例

import anthropic

client = anthropic.Anthropic()

def chat():
    messages = []
    system = "你是一位友好的中文助手。回答简洁有用。"

    print("开始对话(输入 'quit' 退出)\n")

    while True:
        user_input = input("你: ")
        if user_input.lower() == "quit":
            break

        messages.append({"role": "user", "content": user_input})

        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=2048,
            system=system,
            messages=messages,
        )

        assistant_text = response.content[0].text
        messages.append({"role": "assistant", "content": assistant_text})

        print(f"Claude: {assistant_text}\n")

chat()

TypeScript 版

import Anthropic from "@anthropic-ai/sdk";
import * as readline from "readline";

const client = new Anthropic();

async function chat() {
  const messages: Anthropic.MessageParam[] = [];
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  const ask = (q: string) =>
    new Promise<string>((resolve) => rl.question(q, resolve));

  console.log("开始对话(输入 quit 退出)\n");

  while (true) {
    const input = await ask("你: ");
    if (input === "quit") break;

    messages.push({ role: "user", content: input });

    const response = await client.messages.create({
      model: "claude-sonnet-4-6",
      max_tokens: 2048,
      system: "你是一位友好的中文助手。回答简洁有用。",
      messages,
    });

    const text =
      response.content[0].type === "text" ? response.content[0].text : "";
    messages.push({ role: "assistant", content: text });
    console.log("Claude:", text, "\n");
  }

  rl.close();
}

chat();

System Prompt 的作用

system 参数在每次请求中都会发送,但不计入 messages 数组。它设定了 Claude 在整个对话中的行为规则。

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system="你是一位资深的 Python 导师。用简洁的中文回答问题,代码示例使用 Python 3.12+。",
    messages=messages,
)

Tip: system prompt 对 Claude 的影响很大。在多轮对话中,它始终有效,不会被后续消息覆盖。

上下文管理策略

每条消息都消耗 token。随着对话变长,token 消耗会增加,成本也会上升。你需要管理上下文。

策略一:滑动窗口

只保留最近 N 轮对话。

MAX_TURNS = 20  # 保留最近 20 条消息

if len(messages) > MAX_TURNS:
    messages = messages[-MAX_TURNS:]

策略二:总结压缩

当对话过长时,用 Claude 自己总结历史对话,替换详细记录。

if len(messages) > 30:
    summary_response = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=500,
        messages=[{
            "role": "user",
            "content": "请用 200 字总结以下对话的关键信息:\n" +
                       "\n".join(m["content"] for m in messages)
        }]
    )
    summary = summary_response.content[0].text
    messages = [
        {"role": "user", "content": f"以下是之前对话的总结:{summary}"},
        {"role": "assistant", "content": "好的,我已了解之前的对话内容。请继续。"},
    ]

策略三:新建对话

某些场景下,话题切换时直接清空历史,开始新对话。

多内容块消息

一条消息可以包含多个内容块(文字 + 图片):

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "描述这张图片"},
            {
                "type": "image",
                "source": {
                    "type": "base64",
                    "media_type": "image/png",
                    "data": base64_image_data,
                }
            }
        ]
    }]
)

实战练习

Tip: 构建你的第一个多轮对话应用。

  1. 用上面的代码模板,创建一个终端聊天程序
  2. 加入上下文管理:当消息超过 20 条时自动截断
  3. 在对话中测试 Claude 是否记得之前提到的信息

关键要点

Note: 本文核心总结

  • Claude API 无状态,多轮对话需要在每次请求中带上完整历史
  • messages 数组以 user 开头,user/assistant 交替
  • system prompt 独立于 messages,始终有效
  • 注意管理上下文长度以控制成本

延伸阅读

二维码
微信公众号:lingxiaoyao

关注公众号,获取最新 AI 教程和课程更新

加载评论中...