首页
/ ADK.js扩展机制全解析:打造定制化AI代理

ADK.js扩展机制全解析:打造定制化AI代理

2026-03-15 05:19:16作者:凌朦慧Richard

概念解析:探索ADK.js扩展架构

1.核心扩展点:处理器与钩子

在ADK.js框架中,LlmAgent(大语言模型代理)是构建AI应用的核心组件。它提供了两种主要扩展机制:处理器(Processors)钩子(Hooks)

  • 处理器:是实现特定功能的模块化组件,用于处理LLM请求的完整生命周期
  • 钩子:系统预留的功能扩展接口,允许在代理运行的关键节点插入自定义逻辑

ADK.js代理扩展架构图

2.技术选型决策树:选择合适的扩展方式

在开发扩展前,可根据以下决策路径选择合适的扩展方式:

  1. 需求复杂度:简单修改用钩子,完整功能用处理器
  2. 执行时机:请求处理用处理器,生命周期干预用钩子
  3. 复用需求:跨项目复用用处理器,单次使用用钩子
  4. 执行顺序:需要明确顺序用处理器,无顺序要求用钩子

[!TIP] 处理器适合构建可复用的功能模块,钩子适合快速实现特定场景的定制逻辑。

实践案例:从零构建扩展功能

3.打造专属请求管道:自定义处理器开发

以下是一个实现请求加密的自定义处理器,可保护敏感数据在传输过程中的安全性:

import { BaseLlmRequestProcessor, InvocationContext, LlmRequest } from '../core/src/agents/base_llm_processor.ts';
import { EncryptionService } from '../utils/encryption_service.ts';

/**
 * 敏感数据加密处理器
 * 功能:加密请求中的敏感信息,保护数据传输安全
 */
class SensitiveDataEncryptionProcessor extends BaseLlmRequestProcessor {
  // 定义需要加密的字段
  private sensitiveFields = ['apiKey', 'credentials', 'personalInfo'];
  
  async *runAsync(
    invocationContext: InvocationContext, 
    llmRequest: LlmRequest
  ): AsyncGenerator<Event, void, void> {
    // 🔒 加密敏感数据(核心逻辑)
    this.encryptSensitiveData(llmRequest);
    
    // 📝 记录处理事件
    yield this.createProcessingEvent(
      invocationContext, 
      `已加密${this.sensitiveFields.length}个敏感字段`
    );
    
    // ⏭️ 将处理后的请求传递给下一个处理器
    return llmRequest;
  }
  
  // 实现具体的加密逻辑
  private encryptSensitiveData(request: LlmRequest) {
    // 遍历所有内容部分
    request.contents.forEach(content => {
      if (content.parts && content.parts.length > 0) {
        content.parts.forEach(part => {
          // 检查是否为文本类型
          if (typeof part.text === 'string') {
            // 对每个敏感字段进行加密
            this.sensitiveFields.forEach(field => {
              if (part.text.includes(field)) {
                part.text = EncryptionService.encrypt(part.text);
              }
            });
          }
        });
      }
    });
  }
  
  // 创建处理事件辅助方法
  private createProcessingEvent(context: InvocationContext, message: string) {
    return {
      invocationId: context.invocationId,
      author: 'SensitiveDataEncryptionProcessor',
      content: { parts: [{ text: message }] },
      timestamp: new Date().toISOString()
    };
  }
}

注册自定义处理器:

// 导入必要的模块和处理器
import { LlmAgent } from '../core/src/agents/llm_agent.ts';
import { 
  BASIC_LLM_REQUEST_PROCESSOR,
  IDENTITY_LLM_REQUEST_PROCESSOR 
} from '../core/src/agents/processors/built_in_processors.ts';
import { SensitiveDataEncryptionProcessor } from './processors/sensitive_data_encryption_processor.ts';

// 创建并配置LlmAgent
const secureAgent = new LlmAgent({
  name: 'secure-finance-agent',
  model: 'gemini-pro',
  instruction: '你是一个处理财务数据的安全代理',
  // 注册处理器(注意顺序很重要)
  requestProcessors: [
    BASIC_LLM_REQUEST_PROCESSOR,      // 基础请求处理
    IDENTITY_LLM_REQUEST_PROCESSOR,   // 身份信息处理
    new SensitiveDataEncryptionProcessor()  // 自定义加密处理器
  ]
});

[!WARNING] 常见陷阱:处理器注册顺序错误会导致功能异常。确保基础处理器先于自定义处理器运行,以便正确构建请求基础结构。

4.三大必学钩子:重塑代理行为

钩子提供了在代理生命周期关键节点插入逻辑的能力。以下是三个最常用的钩子及其应用场景:

4.1 BeforeModel钩子:请求发送前的最终调整

// 实现请求限流钩子
const rateLimitHook = async ({ context, request }) => {
  // 获取当前时间戳
  const now = Date.now();
  // 从上下文中获取上次请求时间
  const lastRequestTime = context.get('lastRequestTime') || 0;
  // 设置请求间隔(1000ms)
  const MIN_INTERVAL = 1000;
  
  // ⏱️ 检查请求频率是否过高
  if (now - lastRequestTime < MIN_INTERVAL) {
    // 计算需要等待的时间
    const waitTime = MIN_INTERVAL - (now - lastRequestTime);
    console.log(`请求过于频繁,等待${waitTime}ms`);
    // 等待指定时间
    await new Promise(resolve => setTimeout(resolve, waitTime));
  }
  
  // 更新最后请求时间
  context.set('lastRequestTime', Date.now());
  // 返回修改后的请求(或不修改)
  return request;
};

4.2 AfterModel钩子:响应处理与优化

// 实现响应内容过滤钩子
const contentFilterHook = async ({ response }) => {
  if (!response || !response.content || !response.content.parts) {
    return response;
  }
  
  // 🔍 过滤不安全内容
  response.content.parts = response.content.parts.map(part => {
    if (typeof part.text === 'string') {
      // 替换敏感词
      return {
        ...part,
        text: part.text
          .replace(/敏感词1/g, '[已过滤]')
          .replace(/敏感词2/g, '[已过滤]')
      };
    }
    return part;
  });
  
  return response;
};

4.3 AfterTool钩子:工具调用结果处理

// 实现工具结果缓存钩子
const resultCacheHook = async ({ tool, args, response, context }) => {
  // 只缓存特定工具的结果
  if (tool.name !== 'data_fetcher') return response;
  
  // 🔑 创建缓存键
  const cacheKey = `tool:${tool.name}:${JSON.stringify(args)}`;
  
  // 💾 存储结果到缓存
  await context.cache.set(cacheKey, response, { 
    ttl: 3600000 // 缓存1小时
  });
  
  return response;
};

注册钩子到代理:

const agent = new LlmAgent({
  name: 'optimized-agent',
  model: 'gemini-pro',
  // 注册钩子
  beforeModelCallback: rateLimitHook,
  afterModelCallback: contentFilterHook,
  afterToolCallback: [
    resultCacheHook,
    // 可以注册多个钩子,按顺序执行
    async ({ response }) => {
      console.log('工具调用完成,处理结果长度:', response?.length || 0);
      return response;
    }
  ]
});

进阶技巧:构建企业级扩展

5.扩展开发Checklist

开发ADK.js扩展时,请确保完成以下验证步骤:

  1. 功能验证:确认扩展按预期工作,覆盖正常和边界情况
  2. 兼容性测试:验证与不同LLM模型和ADK.js版本的兼容性
  3. 性能基准:测量扩展对代理响应时间的影响(目标:<100ms)
  4. 错误处理:实现完善的错误捕获和恢复机制
  5. 安全审查:检查是否存在数据泄露或注入风险

6.性能优化指南

不同扩展方式的资源消耗对比:

扩展类型 内存占用 执行时间 适用场景
简单钩子 快(<10ms) 简单数据转换、日志记录
复杂钩子 中等(10-50ms) 数据过滤、缓存处理
基础处理器 中等(20-80ms) 请求格式化、基础转换
复杂处理器 慢(50-200ms) 加密、复杂内容生成

性能优化建议:

  • 避免在钩子中执行复杂计算或网络请求
  • 处理器中使用流式处理(async generator)减少内存占用
  • 对于频繁调用的扩展,考虑结果缓存
  • 复杂处理逻辑可考虑使用Web Worker避免阻塞主线程

7.完整扩展开发模板

以下是一个完整的ADK.js扩展开发模板,可作为开发新扩展的起点:

import { 
  BaseLlmRequestProcessor, 
  InvocationContext, 
  LlmRequest, 
  LlmResponse 
} from '../core/src/agents/base_llm_processor.ts';

/**
 * [扩展名称]处理器
 * 功能描述:[简要描述扩展功能]
 * 适用场景:[说明适合使用该扩展的场景]
 */
export class TemplateProcessor extends BaseLlmRequestProcessor {
  // 扩展配置选项
  private config: TemplateProcessorConfig;
  
  /**
   * 构造函数
   * @param config 处理器配置选项
   */
  constructor(config: Partial<TemplateProcessorConfig> = {}) {
    super();
    // 设置默认配置并合并用户配置
    this.config = {
      enabled: true,
      priority: 50,
      ...config
    };
  }
  
  /**
   * 处理器主逻辑
   * @param invocationContext 调用上下文
   * @param llmRequest LLM请求对象
   */
  async *runAsync(
    invocationContext: InvocationContext,
    llmRequest: LlmRequest
  ): AsyncGenerator<Event, void, LlmRequest> {
    try {
      // 1. 验证配置和输入
      if (!this.config.enabled) {
        yield this.createEvent(invocationContext, '处理器已禁用');
        return llmRequest;
      }
      
      // 2. 执行核心处理逻辑
      const processedRequest = this.processRequest(llmRequest);
      
      // 3. 生成处理事件
      yield this.createEvent(
        invocationContext, 
        `请求处理完成,修改了${this.getChangeCount()}处内容`
      );
      
      // 4. 返回处理后的请求
      return processedRequest;
    } catch (error) {
      // 错误处理
      yield this.createErrorEvent(invocationContext, error);
      // 出错时返回原始请求,确保流程继续
      return llmRequest;
    }
  }
  
  /**
   * 实际处理请求的方法
   * @param request 原始请求
   * @returns 处理后的请求
   */
  private processRequest(request: LlmRequest): LlmRequest {
    // 实现具体的请求处理逻辑
    // ...
    
    return request;
  }
  
  /**
   * 创建事件辅助方法
   */
  private createEvent(context: InvocationContext, message: string): Event {
    return {
      invocationId: context.invocationId,
      author: 'TemplateProcessor',
      content: { parts: [{ text: message }] },
      timestamp: new Date().toISOString()
    };
  }
  
  /**
   * 创建错误事件辅助方法
   */
  private createErrorEvent(context: InvocationContext, error: Error): Event {
    return {
      invocationId: context.invocationId,
      author: 'TemplateProcessor',
      content: { parts: [{ text: `处理错误: ${error.message}` }] },
      type: 'error',
      timestamp: new Date().toISOString()
    };
  }
  
  /**
   * 获取修改计数(示例辅助方法)
   */
  private getChangeCount(): number {
    // 实现统计修改次数的逻辑
    return 0;
  }
}

/**
 * 处理器配置接口
 */
interface TemplateProcessorConfig {
  enabled: boolean;
  priority: number;
  // 其他配置选项...
}

[!TIP] 扩展开发完成后,建议创建对应的单元测试,确保功能稳定性。可参考项目中test/agents/processors/目录下的测试文件结构。

总结

ADK.js提供的扩展机制为构建定制化AI代理提供了强大支持。通过处理器和钩子的灵活组合,开发者可以深度定制AI代理的行为,满足各种复杂业务需求。

无论是简单的数据转换还是复杂的请求处理流程,ADK.js的扩展架构都能提供清晰的实现路径。掌握这些扩展技术,将帮助你构建更智能、更安全、更高效的AI应用。

要开始使用ADK.js构建自定义扩展,可通过以下命令克隆项目:

git clone https://gitcode.com/GitHub_Trending/ad/adk-js
cd adk-js
npm install

然后参考core/src/agents/processors/目录下的内置处理器实现,开始你的扩展开发之旅。

登录后查看全文
热门项目推荐
相关项目推荐