Execution Result
脚本里最简单的读法是直接拿 close snapshot:
snapshot = await flow.async_start(input_data)服务里经常不止要最终业务结果。它还要给 UI 展示状态、给日志写 execution id、读取 runtime intervention ledger,或者兼容旧 flow 的 $final_result。这时保留 execution handle,用 execution.result 做统一读取。
execution.result 不是第二份结果存储。它只是把 execution 已经拥有的 state、close snapshot、兼容 final result、intervention ledger 和 lifecycle metadata 组织成几个 reader。
推荐读取顺序
新代码优先这样读:
execution = flow.create_execution(auto_close=False)
await execution.async_start(input_data)
snapshot = await execution.async_close()
report = snapshot["report"]如果服务已经持有 execution,并且要在 close 前后读取同一个字段:
report = execution.result.get_state("report")
meta = execution.result.get_meta()close 前,get_state(...) 读实时 state;close 后,它读冻结后的 close snapshot。这个行为适合 UI 轮询或服务日志,不会要求业务方维护两套读取逻辑。
Reader 一览
| Reader | 什么时候用 |
|---|---|
execution.result.get_state(key=None, default=None) | 读取业务 state。支持 dot path。close 前读 live state,close 后读 frozen snapshot。 |
await execution.result.async_get_final_result(timeout=None) | 兼容旧 .end() / set_result() 写出的 final result。 |
execution.result.get_final_result(timeout=None) | 同步包装,主要给同步兼容代码使用。 |
execution.result.get_interventions(...) | 读取 runtime intervention ledger。 |
execution.result.get_latest_intervention(default=None, **filters) | 读取最近一条匹配的 intervention。 |
execution.result.get_meta() | 读取 execution id、flow name、状态、时间戳、close reason、state version 等 metadata。 |
close snapshot 仍然是完成态
TriggerFlow 新生命周期里,业务完成态是 close snapshot。它来自 execution state:
async def finalize(data):
await data.async_set_state("report", {"status": "ready"})
snapshot = await execution.async_close()
assert snapshot["report"]["status"] == "ready"async_get_final_result(...) 只用于迁移和桥接。它会先找 "$final_result",再找显式内部 result,close 后再回退到 close snapshot。新代码不应该为了“有一个 result”而继续调用 .end() 或 set_result()。
metadata 不进业务 snapshot
metadata 适合日志和诊断,不适合混进业务 state。
meta = execution.result.get_meta()
logger.info(
"flow closed",
extra={
"execution_id": meta["execution_id"],
"flow_name": meta["flow_name"],
"status": meta["status"],
},
)如果把 execution id、时间戳、close reason 这类系统字段写进业务 snapshot,API 调用方会分不清哪些是业务结果,哪些是运行元数据。get_meta() 把这两类信息分开。
intervention ledger 也从这里读
Runtime intervention 会留下 ledger。流程结束后,服务可以做审计:
applied = execution.result.get_interventions(status="applied")
expired = execution.result.get_interventions(status="expired")
latest = execution.result.get_latest_intervention(default=None)这比把外部补充上下文塞进普通 state 更清楚:业务 state 记录模型或流程最终采用的内容,ledger 记录外部上下文的生命周期。
什么时候不用 execution.result
| 场景 | 直接用什么 |
|---|---|
| 单次脚本只要最终业务结果 | snapshot = await flow.async_start(...) |
| SSE / WebSocket 增量输出 | execution.get_async_runtime_stream(...) |
| 读取 chunk 内中间值 | data.get_state(...) |
execution.result 是服务侧 reader,不是新的 stream 入口,也不是替代 chunk 内 data 的对象。
另见
- Lifecycle - start、seal、close 与 close snapshot
- State 与 Resources - state 为什么是完成态来源
- Runtime Intervention - ledger 怎么写入和消费
- 兼容 - 从
.end()/set_result()迁移