ADK.js PluginManager教程:扩展Agent功能的插件系统
ADK.js是一个开源的、代码优先的TypeScript工具包,用于构建、评估和部署复杂的AI代理,具有灵活性和控制力。PluginManager作为ADK.js的核心组件,提供了强大的插件系统,让开发者能够轻松扩展AI Agent的功能,实现自定义日志记录、性能监控、请求拦截等高级特性。## 什么是PluginManager?PluginManager是ADK.js中负责插件注册和执行的
ADK.js PluginManager教程:扩展Agent功能的插件系统
ADK.js是一个开源的、代码优先的TypeScript工具包,用于构建、评估和部署复杂的AI代理,具有灵活性和控制力。PluginManager作为ADK.js的核心组件,提供了强大的插件系统,让开发者能够轻松扩展AI Agent的功能,实现自定义日志记录、性能监控、请求拦截等高级特性。
什么是PluginManager?
PluginManager是ADK.js中负责插件注册和执行的核心类,它能够在SDK执行生命周期的关键节点协调插件回调的调用。通过PluginManager,开发者可以注册多个插件,实现对Agent行为的全局干预和扩展。
PluginManager的核心特性包括:
- 插件注册与管理:支持添加、检索插件,确保插件名称的唯一性
- 生命周期回调:在Agent运行、工具调用、模型请求等关键阶段触发插件回调
- 短路执行策略:如果某个插件回调返回非undefined值,后续插件将停止执行
PluginManager的核心功能
插件注册机制
PluginManager通过registerPlugin方法管理插件,确保每个插件名称的唯一性。当尝试注册重复名称的插件时,将抛出错误:
// 插件注册逻辑 [core/src/plugins/plugin_manager.ts]
registerPlugin(plugin: BasePlugin): void {
if (this.plugins.has(plugin)) {
throw new Error(`Plugin '${plugin.name}' already registered.`);
}
if (Array.from(this.plugins).some(p => p.name === plugin.name)) {
throw new Error(`Plugin with name '${plugin.name}' already registered.`);
}
this.plugins.add(plugin);
logger.info(`Plugin '${plugin.name}' registered.`);
}
生命周期回调系统
PluginManager提供了丰富的生命周期回调,覆盖了从用户消息处理到Agent运行、工具调用和模型请求的完整流程。主要回调包括:
- 用户消息处理:
onUserMessageCallback- 在收到用户消息时触发 - Agent运行:
beforeRunCallback和afterRunCallback- 在Agent运行前后执行 - 工具调用:
beforeToolCallback和afterToolCallback- 在工具调用前后执行 - 模型请求:
beforeModelCallback和afterModelCallback- 在模型请求前后执行 - 错误处理:
onModelErrorCallback和onToolErrorCallback- 处理模型和工具调用错误
插件执行流程
PluginManager采用"短路执行"策略,当某个插件回调返回非undefined值时,将停止后续插件的执行并返回该值。这种机制允许插件拦截和修改执行流程,实现诸如缓存、权限控制等高级功能。
执行逻辑如下:
// 插件执行核心逻辑 [core/src/plugins/plugin_manager.ts]
private async runCallbacks(
plugins: Set<BasePlugin>,
callback: (plugin: BasePlugin) => Promise<unknown>,
callbackName: string,
): Promise<unknown> {
for (const plugin of plugins) {
try {
const result = await callback(plugin);
if (result !== undefined) {
logger.debug(
`Plugin '${plugin.name}' returned a value for callback '${
callbackName}', exiting early.`);
return result;
}
} catch (e) {
const errorMessage = `Error in plugin '${
plugin.name}' during '${callbackName}' callback: ${e}`;
logger.error(errorMessage);
throw new Error(errorMessage);
}
}
return undefined;
}
如何创建自定义插件
创建自定义插件非常简单,只需继承BasePlugin类并实现所需的回调方法。以下是创建一个简单日志插件的步骤:
1. 创建插件类
import { BasePlugin } from '../core/src/plugins/base_plugin.ts';
import { BaseTool } from '../core/src/tools/base_tool.ts';
import { ToolContext } from '../core/src/tools/tool_context.ts';
export class ToolLoggerPlugin extends BasePlugin {
constructor() {
super('tool_logger');
}
override async beforeToolCallback({ tool, toolArgs, toolContext }: {
tool: BaseTool;
toolArgs: Record<string, unknown>;
toolContext: ToolContext;
}): Promise<Record<string, unknown> | undefined> {
console.log(`[${this.name}] Calling tool '${tool.name}' with args: ${JSON.stringify(toolArgs)}`);
return undefined;
}
override async afterToolCallback({ tool, result }: {
tool: BaseTool;
toolArgs: Record<string, unknown>;
toolContext: ToolContext;
result: Record<string, unknown>;
}): Promise<Record<string, unknown> | undefined> {
console.log(`[${this.name}] Tool '${tool.name}' finished with result: ${JSON.stringify(result)}`);
return undefined;
}
}
2. 注册插件到Runner
import { Runner } from '../core/src/runner/runner.ts';
import { ToolLoggerPlugin } from './tool_logger_plugin.ts';
// 创建Runner实例并注册插件
const runner = new Runner({
// ...其他配置
plugins: [new ToolLoggerPlugin()],
});
内置插件介绍
ADK.js提供了一些实用的内置插件,可以直接使用:
LoggingPlugin
日志插件,用于记录Agent执行过程中的关键事件和数据。源码位于[core/src/plugins/logging_plugin.ts]。
SecurityPlugin
安全插件,提供输入验证和权限检查功能,保护Agent免受恶意输入的影响。源码位于[core/src/plugins/security_plugin.ts]。
插件开发最佳实践
1. 单一职责原则
每个插件应专注于单一功能,如日志记录、性能监控或缓存。这使得插件更易于维护和复用。
2. 避免副作用
插件应尽量避免修改外部系统状态,保持功能的纯粹性和可预测性。
3. 错误处理
插件应妥善处理内部错误,避免影响整个Agent的执行:
async beforeToolCallback({ tool, toolArgs }: {
tool: BaseTool;
toolArgs: Record<string, unknown>;
toolContext: ToolContext;
}): Promise<Record<string, unknown> | undefined> {
try {
// 插件逻辑
} catch (error) {
logger.error(`Plugin error: ${error}`);
// 返回undefined继续执行
return undefined;
}
}
4. 文档注释
为插件和回调方法提供清晰的文档注释,说明功能、参数和返回值。
常见问题解答
Q: 插件执行顺序如何确定?
A: 插件按照注册顺序执行,先注册的插件先执行。如果需要控制执行顺序,可以调整插件注册的顺序。
Q: 如何在插件中共享数据?
A: 可以使用InvocationContext或ToolContext来在插件之间共享数据,这些上下文对象在整个执行过程中保持不变。
Q: 插件可以修改Agent的行为吗?
A: 是的,通过在回调中返回非undefined值,可以修改Agent的输入、工具参数或模型响应,甚至可以短路执行流程。
总结
ADK.js的PluginManager提供了一个灵活而强大的插件系统,让开发者能够轻松扩展AI Agent的功能。通过本文介绍的PluginManager核心概念、使用方法和最佳实践,你可以开始创建自己的插件,为ADK.js Agent添加日志记录、性能监控、安全验证等各种功能。
无论是构建简单的工具调用日志插件,还是复杂的模型请求缓存系统,PluginManager都能为你提供所需的基础设施和灵活性,帮助你构建更强大、更可靠的AI Agent应用。
更多推荐




所有评论(0)