context collapse
设计理念
问题
解决方案
[Earlier conversation: User asked about project structure,
I analyzed 15 files and identified the main components...]
[Recent conversation preserved in full][Earlier conversation: User asked about project structure,
I analyzed 15 files and identified the main components...]
[Recent conversation preserved in full]function contextCollapse(messages: Message[]): Message[] {
const KEEP_RECENT = 10; // 保留最近 10 条消息
if (messages.length <= KEEP_RECENT) {
return messages; // 不需要折叠
}
const recent = messages.slice(-KEEP_RECENT);
const old = messages.slice(0, -KEEP_RECENT);
// 生成摘要
const summary = summarizeMessages(old);
// 创建摘要消息
const summaryMessage = {
role: 'user',
content: `[Earlier conversation summary: ${summary}]`,
};
return [summaryMessage, ...recent];
}function summarizeMessages(messages: Message[]): string {
const points = [];
// 提取用户请求
const userRequests = messages
.filter(m => m.role === 'user')
.map(m => extractIntent(m.content));
points.push(`User requests: ${userRequests.join(', ')}`);
// 提取工具调用
const toolCalls = messages
.filter(m => m.role === 'assistant')
.flatMap(m => extractToolCalls(m.content));
points.push(`Tools used: ${[...new Set(toolCalls)].join(', ')}`);
// 提取关键结论
const conclusions = messages
.filter(m => m.role === 'assistant')
.map(m => extractConclusion(m.content))
.filter(Boolean);
if (conclusions.length > 0) {
points.push(`Key findings: ${conclusions.join('; ')}`);
}
return points.join('. ');
}function slidingWindowCollapse(
messages: Message[],
windowSize: number
): Message[] {
if (messages.length <= windowSize) {
return messages;
}
const windows = [];
for (let i = 0; i < messages.length; i += windowSize) {
const window = messages.slice(i, i + windowSize);
if (i + windowSize < messages.length) {
// 折叠旧窗口
windows.push(collapseWindow(window));
} else {
// 保留最新窗口
windows.push(...window);
}
}
return windows;
}function importanceBasedCollapse(messages: Message[]): Message[] {
return messages.map(msg => {
const score = calculateImportance(msg);
if (score > 0.7) {
return msg; // 保留重要消息
} else if (score > 0.3) {
return summarizeMessage(msg); // 摘要
} else {
return null; // 移除
}
}).filter(Boolean);
}
function calculateImportance(message: Message): number {
let score = 0;
// 包含错误 +0.3
if (message.content.includes('error')) score += 0.3;
// 包含工具调用 +0.2
if (hasToolCalls(message)) score += 0.2;
// 最近的消息 +0.5
const age = Date.now() - message.timestamp;
if (age < 5 * 60 * 1000) score += 0.5; // 5 分钟内
return Math.min(score, 1.0);
}async function* query(messages, tools, options) {
const tokenCount = estimateTokens(messages);
if (tokenCount > 150000) {
// 触发 Context Collapse
messages = contextCollapse(messages);
}
// 继续执行
// ...
}if (messages.length > 50) {
// 对话轮次过多,触发折叠
messages = contextCollapse(messages);
}User: 分析项目结构
Assistant: [分析过程...]
User: 读取 main.tsx
Assistant: [读取结果...]
User: 搜索所有工具
Assistant: [搜索结果...]
...
[25 条历史消息]
...
User: 修复 bug
Assistant: [修复过程...]User: [Earlier conversation: Analyzed project structure, read main.tsx,
searched for tools, reviewed 15 files. Key findings: Project uses React + Ink,
30+ tools implemented, main entry at src/main.tsx]
[最近 10 条消息保持完整]
User: 修复 bug
Assistant: [修复过程...]// .kiro/config.json
{
"contextCollapse": {
"enabled": true,
"keepRecent": 10,
"triggerThreshold": 150000,
"summaryStyle": "detailed" // 或 "brief"
}
}