# Agent Runtime 实践与源码阅读指南

正文从任务身份、状态和执行语义进入实践。所有订单、审批和支付均为教学数据；本轮未执行示例、测试、框架、模型调用、安装、构建或预览。下面是读者可选运行说明，不是实测记录。

## 阅读顺序

1. [Agent Runtime 是什么：从一次调用到一个持续执行的任务](/posts/agent_runtime/7.runtime/01-runtime-and-workflows/)
2. [任务状态怎样设计：Thread、Run、Step、Event 与业务事实](/posts/agent_runtime/7.runtime/02-state-and-identities/)
3. [工作流怎样执行：节点、分支、循环、并行与 Reducer](/posts/agent_runtime/7.runtime/03-graphs-and-reducers/)
4. [崩溃后怎样继续：持久化边界、Checkpoint 与 Replay](/posts/agent_runtime/7.runtime/04-checkpoints-and-replay/)
5. [怎样避免重复副作用：幂等、事务、Outbox 与补偿](/posts/agent_runtime/7.runtime/05-idempotency-and-outbox/)
6. [人工介入怎样恢复：澄清、审批、编辑与接管](/posts/agent_runtime/7.runtime/06-human-intervention/)
7. [Worker 怎样调度任务：队列、租约、心跳与背压](/posts/agent_runtime/7.runtime/07-workers-and-backpressure/)
8. [执行过程怎样交给用户：事件流、断线重连与取消](/posts/agent_runtime/7.runtime/08-events-and-cancellation/)
9. [多 Agent 怎样运行：子任务生命周期、并行与失败传播](/posts/agent_runtime/7.runtime/09-multi-agent-runtime/)
10. [A2A 怎样连接独立 Agent：从发现能力到任务交付](/posts/agent_runtime/7.runtime/10-a2a-tasks/)
11. [生产中的 Runtime 怎样设计：状态、执行、存储与版本升级](/posts/agent_runtime/7.runtime/11-production-runtime/)
12. [用 LangGraph 实现可恢复任务：完整 Python 实战与源码解读](/posts/agent_runtime/7.runtime/12-learning-from-langgraph/)
13. [读懂 Temporal：历史重放怎样驱动长期业务流程](/posts/agent_runtime/7.runtime/13-learning-from-temporal/)
14. [读懂 AgentScope Java Runtime：会话状态怎样进入业务系统](/posts/agent_runtime/7.runtime/14-learning-from-agentscope/)
15. [读懂 DBOS：数据库怎样让普通 Python 程序获得持久执行能力](/posts/agent_runtime/7.runtime/15-learning-from-dbos/)

前七篇建立恢复与副作用的基础，第八至十一篇讨论交付、协作和生产设计，最后四篇把概念对应到固定源码。无需为学习一套框架同时部署全部项目。

## 文件与实现边界

| 文件 | 解释的问题 | 明确限制 |
| --- | --- | --- |
| python/runtime_store.py | 任务、审批、事件和 Outbox 的本地事务 | 单机 SQLite；虚构身份；不提供 CAS 或分布式租约 |
| python/payment_simulator.py | 独立支付账本、幂等参数与响应丢失 | 不连接真实资金系统 |
| python/refund_cli.py | 分进程提交、决定、推进与事件读取 | CLI 没有认证；一份固定订单数据 |
| python/outbox_demo.py | 重复投递、Inbox 与本地原子更新 | 模拟交付，不连接真实消息队列 |
| python/reducer_demo.py | 按证据 ID 合并与冲突拒绝 | 纯函数，不是分布式状态服务 |
| python/lease_demo.py | 租约代次与过期旧执行器 | 可控逻辑时钟；不是真实锁 |
| python/durable_refund_graph.py | SQLite Checkpoint、interrupt 与 Command | 同步教学图；不调用模型 |
| python/temporal_workflow.py、temporal_demo.py | Workflow、Activity、Signal 与 Query | 需要已有 Temporal Server；本地模拟支付 |
| python/dbos_demo.py | Workflow、Step、消息等待与落盘 | 可选固定源码依赖；没有生产认证 |
| java/RuntimeSessionDemo（完整路径见正文） | RuntimeContext 下的连续调用 | Maven 2.0.1 历史示例；会调用真实模型 |

## 先看标准库退款过程

进入本目录的 python 子目录，使用 Python 3.10 或更新版本。不要为标准库示例安装框架。金额统一为 CNY 分：29900 表示 299 元，True/False 不能充当金额。

```bash
# 创建固定 A1042 订单的申请。相同任务 ID、相同金额重复提交返回原申请。
python refund_cli.py submit T17
# 明确批准；这里的审批者是虚构身份，真实系统必须验证认证与授权。
python refund_cli.py approve T17 --decision-id D17
# 模拟支付已提交后响应丢失，业务记录停留在 reconciling。
python refund_cli.py advance T17 --lose-response
# 新进程先查询原 operation ID 的回执，再记录 completed，不创建第二笔退款。
python refund_cli.py advance T17
# 查看权威业务状态与已提交事件；after 表示已处理的最后序号。
python refund_cli.py status T17
python refund_cli.py events T17 --after 0
```

以上状态变化是代码设计的预期，未作为本轮执行结果。默认数据保存在当前工作目录 `.runtime-demo`：tasks.sqlite 保存任务、事件和 Outbox；payment.sqlite 保存独立支付回执与剩余余额。

数据库不会在每次进程启动时重置。固定订单总可退金额为 29900 分；完成全额退款后，再创建不同任务申请全额退款会被支付模拟器拒绝。研究另一条独立时间线时，显式使用新的 `--data-dir`，不要误认为应该靠重建数据库解决生产重复退款。

教学订单固定为版本 13、质量问题核验通过。前序 Harness 的版本 12 尚未核验；新证据推进版本这一点在 Runtime 第一篇交代。示例没有订单编辑服务，执行时真实订单重读与权限撤销是生产扩展，不假称已实现。

审批有效期一小时。过期阻止新的支付提交，但旧支付回执仍应被查询和记录。示例只接受一次有效决定，不支持原地改金额、重新审批或真实取消接口；对应原则在正文解释。它也不宣称审批检查与外部支付之间存在跨系统原子锁。

## 观察重复消息与 Reducer

```bash
# 消费者提交后丢失确认，命令故意以异常结束；这不是支付故障。
python outbox_demo.py --lose-ack
# 再次交付相同消息，消费者 Inbox 阻止本地计数重复。
python outbox_demo.py
# 两个纯教学程序，不启动服务，不调用模型。
python reducer_demo.py
python lease_demo.py
```

Outbox 演示消费的是已保存事件通知，没有实现 Worker 任务队列。Inbox 与本地计数在同一事务内；如果计数换成远端邮件或支付，必须重新处理外部边界。

## LangGraph：分进程恢复暂停点

可选依赖在 python/requirements.txt：langgraph 1.2.11、langgraph-checkpoint-sqlite 3.1.1，并保留原 langchain 依赖。建议独立环境安装，不与所有历史示例共用一个环境。

```bash
# 这一步会安装可选依赖；本轮没有执行。
python -m pip install -r requirements.txt
# 三个独立命令使用同一目录与 task/thread ID。
python durable_refund_graph.py submit T-graph --data-dir .graph-demo
python durable_refund_graph.py approve T-graph --data-dir .graph-demo
python durable_refund_graph.py status T-graph --data-dir .graph-demo
```

若节点异常留下待执行工作，用 retry 命令继续；若处于审批 interrupt，仍需 approve/reject 提供恢复值。若业务结果为 reconciling，可用 refund_cli advance 和同一 data-dir 对账。此时图内 status 可能仍是旧投影，应读取 business 字段，不将图 END 当作支付成功。

不要对已完成任务重新提交新的图输入来模拟恢复。示例 submit 会检查是否已有图快照，避免把同一业务任务创建成多轮图执行。跨版本恢复要求图结构与序列化状态兼容。

## Temporal：先有服务，再启动 Worker

依赖单独放在 requirements-temporal.txt。Server 的部署、命名空间和认证不包含在本示例内；默认连接 localhost:7233。下面操作会保持 Worker 运行，需不同终端：

```bash
# 在专用环境安装可选 SDK；没有在本轮执行。
python -m pip install -r requirements-temporal.txt
# 终端一：Worker 处理任务。SQLite 路径属于本地教学环境。
python temporal_demo.py worker
# 终端二：提交工作流，再发送审批信号。
python temporal_demo.py start T-temporal
python temporal_demo.py approve T-temporal
python temporal_demo.py status T-temporal
```

Workflow 等待 Signal，本例未加入审批等待定时器。Activity 使用稳定业务 ID，最多重试三次，参数错误不重试。Signal 接收成功不是业务完成；Query 读取的是 Workflow 状态。跨副本部署应将本地模拟支付替换为共享服务。

## DBOS：函数、步骤与消息

requirements-dbos.txt 固定到源码提交，不声称等同于某个发布版本。start 命令保持进程等待结果，另一终端发送决定：

```bash
# 可选安装；Git 来源固定提交，不安装浮动 main。
python -m pip install -r requirements-dbos.txt
# 终端一：使用同一工作流 ID 与数据库；重启时保留它们。
python dbos_demo.py start T-dbos
# 终端二：发送教学审批。
python dbos_demo.py approve T-dbos
```

recv 一小时超时后工作流返回 approval_wait_expired；业务记录仍需另行处理。该示例用于解释机制，不是完备审批产品。恢复范围受到应用版本与执行器配置影响，参见源码解读，不宣称任意机器会自动接管所有任务。

## 历史示例继续保留，但职责重新标清

根目录 ticket_triage.py 与 refund_workflow.py 保留既有抽取/分类接口和 A1024 教学数据。这条历史案例使用真实模型和进程内 InMemorySaver，只生成回复，不提交退款；与新 A1042 落盘示例分开阅读。退款审批已改为严格布尔校验，缺失或非法金额不能仅凭批准变为有效。

invoice_audit_agent.py 保留 AgentScope Python 历史入口，读取、枚举和搜索统一检查路径与文件大小。它处理受信本地样本，不能让敌对进程并发修改目录；路径解析不构成沙箱，Schema 也不证明引文实际被读取。历史 SDK API 本轮未运行核验。

Java 源码解读与 Maven 示例分开版本标记，详见 [Java 指南](/examples/agent-runtime/java/README.md)。旧文的 Temporal Java 接口结构也保留在该指南中，不放入未配置 Temporal Java SDK 的 Maven 编译目录。

## 原内容去向

| 原文章 | 主要承接文章 |
| --- | --- |
| 00-agent-runtime学习路线.md | [01-runtime-and-workflows](/posts/agent_runtime/7.runtime/01-runtime-and-workflows/) |
| 01-agent模式.md | [01-runtime-and-workflows](/posts/agent_runtime/7.runtime/01-runtime-and-workflows/) |
| 02-agent状态模型.md | [02-state-and-identities](/posts/agent_runtime/7.runtime/02-state-and-identities/) |
| 03-graph-workflow.md | [03-graphs-and-reducers](/posts/agent_runtime/7.runtime/03-graphs-and-reducers/) |
| 04-durable-execution.md | [04-checkpoints-and-replay](/posts/agent_runtime/7.runtime/04-checkpoints-and-replay/) |
| 05-LangGraph.md | [12-learning-from-langgraph](/posts/agent_runtime/7.runtime/12-learning-from-langgraph/) |
| 06-Temporal与Agent.md | [13-learning-from-temporal](/posts/agent_runtime/7.runtime/13-learning-from-temporal/) |
| 07-human-in-the-loop.md | [06-human-intervention](/posts/agent_runtime/7.runtime/06-human-intervention/) |
| 08-多Agent模式.md | [09-multi-agent-runtime](/posts/agent_runtime/7.runtime/09-multi-agent-runtime/) |
| 09-A2A协议.md | [10-a2a-tasks](/posts/agent_runtime/7.runtime/10-a2a-tasks/) |

持久执行旧文进一步拆入幂等与 Outbox、Worker 调度和事件流；旧人工介入内容覆盖澄清、审批、编辑与接管；LangGraph/Temporal 对照与组合分别放入项目篇。所有原入口提供编号目录与无编号目录两类重定向配置。这里只按路由源码配置，未运行构建确认或发布。

固定来源见 [SOURCES.md](/examples/agent-runtime/SOURCES.md)，本轮交付记录见 [VALIDATION.md](/examples/agent-runtime/VALIDATION.md)。
