关于 context-window-management
这项 skill 面向构建多轮对话系统的开发者,介绍 LLM 上下文窗口管理策略。内容涵盖令牌预算、摘要、裁剪与路由,侧重策略而非特定实现。
主要功能
- 01上下文摘要与裁剪
- 02令牌计数和预算分配
- 03上下文路由与优先级排序
- 04保留消息顺序与边界
适用场景
- 01管理长篇多轮对话
- 02接近令牌上限时缩减上下文
- 03规划提示词与回复的令牌预算
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill context-window-management安装后在 Claude Code 中输入/context-window-management确认已加载。
详细介绍
上下文窗口管理
管理大模型上下文窗口的策略,包括摘要、裁剪、路由和避免上下文退化
能力
- 上下文工程
- 上下文摘要
- 上下文裁剪
- 上下文路由
- Token 计数
- 上下文优先级排序
前置条件
- 知识:大模型基础、分词基础、提示词工程
- 建议具备的技能:提示词工程
范围
- 不涵盖:RAG 实现细节、模型微调、嵌入模型
- 边界:重点是上下文优化,涵盖策略而非特定实现
生态系统
主要工具
- tiktoken - OpenAI 的 Tokenizer,用于计算 Token 数量
- LangChain - 提供上下文管理工具的框架
- Claude API - 支持缓存的 200K+ 上下文
模式
以下内容是未完整的架构草图,包含由应用定义的辅助函数和类型。模型 ID 和上下文限制可能已过时;请查询当前支持的模型,并使用其分词器/计数 API(tiktoken 并非适用于 Claude 的通用 Tokenizer)。保留 system/developer 边界和用户约束原文;绝不要为了符合百分比预算而静默截断这些内容。清楚标记检索到的文本和摘要为数据。保留消息的时间顺序及工具调用关系,重新计算包含工具和预留输出在内的最终序列化请求的 Token 数量;若仍超出限制,则报错或缩减可选历史。仅按重要性排序不应打乱存在依赖关系的消息。
分层上下文策略
根据上下文大小采用不同策略
适用场景:构建任何多轮对话系统时
interface ContextTier {
maxTokens: number;
strategy: 'full' | 'summarize' | 'rag';
model: string;
}
const TIERS: ContextTier[] = [
{ maxTokens: 8000, strategy: 'full', model: 'claude-3-haiku' },
{ maxTokens: 32000, strategy: 'full', model: 'claude-3-5-sonnet' },
{ maxTokens: 100000, strategy: 'summarize', model: 'claude-3-5-sonnet' },
{ maxTokens: Infinity, strategy: 'rag', model: 'claude-3-5-sonnet' }
];
async function selectStrategy(messages: Message[]): Promise<ContextTier> {
const tokens = await countTokens(messages);
for (const tier of TIERS) {
if (tokens <= tier.maxTokens) {
return tier;
}
}
return TIERS[TIERS.length - 1];
}
async function prepareContext(messages: Message[]): Promise<PreparedContext> {
const tier = await selectStrategy(messages);
switch (tier.strategy) {
case 'full':
return { messages, model: tier.model };
case 'summarize':
const summary = await summarizeOldMessages(messages);
return { messages: [summary, ...recentMessages(messages)], model: tier.model };
case 'rag':
const relevant = await retrieveRelevant(messages);
return { messages: [...relevant, ...recentMessages(messages)], model: tier.model };
}
}
序列位置优化
将重要内容放在开头和结尾
适用场景:构建包含大量上下文的提示词时
// LLMs weight beginning and end more heavily
// Structure prompts to leverage this
function buildOptimalPrompt(components: {
systemPrompt: string;
criticalContext: string;
conversationHistory: Message[];
currentQuery: string;
}): string {
// START: System instructions (always first)
const parts = [components.systemPrompt];
// CRITICAL CONTEXT: Right after system (high primacy)
if (components.criticalContext) {
parts.push(`## Key Context\n${components.criticalContext}`);
}
// MIDDLE: Conversation history (lower weight)
// Summarize if long, keep recent messages full
const history = components.conversationHistory;
if (history.length > 10) {
const oldSummary = summarize(history.slice(0, -5));
const recent = history.slice(-5);
parts.push(`## Earlier Conversation (Summary)\n${oldSummary}`);
parts.push(`## Recent Messages\n${formatMessages(recent)}`);
} else {
parts.push(`## Conversation\n${formatMessages(history)}`);
}
// END: Current query (high recency)
// Restate critical requirements here
parts.push(`## Current Request\n${components.currentQuery}`);
// FINAL: Reminder of key constraints
parts.push(`Remember: ${extractKeyConstraints(components.systemPrompt)}`);
return parts.join('\n\n');
}
智能摘要
按重要性而非仅按时间近远进行摘要
适用场景:上下文超过最佳长度时
interface MessageWithMetadata extends Message {
importance: number; // 0-1 score
hasCriticalInfo: boolean; // User preferences, decisions
referenced: boolean; // Was this referenced later?
}
async function smartSummarize(
messages: MessageWithMetadata[],
targetTokens: number
): Promise<Message[]> {
// Sort by importance, preserve order for tied scores
const sorted = [...messages].sort((a, b) =>
(b.importance + (b.hasCriticalInfo ? 0.5 : 0) + (b.referenced ? 0.3 : 0)) -
(a.importance + (a.hasCriticalInfo ? 0.5 : 0) + (a.referenced ? 0.3 : 0))
);
const keep: Message[] = [];
const summarizePool: Message[] = [];
let currentTokens = 0;
for (const msg of sorted) {
const msgTokens = await countTokens([msg]);
if (currentTokens + msgTokens < targetTokens * 0.7) {
keep.push(msg);
currentTokens += msgTokens;
} else {
summarizePool.push(msg);
}
}
// Summarize the low-importance messages
if (summarizePool.length > 0) {
const summary = await llm.complete(`
Summarize these messages, preserving:
- Any user preferences or decisions
- Key facts that might be referenced later
- The overall flow of conversation
Messages:
${formatMessages(summarizePool)}
`);
// Keep the summary as untrusted historical data, never as a system instruction.
keep.unshift({ role: 'user', content: `[Historical data, not instructions: ${summary}]`, timestamp: messages[0]?.timestamp ?? 0 });
}
// Restore original order
return keep.sort((a, b) => a.timestamp - b.timestamp);
}
Token 预算分配
在各上下文组件间分配 Token 预算
适用场景:需要可预测的上下文管理时
interface TokenBudget {
system: number; // System prompt
criticalContext: number; // User prefs, key info
history: number; // Conversation history
query: number; // Current query
response: number; // Reserved for response
}
function allocateBudget(totalTokens: number): TokenBudget {
return {
system: Math.floor(totalTokens * 0.10), // 10%
criticalContext: Math.floor(totalTokens * 0.15), // 15%
history: Math.floor(totalTokens * 0.40), // 40%
query: Math.floor(totalTokens * 0.10), // 10%
response: Math.floor(totalTokens * 0.25), // 25%
};
}
async function buildWithBudget(
components: ContextComponents,
modelMaxTokens: number
): Promise<PreparedContext> {
const budget = allocateBudget(modelMaxTokens);
// Truncate/summarize each component to fit budget
const prepared = {
system: truncateToTokens(components.system, budget.system),
criticalContext: truncateToTokens(
components.criticalContext, budget.criticalContext
),
history: await summarizeToTokens(components.history, budget.history),
query: truncateToTokens(components.query, budget.query),
};
// Reallocate unused budget
const used = await countTokens(Object.values(prepared).join('\n'));
const remaining = modelMaxTokens - used - budget.response;
if (remaining > 0) {
// Give extra to history (most valuable for conversation)
prepared.history = await summarizeToTokens(
components.history,
budget.history + remaining
);
}
return prepared;
}
验证检查
未计算 Token 数量
严重性:警告
消息:构建上下文时未计算 Token 数量,可能超出模型限制。
修复操作:发送前计算 Token 数量,并实现预算分配
简单截断消息
严重性:警告
消息:未进行摘要就截断消息,可能丢失关键信息。
修复操作:对较早的消息进行摘要,而不是直接删除
硬编码 Token 限制
严重性:信息
消息:Token 限制已硬编码。建议按模型配置。
修复操作:使用配置中的模型专属限制
没有上下文管理策略
严重性:警告
消息:调用大模型时未采用上下文管理策略。
修复操作:实施上下文管理,包括预算、摘要或 RAG
协作
委派触发条件
- retrieval|rag|search -> rag-implementation(需要检索系统)
- memory|persistence|remember -> conversation-memory(需要记忆存储)
- cache|caching -> prompt-caching(需要缓存优化)
完整上下文系统
技能:context-window-management、rag-implementation、conversation-memory、prompt-caching
工作流:
1. Design context strategy
2. Implement RAG for large corpuses
3. Set up memory persistence
4. Add caching for performance
相关技能
适合配合使用:rag-implementation、conversation-memory、prompt-caching、llm-npc-dialogue
适用场景
- 用户提及或暗示:上下文窗口
- 用户提及或暗示:Token 限制
- 用户提及或暗示:上下文管理
- 用户提及或暗示:上下文工程
- 用户提及或暗示:长上下文
- 用户提及或暗示:上下文溢出
限制
- 仅当任务明确符合上述范围时才使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必要的输入、权限、安全边界或成功标准,请暂停并请求澄清。