Echo Agent 插件与技能开发指南:从零编写自定义 Skill 与 Plugin 的完整流程
Echo Agent 插件与技能开发指南:从零编写自定义 Skill 与 Plugin 的完整流程
本文面向新手,带你完整走通 Echo Agent 的扩展开发流程:用 Markdown 编写自定义 Skill(技能),用 Python 开发自定义 Plugin(插件),并覆盖目录结构、清单字段、权限模型、本地测试与发布等全部关键步骤。
Echo Agent 是一个面向长期运行与桌面协作的开源 AI Agent,提供常驻 Runtime、桌面 Agent、长期记忆与持续学习能力。你开发的 Skill 与 Plugin 在终端、Gateway、桌面端三种运行形态中全部生效,一次编写、处处可用。
一、先搞懂:Skill 与 Plugin 分别解决什么问题?
在动手之前,先建立正确的认知。Echo Agent 提供了两种互补的扩展机制:
| 特性 | 技能 (Skill) | 插件 (Plugin) |
|---|---|---|
| 形式 | Markdown 指令文件(SKILL.md) |
Python 代码模块 |
| 作用 | 教会 Agent 如何完成特定任务 | 注册新工具、监听生命周期事件 |
| 开发成本 | 🟢 低,只需写 Markdown | 🟡 中等,需要 Python 编程 |
| 能力范围 | 组合现有工具 | 新增工具、钩子拦截 |
| 发现方式 | skills/ 目录自动扫描 |
多来源发现机制(pip / 用户目录 / 项目目录) |
简单决策原则:想让 Agent「学会做事」→ 写 Skill;想给 Agent「装上新器官」→ 写 Plugin。
从上图可以看到,Skills 与 Plugins 都汇入统一的 Agent Runtime:Agent 根据你的意图自动选择技能、调用工具,插件注册的工具与内置工具一视同仁,无需你手动指定。
二、Skill 开发:一个 Markdown 文件教会 Agent 新本领
Skill 是 Echo Agent 的「知识扩展单元」。Agent 根据用户意图自动选择并执行合适的 Skill——你只需要描述想做什么,不用记住任何技能名称。
1. Skill 的目录结构
每个 Skill 是一个独立文件夹,核心是 SKILL.md 文件,可选附带脚本:
skills/
└── productivity/
└── my-skill/
├── SKILL.md # Skill 定义(必需)
└── scripts/ # 可选脚本
└── run.py
建议参考仓库内置的成熟示例:calculator 技能 展示了「纯知识 + 脚本辅助」的标准写法,skill-creator 技能 则是官方内置的「帮你写 Skill 的 Skill」。
2. SKILL.md 文件:frontmatter 是灵魂
每个 SKILL.md 由 YAML frontmatter + Markdown 正文组成:
---
name: calculator
description: "Math calculations, unit conversions, date/time arithmetic, and currency rates. Python-powered, no API needed for math."
version: 1.0.0
metadata:
echo:
tags: [Math, Calculator, Units, Utility]
risk_level: read
---
# Calculator
(正文:可执行的代码示例、命令与参数、注意事项……)
各字段说明:
| 字段 | 必需 | 说明 |
|---|---|---|
name |
是 | Skill 唯一标识(小写、连字符分隔,如 web-search) |
description |
是 | 功能描述——Agent 判断何时使用的唯一依据 |
version |
否 | 语义化版本号 |
metadata.echo.tags |
否 | 分类标签,用于搜索和过滤 |
metadata.echo.dependencies |
否 | 需要的 Python 包列表 |
metadata.echo.requires_env |
否 | 需要的环境变量(API Key) |
metadata.echo.risk_level |
否 | 风险等级:read / write / exec |
3. 三条黄金编写原则
① description 是核心。所有启用技能以「名称 + 分类 + 描述」的清单形式一次性注入系统提示,由模型自行判断本轮该用哪个。因此描述要:
- 明确列出能做什么(关键词要丰富)
- 说明不需要外部 API 的能力(降低使用门槛)
- 控制在 1-2 句内
# ✅ 好的 description
description: "Math calculations, unit conversions, date/time arithmetic, and currency rates. Python-powered, no API needed for math."
# ❌ 不好的 description
description: "一个计算器工具"
② 正文提供执行指导。Markdown 正文是 Agent 执行时的参考手册,应包含具体代码示例、可用命令与参数、常见用法模式和边界条件。
③ 脚本是可选的。Skill 可以是纯知识型(只有 SKILL.md,Agent 基于内容推理),也可以是脚本辅助型(附带 scripts/ 目录,Agent 调用脚本执行确定性任务)。确定性高、重复执行的代码建议写成脚本,避免每次让模型现场重写。
4. 按领域放入正确的分类目录
| 目录 | 领域 | 示例 |
|---|---|---|
creative/ |
创意生成 | 写作辅助、图片生成 |
development/ |
软件开发 | 代码执行、工作流编排 |
devops/ |
运维自动化 | Docker 管理、系统监控 |
productivity/ |
生产力 | 日程、任务管理 |
research/ |
研究分析 | 数据收集、文献整理 |
utility/ |
通用工具 | 计算器、文本处理 |
完整 35 个内置技能清单见 技能目录。
三、从零写一个完整 Skill 的五步流程
把前面的知识串起来,完整的开发流程如下:
第 1 步:想清楚触发场景 问自己三个问题:这个技能要支持什么功能?用户会怎么说话才应该触发它?哪些步骤是固定可脚本化的?
第 2 步:创建目录与 SKILL.md 按「分类目录 / 技能名」建文件夹,写好 frontmatter 与正文。正文要简短克制——上下文窗口是公共资源,只写模型确实需要、且自己不具备的知识。
第 3 步:按需编写脚本
把确定性操作放进 scripts/,并在 SKILL.md 中给出精确调用方式,例如:
python3 scripts/calc.py eval "2**32 - 1"
python3 scripts/calc.py convert 100 km mi
第 4 步:手动测试 启动 Agent,在对话中用自然语言触发:
echo-agent run # 在终端直接交互
echo-agent cli # 瘦客户端接入已运行的 Gateway 实例
启动后输入「帮我计算 2 的 32 次方减 1」,观察 Agent 是否正确选中你的技能。
第 5 步:(可选)加入评估数据集 在评估数据集中添加用例,用回归测试锁定触发行为:
- id: calculator_power
input: "计算 2 的 32 次方减 1"
expected_contains: ["4294967295"]
expected_tools: ["skill_run"]
✅ Skill 发布检查清单
- [ ]
SKILL.md包含有效的 YAML frontmatter - [ ]
name全局唯一(小写、连字符) - [ ]
description关键词丰富,与相近技能的描述能互相区分 - [ ] 正文包含可执行的代码示例
- [ ] 依赖已在
metadata中声明 - [ ] 放入了正确的分类目录
- [ ] 手动测试验证 Agent 能正确触发
💡 注意:技能之间没有互斥与优先级机制,区分度完全靠
description写出来。两个含义重叠的技能,模型只能靠措辞猜,结果就不稳定。
四、Plugin 开发:用 Python 注册新工具与钩子
当「组合现有工具」无法满足需求(比如要接入自己的数据库、内部 API),就需要开发 Plugin 了。
1. 插件目录结构与 plugin.yaml 清单
my-echo-plugin/
├── plugin.yaml # 插件清单(必需)
├── __init__.py # 入口模块
├── tools.py # 工具实现(可选)
└── hooks.py # 钩子实现(可选)
plugin.yaml 声明插件元数据与能力:
name: my-awesome-plugin
version: 1.0.0
description: "天气查询与通知插件"
requires_echo_agent: ">=0.3.0"
requires_env: [WEATHER_API_KEY] # 启动时检查的环境变量
provides:
tools: [weather_lookup] # 提供的工具
hooks: [on_agent_start, post_tool_call]
kind: integration # integration / extension / theme
config_key: weather # 配置命名空间
permissions:
- tool.register # 允许注册工具
- hook.register # 允许注册钩子
2. 入口模块:activate 与 deactivate
__init__.py 是插件的 Python 入口,运行时只解析两个回调——工具与钩子必须在 activate 中显式注册:
async def activate(context):
"""插件激活:注册工具与钩子。"""
context.register_tools([WeatherLookupTool()])
context.register_hook("on_agent_start", on_agent_start)
context.register_hook("post_tool_call", post_tool_call)
async def deactivate(context):
"""插件停用:清理插件自己拥有的资源。"""
...
3. 生命周期钩子一览
插件可以监听 10 类生命周期事件,在关键点介入 Agent 行为:
| 钩子 | 时机 | 典型用途 |
|---|---|---|
on_agent_start / on_agent_stop |
Agent 启停 | 初始化连接池、加载缓存 |
on_session_start / on_session_end |
会话开始/结束 | 记录会话上下文 |
pre_tool_call |
工具调用前 | 拦截危险命令(可取消) |
post_tool_call |
工具调用后 | 修改结果、追加记录 |
pre_llm_call / post_llm_call |
LLM 调用前后 | 注入/改写上下文 |
pre_approval / post_approval |
审批前后 | 定制审批策略 |
on_error |
错误发生时 | 发送告警、记录日志 |
钩子函数统一接收 **kwargs 并可选返回 HookResult(可修改数据、阻止传播或直接取消操作)。钩子签名务必保留 **kwargs,保证向后兼容未来新增参数。
4. 权限与信任模型(重要!)
⚠️ Python 插件是与 Echo Agent 同进程的受信任代码,不是 OS 级沙箱:
tool.register与hook.register在注册时强制检查(permission_mode: strict下缺少声明会拒绝注册);network、subprocess、filesystem.*只是声明性元数据,不会真正阻止访问- 插件注册的工具遵循与内置工具相同的审批流程
- 不受信任的代码应放到独立进程或容器中,通过 MCP 接入
5. 安装与发现机制
Echo Agent 按以下优先级发现插件:
- pip 入口点 —
pyproject.toml中声明[project.entry-points."echo_agent.plugins"](推荐,用于发布到 PyPI) - 用户目录 —
~/.echo-agent/plugins/ - 项目目录 — 项目根目录下的
plugins/ - 额外目录 — 配置中
plugins.extra_dirs指定的路径
config.yaml 中可用 plugins.allow(白名单)/ plugins.deny(黑名单)精细控制加载范围,deny 优先于 allow。插件声明的 requires_env 环境变量缺失时,插件不会被激活并在日志中给出警告。
五、本地测试与发布
插件测试与调试
# 将插件目录软链到用户插件路径
ln -s $(pwd) ~/.echo-agent/plugins/my-echo-plugin
# 启动并观察插件加载日志(DEBUG 级别)
ECHO_AGENT_OBSERVABILITY__LOG_LEVEL=DEBUG echo-agent run
CLI 提供完整的管理动作:
echo-agent plugin list # 列出已安装插件
echo-agent plugin info <name> # 查看插件详情
echo-agent plugin enable <name> # 启用
echo-agent plugin disable <name> # 禁用
echo-agent plugin check # 校验插件能否正确加载
在桌面端中,你可以在「知识与工具」入口验证技能与插件的调用效果,并直观查看执行过程与权限请求。
Skill 测试与打包
手动对话测试通过后,可用内置的 skill-creator 工具链完成初始化与打包:scripts/init_skill.py 生成带模板的技能目录,scripts/package_skill.py 自动校验(frontmatter 格式、命名规范、描述完整性)并打包为可分发的 .skill 文件。
插件发布到 PyPI
pip install build
python -m build
pip install twine
twine upload dist/*
✅ Plugin 发布检查清单
- [ ]
plugin.yaml清单完整且有效 - [ ]
requires_env正确声明(缺少时给出清晰错误) - [ ]
provides准确列出所有工具和钩子 - [ ] 钩子函数接受
**kwargs - [ ] 错误在插件边界捕获,不泄漏到宿主
- [ ] entry point 正确注册
- [ ] 工具名称加了插件前缀,避免与内置工具冲突
六、常见问题速查
Q:插件加载失败怎么办?
检查日志,常见原因:环境变量未设置、depends_on 声明的依赖插件不存在、Python 模块导入错误、plugin.yaml 格式不正确。
Q:多个插件注册了同名工具? 注册表会拒绝重名工具与内置工具的保留别名:原工具保持不变,冲突插件激活失败。建议为工具名添加插件前缀。
Q:Agent 总是选不中我的技能?
九成是 description 写得不够具体或与其他技能重叠。记住:描述就是模型的唯一选择依据,让每个技能的适用场景在描述里互相排除。
Q:技能缺依赖或缺 API Key 会怎样?
skill_view 会检查声明的 pip 依赖与环境变量,缺失时在返回内容末尾追加提示(不会自动安装);实际安装发生在 skill_run,并需要你授权。密钥只有技能显式声明过才会传入运行环境——不要通过命令行参数传递密钥。
七、延伸阅读
开发细节以官方文档为准,核心资料入口:
- Skill 开发:Skill 开发指南 · 技能系统使用指南 · 内置技能目录
- Plugin 开发:开发 Plugin · Plugin API 完整参考 · 插件系统使用指南
- 源码索引:echo_agent/skills/ 技能加载、准入与审查实现(含 store.py),echo_agent/plugins/ 插件管理器实现
- 测试参考:test_skills.py · test_plugin_loader.py · test_plugin_sandbox.py
掌握 Skill 与 Plugin 后,你可以再进一步探索 MCP 集成——当需要接入外部工具服务或隔离不可信代码时,它是比进程内插件更稳妥的选择。



