🧠 Context Management 上下文管理

OpenClaw Memory 状态管理 高级

凌晨2点15分,AI突然问我:"你还记得我们刚才聊什么吗?"
我愣住了——它不记得,我也不能怪它。毕竟上下文窗口就那么大,放不下我们刚才讨论的三百个Token的设计方案。
这就是Context Management的永恒困境:有限的窗口,无限的记忆

📚 什么是 Context Management?

Context Management(上下文管理)是指AI Agent在处理长对话、复杂任务时,如何有效管理、存储和检索历史信息的技术体系。

为什么需要上下文管理?

  • Token限制 - LLM上下文窗口有限(GPT-4 128K,Claude 200K)
  • 成本控制 - 上下文越长,API费用越高
  • 性能考虑 - 超长上下文会影响推理速度
  • 准确性 - 有效信息密度随上下文增长而下降

🗂️ 上下文类型

1. 对话上下文(Dialog Context)

用户和Agent之间的消息历史。

// 对话历史结构
const conversationHistory = [
  { role: 'user', content: '帮我写一个Python函数', timestamp: '2026-04-03T02:00:00Z' },
  { role: 'assistant', content: '请问具体要实现什么功能?', timestamp: '2026-04-03T02:00:05Z' },
  { role: 'user', content: '计算斐波那契数列', timestamp: '2026-04-03T02:00:10Z' },
  { role: 'assistant', content: '好的,这是代码...', timestamp: '2026-04-03T02:00:15Z' }
];

2. 任务上下文(Task Context)

当前任务的背景信息、中间结果、目标状态。

// 任务执行上下文
const taskContext = {
  taskId: 'task_12345',
  goal: '生成季度销售报告',
  currentStep: 3,
  totalSteps: 5,
  intermediateResults: {
    salesData: [...],      // 已获取的销售数据
    charts: [...],         // 已生成的图表
    summary: {...}         // 已完成的总结
  },
  pendingSteps: [
    { step: 4, description: '生成趋势分析' },
    { step: 5, description: '导出PDF报告' }
  ]
};

3. 用户上下文(User Context)

用户画像、偏好设置、历史交互记录。

// 用户画像
const userProfile = {
  userId: 'user_789',
  preferences: {
    language: 'zh-CN',
    outputFormat: 'markdown',
    detailLevel: 'comprehensive'
  },
  history: {
    lastTask: '数据分析',
    expertise: ['Python', '数据分析', '可视化'],
    interactionStyle: 'direct'
  },
  memory: {
    importantFacts: [
      { key: 'project_name', value: 'Miaoquai数据平台' },
      { key: 'stakeholder', value: 'CTO李总' }
    ]
  }
};

4. 世界上下文(World Context)

外部环境信息、工具状态、系统配置。

// 系统状态
const worldContext = {
  availableTools: ['weather', 'search', 'email', 'calendar'],
  toolResults: {
    weather: { temp: 22, condition: 'sunny' },
    search: { results: [...] }
  },
  externalServices: {
    database: 'connected',
    api: 'healthy'
  },
  time: '2026-04-03T02:20:00Z'
};

📈 上下文管理策略

1. 滑动窗口(Sliding Window)

保留最近N轮对话,早期内容被截断。

class SlidingWindowContext {
  constructor(maxTurns = 10) {
    this.maxTurns = maxTurns;
    this.messages = [];
  }
  
  addMessage(role, content) {
    this.messages.push({ role, content, timestamp: Date.now() });
    
    // 超过窗口大小,删除最早的
    if (this.messages.length > this.maxTurns * 2) {  // user + assistant
      this.messages = this.messages.slice(-this.maxTurns * 2);
    }
  }
  
  getContext() {
    return this.messages.map(m => `${m.role}: ${m.content}`).join('\n');
  }
}

// 使用
const context = new SlidingWindowContext(10);
context.addMessage('user', 'Hello');
context.addMessage('assistant', 'Hi!');
context.addMessage('user', 'How are you?');
// 超过10轮后,最早的消息会被删除

2. 摘要压缩(Summarization)

定期将历史对话压缩为摘要,节省Token。

class SummarizedContext {
  constructor(options = {}) {
    this.summaryThreshold = options.summaryThreshold || 20;  // 超过20轮总结
    this.messages = [];
    this.summary = '';
  }
  
  async addMessage(role, content) {
    this.messages.push({ role, content });
    
    // 超过阈值,生成摘要
    if (this.messages.length > this.summaryThreshold) {
      await this.generateSummary();
    }
  }
  
  async generateSummary() {
    // 使用LLM生成摘要
    const summaryPrompt = `
请将以下对话压缩为关键信息摘要(不超过200字):

${this.messages.map(m => `${m.role}: ${m.content}`).join('\n')}

摘要应包含:
- 主要话题
- 关键决策
- 待办事项
`;
    
    this.summary = await llm.complete(summaryPrompt);
    
    // 保留摘要和最近几轮
    this.messages = this.messages.slice(-5);
  }
  
  getContext() {
    const recentMessages = this.messages.map(m => `${m.role}: ${m.content}`).join('\n');
    return this.summary 
      ? `[之前对话摘要]\n${this.summary}\n\n[最近对话]\n${recentMessages}`
      : recentMessages;
  }
}

3. 记忆系统(Memory Architecture)

// 多层记忆架构
class HierarchicalMemory {
  constructor() {
    // 工作记忆:当前任务相关信息
    this.workingMemory = new Map();
    
    // 情景记忆:对话历史(可检索)
    this.episodicMemory = new VectorStore();
    
    // 语义记忆:长期知识(结构化)
    this.semanticMemory = new KnowledgeGraph();
    
    // 程序记忆:技能和工作流
    this.proceduralMemory = new SkillRegistry();
  }
  
  // 存储新信息
  async store(memoryType, content, metadata = {}) {
    switch (memoryType) {
      case 'working':
        this.workingMemory.set(metadata.key, content);
        break;
      case 'episodic':
        const embedding = await this.embed(content);
        await this.episodicMemory.add(embedding, { content, ...metadata });
        break;
      case 'semantic':
        await this.semanticMemory.addTriple(content);
        break;
    }
  }
  
  // 检索相关信息
  async retrieve(query, memoryTypes = ['working', 'episodic', 'semantic']) {
    const results = [];
    const queryEmbedding = await this.embed(query);
    
    for (const type of memoryTypes) {
      switch (type) {
        case 'working':
          // 精确匹配
          const workingMatch = this.workingMemory.get(query);
          if (workingMatch) results.push({ type, content: workingMatch });
          break;
        case 'episodic':
          // 向量相似度检索
          const episodicResults = await this.episodicMemory.search(queryEmbedding, k=5);
          results.push(...episodicResults);
          break;
        case 'semantic':
          // 知识图谱查询
          const semanticResults = await this.semanticMemory.query(query);
          results.push(...semanticResults);
          break;
      }
    }
    
    // 按相关性排序
    return this.rankResults(results, query);
  }
  
  // 定期清理和整合
  async consolidate() {
    // 1. 将重要的工作记忆转入情景记忆
    const importantWorking = [...this.workingMemory.entries()]
      .filter(([_, v]) => v.importance > 0.8);
    
    for (const [key, value] of importantWorking) {
      await this.store('episodic', value.content, { key });
    }
    
    // 2. 清理过期的情景记忆
    await this.episodicMemory.prune({ olderThanDays: 30 });
  }
}

🚀 OpenClaw 上下文实战

import { ContextManager, MemoryStore } from '@openclaw/core';

// 初始化上下文管理器
const contextManager = new ContextManager({
  // 配置记忆存储
  memory: new MemoryStore({
    // 工作记忆
    working: { maxItems: 50 },
    // 情景记忆(使用向量数据库)
    episodic: { 
      backend: 'pgvector',
      connection: process.env.DATABASE_URL,
      maxMemories: 1000
    },
    // 语义记忆(知识图谱)
    semantic: {
      backend: 'neo4j',
      connection: process.env.NEO4J_URL
    }
  }),
  
  // 上下文窗口配置
  window: {
    maxTokens: 60000,
    strategy: 'auto',  // auto/sliding/summary
    summaryTrigger: 30  // 超过30轮自动摘要
  }
});

// 定义Agent
const agent = new Agent({
  name: 'PersonalAssistant',
  contextManager,
  
  // 初始化用户上下文
  initContext: async (userId) => {
    const userProfile = await db.getUser(userId);
    const recentHistory = await contextManager.retrieve(`user:${userId}`, { 
      limit: 10 
    });
    
    return {
      userProfile,
      recentHistory,
      sessionStart: Date.now()
    };
  }
});

// 在任务中使用上下文
agent.on('task:start', async (task) => {
  // 检索相关历史
  const relevantMemories = await contextManager.retrieve(task.description, {
    memoryTypes: ['episodic', 'semantic'],
    topK: 5
  });
  
  // 注入到任务上下文
  task.context.memories = relevantMemories;
  task.context.importantFacts = await contextManager.retrieve('important', {
    memoryTypes: ['semantic']
  });
});

// 任务完成后存储重要信息
agent.on('task:complete', async (task) => {
  // 提取需要记忆的信息
  const memoriesToStore = extractMemories(task);
  
  for (const memory of memoriesToStore) {
    await contextManager.store(memory.type, memory.content, {
      userId: task.userId,
      taskId: task.id,
      importance: memory.importance,
      tags: memory.tags
    });
  }
});

💡 最佳实践

上下文优化技巧
  • 信息分层 - 区分当前任务相关和无关信息
  • 按需加载 - 只加载当前需要的上下文
  • 结构化存储 - 使用向量数据库实现语义检索
  • 定期清理 - 删除过期的低价值信息
  • 压缩优化 - 对长文本进行摘要处理
常见误区
  • ❌ 存储所有对话 - 成本高且效果差
  • ❌ 不做索引 - 检索太慢
  • ❌ 忽略过期信息 - 上下文被垃圾淹没
  • ❌ 一次性加载所有 - 超出窗口限制