“Prompt 太长” / 超出模 型上下文长度
你看到的是什么
典型报错包括:
The prompt is too longmaximum context lengthInput is too long for the modelcontext length exceeded
这些错误来自模型提供方,不是 OPL 数据空间本身。也就是说,模型端在计算“这次请求总共要吃多少 token”之后,发现已经超过了该模型的上下文窗口。
为什么会发生
模型实际看到的“prompt”不是你刚输入的那一句,而是整个会话上下文之和,包括:
- system prompt
- 当前聊天的完整历史
- 直接内联进上下文的附件内容
- tool 定义和既往 tool 调用结果
- filter / RAG / web search / memory 注入的额外上下文
- 你最新的一条消息
聊天越长、附件越大、工具输出越多,就越容易把上下文窗口撑爆。
为什么 OPL 数据空间不默认替你截断
这是一个刻意的设计选 择。原因很现实:
- 不同模型 tokenizer 不同,相同文本的 token 数并不一致。
- 不同模型上下文窗口不同,从 8k 到 1M 不等。
- 不同团队想要的截断策略也不同,有人想按 token,有人想按消息数,有人想优先丢附件,有人想优先总结旧对话。
所以 OPL 数据空间不强推单一策略,而是把控制点交给你。
官方支持的做法:使用 filter Function
上下文管理建议通过 filter Functions 实现。inlet() 会在每次请求发往模型前运行,你可以直接检查并修改 body["messages"]。
常见策略包括:
- 硬性聊天长度上限:超过 N 条消息直接拒绝
- 只保留最近 N 轮:保留 system prompt 和最近若干轮对话
- 按 token 预算裁剪:根据模型不同预算动态删最旧内容
- 总结后替换旧对话:把旧消息压成一条摘要
- 优先裁掉附件 / tool 输出:保留核心对话
社区里已经有不少这类 filter,可直接从 OPL 数据空间 community site 安装后再调 valves。
最小可用策略
如果你只想快速止血:
- 给本地小上下文模型设置更短的对话保留窗口
- 不要把大文件直接内联进聊天
- 对 web search / RAG / tool 输出做更严格的裁剪
- 把长会话拆成多个主题化对话
什么时候优先怀疑上下文太长
以下情况最常见:
- 聊天进行了很多轮以后突然开始 400
- 同一模型在新聊天里正常,旧聊天里报错
- 启用了大量 tools、RAG、web search 后更容易失败
- 小模型报错,大上下文云模型没问题
建议做法
- 小上下文本地模型:强烈建议加 filter 做历史裁剪
- 生产环境:按模型配置不同预算,而不是全实例用同一阈值
- 长会话:考虑总结旧消息,而不是无限保留