Agent Framework 1.13.0 包含对Python工作流执行的细微中断性变更。 大多数应用程序 不需要 更改。 这些更改会影响依赖于确切的超级步数或迭代数、在收敛边界设置 max_iterations 、检查初始消息源 ID 或假设检查检查点放置和排序的应用程序。
背景
在 1.13.0 之前,检查点未完全满足捕获从任何记录边界恢复执行所需的工作流状态的承诺。 启动执行程序在超级步骤和检查点循环之前运行,因此最早的检查点包含启动执行程序的输出和更新状态,但不包含原始工作流输入。 同样,响应请求事件是在未首先记录在检查点的情况下传递和处理的。 因此,任何检查点都无法从原始输入重播启动执行程序,或者从传递的响应中重现人工循环延续。
行为变更
版本 1.13.0 会缩小这些差距。 启动执行程序现在在第一个超级步骤中运行,入口检查点在该超级步骤之前记录初始输入,响应输入检查点记录在处理响应之前传递了响应。 这些更改一起使检查点工作流从其输入(包括人工循环延续)中完全可重播。
Important
这些更改不会影响版本 1.13.0 之前创建的检查点。 现有检查点仍受支持,在升级后仍可还原。
可能需要操作的更改
| 领域 | 1.13.0 之前 | 在 1.13.0 及更高版本中 | 用户影响 |
|---|---|---|---|
| 启动执行程序 | 启动执行程序在超级步骤循环之前运行。 | 输入已排队等待启动执行程序,该执行程序在第一个超级步骤中运行。 | 每次全新运行都会发出一个附加 superstep_started 事件和 superstep_completed 事件。 |
| 迭代计数 | 迭代 1 表示启动执行程序运行后的第一个超级步骤。 | 迭代 1 运行启动执行程序。 以后的工作轮换一次迭代。 | 以前需要 $N$ 迭代的工作流现在需要 $N + 1$。 |
| 输入消息源 | 初始消息具有硬编码的源 ID "Workflow"。 |
初始消息通过启动执行程序的内部边缘传递,并具有源 ID INTERNAL_SOURCE_ID(start_executor.id)。 |
读取或筛选初始消息源 ID 的代码必须使用新值。 |
可重播性改进
| 领域 | 1.13.0 之前 | 在 1.13.0 及更高版本中 | 改进 |
|---|---|---|---|
| 初始检查点 | 迭代 0 检查点是在启动执行程序运行后创建的。 它捕获执行程序的输出消息和更新状态,但未捕获原始输入。 | 在超级步骤 1 之前创建入口检查点。 它记录为启动执行程序排队的原始输入。 | 还原条目检查点会重播完整的运行,包括启动执行程序。 |
| 响应检查点 | 未首先记录在检查点中,就传递了对请求事件的响应。 | 响应输入检查点在传递响应后及其消耗的超级步骤运行之前创建。 | 还原响应条目检查点会重播使用响应的延续。 |
更新 superstep 事件处理
新的工作流运行现在生成一对超级步骤事件,因为启动执行程序在超级步骤 1 中运行:
-
superstep_started与iteration == 1 -
superstep_completed与iteration == 1
后续执行程序工作轮换一个超级步骤。 更新测试、遥测、进度指示器或其他代码,该代码假定确切的事件计数或将特定执行程序映射到固定迭代。
无需依赖事件类型计数或迭代即可响应事件类型的代码无需更改。
查看最大迭代限制
限制 max_iterations 现在包括运行启动执行程序的超级步骤。 如果工作流以前使用了其完整限制,请将配置的值增加一个:
from agent_framework import WorkflowBuilder
workflow = WorkflowBuilder(
start_executor=start_executor,
max_iterations=previous_max_iterations + 1,
).build()
如果工作流在达到配置的限制之前已聚合,则无需更改。
更新初始消息源检查
如果启动执行程序使用初始消息的源 ID,请将硬编码 "Workflow" 的值替换为启动执行程序内部边缘的源 ID。
在 1.13.0 之前:
is_workflow_input = ctx.source_executor_ids != ["Workflow"]
在 1.13.0 及更高版本中:
from agent_framework import INTERNAL_SOURCE_ID
is_workflow_input = ctx.source_executor_ids != [INTERNAL_SOURCE_ID(self.id)]
INTERNAL_SOURCE_ID(executor_id) 当前返回 "internal:<executor_id>"。 使用帮助程序而不是构造此字符串,使代码遵循框架的源 ID 格式。
更新检查点处理
初始输入检查点
启用检查点后,每次全新运行现在都会在该处 iteration_count == 0创建一个入口检查点。 此检查点包含原始输入作为指向启动执行程序的外部消息。 还原它会重新运行启动执行程序,并重现完整的工作流运行。
完成每个超级步骤后,框架将继续创建检查点。 对于具有 $N$ 超级步骤的运行,需要$N + 1$ 检查点:入口检查点后跟每个已完成的超级步骤的一个检查点。
查看假定迭代 0 检查点包含启动执行程序生成的状态的代码。 该状态现在显示在超级步骤 1 之后创建的检查点中。
请求-响应检查点
继续工作流 workflow.run(responses=...)时,框架现在会在对响应进行排队以及运行使用这些响应的超级步骤之前创建响应输入检查点。 还原此检查点会重新传送记录的响应,并重播工作流的其余部分。
响应条目检查点与包含挂起请求的上一个检查点相同 iteration_count 。 它是一个单独的检查点,该 previous_checkpoint_id 检查点指向该挂起的请求检查点。
Important
iteration_count不能保证在人循环检查点历史记录中是唯一的。
previous_checkpoint_id按照链确定检查点顺序。 如果需要最新的检查点,请使用检查点存储 API,而不是选择最大的 iteration_count检查点。
迁移清单
- 更新依赖于确切的超级步数或迭代数的断言和事件使用者。
- 仅针对达到前一限制的工作流增加
max_iterations一个。 - 将初始源 ID 检查
"Workflow"替换为INTERNAL_SOURCE_ID(start_executor.id)。 - 将迭代 0 检查点视为执行前输入检查点。
- 按世系对人工循环检查点进行排序,而不是假设
iteration_count是唯一的。 - 验证重播条目检查点和响应条目检查点是否生成预期的输出和副作用。
有关实现详细信息,请参阅 “允许工作流检查点完全可播放性”。