上下文管理
长会话如何跨轮传递,以及如何保持请求前缀稳定。
每次请求都会新建一个 agent,模型本身看不到本会话此前的对话。Bi 在服务端把落库的会话记录重新打包成模型消息序列,这样多轮对话才能延续。
跨轮打包
打包规则只有一条:最近若干轮完整重建,更早的轮次做摘要。
- 最近
recent_turns_full轮(默认 6)完整重建,包括user、assistant和tool消息。assistant 行里的工具块会还原成assistant.toolCalls加后续role: "tool"消息,保证tool_call/tool配对完整——这是 OpenAI 兼容接口的硬要求,配对缺失会被网关拒掉。 - 更早的轮次折叠成一段摘要,摘要在
<earlier_conversation_summary>标签里,包含用户要点、助手结论、改动文件清单。摘要完全由规则拼装,不调用模型:零额外成本、零延迟、输出稳定可复现。 - 超过 40 轮的历史直接丢弃,不再往更远处回溯。
注意压缩是按轮次计的,不是按 token 计。 轮次多不代表一定触顶,单轮内容极长也可能在很早就超限。要精确控制就调 recent_turns_full:调大保留更多原文,调小更早开始摘要。
工具被中断或超时时结果可能是空串,此时会填入占位文本 (无输出:工具被中断或超时)。占位符让模型知道「这一步没有产出」,同时避免空 content 在严格网关上出问题。
前缀稳定
摘要按「老轮条数 + 末条消息 id」做指纹缓存。只要更早的历史没变化(正常追加聊天的场景),摘要就被冻结复用,请求前缀因此保持逐字节稳定。
还有一层松弛:只有完整注入部分超过 recent_turns_full + 2 轮时,冻结点才会前移。这么设计是为了摊薄前缀失效的频次——否则每多一轮对话,摘要位置就动一次,缓存几乎永远不命中。
这是为模型服务商的 prompt 缓存服务的。 缓存发生在服务商那侧,Bi 本身不存任何缓存;它做的是保证每次请求的头部字节不变,让服务商那边能持续命中。
怎么调
recent_turns_full 写在 .bi/config.json 里。取值 ≤ 0 或缺失时回落到默认值 6。
- 短任务、调 API、跑脚本:调小甚至设 0(按默认 6 走)都无妨,摘要基本不参与
- 长文档分析、多轮迭代:调大到 10~15,保留更多原文,减少「摘要丢细节」带来的偏差
- 上下文很贵的模型:调小,省 token,但要接受更早的信息被摘要掉