跳到主要内容

“Prompt 太长” / 超出模型上下文长度

你看到的是什么

典型报错包括:

  • The prompt is too long
  • maximum context length
  • Input is too long for the model
  • context length exceeded

这些错误来自模型提供方,不是 OPL 数据空间本身。也就是说,模型端在计算“这次请求总共要吃多少 token”之后,发现已经超过了该模型的上下文窗口。

为什么会发生

模型实际看到的“prompt”不是你刚输入的那一句,而是整个会话上下文之和,包括:

  • system prompt
  • 当前聊天的完整历史
  • 直接内联进上下文的附件内容
  • tool 定义和既往 tool 调用结果
  • filter / RAG / web search / memory 注入的额外上下文
  • 你最新的一条消息

聊天越长、附件越大、工具输出越多,就越容易把上下文窗口撑爆。

为什么 OPL 数据空间不默认替你截断

这是一个刻意的设计选择。原因很现实:

  1. 不同模型 tokenizer 不同,相同文本的 token 数并不一致。
  2. 不同模型上下文窗口不同,从 8k 到 1M 不等。
  3. 不同团队想要的截断策略也不同,有人想按 token,有人想按消息数,有人想优先丢附件,有人想优先总结旧对话。

所以 OPL 数据空间不强推单一策略,而是把控制点交给你。

官方支持的做法:使用 filter Function

上下文管理建议通过 filter Functions 实现。inlet() 会在每次请求发往模型前运行,你可以直接检查并修改 body["messages"]

常见策略包括:

  1. 硬性聊天长度上限:超过 N 条消息直接拒绝
  2. 只保留最近 N 轮:保留 system prompt 和最近若干轮对话
  3. 按 token 预算裁剪:根据模型不同预算动态删最旧内容
  4. 总结后替换旧对话:把旧消息压成一条摘要
  5. 优先裁掉附件 / tool 输出:保留核心对话

社区里已经有不少这类 filter,可直接从 OPL 数据空间 community site 安装后再调 valves。

最小可用策略

如果你只想快速止血:

  • 给本地小上下文模型设置更短的对话保留窗口
  • 不要把大文件直接内联进聊天
  • 对 web search / RAG / tool 输出做更严格的裁剪
  • 把长会话拆成多个主题化对话

什么时候优先怀疑上下文太长

以下情况最常见:

  • 聊天进行了很多轮以后突然开始 400
  • 同一模型在新聊天里正常,旧聊天里报错
  • 启用了大量 tools、RAG、web search 后更容易失败
  • 小模型报错,大上下文云模型没问题

建议做法

  • 小上下文本地模型:强烈建议加 filter 做历史裁剪
  • 生产环境:按模型配置不同预算,而不是全实例用同一阈值
  • 长会话:考虑总结旧消息,而不是无限保留

相关文档