agno v2.9.0发布:身份感知调度、缓存隔离、安全加固与组件重建全面升级

2026年8月16日,agno 正式发布 v2.9.0。此次更新覆盖了 Studio 调度能力、组件发现、A2A 流式通信、工作流 WebSocket 执行、Team 人机协作暂停恢复、组件重建、框架注解处理,以及 MCP 工具调用安全和工具缓存隔离等多个关键环节。

如果用一句话概括 agno v2.9.0 的核心方向,那就是:

让组件调度更安全,让用户身份传递更准确,让持久化组件在恢复时更可靠,让多用户场景下的缓存与审批边界更清晰。

本次版本中,最值得关注的是全新的 StudioRunnerTools、MCP 工具名称覆盖漏洞修复、按用户隔离的工具结果缓存,以及组件重建失败时由静默降级改为明确报错。这些变化不仅影响开发体验,也直接关系到多用户 Agent 系统、Studio 组件分发、HITL 审批流和生产环境安全性。


一、全新 StudioRunnerTools:把"运行组件"和"管理组件"彻底拆开

agno v2.9.0 新增了一个身份感知型调度工具包:

agno.tools.studio_runner.StudioRunnerTools

它的核心价值在于,将原先集中在 StudioTools 中的执行能力拆分出来,形成更清晰的职责边界。

过去,Studio 相关能力可能同时包含组件创建、编辑、删除、发现和运行等操作。对于某些场景来说,这种能力集合过于宽泛。例如,一个团队负责人、路由器或者上游 Agent,只需要根据任务去发现并运行 Studio 中已经构建好的 Agent、Team 或 Workflow,但并不应该拥有创建、修改、删除 Studio 组件的权限。

v2.9.0 中的 StudioRunnerTools 正是为这一需求而设计。

它允许任意组件挂载这一工具包,包括但不限于:

  • Team Lead
  • Router
  • 上层调度 Agent
  • 负责请求路由的组件
  • 需要调用 Studio 内部已构建组件的执行节点

挂载后,这些组件可以发现并运行 Studio 中构建好的:

  • Agent
  • Team
  • Workflow

但不会获得 Studio 的创建、编辑、删除能力。

这意味着 agno 在 Studio 调度层面实现了更细粒度的职责切分:

能力类型 StudioRunnerTools 的定位
发现 Studio 组件 支持
运行 Studio Agent 支持
运行 Studio Team 支持
运行 Studio Workflow 支持
创建 Studio 组件 不提供
编辑 Studio 组件 不提供
删除 Studio 组件 不提供

这种拆分的意义非常明显。

对于生产系统而言,能够运行某个组件,不代表应当拥有修改该组件的权限。一个 Router 的职责应当是判断任务该交给哪个 Agent、哪个 Team 或哪个 Workflow,而不是在运行过程中任意改变 Studio 内已有组件的定义。

StudioRunnerTools 的出现,让"调度者"和"管理者"的边界更加清晰:

  • 调度者负责发现与运行
  • Studio 管理面负责创建、编辑与删除
  • 组件执行权限不再天然绑定组件管理权限

这也让 Studio 组件被上层 Agent、Team Lead 或路由逻辑复用时更加稳妥。


二、身份感知执行:run 工具会将调用方 user_id 传入子运行

StudioRunnerTools 不只是简单地把执行能力从 StudioTools 中拆出来,它还带来了一个非常关键的机制:身份感知调度。

在 v2.9.0 中,run_* 工具会把调用方的 user_id 传递到子运行中。

也就是说,当一个组件通过 StudioRunnerTools 去启动另一个 Studio 构建的 Agent、Team 或 Workflow 时,当前调用者的用户身份不会在子运行中丢失。

这项设计解决的是多用户运行上下文中的一个核心问题:

子组件执行时产生的用户级状态,必须归属于正确的用户。

例如,在一个多用户系统中,不同用户可能通过同一个上层 Router 调用下游 Agent。如果用户身份没有继续传递到子运行中,那么下游组件保存的状态、读取的上下文或运行结果,就可能无法正确对应到真正的调用用户。

v2.9.0 通过将调用者的 user_id 贯穿到子运行,确保按用户维度维护的状态会落在正确的人身上。

这意味着:

  • 上游组件识别到的用户身份,可以继续传递给下游组件
  • Studio 中被调度执行的组件可以在正确的用户上下文中运行
  • 用户级状态不再因为子运行而偏离原始调用者
  • Team Lead、Router 等调度型组件在调用下游组件时,身份信息能够持续保留

对于需要区分不同用户状态的 Agent 系统来说,这一点尤其重要。因为一旦用户身份在组件嵌套调用中断裂,后续的状态归属就可能出现偏差。

StudioRunnerTools 的新增,因此不仅是一次工具拆分,更是一次围绕用户身份和运行归属的能力升级。


三、list_components 新增 name 过滤:组件发现更精准

在组件发现能力方面,v2.9.0 为 list_components 新增了 name 过滤功能。

这意味着,在列出组件时,可以通过名称进一步筛选目标组件。

这一改动看起来很小,但对于 Studio 中组件数量不断增加的场景非常实用。

当 Studio 内同时存在多个 Agent、Team 或 Workflow 时,仅仅获取完整组件列表,可能会让上层调度逻辑面对大量无关结果。尤其是当组件命名存在固定规则、业务前缀或模块划分时,按名称过滤能够帮助调用方更快缩小候选范围。

新增 name 过滤后,组件发现流程可以更加聚焦:

  • 只查询名称匹配的组件
  • 降低无关组件出现在发现结果中的概率
  • 让 Router 或 Team Lead 更高效地查找目标组件
  • 让 Studio 组件的检索粒度更加灵活

这项能力与 StudioRunnerTools 的定位形成了很好配合。

前者解决"如何更准确发现组件",后者解决"如何在不拥有管理权限的前提下运行组件"。两者结合后,调度型组件可以在受控边界中完成更精确的组件选择与执行。


四、MCP 工具调用安全修复:禁止调用时覆盖 tool_name

v2.9.0 最重要的安全修复之一,来自 MCP 工具入口。

本次更新后,MCP 工具入口不再允许模型在调用时覆盖 tool_name

此前,模型可能向任意 MCP 工具传入类似下面的参数:

tool_name="delete_repo"

而服务端可能会根据这个调用时提供的名称去执行对应工具。

问题在于,工具执行名称被调用参数影响后,允许列表、是否需要确认、HITL 审批以及日志记录等机制,可能仍然按照声明时的工具名称进行处理,而实际执行的却是另一个工具。

这会造成一个严重的安全风险:

  • 声明名称与实际执行名称不一致
  • 允许列表可能对错误名称进行判断
  • requires_confirmation 可能无法对应真实执行的工具
  • HITL 审批可能绕过实际需要审批的工具
  • 日志记录可能反映的是声明名称,而不是实际执行名称
  • 模型可能借助 tool_name 覆盖,触发本不该直接执行的操作

换句话说,过去模型可能把一个普通 MCP 工具调用伪装成另一个工具的执行请求,而安全控制逻辑与实际执行目标之间出现错位。

v2.9.0 对这一问题进行了明确修复。

现在,实际执行的工具名称会从 tool.name 中闭包确定,不再由模型调用时传入的 tool_name 决定。

也就是说:

  • 模型无法通过调用参数切换实际执行的 MCP 工具
  • 实际执行目标由工具自身声明的名称固定
  • 安全控制逻辑将围绕真实声明的工具名称生效
  • allow-list 不会再因为名称错位而失去意义
  • requires_confirmation 不会再被调用时名称覆盖绕过
  • HITL 审批不会再因为名称替换而失效
  • 日志记录与实际执行工具之间的对应关系更加一致

值得注意的是,这一改动并不是简单删除所有名为 tool_name 的参数。

如果某个工具本身就合法地声明了一个 tool_name 参数,那么模型传入的该参数仍会作为普通参数继续转发给工具。

区别在于:

  • tool_name 参数不再用于选择或切换要执行的工具
  • 它只会作为该工具定义中的普通入参存在
  • 真正执行哪个工具,始终由 tool.name 固定

这是一项兼顾安全性和兼容性的修复。

它阻止了调用时工具名称覆盖带来的安全绕过,同时保留了那些确实需要 tool_name 作为业务参数的工具使用方式。


五、工具结果缓存改为按用户隔离:修复跨用户缓存泄漏

另一个极其关键的安全与行为变更,是工具结果缓存机制的调整。

当启用:

cache_results=True

时,agno v2.9.0 的缓存键将不再仅按原有方式生成,而是加入稳定的运行上下文身份信息:

  • user_id
  • session_id

这意味着工具缓存正式具备按用户、按会话的隔离能力。

此前存在一个跨用户缓存泄漏问题。

如果某个工具接受 run_context,例如 MemoryTools 一类工具,并且工具结果被缓存,那么一个用户产生的缓存结果可能会被另一个用户命中并复用。

这显然会带来严重问题。

因为工具的结果可能依赖用户上下文。即使工具调用参数表面上相同,不同用户对应的 run_context、记忆内容、会话状态或上下文环境也可能完全不同。

如果缓存没有将用户身份纳入键的一部分,那么以下情况就可能发生:

  1. 用户 A 调用某个依赖运行上下文的工具。
  2. 工具结果被缓存。
  3. 用户 B 发起看似相同的调用。
  4. 系统命中用户 A 的缓存结果。
  5. 用户 B 获得原本属于用户 A 的结果。

v2.9.0 通过将 user_idsession_id 加入缓存键,修复了这一问题。

新的缓存键将包含稳定的运行上下文身份信息,因此缓存结果不再简单地跨用户共享。

这带来几个直接影响:

  • 用户 A 的缓存不会被用户 B 直接复用
  • 不同会话之间的缓存边界更加明确
  • 接受 run_context 的工具在缓存场景下更安全
  • 多用户系统中的工具执行结果归属更清晰
  • 缓存机制不再可能把一个用户的数据错误地服务给另一个用户

需要注意的是,run_id 不会加入缓存键。

这是一个经过权衡的设计。

如果把 run_id 放进缓存键中,每一次运行都会形成新的缓存维度,缓存几乎无法在同一用户后续运行中复用,缓存的实际价值会明显降低。

因此,v2.9.0 的策略是:

  • 加入 user_id
  • 加入 session_id
  • 不加入 run_id

这样既能够保障用户与会话维度的隔离,又能让同一用户在后续运行中继续获得缓存带来的收益。


六、缓存行为变化:旧缓存命中逻辑将不再完全一致

由于缓存键的组成方式发生变化,v2.9.0 也带来了一项明确的行为变化。

此前已经存在的缓存键,与新版本的缓存键不再保持一致。

因此,升级后,原先可以命中的缓存结果可能不会再按相同方式命中。

这不是缓存功能失效,而是缓存键结构调整后的自然结果。

因为新版本加入了:

  • 用户身份信息
  • 会话身份信息

缓存从"可能跨用户共用"的模式,转向"面向稳定运行上下文身份隔离"的模式。

所以,已有缓存行为会发生变化:

  • 过去的缓存键与新版本缓存键不一致
  • 旧的缓存命中关系不会完全延续
  • 升级后部分原有缓存可能无法按原逻辑命中
  • 同一用户、同一会话下的跨运行缓存仍然有价值
  • 不同用户之间不再共享可能包含上下文差异的缓存结果

除了缓存键变更外,本次修复还涉及:

  • ToolResult 的往返处理
  • 缓存命中时 Hook 的执行

也就是说,缓存能力不只是完成用户级键隔离,还同步处理了工具结果对象在缓存过程中的往返表现,以及缓存命中时相关 Hook 的行为。

对于依赖工具缓存的应用来说,升级 v2.9.0 后需要理解这一点:缓存仍然存在,但缓存命中边界已经变得更加严格,也更加符合多用户运行环境的安全要求。


七、组件重建不再静默降级:无法解析引用时明确失败

v2.9.0 对组件重建机制进行了重要调整。

过去,当系统反序列化一个持久化组件时,如果组件内部存在无法解析的引用,系统可能不会直接报错,而是选择静默降级后继续运行。

例如:

  • 一个 Agent 的工具可能变成空数组
  • 一个 Team 可能丢失成员
  • Schema 可能被丢弃
  • Knowledge 可能被丢弃

这种静默降级的问题在于,组件表面上看起来仍然可以运行,但实际运行的已经不是原本被保存和定义的组件。

一个 Agent 丢掉工具后继续执行,可能无法完成任务。

一个 Team 丢掉成员后继续执行,可能失去原有分工。

Schema 或 Knowledge 丢失后继续执行,也可能让行为与预期严重偏离。

更危险的是,这类问题不一定会立刻暴露。系统可能继续运行,但运行结果已经因为组件被悄悄降级而不再可信。

v2.9.0 改变了这一行为。

当持久化组件在反序列化时存在无法解析的引用,在严格路径中将直接抛出:

ComponentRehydrationError

该错误属于 AgnoError,状态码为:

422

这意味着系统不再默认接受"缺失部分依赖但仍勉强运行"的组件状态。

相反,系统会明确告诉调用方:组件无法被完整重建,具体存在无法解析的部分。

这项变化的核心价值在于:

宁可明确失败,也不让一个被破坏或被降级的组件在不知情的情况下继续运行。


八、严格模式是调用方属性:公开加载保持兼容,调度路径默认严格

v2.9.0 对重建严格性的设计非常明确:严格与否,是调用方的属性。

这意味着,不同入口可以根据自身场景选择不同的默认行为。

公开的:

  • from_dict
  • load

默认仍然是:

strict=False

这一设计保证了常规 round-trip 场景仍然可以工作,也就是说,公开的反序列化和加载行为保留了兼容性。

但对于 AgentOS 查询和所有调度执行路径,默认会采用:

strict=True

包括:

  • REST POST /runs
  • continue
  • MCP run 工具
  • StudioRunner

在这些严格路径中,如果组件存在无法解析的引用,系统会返回 422 错误,而不是运行一个已经被降级的组件。

返回的错误会指出无法解析的部分。

这一设计体现了两类需求之间的平衡。

一方面,公开的 from_dictload 保持默认非严格模式,避免破坏已有 round-trip 使用方式。

另一方面,真正进入执行与调度流程时,系统必须确保组件引用完整可用,不能容忍缺失工具、缺失成员、缺失 Schema 或缺失 Knowledge 后仍继续运行。

因此,v2.9.0 的组件重建策略可以概括为:

场景 默认严格性
from_dict strict=False
load strict=False
AgentOS 查询 strict=True
REST POST /runs strict=True
continue strict=True
MCP run 工具 strict=True
StudioRunner 调度 strict=True

这项变化将显著提升生产执行路径的可靠性。

因为在真正运行前,系统会先确认组件是否能够被完整、正确地重建,而不是带着丢失的关键部分继续执行。


九、固定成员版本得到尊重:重建与执行更符合已保存定义

在组件重建相关修复中,v2.9.0 还明确支持了固定成员版本。

也就是说,被固定的成员版本将得到正确遵循。

这一点对于 Team、组件组合以及持久化后的组件引用尤其重要。

当一个组件保存了对特定成员版本的引用时,重建和后续执行应当遵循该固定版本,而不是在恢复过程中忽略版本约束或使用不符合预期的成员版本。

结合前面"无法解析引用时明确失败"的变化,v2.9.0 在组件恢复逻辑上形成了更完整的保障:

  • 无法解析的引用不再静默丢弃
  • 严格执行路径会明确报错
  • 被固定的成员版本会得到遵循
  • 恢复后的组件更接近原始保存定义
  • 调度执行不再轻易建立在降级组件之上

这对于依赖 Studio 持久化组件、Team 成员组合和版本固定关系的使用场景非常关键。


十、Team HITL 暂停成员运行持久化:会话重载后仍可继续恢复

在人机协作流程方面,v2.9.0 修复了 Team HITL 的一个重要问题。

此前,如果 Team 中的成员运行因为 HITL 暂停,暂停状态可能无法在会话重新加载后正确恢复。

本次更新后,暂停的成员运行会被持久化。

这意味着,Team HITL 的恢复能力可以跨越会话重新加载。

这项修复解决的是一个非常实际的问题。

在需要人工确认、审批或介入的 Team 执行流中,某个成员可能在中途进入暂停状态。此时,系统需要等待人工处理后再继续。

如果暂停中的成员运行没有被持久化,那么一旦会话被重新加载,原本暂停在哪一步、哪个成员正在等待恢复等信息就可能丢失。

v2.9.0 通过持久化已暂停的成员运行,使 Team 的 HITL 恢复过程更加可靠。

更新后的效果包括:

  • Team 成员进入 HITL 暂停状态后,暂停运行会被保存
  • 会话重新加载后,暂停状态不会轻易丢失
  • 原本等待人工处理的 Team 流程可以继续恢复
  • Team HITL 的执行连续性得到增强
  • 人工介入与系统恢复之间的衔接更加稳定

对于包含审批、确认或人工审核环节的 Team 执行流程来说,这是一项直接提升可用性的修复。


十一、A2A 流式客户端修复:不再因状态更新提前丢失 Task 元数据

v2.9.0 还修复了 A2A 流客户端中的一个问题。

此前,A2A stream client 在收到状态更新时可能直接中断处理,从而导致 Task 级别的元数据被丢失。

具体来说,客户端此前可能因为在 status-update 处提前 break,导致后续与 Task 相关的元数据无法被正确保留。

本次修复后,A2A 流式客户端不会再因为状态更新而错误地提前结束处理,从而保留 Task 级别元数据。

这项修复的重要性在于,状态更新与 Task 元数据并不是互斥信息。

一个流式执行过程中,状态发生变化并不意味着 Task 层面的信息已经全部处理完毕。如果客户端一收到状态更新就停止读取,就可能遗漏仍然需要保留的元数据。

v2.9.0 修复后:

  • 状态更新不会再导致客户端过早退出处理
  • Task 级元数据不会因为 status-update 而被丢失
  • A2A 流式通信中的信息保留更加完整
  • 流式客户端对任务级数据的处理更加可靠

对于依赖 A2A 流式返回内容的场景,这一修复可以避免任务元数据在传输和处理过程中被意外忽略。


十二、Workflow WebSocket 修复:遵循用户选择的工作流版本

在 Workflow 的 WebSocket 执行路径中,v2.9.0 修复了工作流版本选择问题。

更新后,系统会在 WebSocket 场景下遵循用户选定的 Workflow 版本。

这意味着,当用户明确选择某个工作流版本时,通过 WebSocket 执行时将正确使用这个被选择的版本。

这一修复确保了不同执行入口在版本行为上的一致性。

工作流版本通常代表不同的配置、逻辑或组件组合。如果用户已经选择了特定版本,但 WebSocket 执行时没有遵循该选择,就可能导致实际执行的内容与用户预期不一致。

v2.9.0 解决了这一问题后:

  • WebSocket 执行将遵循已选 Workflow 版本
  • 用户选择的版本不会在 WebSocket 路径中被忽略
  • 工作流版本控制在实时连接执行场景下更加可靠
  • 不同版本之间的执行边界更加明确

对于通过 WebSocket 启动或交互式运行 Workflow 的场景来说,这是一次必要的正确性修复。


十三、组件重建时保留 Toolkit Instructions

v2.9.0 修复了组件重建过程中 Toolkit Instructions 丢失的问题。

当组件被重新加载或重建时,Toolkit Instructions 现在能够被正确保留。

Toolkit Instructions 是工具包相关的重要指令信息。如果组件在持久化后再恢复时丢失这些指令,那么恢复后的工具行为和原始配置可能出现偏差。

本次修复意味着:

  • Toolkit Instructions 在 rehydration 过程中得到保留
  • 持久化后恢复的组件可以保留原有工具包指令
  • 组件重建后的工具行为更接近保存前状态
  • 不会因为重建流程而悄悄丢失工具包层面的关键信息

这一项修复与"重建失败不再静默降级"形成呼应。

一个是对无法解析引用时明确失败,另一个是对可解析组件中的 Toolkit Instructions 确保保留。两者共同提升了组件持久化、加载和恢复后的完整性。


十四、框架返回注解保护:增强框架注解处理稳定性

v2.9.0 还加入了对框架返回注解的保护。

该修复用于防护框架返回注解相关的处理情况,提升框架在面对返回注解时的稳定性。

虽然这项更新在发布说明中的描述较为简洁,但它属于框架层面的兼容性和健壮性修复。通过对框架返回注解进行保护,agno 可以避免在相关注解处理路径中出现不符合预期的问题。

此次更新同时与 list_components 的名称过滤能力一同被纳入版本变更中,体现出 v2.9.0 不仅关注调度、安全和持久化,也持续完善底层框架行为与组件发现体验。


十五、v2.9.0 的核心变化全景总结

agno v2.9.0 的更新可以归纳为四个关键词:

调度、身份、安全、可靠性。

在调度层面,新增 StudioRunnerTools,将 Studio 组件运行能力从管理能力中拆分出来。Team Lead、Router 等组件可以发现并运行 Studio 中的 Agent、Team 和 Workflow,但不会获得创建、编辑、删除组件的操作面。

在身份层面,StudioRunnerTools 的 run_* 工具会将调用方的 user_id 传递到子运行中,确保用户级状态归属于正确用户。同时,工具结果缓存键加入 user_idsession_id,解决跨用户缓存泄漏问题。

在安全层面,MCP 工具入口禁止调用时覆盖 tool_name,真实执行工具名称由 tool.name 固定,避免 allow-list、确认机制、HITL 审批与日志记录因名称错位而被绕过。

在可靠性层面,组件重建不再允许在严格执行路径中静默降级。无法解析的引用会抛出 ComponentRehydrationError,并以 422 的方式返回问题,而不是让缺失工具、成员、Schema 或 Knowledge 的组件继续运行。固定成员版本也会被正确遵循。

此外,本次版本还修复并完善了多个执行细节:

  • list_components 增加 name 过滤
  • Team HITL 暂停成员运行会被持久化
  • 会话重新加载后可继续恢复 Team HITL
  • Toolkit Instructions 在重建时得到保留
  • A2A 流客户端不再因状态更新丢失 Task 级元数据
  • Workflow WebSocket 执行会遵循所选版本
  • 框架返回注解处理获得保护
  • ToolResult 往返处理得到修复
  • 缓存命中时 Hook 行为得到处理

十六、结语:agno v2.9.0 不只是功能更新,更是执行边界的系统性收紧

代码地址:github.com/agno-agi/agno

agno v2.9.0 并非单纯增加几个工具或修补几个边缘问题,而是围绕真实运行环境中的关键边界进行了系统性调整。

StudioRunnerTools 让运行权限与管理权限分离。

用户身份在子运行中的传递,让状态能够落在正确用户身上。

缓存键引入用户与会话维度,让多用户场景下的缓存不再可能跨用户泄漏。

MCP 工具名称固定,让审批、确认、允许列表和日志机制重新与真实执行目标保持一致。

组件重建从静默降级转向严格报错,让生产执行路径不再建立在不完整组件之上。

Team HITL、A2A 流式通信和 Workflow WebSocket 的修复,则进一步增强了暂停恢复、元数据保留与版本选择的正确性。

整体来看,agno v2.9.0 的核心价值在于:

让 Agent、Team、Workflow 与工具在多用户、多组件、多入口的运行环境中,拥有更清晰的身份归属、更严格的安全边界、更可靠的重建机制,以及更一致的执行行为。

相关推荐
数据知道2 小时前
网络安全实战:子域名接管实战——从 CNAME 配置错误到完全控制
网络·安全·web安全·网络安全
测试修炼手册4 小时前
[测试技术] 文件上传功能怎么测:格式、大小、并发与安全
安全
Aision_6 小时前
代码安全学习手记(二):SCA 软件成分分析原理与 OWASP Dependency-Check 集成实战
运维·人工智能·学习·安全·web安全·网络安全
虹科网络安全6 小时前
从33.2%降至4.2%:KnowBe4 2026报告揭示持续培训如何重塑企业安全防线
安全
是隼人6 小时前
buuctf-pwn bjdctf_2020_babystack2题解 整数溢出(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
艺杯羹6 小时前
古典密码学攻防演进全景:从凯撒移位、频率分析到一次一密与恩尼格玛机破译
网络·人工智能·安全·网络安全·密码学·密码安全
MartinYeung57 小时前
Aztec Connect 黑客攻击深度剖析:结算边界绕过漏洞
安全·区块链
MartinYeung57 小时前
[论文学习]Latent Fusion Jailbreak: 融合有害与无害表征以诱导大语言模型产生不安全输出
学习·安全·语言模型
飞飞传输8 小时前
机器人行业数据流转深度研究:内外网数据摆渡平台应用现状与趋势
大数据·运维·安全