资讯动态

Agent Zero 插件开发完全指南:从 plugin.yaml 到 Plugin Hub 发布全流程

发布时间:2026/9/15 3:18:34 来源:尧图企业网站定制
Agent Zero 插件开发完全指南从 plugin.yaml 到 Plugin Hub 发布全流程【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zeroAgent Zero 的插件系统允许开发者以标准化的全栈结构后端 API、工具、生命周期钩子、WebUI 扩展与设置界面扩展框架能力。本文以官方技能文档 skills/a0-create-plugin/SKILL.md 为核心骨架结合 plugins/AGENTS.md、helpers/plugins.py 等源码级依据系统讲解插件清单编写、目录布局、前端 Store Gate 模式、后端 AgentContext 集成、execute.py与hooks.py生命周期脚本以及从本地插件到 Plugin Index 社区发布的完整流程。读完本文你将能够独立创建一个结构合规、可配置、可发布的 Agent Zero 插件。一、动工之前先确定本地插件还是社区插件创建插件的第一步不是写代码而是回答一个关键问题——这个插件是仅本地使用还是打算**发布到社区插件索引Plugin Index**供其他用户安装两种形态的存放位置与工程要求完全不同形态存放位置是否需要代码仓库后续流程本地插件Local plugin/a0/usr/plugins/plugin_name/不需要直接编写 manifest 并进入开发社区插件Community plugin独立 GitHub 仓库运行时 manifest 位于仓库根目录需要构建本地验证通过后再向插件索引仓库提交 index 条目[!IMPORTANT]新插件必须创建在/a0/usr/plugins/plugin_name/下。/a0/plugins/目录专门保留给框架自带的核心系统插件不应用于存放自定义插件。这一点在 plugins/AGENTS.md 中被定义为插件架构契约打包的系统插件目录名与 manifestname一律以_开头以避免与社区插件冲突。二、插件清单plugin.yaml一切发现的起点每个插件目录必须包含plugin.yaml否则框架根本不会发现它。helpers/plugins.py 中PluginMetadata模型helpers/plugins.py完整定义了运行时清单的字段集合name: my_plugin # 社区插件必填必须与目录名一致^[a-z0-9_]$ title: My Plugin description: What this plugin does. version: 1.0.0 settings_sections: - agent per_project_config: false per_agent_config: false各字段的语义与约束name仅允许小写字母、数字、下划线正则^[a-z0-9_]$不允许连字符。提交到 Plugin Index 时 CI 会强制校验name必须与索引目录名完全一致否则校验失败。title/description/version用于插件列表 UI 的展示。description应一句话说明插件做什么社区提交时长度上限为 500 字符。settings_sections控制 Settings 选项卡中哪些 Tab 会为该插件显示配置分区合法值为agent、external、mcp、developer、backup不需要配置分区时使用[]。per_project_config/per_agent_config设为true后启用项目级/Agent 档案级的配置切换能力详见下文插件设置的作用域。always_enabled仅供框架核心插件使用设为true会永久锁定插件为开启状态并禁用 UI 开关。从 helpers/plugins.py 可以看到get_toggle_state()首先检查always_enabled命中则直接返回enabled。激活机制默认开启用 toggle 文件控制从源码可以确认一个容易被忽略的事实插件默认处于开启状态。在 helpers/plugins.py 的get_enabled_plugins()中每个插件默认enabled True只有当用户目录中存在禁用标记.toggle-0时才被关闭反向恢复则依赖.toggle-1文件。也就是说新增插件即生效是框架的默认行为禁用插件本质上是写入标记文件而不是删除目录。最小可用插件docs/developer/plugins.md 给出了一个最小本地插件的形态——只需三样东西即可被框架发现并展示/a0/usr/plugins/plugin_name/ ├── plugin.yaml ├── README.md └── webui/对应最小可用的plugin.yamlname: my_plugin title: My Plugin description: A short sentence that explains what it does. version: 1.0.0官方文档的建议是第一个版本尽量小。一个只做一件可见事情的微型插件更容易测试、评审和分享。三、目录布局插件的标准文件结构一个功能完整的插件可以包含以下全部构件/a0/usr/plugins/name/ plugin.yaml # 必需运行时清单 execute.py # 可选用户主动触发的安装/维护/修复脚本 hooks.py # 可选框架运行时钩子函数 default_config.yaml # 可选默认设置兜底 README.md # 本地可选社区插件强烈建议提供 LICENSE # 本地可选存在时显示在插件列表 UI 中提交 Plugin Index 时仓库根目录必须提供 agents/ profile/agent.yaml # 可选随插件分发的 Agent 档案 api/ # API 处理器ApiHandler 基类 tools/ # 工具子类 helpers/ # 共享 Python 逻辑 prompts/ # 提示词模板 conf/ model_providers.yaml # 可选新增或覆盖模型提供商 extensions/ python/extension_point/ # 具名 Python 生命周期扩展点 python/_functions/module/qualname/start|end/ # 隐式 extensible 钩子 webui/point/ # HTML/JS 前端钩子扩展 webui/ config.html # 可选插件设置 UI my-modal.html # 完整插件页面 my-store.js # Alpine store需要特别注意的扩展点布局规则plugins/AGENTS.md 中的本地契约不要使用已废弃的扁平化可扩展路径形式extensions/python/module_qualname_start|end/。当前运行时只为隐式extensible钩子解析深目录形式_functions/module/qualname/start|end且该布局会保留模块与嵌套 qualname 的每一层段。插件扩展布局必须使用三种规范形态extensions/python/point/、extensions/python/_functions/module/qualname/start|end/、extensions/webui/point/。插件设置默认值属于default_config.yaml运行期用户设置存放在usr/下详见下文配置解析顺序。插件模型提供商覆盖放在插件自己的conf/model_providers.yaml会在基础conf/model_providers.yaml之后合并。插件本地 Python 代码的导入规则插件内的 Python 模块必须使用完全限定路径usr.plugins.plugin_name...导入from usr.plugins.my_plugin.helpers.runtime import do_work import usr.plugins.my_plugin.helpers.state as state这样插件可以保留普通的helpers/目录而无需改名成name_helpers同时避免了sys.path注入和符号链接安装步骤。以下两种方式都是反模式sys.path.insert(0, ...) from helpers.runtime import do_work from plugins.my_plugin.helpers.runtime import do_work补充说明plugins.plugin_name...形式的导入仅对从plugins/树随框架一起发布的核心系统插件有效用户/社区插件位于usr/plugins/下必须走usr.plugins.plugin_name...。这也是 plugins/AGENTS.md 明确定义的契约差异。四、前端强制模式Store Gate、独立 Store 与 A0 通知官方技能文档把以下三条列为开发 WebUI 插件的强制模式任何组件都必须遵守。1. Store Gate 模板防竞态条件为避免竞态条件与 undefined 错误每个组件都必须使用这层包装div x-data template x-if$store.myPluginStore div x-init$store.myPluginStore.onOpen() x-destroy$store.myPluginStore.cleanup() !-- Content goes here -- /div /template /divx-if确保 store 已挂载后才渲染内容x-init/x-destroy负责进入与离开时的初始化和清理。2. 独立 Store 模块Store 逻辑必须放在独立的.js文件中禁止在 HTML 内部使用alpine:init监听器// webui/my-store.js import { createStore } from /js/AlpineStore.js; export const store createStore(myPluginStore, { status: idle, init() { ... }, onOpen() { ... }, cleanup() { ... } });随后在 HTML 的head中导入head script typemodule src/plugins/plugin_name/webui/my-store.js/script /head仓库内几乎每个内置插件都遵循这一模式例如 plugins/_browser/webui/browser-store.js、plugins/_email_integration/webui/email-config-store.js 等均可作为参考实现。3. 用户反馈只用 A0 通知系统禁止通过内联提示框例如绑定store.error的红色div展示错误或成功信息。统一走项目通知系统保持 toast 与通知历史一致错误toastFrontendError(message, My Plugin)或$store.notificationStore.frontendError(...)成功toastFrontendSuccess(message, My Plugin)警告/信息toastFrontendWarning、toastFrontendInfo均来自/components/notifications/notification-store.js应在 store 中导入并调用这些函数不要在模板里渲染专门的错误/成功区块。完整的通知 API 见 docs/developer/notifications.md。这一约定同时被 plugins/AGENTS.md 与 webui/components/plugins/AGENTS.md 双重确认插件 UI 必须使用 A0 通知系统来反馈错误、警告、成功与信息而不是内联的成功/错误框。五、插件设置config.html 与设置模态框契约如果插件需要用户可配置的设置项添加webui/config.html即可。系统会自动检测该文件并根据plugin.yaml中的settings_sections在对应选项卡显示设置按钮。设置模态框契约模态框会提供Project Agent profile上下文选择器。插件设置包装器通过$store.pluginSettingsPrototype实例化一个本地模态框上下文。在config.html内插件字段绑定到config.*模态框级状态与操作使用context.*html head titleMy Plugin Settings/title script typemodule import { store } from /components/plugins/plugin-settings-store.js; /script /head body div x-data input x-modelconfig.my_key / input typecheckbox x-modelconfig.feature_enabled / /div /body /html模态框的 Save 按钮会把config持久化到正确作用域项目/Agent 档案/全局下的config.json。从源码看这个契约的实现位于 webui/components/plugins/plugin-settings-store.js_resolveScope()会根据per_project_config/per_agent_config决定设置写入的项目与档案作用域loadSettings()通过POST /plugins的get_config动作读取配置save()通过save_config动作写入此外还支持resetToDefault重置为插件默认值与list_configs/delete_config跨作用域配置管理。config.html最终通过settingsComponentHtml以x-component path/plugins/name/webui/config.html的方式注入设置弹窗。设置解析顺序作用域优先级plugins/AGENTS.md 明确了插件设置的解析顺序这是排查我的配置为什么没生效的关键项目/档案project/profile→ 项目project→ 用户/档案user/profile→ 用户插件配置user plugin config→ 打包的default_config.yamlbundled default对应到 helpers/plugins.py 的get_plugin_config()实现优先在所有可能位置查找config.json按项目/档案作用域找不到时回退到插件目录下的default_config.yaml兜底且回退默认值时还会应用环境变量覆盖_apply_defaults_from_env使用__连接的plugin_name__key环境变量名规则。侧边栏按钮入口点若插件需要从侧边栏进入按以下规范挂载扩展点sidebar-quick-actions-main-start样式类classconfig-button放置位置x-move-after.config-button#dashboard动作clickopenModal(/plugins/plugin_name/webui/my-modal.html)该扩展点在 webui/components/sidebar/top-section/quick-actions.html 中以x-extension idsidebar-quick-actions-main-start/x-extension的形式存在config-button类与#dashboard断点也由该文件及其 CSS 提供。六、后端 API 与 AgentContext导入路径规范后端 Python 代码必须使用以下导入路径禁止sys.pathhack 与依赖符号链接的导入from agent import AgentContext, AgentContextType from initialize import initialize_agent from usr.plugins.name.helpers.module import ... # 插件本地模块主动发送消息插件可以主动向 Agent 上下文投递用户消息并等待结果from agent import AgentContext from helpers.messages import UserMessage context AgentContext.use(context_id) task context.communicate(UserMessage(Message text)) response await task.result()从源码看AgentContext定义在 agent.py其communicate()方法agent.py接受UserMessage并按广播级别投递AgentContextType枚举agent.py区分USER、TASK、BACKGROUND三类上下文插件可按需选择使用场景。后端读取与保存插件设置from helpers.plugins import get_plugin_config, save_plugin_config # 运行期读取有运行中的 agent 时自动从上下文解析项目/档案 settings get_plugin_config(my-plugin, agentagent) or {} # 显式指定写入目标项目/档案作用域 save_plugin_config( my-plugin, project_namemy-project, agent_profiledefault, settingssettings, )save_plugin_config在 helpers/plugins.py 中会把设置序列化为 JSON 写入对应作用域的config.json同时它是一个extension.extensible函数允许其他扩展通过钩子改写保存结果。七、execute.py用户主动触发的脚本如果插件需要用户主动触发的安装、安装后处理、维护或其他手工操作在插件根目录添加execute.py。适合放在这里的典型工作包括安装依赖或下载模型/资源插件被复制到位后执行安装后步骤重建缓存、索引或生成文件执行迁移、修复步骤或用户可能需要稍后再次运行的同步任务仅在用户明确请求时才执行的周期性维护关键原则execute.py只承载用户发起的工作。如果行为属于框架内部、应随插件生命周期自动发生请改用hooks.py或生命周期扩展。插件副作用的第一原则不要对系统做超出插件生命周期的永久性修改。插件被删除后不应残留符号链接、未托管的服务或插件自有路径之外的散落文件——除非用户明确要求该行为且插件文档说明了清理方式。标准模板如下import subprocess import sys def main(): print(Installing plugin dependencies...) result subprocess.run( [sys.executable, -m, pip, install, requests2.31.0], textTrue, ) if result.returncode ! 0: print(ERROR: Installation failed) return result.returncode print(Refreshing plugin resources...) # Add post-install, repair, migration, or maintenance logic here. print(Done.) return 0 if __name__ __main__: sys.exit(main())用户从Plugins UI触发它。把它当作手工、可重复运行的操作成功返回0失败返回非零并打印进度让用户了解发生了什么尽可能做到多次运行安全若不可重复运行则应检测状态并输出清晰提示。八、hooks.py框架运行时钩子如果插件需要框架内部钩子点在插件根目录添加hooks.py。框架通过helpers.plugins.call_plugin_hook(...)按函数名调用导出的钩子函数。hooks.py运行在Agent Zero 框架运行时内而不是独立的 Agent 执行环境中。适用于安装钩子、更新前钩子、插件注册、缓存建立、文件准备等框架内部操作。当前内置用法可在 plugins/_plugin_installer/helpers/install.py 中看到调用链插件安装器在把插件放入usr/plugins/后调用hooks.py中的install()插件更新器在拉取新代码到位前立即调用pre_update()插件卸载器在删除插件目录前调用uninstall()——用它清理install()创建的任何依赖或状态钩子函数可以是同步或异步的call_plugin_hook在 helpers/plugins.py 中会通过asyncio.iscoroutinefunction检测并安全调度异步钩子。钩子应可逆、可安全清理优先使用框架托管的状态与插件自有路径避免永久性系统修改。环境定向规则重要如果hooks.py直接运行sys.executable -m pip install ...依赖会被装进正在运行 Agent Zero 的那个 Python 环境。对于框架运行时内插件所需的依赖这是正确的。但如果依赖属于独立的 Agent 运行时或OS 级工具不要假定当前环境正确而应在子进程中显式切换目标调用目标运行时的精确 Python 解释器在子进程中先激活目标虚拟环境再运行pip或从配置了预期环境的子进程中运行相应的 OS 包管理器在 Docker 场景下通常意味着hooks.py只会影响/opt/venv-a0除非你特意指定/opt/venv或其他环境。九、社区插件GitHub 仓库 Plugin Index 提交如果用户选择了社区插件在本地构建并测试通过后还需要走以下发布流程。1. 仓库结构插件内容放在仓库根目录插件必须拥有自己的独立代码仓库插件内容位于仓库根目录不能在子文件夹中your-plugin-repo/ ← GitHub 仓库根目录 ├── plugin.yaml ← 运行时清单必须包含 name 字段 ├── default_config.yaml ├── README.md ├── LICENSE ← 提交 Plugin Index 前仓库根目录必须提供 ├── api/ ├── tools/ ├── extensions/ └── webui/仓库根目录的运行时plugin.yaml必须包含name字段且与索引目录名精确一致name: my_plugin # 必填 - 必须与索引目录名完全一致 title: My Plugin description: What this plugin does. version: 1.0.02. 索引清单 index.yaml与运行时清单不同Plugin Index 使用独立的index.yaml它只描述可发现性——不是运行时plugin.yamlschema 也不同title: My Plugin description: What this plugin does. github: https://github.com/yourname/your-plugin-repo tags: - tools - example screenshots: # 可选最多 5 个完整图片 URL - https://raw.githubusercontent.com/yourname/your-plugin-repo/main/docs/screen1.png必填字段title、description、github可选tags最多 5 个推荐参考索引仓库维护的推荐标签列表、screenshots最多 5 个 URL。CI 还会校验你的远端plugin.yaml包含与索引目录名精确一致的name字段。3. 提交流程Fork 插件索引仓库a0-plugins。在 fork 中创建目录plugins/your_plugin_name/目录名仅限小写字母、数字、下划线^[a-z0-9_]$不能有连字符必须与远端plugin.yaml的name字段完全一致在目录内添加index.yaml可选添加方形缩略图thumbnail.png/thumbnail.jpg/thumbnail.webp≤ 20 KB。打开 Pull Request——一个 PR 只能新增一个插件目录。CI 自动校验维护者评审后合并。提交约束汇总目录名唯一、稳定、^[a-z0-9_]$以_开头的目录保留给内部使用title最长 50 字符description最长 500 字符index.yaml总大小上限 2000 字符如需完整的引导式贡献流程含 git 操作可进一步阅读 skills/a0-contribute-plugin/SKILL.md发布前的合规自查可参考 skills/a0-review-plugin/SKILL.md 与 docs/developer/sharing-and-safety.md。十、Plugin Index 与 Plugin HubPlugin Index是社区插件中心a0-plugins 仓库。Agent Zero 通过内置的Plugin Hub向用户暴露索引插件用户可以从Plugins对话框的Browse选项卡或通过Install按钮打开 Plugin Hub查看插件详情并直接在 UI 中安装。安装、更新、卸载的底层实现位于 plugins/_plugin_installer支持 ZIP、Git 与 Plugin Index 三种来源社区插件在本地以 git 仓库形态管理helpers/plugins.py 中的get_custom_plugins_updates()通过对比本地与远端提交来报告可更新状态。十一、框架如何发现与加载插件源码级机制理解插件系统如何工作能显著降低排查问题的成本。以下是几个核心机制的源码依据双根目录发现用户优先get_plugin_roots()helpers/plugins.py返回usr/plugins/与plugins/两个根用户目录优先同名插件用户目录覆盖系统目录find_plugin_dir()先查用户目录再查默认目录见 helpers/plugins.py。清单驱动列表get_enhanced_plugins_list()helpers/plugins.py按目录约定扫描逐一校验plugin.yaml是否存在并探测webui/main.html主界面、webui/config.html设置界面、README.md、LICENSE、execute.py、缩略图与 git 提交信息最终呈现在插件列表 UI 中。变更热响应框架通过 watchdog 监听插件根、项目级插件覆盖projects/*/.a0proj/plugins/等与 Agent 档案级插件目录Python 文件变更会触发模块命名空间清理purge_namespace(usr.plugins)带 WebUI 扩展的插件变更会通过send_frontend_reload_notification()提示前端刷新页面helpers/plugins.py。插件路由插件静态资源路由为GET /plugins/name/pathAPI 处理器为POST /api/plugins/name/handler管理动作为POST /api/plugins见 plugins/AGENTS.md。十二、动手实践一个可落地的迷你插件想最快验证以上全部概念官方在 docs/guides/create-plugin.md 中提供了一个端到端的实战示例本地插件unread_dot在聊天列表中为收到新活动但未被选中的聊天显示脉冲圆点。它刻意保持前端专用——无服务端端点、无工具、无依赖、无网络调用只触碰 Web UI 与一个localStorage键。其最终结构印证了本文第三节的布局规则/a0/usr/plugins/unread_dot/ ├── plugin.yaml ├── README.md ├── extensions/ │ └── webui/ │ ├── apply_snapshot_before/ │ │ └── track-unread.js │ └── initFw_end/ │ └── bootstrap-unread-dot.js └── webui/ ├── unread-dot.css └── unread-dot-store.js其中initFw_end/bootstrap-unread-dot.js在 Web UI 启动后加载 store 与样式apply_snapshot_before/track-unread.js监听状态快照以察觉其他聊天的变化。你可以直接向 Agent Zero 下达类似这样的指令来创建它Use the a0-create-plugin skill. Create a local-only plugin named unread_dot in /a0/usr/plugins/unread_dot. The plugin should show a pulsing dot in the chat list whenever a non-selected chat receives new agent activity. Keep it minimal and frontend-only: - no external dependencies; - no backend API; - no tools; - no network calls.创建或修改插件后需重启 Agent Zero以便重建 Web UI 扩展列表随后新建聊天、发送一条短提示词、立刻切到其他聊天即可验证圆点是否按预期出现与清除。验证通过后可再用 skills/a0-review-plugin/SKILL.md 按阶段清单、结构、代码模式、安全与索引评审得到 PASS/WARN/FAIL 结论。结语Agent Zero 的插件系统遵循清单驱动、目录约定、作用域配置、钩子可逆四大设计原则plugin.yaml决定插件是否被发现目录布局决定扩展点挂载方式config.html决定用户如何配置execute.py与hooks.py分别承载用户主动操作与框架生命周期行为。本地插件usr/plugins/与社区插件独立仓库 Plugin Index 提交两套流程边界清晰。掌握本文覆盖的契约后无论是为个人工作流添加一个前端小功能还是构建一个带后端 API 与设置界面的完整插件并发布到社区你都可以基于 skills/a0-create-plugin/SKILL.md、plugins/AGENTS.md 与 helpers/plugins.py 三份核心资料独立完成。【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价