上下文窗口是模型单次请求能处理的硬上限。它用 token 计量——英文大约 4 个字符一个 token——而且输入和输出合在一起算。
输入 token 和输出 token
输入 token 来自你发送的所有内容:messages 数组(完整对话历史)、system prompt、以及所有工具定义。输出 token 是模型生成的响应内容。
max_tokens 参数只限制输出,不限制输入。假设你在 200K 的上下文窗口里塞了 190K 的输入,响应只剩 10K 的空间——但 max_tokens 不会缩减你的输入。
为什么成本随对话长度增长
因为 API 是无状态的,每次请求都带上完整对话历史。第 1 轮你发 1 条消息,第 50 轮你要发全部 100 条消息(50 条 user + 50 条 assistant)。每一轮不仅加上用户的新消息,还加上模型上一轮的响应。
这意味着输入 token 大致随对话长度二次方增长。一个 50 轮的对话,成本不是第一轮的 50 倍——而是远超 50 倍,因为每次请求都背着前面所有轮次的历史。
这就是为什么长对话必须要有上下文管理策略:摘要提取、事实抽取、或者滑动窗口。没有这些,成本和延迟会不可持续地增长。
上下文窗口是共享的
输入 token 和输出 token 共用同一个上下文窗口。一个 200K 的窗口如果输入占了 195K,输出就只剩 5K。模型没有单独的输出配额——全从一个池子里出。
一句话总结: 输入 token 每轮都在增长,因为每次都要重发完整历史——max_tokens 只限制输出,而输入和输出共享同一个上下文窗口。