Agent 长程上下文与状态运行时:从“记忆”到可重建、可验证、可恢复的 Context Runtime 的思考与设计

核心主题:硬切窗口 + 外部状态 + 事件溯源 + 确定性状态写入 + 按需投影 + 任务预算感知的主动切窗


1. 总结先行:为什么 Agent 需要“Context Runtime”

随着 Agent 从简单问答进入 Coding Agent、Research Agent、Workflow Agent、多 Agent 协作和数小时乃至数天的长程任务,传统的“把历史对话不断塞进 Context Window”正在暴露出结构性问题:

  • 上下文窗口会耗尽;
  • 摘要压缩会丢失真正影响执行的细节;
  • 旧事实和新事实同时存在时,模型需要重新猜“哪个算数”;
  • 多 Agent 并发修改共享状态时容易产生覆盖和竞争;
  • 工具执行到一半进程崩溃后,无法判断副作用到底有没有发生;
  • 每一步都重复注入全部历史,累计输入 Token 会快速增长;
  • 即使最终任务成功,中间的 State 也可能已经漂移。

因此,本分享提出一个核心判断:

Context Window 不应该承担 Memory、State、History 和 Recovery 的全部职责。

模型运行在 Window 中,但任务运行在 Window 之外。

整个系统应该升级为一个独立的 Agent Context-State Runtime

模型负责:
理解 / 判断 / 规划 / 提出方案

Runtime 负责:
状态 / 权限 / 校验 / 持久化 / 恢复 / 上下文重建

Event Store 负责:
记录发生过什么 / 证据 / 回放

Context Runtime 负责:
决定此刻模型真正需要看到什么

最终形成一个完整闭环:

User Goal
   ↓
Agent Reason / Plan
   ↓
Tool / Action
   ↓
Deterministic Effect
   ↓
State Patch
   ↓
Validation
   ↓
Atomic Commit
   ├── Event
   └── State
   ↓
Projection / Evidence
   ↓
Context Builder
   ↓
New Model Turn

核心结论:Agent 的长期连续性不应该依赖“保留多少历史”,而应该依赖“外部系统能否重建当前任务状态”。


2. 问题背景:为什么传统 Context 管理逐渐失效

2.1 全量历史注入的问题

最直观的做法是:

Turn 1
 ↓
Turn 1 + Turn 2
 ↓
Turn 1 + Turn 2 + Turn 3
 ↓
...

随着任务变长,当前状态实际上是模型每一轮都从历史中重新“拼装”出来的。

如果每一步新增上下文规模近似稳定,而每轮都重复发送不断增长的完整历史,那么累计输入 Token 可以呈现 O(n²) 的增长趋势。

问题不仅是成本,还有注意力稀释:

旧消息
旧工具结果
旧计划
旧假设
旧状态
...
最新事实

所有信息都在竞争注意力。


3. 摘要为什么不是根本解决方案

很多系统会采用:

长历史
  ↓
Summary
  ↓
新 Context

摘要适合保留:

  • 任务大意;
  • 已完成工作;
  • 主要结论。

但 Agent 真正不能丢掉的往往是:

  • 精确参数;
  • 文件路径;
  • 订单号;
  • 工具返回值;
  • 实体 ID;
  • 当前版本号;
  • 具体约束;
  • 哪个事实被哪个事实覆盖。

这些内容可能在自然语言层面“显著性不高”,但在执行层面却非常关键。

因此:

摘要优化的是“语义大意”,而长程执行需要的是“可执行状态”。

这两个目标并不完全一致。

所以更稳妥的方式不是:

History → Better Summary

而是:

History → External State + Event Store
Context → 从外部状态重新构建

4. 上下文污染:真正危险的不是“信息太多”,而是“状态语义没有坍缩”

假设历史中出现:

item_42 在 shelf_A

后来工具执行:

item_42 移动到 shelf_B

如果两个信息继续平铺在 Context 中,模型可能看到:

shelf_A
shelf_B

然后自己判断哪个更新。

这意味着系统把一个本应由 Runtime 解决的问题重新交给了模型。

正确方式应该是:

旧事实
   ↓
superseded

新事实
   ↓
current

即:

旧状态不能只是“还存在历史里”,而必须被显式标记为失效、过期或被覆盖。


5. 核心思想:把“上下文管理”升级成 Context-State Runtime

整个系统分成几个关键角色:

┌─────────────────────────────────────────────────────┐
│                  Agent Runtime                      │
│                                                     │
│  Orchestrator / Scheduler / Window Manager         │
└──────────────┬──────────────────────────────────────┘
               │
       ┌───────┼────────┬────────────┐
       ↓       ↓        ↓            ↓
   Context    State    Event      Operation
   Runtime   Runtime   Runtime      Runtime
       │       │        │            │
       └───────┼────────┴────────────┘
               ↓
       Schema / Policy Registry

这几个概念必须严格区分。


6. 十条 Kernel Laws:整个系统最重要的边界

LAW-01

Context Window ≠ Memory

Window 是临时工作区,不是长期记忆。

LAW-02

State ≠ History

State 是当前工作状态,History 是曾经发生过什么。

LAW-03

Event Store ≠ Current State

Event 保存历史事实,State 保存当前投影。

LAW-04

Search Result ≠ Evidence

搜索只是导航,最终证据必须回到权威存储。

LAW-05

Schema Valid ≠ Fact True

结构合法不等于事实真实。

LAW-06

Tool Success ≠ World State

工具返回成功,不天然等于真实世界已经完成对应变化。

LAW-07

Model Proposal ≠ State Commit

模型只能提出,Runtime 决定是否提交。

LAW-08

Version Match ≠ Semantic Consistency

版本没冲突,不代表业务语义没冲突。

LAW-09

Window Reset ≠ Task Reset

切窗只是换工作空间,不是任务重启。

LAW-10

Crash Recovery ≠ Replay Everything

恢复必须结合 Checkpoint、Event Cursor、Operation 和 Receipt 做协调恢复。


7. State:从“变量”升级为“可验证的当前事实”

传统 State 常常只是:

fields: dict

这对于长程 Agent 不够。

建议 State 至少包含:

@dataclass
class State:
    task_id: str
    version: int

    schema_name: str
    schema_version: str

    aggregates: dict[str, AggregateState]

    goals: GoalTree
    constraints: ConstraintSet

    metadata: dict

    last_event_seq: int

8. 为什么要 Aggregate 化

多 Agent 场景下,如果整个任务只有一个 Global State Version:

Agent A ─┐
Agent B ─┼→ Global State v100
Agent C ─┘

很容易产生高竞争。

更合理的是按业务实体或 Aggregate 分区:

WarehouseTask
├── order:001
├── item:42
├── item:43
└── warehouse:A

这样:

Agent A → item:42
Agent B → item:43

就不必竞争整个任务状态。


9. State 中的 Fact 必须带 Provenance

不要只记录:

{
  "item42": "shelf_B"
}

而应该表达:

@dataclass
class Fact:
    value: Any

    status: Literal[
        "known",
        "unknown",
        "stale",
        "conflicted"
    ]

    source_event_ids: list[str]

    observed_at: datetime

    valid_from: datetime | None
    valid_to: datetime | None

例如:

{
  "item42.location": {
    "value": "shelf_B",
    "status": "known",
    "source_event_ids": ["evt_0198"],
    "observed_at": "2026-09-04T10:20:00Z"
  }
}

这样 Runtime 可以回答:

为什么现在是 shelf_B?

答案可以直接追溯到:

evt_0198

而不是让模型重新回忆。


10. UNKNOWN 是一种合法状态

这是整个系统必须严格贯彻的原则:

UNKNOWN ≠ NULL

更不能:

UNKNOWN → LLM 猜测

正确链路:

UNKNOWN
  ↓
Archive Query
  ↓
Evidence
  ↓
Verify
  ↓
Known / Stale / Conflicted / Still Unknown

如果仍然 Unknown:

→ 请求用户澄清
或
→ 转人工

这比“让模型给一个看起来合理的答案”安全得多。


11. Event Store:记录“发生过什么”

最终 Event 模型建议:

@dataclass(frozen=True)
class Event:
    event_id: str

    task_id: str
    run_id: str

    agent_id: str
    window_id: str

    seq: int

    event_type: str

    aggregate_id: str | None

    causation_id: str | None
    correlation_id: str | None

    payload: dict

    schema_version: str

    timestamp: datetime

    prev_hash: str | None
    content_hash: str

12. Event Identity 与完整性必须分开

建议:

event_id
↓
身份

推荐 UUIDv7。

content_hash
↓
内容完整性 / 去重

例如:

SHA256(canonical_event)
prev_hash
↓
链式完整性

形成:

Event1
  ↓ hash
Event2
  ↓ hash
Event3

这样 Identity、Integrity、Chain Integrity 的语义不会混在一起。


13. State 与 Event 为什么必须原子提交

一个危险的实现是:

state.commit()
event_store.append()

可能出现:

State 成功
Event 失败

最终:

State ≠ Event Log

或者反过来:

Event 成功
State 失败

因此 MVP 最推荐:

PostgreSQL Transaction

一个事务内同时提交:

BEGIN

insert event
update state_head
insert state_patch
insert receipt
insert checkpoint

COMMIT

State 是当前视图,Event 是事实轨迹;二者必须保持可恢复的一致性。


14. Model 为什么不能直接改 State

错误方式:

LLM
 ↓
JSON
 ↓
State

正确方式:

LLM
 ↓
Typed Proposal
 ↓
StatePatch
 ↓
Schema Validation
 ↓
Authority Validation
 ↓
Version Validation
 ↓
Invariant Validation
 ↓
Atomic Commit

这样才能真正实现:

让模型的随机性只用于选择和判断,让状态读写落在确定性代码里。


15. Patch:所有状态修改的唯一写路径

推荐 Operation-Based Patch:

@dataclass(frozen=True)
class StateOperation:
    op: Literal[
        "set",
        "clear",
        "append",
        "remove",
        "increment",
        "replace_if"
    ]

    path: str
    value: Any | None

Patch:

@dataclass(frozen=True)
class StatePatch:
    patch_id: str

    source: Literal[
        "tool_effect",
        "user",
        "model_proposal",
        "orchestrator"
    ]

    based_on_version: int

    operations: list[StateOperation]

    evidence_event_ids: list[str]

    requested_by: str

    created_at: datetime

禁止:

state.fields = model_output

16. Write Authority:谁可以改什么

Schema 只解决:

字段是什么。

Authority 解决:

谁可以写。

建议定义权限矩阵:

状态类型ToolUserModelOrchestrator
工具执行事实
用户目标Proposal
用户偏好Proposal
当前业务事实Confirmation
PlanProposal
Open QuestionProposal
审计字段

因此:

Schema 决定“能不能写”,Authority 决定“谁能写”。


17. Tool Effect:把“事实更新”交给代码

一个工具除了 input/output,还应该声明:

@dataclass
class ToolSpec:
    name: str

    input_schema: dict
    output_schema: dict

    reads: list[str]

    effects: list[ToolEffect]

    idempotency: Literal[
        "required",
        "optional",
        "none"
    ]

    retry_policy: RetryPolicy

例如:

move_item(item42, shelfB)

模型只负责发起动作。

Runtime 根据工具定义:

Tool Result
 ↓
ToolEffect
 ↓
StatePatch

这样,状态变化不需要再依赖模型“复述一遍”。


18. Tool Success 不等于 World State

例如:

move_item()
→ HTTP 200

不代表:

真实库存一定完成了移动

可能:

  • 外部系统异步;
  • 机械设备尚未完成;
  • 数据同步延迟;
  • 其他 Agent 已经做了竞争性修改。

所以需要:

Command
Observation
Projection

而不是简单:

Tool Result = Truth

19. Tool Receipt:为崩溃恢复做准备

新增:

@dataclass
class ToolReceipt:
    operation_id: str

    tool_name: str

    request_hash: str

    started_at: datetime
    finished_at: datetime

    status: Literal[
        "success",
        "failed",
        "timeout",
        "unknown"
    ]

    external_reference: str | None

    response_hash: str | None

这样,当进程崩溃时,Runtime 能回答:

这次副作用到底有没有发生?


20. Idempotency:避免恢复带来的重复副作用

例如:

operation_id = op_123

进程在工具调用后崩溃。

恢复时不能直接创建:

op_124

然后重新执行一次。

而应该先查:

op_123

看是否已经有 Receipt。

因此对于:

  • 扣款;
  • 发邮件;
  • 删除;
  • 创建资源;
  • 修改外部订单;

等具有真实副作用的工具,幂等键应该成为强制能力。


21. Context Projection:Context 不是 State 全量 Dump

一个成熟的 Context Runtime 不应该把整个 State 都送给模型。

例如工具声明:

reads = [
    "item_locations",
    "shelf_contents"
]

Runtime 只投影:

{
  "version": 102,
  "item_locations": {
    "item42": "shelf_B"
  },
  "shelf_contents": {
    "shelf_B": ["item42"]
  }
}

而不是把整个仓库 10,000 个实体都送进去。

最终形成:

State = 完整
Context = 最小充分切片

22. Context 分层模型

推荐把 Context 组织成:

L0 System Contract
L1 Task Contract
L2 State Projection
L3 Goals / Constraints
L4 Active Plan
L5 Recent Tool Receipts
L6 Retrieved Evidence
L7 Ephemeral Model Context

其中最关键的一个原则是:

L7

是临时上下文。

Window 切换时可以丢。

而 L0-L6 都可以通过外部系统重建。


23. Hard Rollover:窗口不是 Memory,随时可以丢

传统方式:

Context 快满
 ↓
Summary
 ↓
继续

本方案:

Context 快满
 ↓
Checkpoint
 ↓
Handoff
 ↓
关闭 Window
 ↓
丢弃模型可见历史
 ↓
从 State + Evidence + Plan 重建
 ↓
New Window

这意味着:

切掉的是 Context,不是任务。


24. Window Handoff Protocol

新旧 Window 之间不能只有一句“下面继续”。

必须存在结构化 Handoff:

@dataclass
class WindowHandoff:
    handoff_id: str

    task_id: str

    previous_window_id: str
    new_window_id: str

    state_version: int

    last_event_seq: int

    active_goal_ids: list[str]

    active_constraints: list[str]

    active_operations: list[str]

    unresolved_questions: list[str]

    required_state_paths: list[str]

    required_evidence_ids: list[str]

    recent_receipt_ids: list[str]

    checkpoint_id: str

这样,新窗口知道:

  • 当前任务目标;
  • 当前状态版本;
  • 哪些操作还没完成;
  • 当前有哪些未解决问题;
  • 需要读取哪些 State;
  • 需要带哪些证据。

25. 真正的升级:Context Budget 不应该只看“还剩多少 Token”

单纯做:

当前 Token
 ↓
超过阈值?
 ↓
切窗

只是被动式 Window Manager。

更高级的设计应该问:

如果现在继续执行,剩余窗口容量能不能覆盖未来这段工作的真实上下文需求?

这就是:

Task-Aware Proactive Context Management


26. 三级预算体系

必须区分:

Task Budget
     ↓
Phase Budget
     ↓
Window Budget
     ↓
Turn Budget

Task Budget

控制整个任务还能花多少资源。

Phase Budget

控制当前阶段还能花多少。

Window Budget

控制当前 Context Window 还能容纳多少。


27. Task Budget Model

建议:

@dataclass
class TaskBudget:
    max_input_tokens: int
    max_output_tokens: int

    max_total_tokens: int

    max_llm_calls: int
    max_tool_calls: int

    max_runtime_seconds: int

    max_cost_usd: float

再维护 Budget Ledger:

@dataclass
class BudgetLedger:
    task_input_tokens: int
    task_output_tokens: int

    task_tool_tokens: int
    task_evidence_tokens: int

    llm_calls: int
    tool_calls: int

    total_cost_usd: float

    remaining_budget: TaskBudget

28. Context Budget:窗口自己的安全余量

例如:

Context Limit = 200K
Safety Reserve = 20K
Effective Limit = 180K

如果:

Current = 175K

虽然理论上还有 25K,但真正可安全使用的空间只有:

5K

因此不应等到 200K 才切。


29. Forecast:预测未来还需要多少 Context

建议增加:

@dataclass
class BudgetForecast:
    estimated_input_tokens: int
    estimated_output_tokens: int

    estimated_tool_tokens: int
    estimated_evidence_tokens: int

    estimated_future_turns: int

    confidence: float

比如当前:

Window Remaining = 40K

但是当前任务马上进入:

读取 8 个文件
执行 6 个工具
生成测试
修复 3 次

预测需要:

Forecast = 72K

那么:

40K < 72K

应该主动切窗。


30. Context Decision Engine

最终新增:

Context Meter
       │
       ├── Current Usage
       ├── Safe Remaining
       └── Token Trend
              │
              ▼
Budget Manager ─────── Task / Phase Budget
              │
              ▼
Forecast Engine ────── Future Work Estimate
              │
              ▼
Decision Engine
              │
       ┌──────┼────────┬────────────┐
       ↓      ↓        ↓            ↓
   CONTINUE  TRIM  PREPARE       ROLLOVER

31. 四级 Context 水位

建议不要只有 80% / 100%。

定义:

GREEN
YELLOW
ORANGE
RED

示意:

0 ───── 60% ───── 75% ───── 90% ───── 100%
        GREEN      YELLOW     ORANGE      RED

GREEN

正常运行。

YELLOW

开始减少低价值临时内容。

ORANGE

进入 Handoff 准备状态。

RED

禁止继续普通模型推理,必须切窗。


32. 什么时候主动切窗

建议至少存在五类 Trigger。

Trigger 1:Hard Limit

Current >= SafeLimit

必须切。

Trigger 2:Forecast

SafeRemaining < ForecastNeed

提前切。

Trigger 3:Phase Boundary

例如:

Repository Discovery
→
Implementation

即使 Context 很空,也可以主动切,因为任务语义发生了阶段转换。

Trigger 4:Semantic Density

Context 虽然没有超限,但低价值历史越来越多,Signal / Noise Ratio 明显下降。

可以主动切。

Trigger 5:Recovery Boundary

某个稳定 Checkpoint 完成后,主动切换成一个干净窗口,为下一阶段降低历史负担。


33. Rollover 不应该是“瞬时关机”

推荐采用:

Graceful Rollover

流程:

ORANGE
 ↓
冻结非关键执行
 ↓
生成 Checkpoint
 ↓
生成 Handoff
 ↓
完成当前安全边界
 ↓
关闭 Window
 ↓
创建 New Window
 ↓
重建 Context
 ↓
继续执行

这样不会在任意一个危险中间点强制截断。


34. 任务阶段感知是主动切窗的第二个核心

例如 Coding Agent:

Phase 1  Repository Discovery
Phase 2  Architecture Analysis
Phase 3  Implementation
Phase 4  Testing
Phase 5  Debugging
Phase 6  Final Verification

当:

Architecture Analysis
→
Implementation

发生时,即使当前 Window 仍有大量空间,也可以主动切窗。

原因不是 Token 不够,而是:

新的工作阶段需要不同的信息密度和上下文组成。


35. LLM 可以参与 Forecast,但不能拥有最终决策权

可以让模型提出:

“预计下一阶段还需要 5~8 次工具调用。”

但不能让模型决定:

“我觉得现在应该换窗口。”

正确方式:

LLM Forecast / Proposal
         ↓
Runtime Validation
         ↓
Budget Calculation
         ↓
Runtime Decision

这样才能保持系统的确定性边界。


36. Context Decision Algorithm

第一版无需机器学习,直接使用规则即可:

def decide_context_action(
    current_tokens: int,
    context_limit: int,
    forecast_need: int,
    safety_margin: int,
    phase_boundary: bool,
    critical_operation: bool,
):
    safe_limit = context_limit - safety_margin
    remaining = safe_limit - current_tokens

    if current_tokens >= safe_limit:
        return "ROLLOVER"

    if critical_operation:
        return "CONTINUE"

    if phase_boundary:
        return "PREPARE_ROLLOVER"

    if remaining < forecast_need:
        return "PREPARE_ROLLOVER"

    if remaining < forecast_need * 0.5:
        return "TRIM"

    return "CONTINUE"

这是一个非常重要的工程原则:

能用确定性规则解决的问题,不要先交给模型。


37. Plan 必须与 State 分离

原设计中 Notes 容易把:

事实
计划

混在一起。

最终应该拆开:

Fact
   ↓
State

Evidence
   ↓
Archive

Plan
   ↓
Planning Layer

模型可以生成:

Plan Proposal

但必须经过 Runtime 接受后才能成为:

Accepted Plan

38. Plan Model

@dataclass
class Plan:
    plan_id: str

    goal_id: str

    status: Literal[
        "proposed",
        "accepted",
        "executing",
        "blocked",
        "completed",
        "cancelled"
    ]

    steps: list[PlanStep]

    created_by: str

    based_on_state_version: int

因此形成:

Fact
≠
Evidence
≠
Plan

这三个概念不能混在同一份“Memory”里。


39. Archive:搜索、检索、验证必须分离

原方案建议 Elasticsearch 作为 Archive Retrieval。

更严谨的架构应该是:

Event Store
    ↓
Async Indexer
    ↓
Search Index
    ↓
Search
    ↓
Retrieve from Event Store
    ↓
Verify
    ↓
Evidence

所以:

Search Engine 是导航系统,不是事实系统。

推荐:

PostgreSQL
→ Source of Truth

OpenSearch / Elasticsearch
→ Secondary Index

40. Supersession:历史事实必须知道自己是否已失效

例如:

event_100
item42 = shelf_A

之后:

event_110
item42 = shelf_B
supersedes = event_100

那么 Runtime 能明确区分:

Historical Fact
Current Fact
Superseded Fact
Conflicted Fact

而不需要把所有历史送给模型后让模型自行判断。


41. Multi-Agent:共享 State 必须受控

不要:

Agent A ─┐
Agent B ─┼→ Mutable Global State
Agent C ─┘

推荐:

             Orchestrator
                  │
         Global Task State
                  │
      ┌───────────┼───────────┐
      ↓           ↓           ↓
   Agent A     Agent B     Agent C
      │           │           │
 Local State  Local State  Local State
      └───────────┼───────────┘
                  ↓
           Commit Protocol
                  ↓
           Global State

42. Multi-Agent 冲突不是只有 Version Conflict

建议至少分成:

L0 Version Conflict
L1 Field Conflict
L2 Invariant Conflict
L3 Semantic Conflict

例如:

Agent A:
customer.risk = low

Agent B:
customer.risk = high

可能两个 Patch 都结构合法、版本也没问题。

这时不是 CAS 能解决的,而是:

Evidence
+
Policy
+
Arbitration

43. Arbitration:最后一道安全网

建议优先级:

1. 强证据
2. 最新有效事实
3. 权威来源
4. 领域规则
5. Human Review
6. Model Judgment

不要使用:

Last Write Wins

来粗暴解决所有语义冲突。


44. Recovery:长程 Agent 必须是“可恢复执行系统”

恢复链路:

Process Crash
      ↓
Load Latest Checkpoint
      ↓
Load State Snapshot
      ↓
Read Event Cursor
      ↓
Find Unfinished Operations
      ↓
Check Tool Receipts
      ↓
Reconcile External Side Effects
      ↓
Apply Missing Events / State
      ↓
Rebuild Handoff
      ↓
Resume Agent

45. Recovery Kill Point Matrix

不能只测试“随便 kill 一次”。

应该至少覆盖:

K1 模型请求前
K2 Tool Request 后
K3 Tool Started 后
K4 Tool Success 后
K5 Receipt 写入后
K6 State Patch 后
K7 Event Commit 后
K8 Checkpoint 后
K9 Window Closing

每个 Kill Point 都要验证:

  • 是否能恢复;
  • 是否重复副作用;
  • State 是否正确;
  • Event 是否一致;
  • Window 是否可以重建。

46. Context Pollution 测试

构造:

event_10
item42 = shelf_A

 event_30
item42 = shelf_B
supersedes event_10

旧窗口历史摘要:
item42 在 shelf_A

系统最终应该给模型:

item42 = shelf_B
status = CURRENT
source = event_30

而不是把:

shelf_A
shelf_B

都作为平等信息塞进去。


47. Evaluation:不能只看最终 Task Success

完整评测应该覆盖五个层次:

Task Level
State Level
Event Level
Context Level
Recovery Level

核心指标:

指标含义
State Fidelity当前 State 与 Ground Truth 的一致率
State Probe Accuracy中途状态问答准确率
Stale State Survival Rate旧状态错误存活概率
Conflict Detection Rate冲突识别比例
Recovery Completion崩溃恢复后任务完成率
Duplicate Side Effect Rate恢复导致的重复副作用比例
Input Token / Step每一步平均输入 Token
Input Token / Task每任务累计输入 Token
Rollover Recovery Accuracy新窗口重建后的状态准确率
Patch Rejection Rate无效 Patch 被拦截比例
Arbitration Rate需要语义仲裁的比例

48. Ablation Study:证明每个机制到底有没有价值

建议按阶梯运行:

A  全历史注入
B  滚动窗口
C  摘要压缩
D  C + State Materialization
E  D + Tool Effect
F  E + Context Projection
G  F + Archive Retrieval
H  G + Provenance
I  H + Idempotent Recovery
J  I + Multi-Agent Conflict Control

最终比较:

Token
Accuracy
Task Success
Recovery
Conflict
Pollution Resistance

这样可以回答一个非常重要的问题:

到底是哪一个机制真正带来了收益?


49. 技术栈建议:不要一上来堆满基础设施

MVP

Python 3.12+
Pydantic 2
PostgreSQL
OpenTelemetry

第二阶段

Redis

只用于:

  • Cache;
  • 短期协调;
  • Lock;
  • 临时热点数据。

不要让 Redis 成为唯一 Source of Truth。

第三阶段

OpenSearch / Elasticsearch

作为 Search Index。

高规模阶段

按真实工作负载再考虑:

Kafka
Temporal
Object Storage

50. 推荐工程目录

agent-context-runtime/
│
├── runtime/
│   ├── orchestrator.py
│   ├── scheduler.py
│   ├── lifecycle.py
│   └── recovery.py
│
├── task/
│   ├── model.py
│   ├── lifecycle.py
│   └── repository.py
│
├── window/
│   ├── model.py
│   ├── manager.py
│   ├── rollover.py
│   └── handoff.py
│
├── state/
│   ├── model.py
│   ├── aggregate.py
│   ├── fact.py
│   ├── patch.py
│   ├── authority.py
│   ├── invariants.py
│   ├── provenance.py
│   ├── projection.py
│   └── migration.py
│
├── event/
│   ├── model.py
│   ├── store.py
│   ├── sequence.py
│   ├── hash_chain.py
│   └── replay.py
│
├── operation/
│   ├── model.py
│   ├── executor.py
│   ├── idempotency.py
│   └── receipt.py
│
├── tool/
│   ├── registry.py
│   ├── spec.py
│   ├── execution.py
│   └── effects.py
│
├── plan/
│   ├── model.py
│   ├── planner.py
│   └── validator.py
│
├── evidence/
│   ├── model.py
│   ├── search.py
│   ├── retrieve.py
│   ├── verify.py
│   └── supersession.py
│
├── agent/
│   ├── base.py
│   ├── subagent.py
│   ├── commit.py
│   └── arbitration.py
│
├── context/
│   ├── builder.py
│   ├── projector.py
│   ├── budget.py
│   ├── meter.py
│   ├── forecast.py
│   ├── decision.py
│   ├── phase.py
│   ├── rollover.py
│   └── handoff.py
│
├── schema/
│   ├── registry.py
│   ├── versions.py
│   └── migration.py
│
├── storage/
│   ├── postgres.py
│   ├── repositories/
│   └── migrations/
│
├── observability/
│   ├── tracing.py
│   ├── metrics.py
│   └── logging.py
│
├── evaluation/
│   ├── ablation.py
│   ├── probe.py
│   ├── pollution.py
│   ├── recovery.py
│   ├── concurrency.py
│   └── chaos.py
│
└── tests/
    ├── unit/
    ├── integration/
    ├── contract/
    ├── recovery/
    ├── concurrency/
    └── chaos/

51. 实施路线图:按“确定性核心 → 上下文 → 多 Agent”推进

Phase 0:Contract Freeze

先冻结:

Task Schema
State Schema
Event Schema
Patch Schema
Tool Contract
Operation Contract
Receipt Contract
Handoff Contract
Error Codes

Phase 1:Deterministic Core

实现:

Event
State
Aggregate
Patch
Schema
Invariant
Repository
Transaction
Replay

Phase 2:Tool Runtime

实现:

Tool Registry
Tool Execution
ToolEffect
Operation
Receipt
Idempotency

Phase 3:Recovery

实现:

Checkpoint
Crash Recovery
Reconciliation
Replay

Phase 4:Context Runtime

实现:

Projection
Budget
Meter
Forecast
Decision
Handoff
Hard Rollover

Phase 5:Archive

实现:

Search
Retrieve
Verify
Supersession
Evidence

Phase 6:Multi-Agent

实现:

Local State
Aggregate Concurrency
Commit Protocol
Conflict
Arbitration

Phase 7:Evaluation / Chaos

实现:

Ablation
Probe
Pollution
Recovery
Concurrency
Chaos

52. 最终 Definition of Done

State

  • 所有状态修改都经过 Patch;
  • 未注册字段不能写入;
  • Authority 校验有效;
  • Invariant 校验有效;
  • Provenance 可追踪;
  • UNKNOWN 不会转化为模型猜测。

Event

  • Event 不可变;
  • event_id 唯一;
  • content_hash 可验证;
  • prev_hash 可验证;
  • Event Replay 可以恢复状态。

Tool

  • 外部副作用有 operation_id;
  • 有 Tool Receipt;
  • 有幂等机制;
  • 超时可进入恢复流程。

Context

  • 不依赖完整历史;
  • 支持 Projection;
  • 支持 Budget;
  • 支持 Forecast;
  • 支持主动 Rollover;
  • 新 Window 可以独立重建。

Multi-Agent

  • Agent 不直接修改 Global State;
  • Shared Aggregate 有并发控制;
  • Semantic Conflict 可以进入 Arbitration。

Recovery

  • 多 Kill Point 全覆盖;
  • Tool Success + Process Crash 可恢复;
  • 不产生重复外部副作用。

53. 最终总结:这到底解决了什么问题

如果把传统 Agent 长程任务抽象成:

History
  ↓
LLM
  ↓
Guess Current State
  ↓
Next Action

那么问题在于:

模型每一轮都在重新猜“现在世界是什么样”。

而 Context-State Runtime 的目标是把它改成:

External State
      ↓
State Projection
      ↓
LLM
      ↓
Decision / Plan
      ↓
Tool / Operation
      ↓
Deterministic Effect
      ↓
Validated State Update
      ↓
Event + Checkpoint
      ↓
Context Reconstruction

于是模型不再负责维护世界状态,而只负责:

理解
判断
规划
选择

Runtime 负责:

事实
状态
权限
一致性
持久化
恢复
预算
上下文重建

54. 最重要的四个升级

这套方案最终不是简单的“Agent Memory”。

它完成了四个重要升级:

升级一:从 History-centric 到 State-centric

过去:
History → Model → Guess State

现在:
State → Context → Model

升级二:从被动切窗到主动切窗

过去:
Context 快满 → 被迫切窗

现在:
Context Balance
+
Task Budget
+
Phase
+
Forecast
+
Safety Margin
→
提前决定是否切窗

升级三:从“模型写记忆”到“Runtime 写状态”

过去:
LLM → Memory

现在:
LLM → Proposal
Runtime → Validate → Commit

升级四:从“长上下文系统”到“Agent Execution Substrate”

最终架构已经具备:

Context
+
State
+
Event
+
Operation
+
Budget
+
Recovery
+
Multi-Agent Coordination

这已经不只是一个 Memory Layer,而是一个:

Agent Context-State Runtime


55. 最后的核心公式

整套系统可以最终浓缩成下面这组公式:

Context Continuity
≠
Conversation Continuity

而是:

Context Continuity
=
State Reconstruction
+
Evidence Reconstruction
+
Plan Reconstruction
+
Window Handoff

窗口切换的决策也不应该是:

Current Tokens > Limit

而应该是:

Rollover Decision
=
Context Remaining
+
Task Remaining Budget
+
Phase Budget
+
Future Work Forecast
+
Safety Margin
+
Phase Boundary
+
Pending Operations
+
Rollover Cost

最终真正的系统哲学是:

模型决定“下一步做什么”,Runtime 决定“现在是什么状态”;模型提出,Runtime 验证;Event 保存事实,State 表示当前;Context 随时可以丢弃,任务始终可以重建。

这才是长程 Agent 从“会话式 AI”走向“工程化执行系统”的关键一步。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐