---
title: "上下文管理"
description: "长会话如何跨轮传递，以及如何保持请求前缀稳定。"
---

每次请求都会新建一个 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，但要接受更早的信息被摘要掉
