【AI Agent】Agent 长程上下文与状态运行时-技术思考
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 解决:
谁可以写。
建议定义权限矩阵:
| 状态类型 | Tool | User | Model | Orchestrator |
|---|---|---|---|---|
| 工具执行事实 | ✅ | ❌ | ❌ | ✅ |
| 用户目标 | ❌ | ✅ | Proposal | ✅ |
| 用户偏好 | ❌ | ✅ | Proposal | ✅ |
| 当前业务事实 | ✅ | Confirmation | ❌ | ✅ |
| Plan | Proposal | ✅ | ✅ | ✅ |
| Open Question | Proposal | ✅ | ✅ | ✅ |
| 审计字段 | ❌ | ❌ | ❌ | ✅ |
因此:
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”走向“工程化执行系统”的关键一步。
更多推荐


所有评论(0)