尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Agent 工具注册与发现机制:从硬编码到插件式动态加载的架构演进
Agent 工具注册与发现机制从硬编码到插件式动态加载的架构演进一、硬编码工具的维护灾难每新增一个工具都要改核心代码Agent 的核心能力是调用工具——搜索信息、查询数据库、发送邮件、执行脚本。最初的实现通常是硬编码的 switch-casedef call_tool(tool_name, params): if tool_name search: return search_web(params[query]) elif tool_name calculator: return calculate(params[expression]) elif tool_name weather: return get_weather(params[city]) # 每次新增工具都要加一个 elif改核心代码当工具只有 3 个时这段代码没问题。当工具增加到 15 个时switch-case 变成了一面难以维护的代码墙。更糟的是——新增工具需要修改核心 Agent 逻辑、重新部署、重启服务。这在开源项目中意味着外部贡献者无法独立开发新工具每个工具 PR 都要等核心维护者合并。工具注册与发现机制是解药。它的核心思想是Agent 不关心工具的具体实现只关心工具的签名——名称、描述、参数 Schema。工具提供方按规范注册工具Agent 运行时动态发现并调用。graph TB subgraph Discovery[工具发现] D1[本地插件目录] D2[远程注册中心] D3[环境变量配置] end D1 -- R[工具注册表 Registry] D2 -- R D3 -- R R -- S[Schema 索引br/名称 描述 参数] subgraph Agent[Agent 运行时] A1[用户查询] -- A2[LLM 分析意图] A2 -- A3[从 Registry 匹配工具] A3 -- A4{工具存在?} A4 --|是| A5[调用工具执行] A4 --|否| A6[降级: 告知用户不支持] end subgraph Tools[已注册工具] T1[SearchTool] T2[CalculatorTool] T3[WeatherTool] T4[自定义插件 Tool] end S -- A3 A5 -- T1 A5 -- T2 A5 -- T3 A5 -- T4 style A6 fill:#ffd43b,color:#000 style A5 fill:#51cf66,color:#fff二、工具注册的核心抽象Tool 接口与 Register 机制工具注册系统的核心是一个统一的Tool接口和Registry容器。接口定义了每个工具必须具备的能力interface Tool { name: string; // 唯一标识 description: string; // 给 LLM 看的描述 parameters: JSONSchema; // 参数定义 execute(params: any): Promiseany; // 执行逻辑 }Registry负责管理所有已注册的工具提供注册、注销、查询三个能力。关键设计工具注册发生在 Agent 启动时而非运行时。这意味着工具的加载是一次性的不存在运行时动态替换的安全风险。三、完整的工具注册系统实现// tool-registry.ts import { z } from zod; // 工具接口定义 export interface ToolTInput any, TOutput any { name: string; description: string; schema: z.ZodSchemaTInput; execute(input: TInput): PromiseTOutput; } // 工具注册表 export class ToolRegistry { private tools: Mapstring, Tool new Map(); private loadedPlugins: Setstring new Set(); // 注册单个工具 register(tool: Tool): void { if (this.tools.has(tool.name)) { throw new Error(Tool ${tool.name} is already registered); } this.tools.set(tool.name, tool); } // 注销工具 unregister(name: string): void { this.tools.delete(name); } // 获取工具 get(name: string): Tool | undefined { return this.tools.get(name); } // 生成给 LLM 的 Function Calling Schema generateLLMSchema(): Array{ type: function; function: { name: string; description: string; parameters: any }; } { const schemas: Arrayany []; for (const tool of this.tools.values()) { schemas.push({ type: function, function: { name: tool.name, description: tool.description, parameters: this.zodToJSONSchema(tool.schema), }, }); } return schemas; } // 执行工具调用 async execute(name: string, input: any): Promiseany { const tool this.tools.get(name); if (!tool) { throw new Error(Tool ${name} not found. Available: ${this.listNames()}); } // 参数验证 const parsed tool.schema.safeParse(input); if (!parsed.success) { throw new Error(Invalid parameters for ${name}: ${parsed.error.message}); } return tool.execute(parsed.data); } listNames(): string[] { return Array.from(this.tools.keys()); } size(): number { return this.tools.size; } // Zod Schema 转 JSON Schema用于 Function Calling private zodToJSONSchema(schema: z.ZodSchema): any { // 使用 zod-to-json-schema 库转换 // 简化实现 return zodToJsonSchema(schema); } // 从插件目录加载工具动态发现 async loadPlugins(pluginDir: string): Promisenumber { const fs require(fs); const path require(path); if (!fs.existsSync(pluginDir)) return 0; const files fs.readdirSync(pluginDir); let loaded 0; for (const file of files) { if (!file.endsWith(.js) !file.endsWith(.ts)) continue; const pluginPath path.join(pluginDir, file); if (this.loadedPlugins.has(pluginPath)) continue; try { const plugin require(pluginPath); if (plugin.default typeof plugin.default object) { this.register(plugin.default); this.loadedPlugins.add(pluginPath); loaded; } } catch (err) { console.error(Failed to load plugin ${file}:, err); } } return loaded; } } // 工具实现示例 // 搜索工具 export const SearchTool: Tool { name: web_search, description: 搜索互联网信息。当需要查找实时信息时使用。, schema: z.object({ query: z.string().describe(搜索关键词), max_results: z.number().optional().default(5).describe(最大结果数), }), async execute(input) { // 实际调用搜索引擎 API const response await fetch(https://api.search.example.com?q${encodeURIComponent(input.query)}n${input.max_results}); return response.json(); }, }; // 计算器工具 export const CalculatorTool: Tool { name: calculator, description: 执行数学计算。支持 、-、*、/ 和括号。, schema: z.object({ expression: z.string().describe(数学表达式如 2 3 * 4), }), async execute(input) { try { // 安全计算使用 Function 在一些场景不安全实际应使用 math.js const result Function(use strict; return (${input.expression}))(); return { expression: input.expression, result }; } catch (err) { return { error: 计算失败: ${err.message} }; } }, }; // Agent 中使用 import OpenAI from openai; class Agent { private registry: ToolRegistry; private openai: OpenAI; constructor(registry: ToolRegistry) { this.registry registry; this.openai new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); } async chat(userMessage: string) { const messages: any[] [ { role: system, content: 你是一个 AI 助手可以使用工具帮助用户。 }, { role: user, content: userMessage }, ]; const response await this.openai.chat.completions.create({ model: gpt-4o, messages, tools: this.registry.generateLLMSchema(), }); const choice response.choices[0]; // 处理工具调用 if (choice.finish_reason tool_calls choice.message.tool_calls) { for (const toolCall of choice.message.tool_calls) { const args JSON.parse(toolCall.function.arguments); const result await this.registry.execute(toolCall.function.name, args); messages.push(choice.message); messages.push({ role: tool, tool_call_id: toolCall.id, content: JSON.stringify(result), }); } // 继续对话 const finalResponse await this.openai.chat.completions.create({ model: gpt-4o, messages, }); return finalResponse.choices[0].message.content; } return choice.message.content; } }四、动态加载的安全考量插件隔离动态加载的插件代码运行在 Agent 进程中没有沙箱隔离。恶意插件可以访问文件系统、环境变量、网络。安全策略插件应有签名验证通过 checksum 或 GPG 签名生产环境推荐使用 WASM 沙箱或子进程隔离加载前做静态分析AST 扫描是否访问敏感 API不适用场景工具数量固定且不需要外部贡献 5 个工具金融等严格安全审查的场景不允许动态加载未知代码Serverless 环境启动时间不包含插件扫描五、总结工具注册与发现机制将 Agent 的工具管理从硬编码升级为插件化。核心只有两个组件Tool接口定义工具契约和Registry管理工具生命周期。落地路径先定义Tool接口将现有的 3-5 个工具迁移到接口模式然后实现Registry和插件加载最后在 Agent 的 Function Calling 中集成。少即是多。不要在 3 个工具的时候就上插件系统——等到工具数量超过 8 个、或者有外部贡献者需要独立开发工具时再引入。
RELATED

相关推荐

考研数学、力扣算法 与 大模型底层研究、SCI公式、模型自研的核心关联

考研数学、力扣算法 与 大模型底层研究、SCI公式、模型自研的核心关联

大模型开发交流群:306671879 自研小参数模型和落地模型部署应用感兴趣的可以来 彻底打通:考研数学、力扣算法 与 大模型底层研究、SCI公式、模型自研的核心关联 很多AI博士都会卡在同一个致命误区:我学的数学是考研数学、算法是力扣刷题&…

📅 2026/9/16 4:50:02
为什么你的提示词总被MJ“理解错”?——神经提示工程视角下的语义锚点定位法(仅限前500名设计师掌握)

为什么你的提示词总被MJ“理解错”?——神经提示工程视角下的语义锚点定位法(仅限前500名设计师掌握)

更多请点击: https://kaifayun.com 第一章:为什么你的提示词总被MJ“理解错”?——神经提示工程视角下的语义锚点定位法(仅限前500名设计师掌握) MidJourney 的文本到图像生成并非简单地“读取字面意思”,…

📅 2026/8/22 19:39:52
Agent Memory 设计笔记:从短期上下文到长期经验

Agent Memory 设计笔记:从短期上下文到长期经验

echo-agent 前身为 2025 年 11 月启动的个人助理项目 fubot,最初面向长期陪伴型个人智能体,围绕认知记忆、上下文延续、用户偏好沉淀、任务闭环与持续自我优化展开。随着真实场景迭代,项目逐步形成多入口接入、统一事件模型、消息总线、Agent…

📅 2026/8/22 20:15:52
MORE NEWS

更多资讯

📰

AI结合优化测序与机器学习实现早期肺癌筛查技术全流程解析

最近几天,一篇新研究在AI医疗的圈子里传得挺热:AI结合优化后的测序方案,再用机器学习方法做分类,能在比较早的阶段把肺癌患者从普通筛查人群里识别出来。我花时间把这篇研究公开的技术路线、补充材料和分析流程完整过了一遍&#…

📰

超级端口转发工具V3.0:让Windows端口转发可控、可看、可优化

做Windows下的端口转发工具,最开始其实就是被游戏联机给整烦了。家里两台电脑,一台主力机一台客厅小主机,想把游戏串流过去玩,结果折腾半天发现根本连不通——问题不在游戏本身,而是本地网络压根没把端口映射对。后来用…

📰

RS485物理层工程语言:从MAX485芯片到R7KA8D2KFLCAC链路设计

1. 标题背后的通信技术真相:MAX485不是“芯片”,R7KA8D2KFLCAC不是“型号”,而是一套工业级RS485链路设计语言刚看到这个标题时,我下意识点开查了三遍数据手册——不是怀疑自己眼花,而是因为“R7KA8D2KFLCAC”这个字符…

📰

端口转发工具V3.0实战:低延迟游戏模式与智能规则引擎详解

最近把手里那套端口转发工具从头到尾重写了一遍,升级到 V3.0 之后,最直观的感受就是:游戏链路的延迟终于降下来了,规则管理也比以前清晰太多。如果你也碰过 Windows 下的端口转发,大概能明白我在说什么——市面上的方案…

📰

HDC3120与瑞萨MCU的温湿度传感器实战应用全攻略

如果你正在做一个环境监测、智能家居或者农业大棚的项目,温湿度传感器肯定是绕不开的核心器件。市面上可选方案不少,但我最近一个产品里正好用了 HDC3120 传感器搭配 R7KA8D2KFLCAC 主控来实现湿度与温度测量,整套方案跑下来的体验比预期要顺…

📰

阿里云RAG系统自动化评测实战:Ragas+百炼+PGVector

1. 这不是“刷题”,而是用工程思维拆解大模型评测的实战现场你手里的这份《阿里云大模型高级工程师ACP习题集》2.4节,标题写着“自动化评测答疑机器人的表现”,但实际考的从来不是“怎么背答案”,而是你在真实项目里——当客户指着…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬