跳到主要内容
非官方简体中文翻译,内容版权归 Mastra 所有,遵循 Apache-2.0 许可。

Agent 生命周期

当你调用 generate() 或 stream() 时,Mastra 会启动一次 agent 运行。它在调用模型之前准备好 agent 及其输入。如果模型请求使用工具,Mastra 会执行该工具,并可能再次调用模型。工作完成后,Mastra 执行收尾并返回结果。

本指南将这项工作拆分为准备、循环执行和收尾三个阶段。它解释了 processors 在哪里运行、哪些情况会触发另一次模型调用,以及常规运行与持久化运行有何不同。

运行、迭代与模型步骤
运行、迭代与模型步骤的直接链接

工作发生在三个层级:

  • 运行(Run):由一次 generate() 或 stream() 调用所启动的全部工作,直到最终结果或错误,包括持久化执行等待外部输入期间的所有暂停与恢复。
  • 循环迭代(Loop iteration):agent 循环的一轮,从模型步骤开始,包含所请求的工具工作,直到 Mastra 决定是否继续。
  • 模型步骤(Model step):一次对模型提供方的请求及其响应,以及围绕该请求运行的输入和输出 processors。

准备阶段取决于运行时上下文和初始输入处理:

  • RequestContext 将可信的运行时数据(例如身份或租户信息)传递给动态配置、processors 和工具,但其值不会自动包含在模型提示词中。
  • processInput 在循环开始前处理初始消息,它可以转换这些消息,并建立供后续 processor 钩子和工具使用的状态。

一次运行包含一个或多个循环迭代。当模型返回最终答案后,运行在当前迭代结束时停止。当模型请求工具时,Mastra 会处理结果,并可能开始另一次迭代,除非已配置的 stopWhen 或终止条件在工具工作后结束运行。一次迭代通常对应一个模型步骤,但请将该对应关系视为实现行为,而非稳定的契约。

生命周期概览
生命周期概览的直接链接

图中展示的是三个主要阶段,而不是内部 workflow 步骤。准备阶段创建第一次模型交互。循环可能多次重复模型与工具工作,然后由收尾阶段产出结果。常规运行在当前进程中持续工作,而持久化运行可以保存其状态并在之后恢复。

准备
准备的直接链接

准备阶段将 agent 定义和当前请求转换为可运行的模型交互。在此阶段,Mastra 会:

  • 验证传入的 RequestContext。
  • 解析模型、指令、工作区、skills 及其他动态配置。
  • 根据当前输入和已配置的 memory 构建消息列表。
  • 准备循环期间使用的工具和 processors。

到准备阶段结束时,运行已具备第一次模型步骤所需的消息、工具和 processor 配置,尽管这些任务并非都严格按同一顺序发生。

准备工作时机对 RequestContext 意味着什么
验证、工作区、模型和指令在 processInput 之前必需的值必须在运行开始时已经存在。
供 processInput 使用的、由 memory、工作区和 skills 派生的 processor 实例在 processInput 之前解析在 processInput 内部修改上下文,无法改变这些实例的选择方式。
动态 skill 解析在 processInput 之前skill 选择不能依赖由 processInput 首次添加的值。
常规运行中的工具转换与 memory 和输入准备并行动态 tools 回调与 processInput 之间没有保证的顺序。
processInput在初始输入准备期间执行一次它可以转换消息,并为之后的循环回调和工具执行建立状态。
循环使用的有效输入、LLM 请求和错误 processor 工厂在常规准备的各个分支汇合之后这些工厂可以观察到较早的上下文变更,但 processInput 并非对所有 resolver 都安全的设置点。
持久化准备在持久化循环执行之前其位置与常规路径不同,恢复的工作可能会跳过初始输入处理。

generate() 和 stream() 在调用 getDefaultOptions() 之前验证 RequestContext。因此,基于函数的默认选项无法及时添加缺失的必需值以供验证。

在常规运行中,Mastra 在整个执行过程中复用调用方的 RequestContext 实例。动态配置、processors 和工具执行接收的是该实时实例,而不是单独的副本。变更是否可见取决于消费者是否已经完成解析。

选择 RequestContext 的边界
选择-requestcontext-的边界的直接链接

上下文值只能影响尚未发生的工作。请在最合理的、需要它的最早可信边界设置每个值。

例如,应用可以检查用户访问权限并推导出租户或账号作用域。请在 agent 之外执行该检查,将结果存入新的 RequestContext,然后把上下文传给 generate() 或 stream()。动态配置和工具可以读取同一个可信作用域,而无需再次执行检查。

上下文携带的是授权检查的结果,它并不替代应用边界上的授权。

该值必须影响建立时机原因
验证、模型、指令、skills、工作区、processInput 使用的输入 processors,或动态工具在 generate() 或 stream() 之前,通常在服务器中间件或调用方代码中这些消费者在 processInput 之前或与之并发地解析。
后续循环 processor 工厂、processor 钩子或工具执行尽量在 generate() 或 stream() 之前,或在 processInput 中这些消费者在输入处理之后接收同一个实时上下文。
恢复的持久化工作在可信的请求或恢复边界初始输入 processors 可能不会再次运行,且不可序列化的值必须重建。
模型推理在模型可见的指令或消息中RequestContext 是运行时数据,不会自动加入提示词。

除非你有意共享上下文值,否则应为每个独立请求创建一个上下文。请求上下文指南介绍了 schema 和服务器中间件。

processInput 对于消息转换以及循环后续所需的状态仍然有用。其中的变更可以触达之后的 processor 钩子和工具执行。它无法改变初始验证或已完成的 skill 与输入 processor 解析,而动态工具准备可能已经在运行。

Agent 循环
Agent 循环的直接链接

循环处理截至目前累积的消息。

工具结果会在下一次迭代之前加入累积消息,而最终答案则离开循环进入收尾。

每个模型步骤前后
每个模型步骤前后的直接链接

Processor 回调按以下公开顺序运行:

  1. processInputStep 在下一次模型调用前接收累积的消息列表。
  2. processLLMRequest 在消息转换之后接收面向提供方的提示词。
  3. 提供方流式返回响应,processOutputStream 可以检查或转换每个 chunk。
  4. processLLMResponse 在该步骤的提供方流完成后运行。
  5. processOutputStep 在模型步骤之后、本地执行的工具之前运行。
  6. 如果模型请求本地或客户端工具,Mastra 会处理其输入并执行任何已配置的审批,然后执行工具或等待其结果。
  7. processToolResult 在每个本地或客户端工具结果进入消息列表之前接收它。

由提供方执行的工具可能以不同方式返回结果。如果延迟的提供方结果在之后的模型流期间到达,processToolResult 会在该结果到达时运行。它在每个模型步骤之后并没有统一的固定位置。

关于确切的触发频率、可见性保证、参数和返回类型,请参阅 Processor 接口中的回调时机。

哪些变更会被持久化
哪些变更会被持久化的直接链接

Processor 方法并非都会修改同一种表示:

  • processInput 和 processInputStep 操作实时消息列表。它们的变更会影响后续模型步骤,并可能被 memory processors 保存。
  • processLLMRequest 仅修改该次提供方调用所发送的提示词。它适用于不应改变已存储对话历史的、面向提供方的临时修改。
  • processOutputStream 修改流式 chunk。Processor 状态可以在同一请求的 chunk 之间以及后续输出回调之间传递数据。
  • processToolResult 在原始工具结果进入消息列表之前运行,从而允许在后续模型步骤或持久化之前进行校验或脱敏。
  • 在收尾期间,processOutputResult 可以修改返回的消息及其消息元数据。

循环如何决定继续
循环如何决定继续的直接链接

在模型步骤及任何所请求的工具工作之后,Mastra 会决定该运行是否需要另一次迭代。工具结果通常会触发另一次模型调用,因为模型必须利用这些结果来生成下一次响应。

当达到已配置或终止条件时,循环停止。这些条件包括:

  • 没有请求另一个工具的最终模型响应。
  • 基于累积步骤评估的自定义 stopWhen 条件。
  • maxSteps 限制。
  • 任务完成、目标或 subagent 委托结果。
  • 提供方的终止 finish reason、错误、processor tripwire 或中止。

这些检查协同工作,而不是构成一个公开、详尽的内部顺序。请将 maxSteps 视为模型步骤的上限,并使用 stopWhen 定义应用特定的完成规则。

收尾
收尾的直接链接

停止会将运行带入收尾阶段。无论运行正常完成还是提供方抛出异常,processOutputResult 都会针对完成后的结果和消息按每个请求运行一次。这些消息可能不包含最终 assistant 响应,例如当 maxSteps 在工具调用处结束时。

已配置的输出 processors 先运行,随后自动附加的 memory 输出 processors 运行,以便消息历史能持久化最终形式。Observational Memory 使用自己的钩子持久化,而不依赖该自动附加的 memory 输出 processor。收尾完成后,generate() 解析或流关闭。

收尾独立于模型步骤。它针对整个运行的结果操作,而不是单次提供方调用的响应。

错误、重试与中止
错误、重试与中止的直接链接

提供方 API 的拒绝可以到达 processAPIError。错误 processor 可以修改请求或消息,并请求再次尝试提供方。processAPIError 的重试与 tripwire 重试共享请求上的同一个 maxProcessorRetries 上限。配置了错误 processors 且省略 maxProcessorRetries 时,Mastra 会应用默认的错误重试预算。若需要特定限制,请显式设置 maxProcessorRetries。

从输入或输出 processor 调用 abort() 会引发 tripwire。设置 retry: true 可让符合条件的 input-step 或 output-step 检查带着反馈重放模型步骤。maxProcessorRetries 限制重放尝试次数。不带重试的 tripwire 会停止正常执行,并被包含在结果或流中。

外部中止信号会贯穿提供方调用和工具生命周期工作。触发时,它会停止后续循环执行并终止流,同时在支持的情况下保留部分结果。没有任何 processor 恢复的错误会传播给调用方。

关于重试配置、tripwire 和 API 错误处理,请参阅 Processors。

常规运行与持久化运行
常规运行与持久化运行的直接链接

常规的 Agent 运行将循环保留在当前进程中。如果该进程结束,内存中的执行也随之结束。

持久化 agent 将相同的 agent 循环包装在 workflow 中。它会持久化运行状态,并通过 PubSub 发布事件,以便受支持的运行时能够恢复工作、客户端能够重新连接。当状态和事件历史必须在进程重启后保留时,需要持久化的生产后端。

持久化执行还允许运行挂起(例如工具等待审批时),并在之后从已存储状态恢复,跨越常规进程内运行所不存在的序列化边界。

Mastra 会为持久化工作快照可序列化的 RequestContext 条目。函数、类实例、打开的连接以及类似的不可序列化值,不应期望在挂起或传输到另一个进程后仍然存在。请在可信的请求或恢复边界使用稳定标识符重建它们。

当持久化运行从已存储快照恢复时,会跳过初始 processInput 处理。启动新分段的唤醒(包括 signal 和 schedule 唤醒)会再次运行它。

  • 每当外部请求恢复运行时,重复执行权威的补充(enrichment)步骤。
  • 只存储下游所需的可序列化作用域数据。
  • 不要依赖一次性的 processInput 副作用。

接下来阅读
接下来阅读的直接链接

  • 请求上下文:定义、验证并填充运行时上下文。
  • 认证与身份:将可信身份和授权数据置于模型控制的输入之外。
  • Processors:配置 processors、重试和 tripwire。
  • Processor 接口:查看回调参数和返回值。
  • 工具:配置工具执行、审批和生命周期钩子。
  • 持久化 agent:持久化并恢复长时间运行的 agent 执行。