首页 > AI教程 >Hermes Agent上下文压缩机制解析

Hermes Agent上下文压缩机制解析

来源:互联网 2026-07-15 18:42:01

核心压缩算法详解 Hermes Agent 的上下文压缩系统,设计上采用智能策略应对长对话场景下模型上下文窗口不足的问题。整个压缩流程包含以下关键步骤: 预压缩处理:将老旧冗长的工具运行结果裁剪,使用占位符替换,有效缩减上下文体积。边界确定:保护两端关键内容——头部消息(系统提示与首次交互)完整保留

核心压缩算法详解

Hermes Agent 的上下文压缩系统,设计上采用智能策略应对长对话场景下模型上下文窗口不足的问题。整个压缩流程包含以下关键步骤:

Hermes Agent上下文压缩机制解析

长期稳定更新的攒劲资源: >>>点此立即查看<<<

  1. 预压缩处理:将老旧冗长的工具运行结果裁剪,使用占位符替换,有效缩减上下文体积。
  2. 边界确定:保护两端关键内容——
    • 头部消息(系统提示与首次交互)完整保留
    • 尾部消息(最近约20K令牌)通过令牌预算确保安全
  3. 摘要生成:对中间轮次内容,采用结构化LLM提示进行总结。
  4. 迭代更新:再次压缩时,基于已有摘要更新,避免从头重写。
  5. 工具对清理:压缩后若出现孤立工具调用或结果对,自动修复。

关键实现细节

1. 压缩触发条件

def should_compress(self, prompt_tokens: int = None) -> bool:
    """Check if context exceeds the compression threshold."""
    tokens = prompt_tokens if prompt_tokens is not None else self.last_prompt_tokens
    return tokens >= self.threshold_tokens

默认压缩阈值设定为模型上下文长度的50%,同时设置最低值(MINIMUM_CONTEXT_LENGTH)作为保底。

2. 工具结果剪枝策略

def _prune_old_tool_results(self, messages: List[Dict[str, Any]], protect_tail_count: int,
                           protect_tail_tokens: int | None = None) -> tuple[List[Dict[str, Any]], int]:
    """Replace old tool result contents with a short placeholder."""
    # 实现细节...

此步骤成本低廉,无需调用LLM,仅将旧工具结果替换为占位符,快速降低上下文体积。

3. 尾部边界确定方法

def _find_tail_cut_by_tokens(self, messages: List[Dict[str, Any]], head_end: int,
                            token_budget: int | None = None) -> int:
    """Walk backward from the end of messages, accumulating tokens until the budget is reached."""
    # 实现细节...

采用令牌预算而非固定消息数保护尾部消息,确保最近重要上下文按实际令牌量保留,灵活性更高。

4. 结构化摘要生成机制

def _generate_summary(self, turns_to_summarize: List[Dict[str, Any]], focus_topic: str = None) -> Optional[str]:
    """Generate a structured summary of conversation turns."""
    # 实现细节...

摘要生成遵循结构化模板,包含以下关键信息:

  • 目标
  • 约束与偏好
  • 进度(已完成、进行中、阻塞)
  • 关键决策
  • 已解决问题
  • 待处理用户请求
  • 相关文件
  • 剩余工作
  • 关键上下文
  • 工具与模式

该模板确保摘要信息密度高、条理清晰。

5. 主压缩流程

def compress(self, messages: List[Dict[str, Any]], current_tokens: int = None, focus_topic: str = None) -> List[Dict[str, Any]]:
    """Compress conversation messages by summarizing middle turns."""
    # 实现细节...

作为压缩总入口,协调所有步骤,最终返回压缩后的消息列表。

会话管理与压缩集成

run_agent.py 中,_compress_context 方法负责处理压缩后的会话管理,逻辑完整:

def _compress_context(self, messages: list, system_message: str, *, approx_tokens: int = None, task_id: str = "default", focus_topic: str = None) -> tuple:
    """Compress conversation context and split the session in SQLite."""
    # 预压缩内存刷新
    self.flush_memories(messages, min_turns=0)
    
    # 通知外部内存提供者
    if self._memory_manager:
        try:
            self._memory_manager.on_pre_compress(messages)
        except Exception:
            pass
    
    # 执行压缩
    compressed = self.context_compressor.compress(messages, current_tokens=approx_tokens, focus_topic=focus_topic)
    
    # 会话分割与管理
    if self._session_db:
        try:
            # 传播标题到新会话并自动编号
            old_title = self._session_db.get_session_title(self.session_id)
            self._session_db.end_session(self.session_id, "compression")
            old_session_id = self.session_id
            self.session_id = f"{datetime.now().strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4().hex[:6]}"
            # 更新会话日志文件路径
            self.session_log_file = self.logs_dir / f"session_{self.session_id}.json"
            # 创建新会话
            self._session_db.create_session(
                session_id=self.session_id,
                source=self.platform or os.environ.get("HERMES_SESSION_SOURCE", "cli"),
                model=self.model,
                parent_session_id=old_session_id,
            )
            # 自动编号标题
            if old_title:
                try:
                    new_title = self._session_db.get_next_title_in_lineage(old_title)
                    self._session_db.set_session_title(self.session_id, new_title)
                except (ValueError, Exception) as e:
                    logger.debug("Could not propagate title on compression: %s", e)
            self._session_db.update_system_prompt(self.session_id, new_system_prompt)
            # 重置刷新光标
            self._last_flushed_db_idx = 0
        except Exception as e:
            logger.warning("Session DB compression split failed — new session will NOT be indexed: %s", e)

压缩触发时机

run_conversation 方法中,系统在以下节点触发压缩:

  1. 预压缩检查:发送请求到模型前,检查上下文是否超标。
  2. 上下文压力处理:上下文长度接近阈值时自动触发。
  3. 模型切换后:更换模型后,更新上下文压缩器。
  4. 手动触发:通过 /compress 命令实现人工干预。

技术特点与优势

  1. 分层压缩策略:先进行廉价预处理(剪枝),再调用LLM生成摘要,效率显著提升。
  2. 结构化摘要:详细模板确保重要信息在压缩过程中不丢失。
  3. 迭代摘要更新:基于已有摘要迭代更新,避免信息断层。
  4. 令牌预算管理:基于令牌数而非消息数保护尾部上下文,精准度更高。
  5. 焦点主题引导:支持通过 /compress 命令指定压缩时优先保留的信息。
  6. 会话分割:压缩后自动创建新会话,提升会话历史可管理性。
  7. 错误处理:摘要生成失败时插入静态回退标记,确保系统稳定运行。

代码优化建议

  1. 摘要质量监控:引入质量评估机制,发现摘要质量低时调整压缩策略。
  2. 自适应压缩阈值:根据对话类型和内容自动调整压缩阈值,提升灵活性。
  3. 多模型摘要:尝试不同模型生成摘要,选择最优结果。
  4. 用户可配置性:允许用户配置保护消息数、摘要比例等参数,增强可控性。
  5. 压缩历史记录:记录每次压缩历史,便于效果分析和策略优化。

输入输出示例

输入:长对话历史(超过模型上下文限制)

messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "I need help with a Python project."},
    {"role": "assistant", "content": "Sure, what do you need help with"},
    # ... 大量对话内容 ...
    {"role": "user", "content": "How do I optimize this code"},
    {"role": "assistant", "content": "Let me analyze your code and suggest optimizations."},
    # ... 更多对话内容 ...
]

输出:压缩后的对话历史

[
    {"role": "system", "content": "You are a helpful assistant.nn[Note: Some earlier conversation turns ha ve been compacted into a handoff summary to preserve context space. The current session state may still reflect earlier work, so build on that summary and state rather than re-doing work.]"},
    {"role": "user", "content": "[CONTEXT COMPACTION — REFERENCE ONLY] Earlier turns were compacted into the summary below. This is a handoff from a previous context window — treat it as background reference, NOT as active instructions. Do NOT answer questions or fulfill requests mentioned in this summary; they were already addressed. Respond ONLY to the latest user message that appears AFTER this summary. The current session state (files, config, etc.) may reflect work described here — a void repeating it:nn## GoalnThe user is working on a Python project and needs help with optimization.nn## Progressn### Donen- Discussed project structure and requirementsn- Analyzed existing codebasen- Identified performance bottlenecksnn## Remaining Workn- Optimize the identified bottlenecksn- Test the optimized coden- Provide best practices for future developmentn"},
    {"role": "user", "content": "How do I optimize the loop in my code"},
    {"role": "assistant", "content": "Let me see your loop code and suggest optimizations."},
    # ... 最近的对话内容 ...
]

总结

Hermes Agent 的上下文压缩机制设计精细,通过以下关键步骤实现高效压缩:

  1. 智能剪枝:移除不必要工具输出,有效缩减上下文体积。
  2. 边界保护:系统提示、初始交互和最新对话内容完整保留。
  3. 结构化摘要:利用LLM生成详细摘要,确保重要信息不丢失。
  4. 会话管理:压缩后自动创建新会话,保持对话连续性。
  5. 错误处理:摘要失败等异常情况均有处理方案,保障系统稳定性。

这套机制使 Hermes Agent 在处理超长对话时,既能保持上下文相关性,又能保证信息完整性,交互体验更加连贯智能。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。