Table of contents
Open Table of contents
- 1. 为什么
messages[]不足以支撑工业级 Agent - 2. 三层模型:Event、State、Context
- 3. Event Sourcing 思维为什么适合 Agent
- 4. Event 设计:不要把所有东西都叫 Message
- 5. 推荐 Event 数据结构
- 6. State Reducer:从事件推导状态
- 7. 为什么 Derived State 很重要
- 8. Crash Consistency:事件什么时候写入
- 9. Tool 执行恢复与幂等性
- 10. Checkpoint:是否还需要
- 11. Checkpoint 和 Compaction 不是一回事
- 12. Context Projection:Event 不应该全部进入模型
- 13. Session 与 Context 的边界
- 14. Compaction 应该产生 Event
- 15. Steering 也应该是一等 Event
- 16. Resume:恢复的是 Session,不只是 Messages
- 17. Replay:不是简单重新调用模型
- 18. Deterministic Replay 的边界
- 19. Fork:从某个历史点分叉
- 20. Fork 的存储模型
- 21. Event Causality:并发 Tool 后顺序怎么办
- 22. 推荐 Tool Event 链
- 23. Session Status 应该显式存在
- 24. Session 与 Agent Loop 的职责边界
- 25. 推荐 Session API
- 26. Session Store:从内存到持久化
- 27. 为什么 Append-only 很重要
- 28. 但 Event Log 也不是万能的
- 29. Event Schema Versioning
- 30. Secret / Sensitive Data Redaction
- 31. Observability:Event Log 天然是 Trace 来源
- 32. Session Model 与 Eval 的关系
- 33. 推荐的完整 Session 架构
- 34. 推荐实践:自己实现一个 SessionStore
- 35. 本章必答的 18 个问题
- 36. 与下一篇 Context Management 的衔接
- 37. 一句话总纲
1. 为什么 messages[] 不足以支撑工业级 Agent
最小 Agent 通常直接维护:
messages = [
{"role": "system", "content": "..."},
{"role": "user", "content": "..."},
{"role": "assistant", "tool_calls": [...]},
{"role": "tool", "content": "..."},
]
对于 Demo,这已经足够。
但一旦 Agent 进入长期运行,就会遇到:
用户中途 Steering
Tool 执行中断
Permission Pending
Permission Denied
Session Resume
Context Compaction
Tool Retry
并发 Tool Call
Subagent
Checkpoint
模型输出部分成功
进程崩溃恢复
审计与 Replay
这些信息并不天然适合被压进一串模型消息。
例如:
用户拒绝某个 Tool
模型最终可能只需要看到:
Tool execution was denied.
但 Runtime 还需要知道:
谁拒绝的?
什么时候拒绝的?
哪条 Policy 命中?
原 Tool Call 参数是什么?
是否允许后续重新申请?
因此:
模型需要看到的 Context,只是 Session 事实的一种投影,而不是 Session 本身。
2. 三层模型:Event、State、Context
这是整篇最重要的心智模型。
flowchart TD
A["Session Event Log<br/>真实发生过的事实"]
B["State Reducer<br/>根据事件推导当前状态"]
C["Derived Agent State<br/>当前运行状态"]
D["Context Builder<br/>为下一次模型调用选择与组织信息"]
E["Model-visible Context<br/>messages / tools / instructions"]
A --> B
B --> C
C --> D
A --> D
D --> E2.1 Event Log:发生过什么
事件是不可变事实,例如:
UserMessage
AssistantMessage
ToolCallRequested
PermissionRequested
PermissionGranted
PermissionDenied
ToolExecutionStarted
ToolExecutionCompleted
ToolExecutionFailed
SteeringReceived
CompactionCreated
CheckpointCreated
SessionSuspended
SessionResumed
CancellationRequested
2.2 Derived State:现在是什么状态
例如:
当前用户目标
当前 step
哪些 Tool Call 正在执行
哪些 Tool Call 已完成
是否等待用户审批
是否存在 Steering
最近一次 Compaction
当前 Token Budget
是否处于 Suspended
这些状态可以从 Event Log 推导,而不一定需要作为独立“事实”反复写入。
2.3 Context:模型下一步应该看到什么
Context Builder 决定:
System Instructions
Project Instructions
Relevant Conversation
Current Goal
Recent Tool Results
Compacted History
Pending Constraints
Latest Steering
Tool Schemas
最终转换成模型 API 所需要的:
messages
tools
metadata
Session State 和 Model Context 不能混为一谈。
Runtime 可以知道很多信息,但模型不一定需要全部看到。
3. Event Sourcing 思维为什么适合 Agent
Agent 天然是一个事件密集型系统:
用户输入
↓
模型响应
↓
Tool Call
↓
Permission
↓
执行
↓
Tool Result
↓
下一轮推理
所以采用 Append-only Event Log 有明显优势。
flowchart TD
A["Append Event"]
B["Persist Event"]
C["Update Derived State"]
D["Emit Trace / Metrics"]
E["Build Next Context"]
F["Continue Agent Loop"]
A --> B
B --> C
C --> D
D --> E
E --> F它允许把:
状态推进
持久化
审计
调试
上下文构建
回放
建立在同一组事实之上。
4. Event 设计:不要把所有东西都叫 Message
一个常见坏味道是:
Everything = Message
结果:
Permission
Tool Runtime
Checkpoint
Compaction
Cancellation
都被强行伪装成对话消息。
更合理的 Event Taxonomy 可以拆成几类。
4.1 Conversation Events
UserMessage
AssistantMessage
SystemObservation
SteeringReceived
这些事件可能直接影响模型上下文。
4.2 Tool Lifecycle Events
ToolCallRequested
ToolCallValidated
ToolExecutionStarted
ToolExecutionCompleted
ToolExecutionFailed
ToolExecutionCancelled
ToolExecutionTimedOut
这些事件描述真实执行生命周期。
4.3 Permission Events
PermissionRequested
PermissionGranted
PermissionDenied
PermissionExpired
4.4 Context Events
CompactionStarted
CompactionCompleted
ContextPruned
SummaryCreated
4.5 Session Lifecycle Events
SessionCreated
SessionSuspended
SessionResumed
CheckpointCreated
SessionCompleted
SessionFailed
4.6 Runtime / Governance Events
RetryScheduled
LoopDetected
CancellationRequested
PolicyViolation
SandboxViolation
Event 类型越明确,后续 Observability、Eval、Replay 越容易做。
不要只存一个:
{"type": "error", "message": "..."}然后让所有后处理系统猜它到底是什么错误。
5. 推荐 Event 数据结构
一个 Event 至少应该具备:
@dataclass
class SessionEvent:
event_id: str
session_id: str
seq: int
type: str
timestamp: float
payload: dict
parent_event_id: str | None = None
correlation_id: str | None = None
核心字段含义:
| 字段 | 作用 |
|---|---|
event_id | 全局唯一标识 |
session_id | 所属 Session |
seq | Session 内严格排序 |
type | 事件类型 |
timestamp | 时间 |
payload | 事件数据 |
parent_event_id | 因果关系 |
correlation_id | 把一次 Tool Call / Retry / Approval 链路串起来 |
对于 Agent Runtime 来说,seq 往往比时间戳更关键,因为:
时间相近不代表逻辑顺序,Session 状态恢复需要确定的事件顺序。
6. State Reducer:从事件推导状态
可以把 State Reducer 理解成:
state = reduce(events)
它的职责不是“调用模型”,而是:
根据发生过的事实
↓
得到现在的 Runtime 状态
例如:
@dataclass
class AgentState:
status: str
step: int
pending_tool_calls: dict
running_tool_calls: dict
completed_tool_calls: dict
pending_approval: dict | None
latest_user_goal: str | None
latest_steering: str | None
last_compaction_event_id: str | None
Reducer:
def reduce_event(state, event):
if event.type == "ToolExecutionStarted":
state.running_tool_calls[event.payload["call_id"]] = event.payload
elif event.type == "ToolExecutionCompleted":
call_id = event.payload["call_id"]
state.running_tool_calls.pop(call_id, None)
state.completed_tool_calls[call_id] = event.payload
elif event.type == "PermissionRequested":
state.pending_approval = event.payload
elif event.type == "PermissionGranted":
state.pending_approval = None
elif event.type == "SteeringReceived":
state.latest_steering = event.payload["content"]
return state
7. 为什么 Derived State 很重要
如果把所有状态都直接修改:
session.pending_tool = ...
session.status = ...
session.messages.append(...)
session.permission = ...
系统崩溃后你必须相信:
内存中的这些字段一定全部同步成功
而 Event Log 思路是:
事实先落盘
↓
状态由事实推导
因此恢复时:
flowchart TD
A["Load Session Events"]
B["Replay Events"]
C["Rebuild Derived State"]
D["Detect Incomplete Operations"]
E["Apply Recovery Policy"]
F["Resume Agent"]
A --> B
B --> C
C --> D
D --> E
E --> F8. Crash Consistency:事件什么时候写入
这是生产级 Session 很关键的细节。
例如:
Agent 决定执行 Tool
↓
Tool 实际执行成功
↓
Harness 崩溃
↓
ToolResult 尚未写入 Session
恢复后系统看到:
ToolCallRequested
但不知道:
Tool 到底有没有执行成功?
这是典型的 Unknown Outcome。
因此 Tool Lifecycle 最好显式记录:
ToolCallRequested
↓
ToolExecutionStarted
↓
ToolExecutionCompleted
而不是只有:
ToolCall
↓
ToolResult
9. Tool 执行恢复与幂等性
恢复时最危险的是:
不知道 Tool 是否已经产生副作用
比如:
发送邮件
创建 GitHub Issue
删除文件
创建云资源
提交订单
不能简单:
if no ToolResult:
retry()
更合理的流程:
flowchart TD
A["恢复 Session"]
B["发现 ToolExecutionStarted<br/>但没有 Completed"]
C{"Tool 是否 Read-only / Idempotent?"}
D["安全重试"]
E["检查 Operation ID / External State"]
F{"可以确认结果?"}
G["补写 Completed Event"]
H["标记 Unknown Outcome"]
I["请求用户 / Policy 决策"]
A --> B
B --> C
C -- "Yes" --> D
C -- "No" --> E
E --> F
F -- "Yes" --> G
F -- "No" --> H
H --> IResume 不等于 Retry。
Resume 首先要做的是恢复事实与状态,然后根据 Tool 的副作用性质决定下一步。
10. Checkpoint:是否还需要
如果已经有完整 Event Log,理论上可以从第一个 Event 一路 Replay。
但 Session 很长以后:
10 万 Event
每次都从头 Reduce 会很昂贵。
因此可以加入 Checkpoint:
Event 1
Event 2
...
Event 5000
↓
Checkpoint
↓
Event 5001
Event 5002
...
恢复时:
Load Latest Checkpoint
↓
Replay Events After Checkpoint
↓
Current State
11. Checkpoint 和 Compaction 不是一回事
这两个概念很容易混淆。
| 概念 | 面向谁 | 目的 |
|---|---|---|
| Checkpoint | Runtime | 快速恢复状态 |
| Compaction | Model Context | 减少模型上下文体积 |
Checkpoint 保存的可能是:
pending tool calls
permission state
session status
latest event seq
runtime metadata
Compaction 保存的是:
任务摘要
重要历史
关键文件修改
未解决问题
因此:
Checkpoint 是 Runtime State Optimization;Compaction 是 Context Optimization。
12. Context Projection:Event 不应该全部进入模型
Session 可能有:
PermissionRequested
PermissionGranted
ToolExecutionStarted
Trace Metadata
RetryScheduled
SandboxProfile
CheckpointCreated
模型并不需要看到这些全部事实。
Context Builder 应该把 Runtime Event 转换为模型有用的信息。
例如:
PermissionRequested
PermissionDenied
可以投影成:
Tool execution was denied by user policy.
Choose a safer alternative.
这就是:
flowchart TD
A["Runtime Events"]
B["Filter"]
C["Transform"]
D["Prioritize"]
E["Compact / Prune"]
F["Model-visible Messages"]
A --> B
B --> C
C --> D
D --> E
E --> F13. Session 与 Context 的边界
推荐强制建立这条规则:
Session can be richer than Context.
例如 Session 可以保存:
完整 Tool 输出
完整 Diff
完整 Trace
Permission Metadata
Sandbox Metadata
Token Metrics
Timing Metrics
但 Context 只选择:
下一步推理真正需要的信息
这样才能做到:
可审计
+
可恢复
+
上下文受控
而不是为了节省 Token 直接丢掉历史事实。
14. Compaction 应该产生 Event
如果系统进行了 Context Compaction,不应该悄悄把:
旧 messages
直接替换掉。
更合理的是记录:
CompactionCompleted
{
source_event_range,
summary,
strategy,
token_before,
token_after
}
这样:
Runtime 历史仍然完整
↓
Context 可以选择 Summary
因此:
Compaction 不应该破坏 Session 的事实历史。
15. Steering 也应该是一等 Event
用户中途说:
不要修改 auth.py,只改调用方。
这不是普通聊天消息那么简单。
它会影响:
当前 Goal
当前 Plan
正在执行的 Tool
后续 Context
因此推荐:
SteeringReceived
作为显式事件。
处理流程:
flowchart TD
A["Agent Running"]
B["SteeringReceived"]
C["Persist Event"]
D["Update Derived Intent"]
E{"当前 Tool 是否可取消?"}
F["Cancel / Interrupt"]
G["等待安全结束"]
H["Rebuild Context"]
I["Next Inference"]
A --> B
B --> C
C --> D
D --> E
E -- "Yes" --> F
E -- "No" --> G
F --> H
G --> H
H --> I16. Resume:恢复的是 Session,不只是 Messages
最简单的 Resume:
messages = load_messages()
continue_loop()
只适用于没有复杂 Runtime 状态的 Agent。
工业级 Resume 至少需要恢复:
Last Event Seq
Current Session Status
Pending Approval
Running / Unknown Tool Calls
Latest Goal
Latest Steering
Last Compaction
Checkpoint
Cancellation State
推荐流程:
flowchart TD
A["Load Session"]
B["Load Latest Checkpoint"]
C["Replay Later Events"]
D["Rebuild Derived State"]
E["Detect Incomplete Operations"]
F["Run Recovery Policy"]
G["Rebuild Model Context"]
H["Resume Agent Loop"]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
G --> H17. Replay:不是简单重新调用模型
Replay 可以有两种不同含义。
17.1 State Replay
只重放 Event:
Events
↓
Reducer
↓
Derived State
目的是:
恢复状态
调试
审计
不重新调用模型。
17.2 Execution Replay
真正重新运行:
模型
Tool
Sandbox
目的是:
复现实验
回归测试
Eval
但由于模型输出可能非确定,Execution Replay 不一定生成完全相同结果。
因此:
State Replay 可以高度确定;Agent Execution Replay 通常只能做到“环境与输入可复现”,不能保证模型路径完全一致。
18. Deterministic Replay 的边界
如果希望最大程度复现一次 Agent 行为,需要固定:
Model Version
Prompt / Context
Tool Schemas
Repository Commit
Environment Image
Dependency Versions
Sandbox Policy
Random Seed(若支持)
Tool Outputs / External Responses
但仍然要承认:
Remote Model Service
Network
External API
动态网页
时间相关数据
都可能导致不同结果。
所以生产级 Trace 应区分:
Replayable Input
Recorded Observation
External Nondeterminism
19. Fork:从某个历史点分叉
Fork 对 Agent 非常有价值。
例如:
同一个 Bug
↓
路径 A:修改 API
路径 B:修改调用方
如果有 Event Log,可以:
flowchart TD
A["Session Event 1"]
B["Event 2"]
C["Event 3"]
D["Fork Point"]
E["Branch A"]
F["Branch B"]
A --> B
B --> C
C --> D
D --> E
D --> FFork 可以用于:
Plan Comparison
Model Comparison
Prompt Experiment
Human Alternative
Eval
20. Fork 的存储模型
不需要复制整个 Session。
可以表示成:
Branch Session
├── parent_session_id
├── fork_event_seq
└── branch_events[]
读取时:
Parent Events until fork point
+
Branch Events
得到当前分支状态。
这和 Git 的思维非常接近。
21. Event Causality:并发 Tool 后顺序怎么办
如果 Agent 同时执行:
read_file(A)
read_file(B)
grep(C)
它们可能不同时间完成。
Session 中至少存在两种顺序:
逻辑请求顺序
实际完成顺序
因此 Event 可以记录:
call_id
parent_event_id
correlation_id
batch_id
避免只依赖:
timestamp
推断因果。
22. 推荐 Tool Event 链
例如:
AssistantMessage
↓
ToolCallRequested
↓
ToolCallValidated
↓
PermissionGranted
↓
ToolExecutionStarted
↓
ToolExecutionCompleted
↓
ToolResultProjected
如果失败:
ToolExecutionStarted
↓
ToolExecutionFailed
↓
ToolResultProjected
这样 Observability 可以清楚区分:
模型调用错了
参数错了
权限拒绝
Runtime 失败
Tool 自身失败
23. Session Status 应该显式存在
推荐最少:
CREATED
RUNNING
WAITING_APPROVAL
SUSPENDED
COMPLETED
FAILED
CANCELLED
状态迁移示意:
flowchart TD
A["CREATED"]
B["RUNNING"]
C["WAITING_APPROVAL"]
D["SUSPENDED"]
E["COMPLETED"]
F["FAILED"]
G["CANCELLED"]
A --> B
B --> C
C --> B
C --> D
B --> D
D --> B
B --> E
B --> F
B --> G
C --> G
D --> GWAITING_APPROVAL 和 SUSPENDED 不应简单等价。
前者是明确等待外部决策;后者可能是用户暂停、资源不足或计划中的中断。
24. Session 与 Agent Loop 的职责边界
一个常见坏设计:
AgentLoop
├── messages
├── persistence
├── permissions
├── retries
├── tool history
├── compaction
├── trace
└── resume
所有东西都塞进 AgentLoop。
更合理:
AgentLoop
↓
Session API
例如:
session.append_event(...)
session.current_state()
session.latest_checkpoint()
session.events_after(...)
Loop 负责推进,Session 负责事实与状态。
25. 推荐 Session API
学习版可以设计成:
class Session:
async def append_event(self, event_type, payload): ...
async def get_events(self, after_seq=None): ...
async def rebuild_state(self): ...
async def create_checkpoint(self): ...
async def fork(self, at_seq): ...
async def resume(self): ...
ContextManager:
class ContextManager:
async def build(self, session): ...
async def compact(self, session): ...
这样:
Session ≠ ContextManager
职责清晰。
26. Session Store:从内存到持久化
第一版可以:
In-memory List
第二版:
JSONL
第三版:
SQLite / Postgres
建议学习顺序:
List
↓
Append-only JSONL
↓
SQLite
↓
真正的 Event Store / Database
JSONL 很适合学习,因为每一行就是一个 Event:
{"seq":1,"type":"UserMessage","payload":{"content":"fix bug"}}
{"seq":2,"type":"AssistantMessage","payload":{...}}
{"seq":3,"type":"ToolCallRequested","payload":{...}}
27. 为什么 Append-only 很重要
如果直接 UPDATE 历史:
UPDATE messages SET content = ...
你会失去:
原始事实
修改历史
审计依据
Replay 能力
Append-only 的基本原则:
新的事实产生新的 Event,而不是悄悄修改旧事实。
例如 Permission:
错误方式:
permission.status = "approved"
更好的方式:
PermissionRequested
↓
PermissionGranted
28. 但 Event Log 也不是万能的
Event Sourcing 会引入复杂度:
Event Schema Version
Migration
Large Log
Snapshot / Checkpoint
Duplicate Event
Ordering
Consistency
Storage Cost
PII / Secret Redaction
因此不要机械照搬。
对于简单 Agent:
messages + lightweight runtime state
完全合理。
只有当系统开始需要:
Resume
Replay
Audit
Fork
Long-running
Concurrent Tool
Human Approval
时,Event Model 的收益才明显增加。
29. Event Schema Versioning
长期运行的 Harness 会升级代码。
旧 Session 里的:
ToolExecutionCompleted v1
可能和新代码的:
ToolExecutionCompleted v3
结构不同。
Event 应携带版本:
{
"type": "ToolExecutionCompleted",
"schema_version": 2,
"payload": {}
}
Reducer 可以:
Old Event
↓
Upcaster / Migration
↓
Current Event Shape
↓
Reducer
30. Secret / Sensitive Data Redaction
Event Log 很容易保存:
API Key
Environment Variables
Authorization Header
User File Content
Private Repository Data
而 Event Log 又通常长期持久化。
因此 Session Store 应考虑:
Redaction
Secret Masking
Retention Policy
Encryption
Access Control
尤其不要直接把:
完整 shell environment
无条件写入 Trace。
31. Observability:Event Log 天然是 Trace 来源
Session Event 可以转换成 Trace:
Turn 4
├── Inference
│ ├── input_tokens
│ └── latency
├── ToolCall
│ ├── name = bash
│ └── args_hash
├── Permission
│ └── auto_allowed
├── Execution
│ ├── exit_code = 1
│ └── duration = 3.2s
└── Observation
└── test failed
然后可计算:
Tool Error Rate
Retry Count
Approval Count
Compaction Count
Dead-loop Rate
Session Duration
Recovery Rate
32. Session Model 与 Eval 的关系
Eval 不应该只记录最终:
success = true
如果 Session Event 完整,就能分析:
为什么成功?
为什么失败?
失败发生在哪一层?
成功花了多少步?
有没有死循环?
发生了多少次 Permission Denied?
Compact 后是否出现性能下降?
这使得 Harness 优化可以从:
感觉
进入:
可测量的系统工程
33. 推荐的完整 Session 架构
flowchart TD
A["Agent Loop"]
B["Session API"]
C["Append-only Event Store"]
D["State Reducer"]
E["Derived State"]
F["Checkpoint Store"]
G["Context Builder"]
H["Model"]
I["Trace / Metrics"]
J["Replay / Fork / Audit"]
A --> B
B --> C
C --> D
D --> E
E --> F
E --> G
C --> G
G --> H
C --> I
E --> I
C --> J
E --> J这张图可以作为本章最终心智模型。
34. 推荐实践:自己实现一个 SessionStore
实验 1:JSONL Event Log
实现:
await session.append_event(
"UserMessage",
{"content": "fix bug"}
)
写入:
session.jsonl
实验 2:Reducer
实现:
state = rebuild_state(events)
要求:
- Pending Tool
- Completed Tool
- Permission
- Latest Goal
- Session Status
都能正确恢复。
实验 3:Crash Recovery
模拟:
ToolExecutionStarted
↓
Process Crash
重启 Agent。
检查它能否检测:
Incomplete Tool Operation
而不是直接重试。
实验 4:Checkpoint
每 100 个 Event:
create_checkpoint()
比较:
Full Replay
vs
Checkpoint + Incremental Replay
恢复时间。
实验 5:Fork
从:
seq = 50
Fork 一个 Branch。
让两个 Agent 分别尝试不同修复方案。
实验 6:Compaction Event
执行 Context Compaction:
Event 1~100
↓
Summary
验证:
- 原事件仍存在
- Context 使用 Summary
- Replay 仍能访问原历史
35. 本章必答的 18 个问题
- 为什么
messages[]不等于 Session? - Event Log 为什么可以成为 Source of Truth?
- Derived State 是什么?
- Context 为什么只是 Session 的投影?
- 为什么 Tool Execution 需要 Started / Completed 两个事件?
- 什么是 Unknown Outcome?
- Resume 为什么不能简单 Retry?
- Tool 幂等性与 Session 恢复有什么关系?
- Checkpoint 与 Compaction 有什么区别?
- Compaction 为什么应该产生 Event?
- Steering 为什么适合成为一等 Event?
- State Replay 与 Execution Replay 有什么区别?
- 为什么模型执行无法保证完全 Deterministic Replay?
- Fork 如何避免复制整个 Session?
- 并发 Tool 的事件顺序怎么表达?
- Session Status 为什么应该显式存在?
- Event Schema 为什么需要版本管理?
- 为什么 Event Log 必须考虑 Secret Redaction?
36. 与下一篇 Context Management 的衔接
有了 Session / Event Model 后,下一步自然就是:
Session 中有这么多事实,下一次模型到底应该看到哪些?
也就是:
Session Events
↓
Derived State
↓
Selection
↓
Pruning
↓
Truncation
↓
Compaction
↓
Ordering
↓
Prefix Stability
↓
Model Context
因此下一篇:
Context Management:上下文选择、裁剪、压缩与缓存治理
会重点解决:
模型看到什么
为什么看到这些
哪些历史被删除
哪些被压缩
Tool Result 保留多久
Context Budget 如何计算
Prefix Cache 如何稳定
Summary Drift 如何避免
37. 一句话总纲
工业级 Agent Session 的关键,不是“保存聊天记录”,而是把整个 Agent 执行过程表示成可持久化的事实序列,再由这些事实推导 Runtime State,并为每一次模型调用构造受控 Context;只有这样,Resume、Replay、Fork、Compaction、Audit 与 Observability 才能建立在同一套可靠基础之上。