最近在折腾Agent把项目里一堆重复的人工操作交给Hermes之后我突然意识到一个问题真正的Agent开发核心不是调模型而是怎么把模型的能力封装成可以复用的东西。Hermes给我最大的启发就是它的自定义技能Skill机制——以前每次都要手写一大段提示词、手工整理输入输出现在直接把这些重复工作流程保存成一个技能Agent就能稳定复现同样的操作真正做到“让Agent学会新能力”。这篇文章我不会讲虚的概念直接从实际需求出发把Hermes自定义技能的设计思路、从下载安装到配置运行的完整流程、以及我踩过的坑全部写出来。如果你正在做Agent开发、想把团队或个人日常的高频重复操作固化下来或者对“Agent技能化封装”这个概念感兴趣这篇文章应该能帮你少走不少弯路。1. 为什么需要自定义技能从“一次性对话”到“可复用能力”1.1 Agent的尴尬每天都在“重新发明轮子”我刚开始做Agent相关项目的时候最大的感受是模型本身很聪明但使用方式极其原始。举个例子我每周要整理项目周报最早的做法是打开对话窗口把本周的Git提交记录、需求文档、会议纪要一股脑粘贴进去然后写上“请帮我整理成周报格式包括本周进展、风险项、下周计划”。模型确实能给出不错的结果但问题也很明显——每次都要重新写这段指令每次都要重新梳理格式要求每次都要反复纠正模型漏掉的字段。这不是个例。团队里其他成员用Agent做数据分析、代码审查、合同摘要的时候都在重复同一个动作写提示词、调格式、改输出。整个流程没有任何沉淀这周解决的问题下周还会再解一遍。用一句话概括没有一个机制把“模型会做的事”变成“Agent稳定能做的事”。Agent的价值应该是把人的操作经验固化下来而不是每次从零开始。1.2 技能的本质给Agent装上一套“标准作业程序”Hermes的自定义技能Skill本质上是一套可复用的标准作业程序SOP。它将一段固定的指令模板、输入参数的约束、执行流程的步骤、输出结果的校验规则打包成一个独立单元。Agent在执行任务时不需要理解你的长篇提示词只需要知道“调用了哪个技能”然后按技能的规则执行。我习惯用一个类比来解释这件事没有技能的Agent就像一个每次凭心情做菜的厨师你告诉他“做一道鱼香肉丝”他每次端出来的菜可能味道不一样、摆盘不一样、甚至可能忘了放葱。而有了技能之后就像给厨师一份精确的菜谱配料多少克、火候多大、步骤先后都写清楚了他每次做出来的菜基本一致出错的概率大幅降低。既然技能这么重要那它和普通的提示词、工作流有什么区别我用一个表格来对照看完你应该就明白了对比维度普通提示词Hermes自定义技能使用方式每次手写输入按名称调用自动执行参数处理靠模型理解上下文声明参数类型和约束显式传值流程控制一次性多轮对话可定义多步骤执行链输出质量依赖模型状态不稳定带校验规则格式可控沉淀复用基本不可复用一次创建多处调用组合能力无法组合多个技能可编排成复杂流程1.3 Hermes技能机制适合谁用根据我这段时间的使用体验以下几类人最应该尽早用上这个能力Agent应用开发者如果你正在搭建面向具体场景的Agent而不是简单套壳聊天机器人技能机制能把业务规则从代码中剥离出来后续维护会舒服很多。有高频重复工作流的个人或团队周报、日报、会议纪要、定时数据汇总、标准格式文书生成……凡是符合“固定模板变化参数”特征的工作都值得固化成技能。正在做Agent开发学习的人理解技能机制其实就是理解Agent的能力边界是如何构建的这比单独看模型API文档更能提升整体认知。2. 动手前先摸清基本功Hermes核心概念与安装落地2.1 先分清几个关键词Agent、Skill、Harness、Studio在动手之前我建议先把Hermes相关的基本概念过一遍否则后面配置的时候容易迷糊。我自己的理解是这样的Agent是整个系统的“大脑”负责理解用户意图、拆解任务、决定调用哪个技能、组织最终回复。你可以把Agent看成调度器它本身不执行具体业务逻辑而是调配资源。Skill是“能力单元”也就是上一节说的标准作业程序。Agent负责“决定做什么”Skill负责“具体怎么做”。比如“生成项目周报”是一个技能“解析PDF合同关键条款”是另一个技能。一个Agent可以挂载多个技能。Harness这个词可能会让很多人困惑其实它就是Agent的“运行环境”或“外壳”。Agent里跑的那些代码、工具调用、文件读写操作都需要在一个受控的环境里执行。Harness负责管理工具调用、执行代码、控制资源访问和权限边界。Agent和Harness的关系就像赛车手和赛车Agent负责判断赛道和策略Harness负责提供动力和稳定性。Studio是可视化的管理工具你可以在这里创建、编辑、测试、发布技能也可以直观地看到当前Agent挂载了哪些技能、每个技能的运行状态如何。把这几个概念放在一起理解一条链路就清晰了用户在对话窗口发起需求 → Agent识别需求并决定调用技能 → Skill按定义好的模板和步骤执行 → Harness提供执行环境和工具调用能力 → 执行结果返回给Agent → Agent组织语言回复用户。2.2 从下载到安装配置的一整套流程接下来是整个环节里最关键的部分——把Hermes装起来。这里我提供一个从零开始的完整流程以目前常用的部署方式为例。我自己实践过两条路线一条是直接用Docker镜像跑另一条是在Python环境里安装运行。如果你的机器已经装了Docker我建议优先用Docker省去依赖管理的麻烦。环境准备方面最基本的要求是操作系统Linux/macOS/Windows均可Windows强烈建议使用WSL2或Docker Desktop直接装在原生Windows下虽然也能跑但后续文件路径和权限问题会多一些。内存至少8GB如果后面要跑本地模型建议16GB以上。需要能正常访问Docker Hub或Python包仓库。先说Docker部署的参考步骤不同系统略有差异但思路一致# 拉取镜像 docker pull hermes-agent/hermes:latest # 创建配置目录用来持久化技能和会话数据 mkdir -p ~/hermes/data mkdir -p ~/hermes/skills # 启动容器挂载数据目录和技能目录 docker run -d \ --name hermes \ -p 8080:8080 \ -v ~/hermes/data:/app/data \ -v ~/hermes/skills:/app/skills \ -e HERMES_MODEL_API_KEY你的模型API密钥 \ -e HERMES_MODEL_BASE_URL模型服务地址 \ -e HERMES_MODEL_NAME模型名称 \ hermes-agent/hermes:latest如果你选择Python安装方式大致是这样# 建议使用虚拟环境 python -m venv hermes-env source hermes-env/bin/activate # Windows下是 hermes-env\Scripts\activate # 安装Hermes核心包以及命令行工具 pip install hermes-agent hermes-cli # 初始化配置目录 hermes init --config-dir ~/.hermes安装完成后需要把模型服务的接入参数配置好。Hermes的模型接口设计得比较简洁兼容OpenAI格式的API。这里以DeepSeek为例做一个配置参考你完全可以用其他兼容OpenAI格式的服务# 推荐写入环境变量避免在命令行明文暴露 export HERMES_MODEL_API_KEYsk-xxxxxx export HERMES_MODEL_BASE_URLhttps://api.deepseek.com/v1 export HERMES_MODEL_NAMEdeepseek-chat或者写进配置文件Hermes会读取~/.hermes/config.yaml这类路径下的内容格式大致如下model: provider: openai-compatible base_url: https://api.deepseek.com/v1 api_key: sk-xxxxxx name: deepseek-chat temperature: 0.3 server: host: 0.0.0.0 port: 8080 skill_paths: - ~/hermes/skills配置完成之后验证安装是否成功。启动服务后在浏览器打开http://localhost:8080应该能看到Hermes的对话界面。如果你想用命令行快速验证可以执行一条简单的测试命令hermes run --message 你好请回复Hermes安装成功如果模型API密钥和网络配置都没问题Agent应该会正常返回一句问候或提示。看到回复说明安装这一步就算顺利通过了。注意在Windows上如果遇到端口占用或路径解析问题优先检查是否以管理员权限运行或者把配置目录调整到用户目录下比如C:\Users\你的用户名\.hermes避免权限拦截。2.3 首次启动后建议做的三件事第一次启动Hermes我先建议你做三件事能省掉后面不少麻烦第一确认技能目录挂载成功。在配置里指定的skill_paths目录下创建一个测试文件夹看看在Studio或后台日志里是否能看到目录变化。这能确认技能文件能被正确扫描加载。第二设置一个合理的系统提示词。在Hermes的Agent配置里有一段system prompt我强烈建议你在这里写清楚Agent的角色定位、回答风格、处理边界。比如“你是项目助理负责周报生成和会议纪要整理遇到超出技能范围的问题请明确告知用户”。这比直接裸奔调用模型要可靠得多。第三跑一个最简单的技能。Hermes安装后会自带几个内置技能你可以先触发一个内置技能试试确认整个调用链路是通的。最简单的方式是在对话窗口输入类似“调用技能角色扮演”或者直接问Agent“你会哪些技能”让它列出当前已加载的技能列表。如果列表正常展示说明Agent与技能系统已经成功串联。3. 创建第一个自定义技能以“固定指令模板”为例3.1 选一个场景把重复工作流程拆解清楚所有技能都起源于一个真实的需求。我强烈建议你从自己工作中最高频、最枯燥的那个流程入手这样能立刻感受到技能化带来的效率提升。我这里以一个非常典型的场景为例生成项目周报。每天早上你有大量零散信息昨天的线上问题记录、今天的代码合并请求、和产品对需求变动的讨论、客户反馈等。以前的做法是手动整理成一份给领导看的周报格式是固定的“本周进展、风险与问题、下周计划”。这个流程重复了无数次非常适合做成技能。在写技能定义之前先把这个工作流程拆清楚输入原始的零散素材比如聊天记录、代码提交记录、会议纪要以及一个时间范围。处理步骤先提取关键事件 → 按类型分类进展、风险、计划→ 结合时间范围过滤 → 整理成通顺的汇报文案。输出一份严格按照模板格式生成的周报Markdown文本。你可能会说这不就是写个提示词吗对但关键区别在于技能会把“输入约束”和“输出校验”也一起固化下来。没写技能之前模型经常用口语化的方式回复你段落格式随意写成技能之后模型的输出会被强制校验格式不对会自动重试。3.2 编写技能定义参数、模板、执行步骤现在进入正题——如何写一个技能定义文件。在Hermes中一个技能通常是一个目录里面放一个描述文件通常为YAML格式可能还附带了若干脚本或模板文件。我先直接给一个参考实现然后逐段拆解name: weekly_report description: 根据零散的原始素材生成格式化项目周报适用于项目周报、部门周报等场景 version: 1.0.0 parameters: start_date: type: string description: 本周起止日期或时间范围描述例如“2025年第3周” required: true raw_materials: type: text description: 原始的零散信息包括代码记录、会议纪要、沟通记录等 required: true tone: type: string description: 周报语气风格默认“正式” required: false default: 正式 steps: - name: 提取关键事件 prompt: | 以下是本周的原始素材请逐条提取其中的关键事件每条事件用一句话概括保留时间、主体和影响 {raw_materials} output_variable: extracted_events - name: 事件分类 prompt: | 将以下提取出的事件分为三类本周进展、风险与问题、下周计划。 如果某条事件不属于这三类归入“其他说明”。 事件列表 {extracted_events} output_variable: classified_events - name: 生成周报正文 prompt: | 请根据以下分类结果生成一份项目周报。要求 1. 严格按照Markdown格式输出 2. 一级标题为“项目周报{start_date}” 3. 包含“本周进展”、“风险与问题”、“下周计划”三个二级章节 4. 语气{style_tone}每章条理清晰不要出现空话套话 分类结果 {classified_events} output_variable: report_content validation: - type: markdown_section_check required_sections: - 本周进展 - 风险与问题 - 下周计划 - type: length_check min_chars: 200 example_trigger: 帮我生成本周周报这段配置看起来很直观但有几个细节我说明一下**参数定义里的required**是核心约束。技能被调用时如果缺少必填参数Hermes会主动问用户要而不是让模型瞎猜。最初我没设置required结果模型偶尔在用户没提供素材的情况下自己编了一段周报出来非常离谱。加了必填校验后这类问题基本消失了。**steps里的output_variable**是步骤之间传递数据的通道。每一步的输出会成为下一步提示词模板中的变量。这种链式设计有三个好处一是每个步骤的任务清晰简单模型不容易跑偏二是中间结果可以被检查如果某一步提取的事件太少说明素材不足或模型理解不到位三是后续可以单独替换某一步比如把“提取关键事件”这一步换成不同的提示词策略不会影响整个技能框架。validation阶段是技能和普通提示词最大的差别。普通提示词输出什么格式完全看模型心情而技能定义允许你指定校验规则。比如校验输出有没有包含要求的章节校验文本长度是否达标。一旦校验不通过Hermes会触发一次修正循环把校验失败信息反馈给Agent让它重新生成。这个机制让技能的稳定性提升了一个量级。3.3 安装技能并实际调用技能文件写好后把它放到Hermes配置里指定的技能目录下。还是以刚才的~/hermes/skills为例mkdir -p ~/hermes/skills/weekly_report # 把上面的YAML内容保存为 ~/hermes/skills/weekly_report/skill.yaml然后重启Hermes服务或者在Studio界面点击“刷新技能列表”。如果技能文件格式正确你会在技能列表里看到weekly_report这项技能。调用方式有两种。一种是直接在对话里触发请调用技能weekly_report生成本周周报时间范围“2025年第3周”原始素材如下……Agent识别到技能名称后会先解析参数然后按技能定义逐步执行。另一种是更直接的触发方式如果你知道技能名称可以在对话中使用斜杠命令/weekly_report start_date2025年第3周 raw_materials周二线上出现订单同步延迟已修复周三完成支付模块代码审查周五和产品确认下个迭代的需求优先级...我个人更推荐第一种自然语言触发因为Agent能做更多上下文理解但斜杠命令在自动化脚本和批量处理时非常实用。3.4 首次调试时最值得看的日志技能跑起来之后第一件事就是打开执行日志。Hermes会为每次技能调用生成一段执行记录里面能看到每一步的输入输出。我建议你重点关注以下三类信息参数解析结果检查真正的输入值是否和预期一致很多时候技能表现不佳是因为参数传递取值有误。每步输出的中间结果逐条核对提取关键事件、事件分类的结果如果模型理解出现了偏差尽早修正步骤提示词而不是等到最后输出周报时才发现问题。校验结果看模型在生成周报后是否通过了章节和长度校验。如果没过Hermes会发起修正循环你可以看到修正前后的差异。提示技能调试阶段尽量使用低温度参数比如temperature设为0.2~0.3保证输出稳定可复现。等技能运行稳定后再根据需要调高温度增加输出多样性。4. 进阶玩法技能编排、记忆与安全边界4.1 把大技能拆成小技能让Agent学会“组合拳”很多新手在配置技能时容易犯一个错试图把整个复杂流程写进一个技能里。比如“从需求文档生成开发排期”这个流程里至少包含了需求理解、任务拆解、工时估算、依赖分析几个环节。全部塞进一个技能会让提示词异常臃肿执行时模型负荷太大一个环节出错就得全部重来。我的经验是把大技能拆成多个责任单一的小技能再让Agent根据实际需求编排调用。还是以周报为例我可以拆成event_extractor信息提取、event_classifier事项分类、weekly_report_generator周报生成三个技能。这样每个技能的提示词都短小精悍稳定度更高而且这三个技能可以自由组合event_extractor除了服务周报也能服务“月度总结”甚至“会议纪要”复用的价值更大。Hermes的Agent本身就具备技能编排能力。它会根据用户需求动态决定调用哪些技能以及调用的先后顺序。当然如果你的业务流程必须严格按顺序走也可以在技能定义的steps里把前置技能作为依赖声明这样Agent就不会乱序执行了。4.2 技能与记忆让Agent记住上下文和偏好技能解决了“怎么做”的问题记忆则解决“这次做和上次有什么关联”的问题。在Hermes中技能执行过程中的中间输出结果可以写入会话上下文这些内容在同一个会话里可以被后续的技能调用使用。举个例子我让Hermes每周自动生成周报如果每次都从零开始提取信息那上一周的结论和本周的风险项就完全割裂了。通过记忆机制我可以让weekly_report技能在生成当前周报时先读取上一周周报的末尾部分把它作为“上期回顾”的输入这样周报的连贯性会好很多。不过这里有一个实际经验不要盲目让技能访问所有历史记忆这会造成两个问题——一是大量历史数据会稀释模型对当前任务的注意力二是上下文过长会增加延迟和费用。我建议只让技能访问最近的几轮会话摘要或者仅传递本次任务直接依赖的数据结构。用专门的工具函数管理记忆是正道别把Agent当记事本。4.3 技能的安全边界与权限控制Agent落地的过程中安全问题迟早会浮出水面。一个逻辑上很完美的技能如果执行环境没有权限隔离后果可能很严重。我在几轮迭代里总结了几个和技能安全直接相关的经验第一技能声明所需权限。在Hermes的技能定义中可以为技能声明它需要访问的资源范围比如是否需要读文件、是否需要执行代码、是否需要访问网络。凡是技能不需要的能力一律不授予。举个例子一个“周报生成”技能根本不需要执行代码也不应该访问网络那就不要给这个技能授予这些权限。这样即使技能被恶意输入引导危害也被限制在生成文本的范围内了。第二敏感信息不落盘。不要在技能模板里写死任何密钥、账号、内部系统地址。模型的输入输出会保留在日志中一旦技能模板里有敏感信息等于把秘密暴露给日志和可能的后续调用者。正确的做法是把敏感信息放到运行时环境变量里由Harness在技能执行时动态注入。第三对输出内容保留人工复核环节。对于涉及合同、财务、对外发布等场景的技能我强烈建议在流程中加一道人工确认“闸门”。比如Hermes技能执行完成后先输出一个“待确认”状态人工审核通过后再放行最终结果。自动化和可控性之间必须取得平衡一味追求全自动在真实业务里反而容易出事故。5. 常见问题与排查技巧实录5.1 执行报错“agent execution terminated due to error”怎么办这是我被问得最多的问题因为这个错误提示非常笼统几乎不包含定位信息。根据我排查的经验出现这个报错通常集中在几个环节排查步骤可以这样走先点开该次执行右侧的日志展开按钮看到完整的调用栈。如果日志里出现了APIError或RateLimitError基本可以确定是模型服务侧的问题检查API额度、网络连通性、请求频率即可。如果日志停在某个steps的prompt阶段说明是模型返回内容为空或格式异常可以把那一步的提示词单独复制到模型对话窗口里测试看是提示词引导不够还是模型本身就没有理解。如果日志显示validation failed那就是输出没有通过校验规则检查一下校验条件是否定得太严格。我也整理了一份速查表遇到问题时可以直接对照现象可能原因解决思路报错“API调用超时”模型服务响应慢或网络波动适当调大请求超时时间减少单次输入长度迁移到响应更稳定的模型服务提示“参数缺失”调用技能时没有提供必填参数在技能定义里确认required是否正确检查参数名称拼写某一步输出为空步骤提示词过于模糊补充示例输出在提示词中加入“若无法提取请输出空列表”等兜底说明输出格式总是校验失败校验规则太严格或提示词未强调格式给模型提供一段“正确输出示例”校验改为可修复模式允许Agent重新生成一次技能没有出现在技能列表文件格式错误或目录路径不对执行hermes skills list --debug查看加载日志检查目录挂载权限5.2 模型输出不稳定或跑偏的实用对策即使有了技能定义模型依然可能出现不稳定输出这在大语言模型应用中是无法完全避免的。我的经验是尽量用“规则”而不是“期望”来控制模型。具体来说其一给出强约束的格式模板。在提示词里只写“请生成周报”是不够的要给出明确的模板结构甚至直接给出输出示例。模型非常擅长模仿格式给它一段正确的例子比告诉它十条规则都管用。其二把修正机会显式写进步骤里。在技能步骤中加上一条“检查以上内容是否符合要求如不符合请重新生成”可以让模型有机会进行自我纠正。虽然模型不一定每次都能发现问题但至少给了它一次主动优化的机会。其三合理拆分输入长度。如果原始素材太长模型在长上下文中的注意力会明显分散。先把素材按时间或来源切割成小块分步处理最后再合并。这比一次性丢给模型要稳定得多。5.3 一个长期维护的心得版本管理技能定义技能文件本质上就是代码不应该被当作一次性配置对待。我自己会在技能目录里增加changelog.md记录每次修改的技能版本和改动原因。比如“v1.0.1调整事件分类步骤的提示词增加了对风险事项的识别权重”这样几个月后再回来看思路非常清晰。更重要的一点是技能在测试环境跑通之后尽量通过文件复制或打包的方式同步到生产环境不要在生产环境里直接改技能。我有一次为了省事直接在线上服务里改了周报技能的模板改完之后没有测试就运行了结果输出格式全乱。从那以后我给自己立了条规矩技能变更必须走和代码一样的流程——先在测试环境验证再同步到生产。写在最后回头来看Hermes自定义技能这套机制真正解决的核心问题不是“让模型更聪明”而是“让一次性的聪明变成稳定的能力”。搭建一个可复用的技能本质上是在完成一次经验的形式化沉淀——把你、你的团队、甚至整个组织的操作经验从人的脑袋里抽出来变成一个可执行、可验证、可迭代的模块。我在实际项目里最大的体会是技能化不是越复杂越好也不建议一开始就追求全自动编排。先从最枯燥、最重复、规则最清晰的那个流程入手把它固化成技能跑通第一个闭环再逐步把其他流程纳入这个体系。踩过几次坑之后你会发现真正让Agent发挥价值的恰恰是这些看起来不太起眼的“标准作业程序”。