返回博客

AstrBot / Architecture / Testing

在 AstrBot 群聊插件中隔离运行时工具

一次关于运行时工具隔离的项目记录:会话策略应用前先复制共享工具集,让提醒、图像能力与函数可见范围保持独立,并验证单次请求不会改变后续请求的工具状态。

共享工具集被复制到局部容器,经过策略过滤后交给单次会话。

共享状态产生的问题

插件接收的工具管理器会在多个请求之间复用。早期过滤代码把这个管理器当成单次请求的局部对象,直接从可变列表中移除工具。这样一来,前一个请求采用的可见范围会改变后续请求能够取得的工具,即使两个请求使用了不同的群聊策略。

这个问题与执行顺序有关。较窄的允许列表先运行后,较宽松的请求仍可能继承已经缩短的容器。只测试一种策略组合时很难发现异常,混合运行不同策略后才会出现工具缺失。需要明确的边界是对象所有权:注册结果可以共享,但共享对象在请求处理期间应保持原状;可见范围只属于当前请求。

应用策略前先建立副本

修正后的处理顺序会在应用允许、拒绝或插件范围规则之前,对工具容器建立浅副本,并为 toolsfunc_list 创建新的数组。过滤局部副本时,原管理器中的工具列表不会随之缩短。面对缺少新版完整工具集接口的旧管理器,兼容分支也使用同一个复制辅助函数。

副本建立后,请求再计算本次可见的工具名称,只过滤这个局部容器,并把结果交给当前运行时。请求结束后,局部对象随其他请求状态释放。共享注册与会话策略因此分别归属于不同层次。

让不同能力保持独立

这次维护也拆开了几类容易混用的信号。工具提醒由独立的提示注入设置控制;Step Image 是否参与由图像配置计算;一般函数工具则继续使用允许名称、拒绝名称和插件范围规则。

这些机制会共同影响一次回复,但各自回答的问题不同。提醒决定上下文中是否加入使用提示,图像配置决定图像能力是否参与,可见范围策略决定哪些已注册函数能够调用。把这些信号分开后,一个功能开关不会无意间改写另一个能力的状态。

验证隔离是否成立

针对性的测试会保留原工具管理器,对两种受支持的容器形态建立副本,在副本上应用可见名称过滤,然后确认原工具列表仍与初始状态一致。测试还检查旧版兼容分支会先调用复制函数,并确认工具提醒在可见范围计算完成后单独处理。

这里的证据范围有意限定在发生过修改的对象边界,并不把测试描述成完整的双会话模拟。能够确认的是:副本与共享对象不同,副本列表可以被过滤,而共享列表保持不变。

这条边界带来的变化

工具状态归属于单次请求后,策略行为更容易分析。检查某个群聊策略时,无需追溯此前运行过哪些会话;旧版兼容接口也遵循相同的对象所有权规则。维护测试可以围绕复制与过滤边界展开,无需构造完整聊天环境。

这个结构也为后续能力留出空间。新的工具类型可以拥有自己的配置与可见范围规则,共享注册表则在请求处理期间保持不变。这样能够在省略部署身份、运行地址和私有配置的前提下,清楚记录设计取舍。