跳转到内容

对话上下文管理与 Token 优化

对话上下文管理与 Token 优化

学习目标

本章要解决什么问题:AutoGen 如何管理 Agent 的对话历史以避免超出模型上下文窗口。你将学到:

  • 四种 ChatCompletionContext 策略的用法和适用场景
  • AssistantAgent 与上下文策略的集成方式
  • 工具调用场景下的上下文保护

前置知识

本章涉及上下文管理的通用原理,建议先阅读:

下文假设你已理解上下文窗口管理的必要性,直接聚焦 AutoGen 的具体实现。


项目实践

四种 ChatCompletionContext 策略

AutoGen Core 在 model_context 模块中定义了四种策略:

from autogen_core.model_context import (
UnboundedChatCompletionContext, # 无限制
BufferedChatCompletionContext, # 缓冲区
HeadAndTailChatCompletionContext, # 首尾保留
TokenLimitedChatCompletionContext, # Token 限制
)
# 无限制:默认策略,适用于短对话
ctx = UnboundedChatCompletionContext()
# 缓冲区:保留最近 10 条消息
ctx = BufferedChatCompletionContext(buffer_size=10)
# 首尾保留:保留前 2 条和后 5 条
ctx = HeadAndTailChatCompletionContext(head=2, tail=5)
# Token 限制:最多 4096 tokens
ctx = TokenLimitedChatCompletionContext(max_tokens=4096)

与 AssistantAgent 集成

from autogen_agentchat.agents import AssistantAgent
from autogen_core.model_context import BufferedChatCompletionContext
agent = AssistantAgent(
"assistant",
model_client=client,
model_context=BufferedChatCompletionContext(buffer_size=10),
)

内部机制AssistantAgent 在每次调用 LLM 时,从 model_context 获取当前对话历史,而非维护一个内部列表。

策略选择指南

策略默认场景工具调用长对话Token 控制
Unbounded适合适合不适合
Buffered不适合部分适合适合按消息数
HeadAndTail不适合部分适合最适合按消息数
TokenLimited不适合最适合适合按 Token 数

问题与规避

工具调用原子性保护

陷阱:当使用 BufferedTokenLimited 策略时,截断点可能恰好位于工具调用的请求和响应之间。

规避:AutoGen 的消息系统将工具调用(ToolCallRequestEvent)和执行结果(ToolCallExecutionEvent)作为独立消息存储。截断发生在消息边界,不会切断单个消息的内容。

最佳实践:对于工具密集型任务,使用 TokenLimited 策略并设置足够大的 max_tokens,确保完整的工具调用对不被截断。

Token 计数偏差

陷阱:不同模型使用不同的 tokenizer,AutoGen 的 Token 估算可能不准确。

规避

  • TokenLimitedChatCompletionContext 中预留 10-20% 的缓冲
  • 对于已知 Token 消耗高的任务(如代码生成),使用更大的缓冲

设计取舍

为什么将上下文管理抽象为独立组件?

优势

  • 与 Agent 逻辑解耦:切换上下文策略不需要修改 Agent 代码
  • 可组合:不同 Agent 使用不同的上下文策略
  • 可扩展:用户可以自定义 ChatCompletionContext 子类

代价

  • 增加了一个抽象层
  • 用户需要理解上下文策略的概念

与 LangChain 的 MessageWindow 对比

维度AutoGen ChatCompletionContextLangChain MessageWindow
抽象方式独立组件集成在 ChatModel 中
策略数4 种1 种(WindowBuffer)
Token 感知TokenLimited 支持需手动实现
HeadAndTail原生支持不支持

AutoGen 提供了更多样的策略选择,特别是 HeadAndTail 和 TokenLimited 是 LangChain 原生不具备的。

参考来源