← 全部公开手记 / AGENT HARNESS

长链路代码智能体的分层记忆调度与容错设计

在大模型智能体 (Autonomous Agent) 执行复杂工程任务时,最容易遭遇的瓶颈并非单步推理能力的不足,而是在 长链路连续工具调用 (Multi-turn Tool Interaction) 下的上下文退化状态漂移

以 SWE-bench 这类真实仓库级评测为例,一个典型的 Bug 修复往往包含 15 到 40 步环境探测、AST 检索、代码重写与回归测试。如果毫无节制地把全部 stdout、工具返回与原始文件灌入 Prompt,上下文窗口不仅迅速被稀释,模型还极易产生幻觉与决策死循环。

本文复盘我们在 MiniCodeAgent 中落地的分层记忆架构 (Hierarchical Memory)幂等状态检查点 (Zero-Drift Checkpointing) 设计。


01 / 问题症结:为什么传统单层记忆会失效?

传统 Agent 通常将对话历史作为单一线性队列(FIFO)进行维护。在短对话场景中,这种模式足够简单;但在长链路代码场景下,暴露出三大致命缺陷:

  1. 上下文信噪比雪崩:一次 grepgit diff 可能返回上千行输出,其中只有 3 行是关键定位信息。其余冗余行快速占满 Token 窗口,稀释系统指令的注意力权重。
  2. 记忆覆盖与回溯困难:当第 8 步尝试的方向被证明是死胡同时,模型需要回退到第 3 步重新思考。若记忆是线性的,模型很难“选择性遗忘”错误路径,常在已确认无效的方案上反复挣扎。
  3. 工具链异常级联:单次工具执行超时或编译语法错误时,如果没有状态隔离机制,错误信息会污染后续的 Plan 生成,引发连锁崩塌。

02 / 系统架构:L1 工作记忆与 L2 经验拓扑

为了解决上述问题,我们设计了分层解耦的记忆体系:

+----------------------------------------------------------------+
|                         LLM Planner                            |
+----------------------------------------------------------------+
             |                                    ^
             | Active Window (Pruned)             | Semantic Recall
             v                                    |
+--------------------------+        +----------------------------+
| L1 Working Memory        |        | L2 Epistemic Memory        |
| - Recent 3 Action Traces | <----> | - Symbol Graph Index       |
| - Current AST Focus Diff |        | - Dense Vectors (BGE-M3)   |
| - Task Goal Constraint   |        | - Historical Failed Tracks |
+--------------------------+        +----------------------------+
             |                                    |
             +----------------+-------------------+
                              |
                              v
                [ Sandbox Execution & Checkpoint ]

1. L1 活跃工作记忆 (L1 Working Memory)

  • 容量上限:严格限制在 4k - 8k Token 之间。
  • 存储内容:包含当前任务核心约束、最近 3 步的原子操作意图、以及经 Tree-sitter AST 过滤后的核心代码上下文(仅保留被修饰函数的定义域,剥离无关结构)。
  • 生命周期:随步骤动态滑动与修剪,确保注意力始终聚焦在当前目标。

2. L2 经验索引记忆 (L2 Epistemic Memory)

  • 存储内容:全量操作日志、历史探测过的文件路径指纹、以及已证伪的假设 (Negative Hypotheses)
  • 检索调度:采用 BM25 + BGE-M3 双路混合检索。当 Planner 准备提出新假设时,优先在 L2 中查询相似度,若发现历史已尝试且失败,直接注入反思约束拦截死循环。

03 / 容错保障:幂等状态检查点 (Zero-Drift Checkpointing)

为了防止长链路执行过程中的“一步错、步步错”,我们引入了类似数据库事务的检查点恢复机制

class AgentCheckpoint:
    def __init__(self, step_id: int, snapshot_hash: str):
        self.step_id = step_id
        self.snapshot_hash = snapshot_hash
        self.workspace_diff = None

    def rollback(self, sandbox_env):
        """回滚代码工作区至上一稳定检查点,并记录负反馈"""
        sandbox_env.git_reset_hard(self.snapshot_hash)
        sandbox_env.memory.record_negative_feedback(
            f"Rollback to step {self.step_id}: previous patch failed verification."
        )
  • 原子隔离:每次代码修改均在临时分支与沙箱容器中进行,只有当轻量级语法检查(Lint)通过后,才生成持久化 Checkpoint。
  • 自适应回滚:当连续 2 次测试未通过时,Agent 不会在污染的代码上继续“打补丁”,而是强制触发回滚,从前一个稳定状态重新分叉规划。

04 / 基准实测与总结

在 SWE-bench 子集与自建代码库评测中,引入分层记忆与检查点机制后,系统呈现出显著提升:

  • 有效上下文压缩率:整体 Prompt 冗余 Token 降低约 68%
  • 长链路死循环率:由于 L2 负向经验约束的介入,无效重复尝试降低了 74%
  • 单任务端到端成功率:在多文件协同修改场景中提升明显。

真正的工程深度,往往不在于接入了多么前沿的 API,而在于面对不可控、长链路的不确定性系统时,用严谨的拓扑设计与工程兜底,构建起可靠的确定性边界。

把真实的思考与工程选择记录下来,持续迭代。

欢迎就本文提到的架构权衡、技术决策或代码实现展开交流探讨。

← 返回手记列表
已复制到剪贴板