Hermes Agent 核心教程:从零开始开发强大的 Python AI 应用
写在前面:关于 Hermes Agent
Hermes Agent 是由知名 AI 研究机构 Nous Research 开发的一款具备高度自我进化能力的开源智能体系统。它旨在打破传统大模型“阅后即焚”的单一对话框限制,让 AI 真正“生活”在开发者的终端、团队的通讯软件以及自动化的流水线中。
核心亮点:
闭环学习与长期记忆 :它不仅能执行任务,还能在跨会话中持久化记忆,甚至从经验中自主创建和优化专属技能。
全平台无缝接入 :内置强大的消息网关,一套代码即可接入 CLI、Telegram、Discord、Slack 等平台,实现跨设备状态同步。
模型无关与热切换 :不被单一厂商锁定,支持随时无缝切换底层大模型(如 OpenAI、Anthropic、本地大模型等)。
多智能体协作与沙盒隔离 :支持生成隔离的子智能体(Subagents)并行处理复杂任务,并在 Docker、SSH 等多种安全沙盒中执行代码。
本教程将带你由浅入深,掌握如何将其作为 Python 库使用,打造你自己的强大 AI 应用。
1. 环境准备 在开始之前,请确保你已经激活了项目的虚拟环境。
对于配置模型,Hermes Agent 采用了全新的配置管理机制:
⚠️ 重要提示: 过去很多 AI 工具喜欢通过终端 export OPENAI_BASE_URL 或在 .env 中设置 LLM_MODEL 等环境变量来控制模型。但在 Hermes Agent 最新版本中,这些旧的环境变量已被完全废弃,即使在终端 export 也不会生效! Hermes 的核心配置来源是统一的配置文件:~/.hermes/config.yaml(或者通过代码显式传参)。
配置第三方中转 API(Custom Provider)的正确姿势:
如果你希望全局使用第三方中转站(使得 CLI 和代码调用都默认生效),最推荐的做法是直接修改 ~/.hermes/config.yaml:
1 2 3 4 5 6 model: default: gpt-5.4-mini provider: custom base_url: https://api.your-proxy.com/v1 api_key: your-api-key-here
或者使用交互式命令自动配置:
当然,你也可以完全在代码中动态覆盖这些配置(见下一节)。
2. 基础篇:最简单的单次对话 (Single-turn Chat) 使用 Hermes 最简单的方法是调用 chat() 方法 —— 传入一条消息,返回一段字符串文本。它会在内部自动处理完整的对话循环(包括工具调用、重试等)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from run_agent import AIAgentagent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , quiet_mode=True , skip_memory=True , skip_context_files=True ) response = agent.chat("用一句话解释一下什么是 Python 装饰器?" ) print ("AI 回复:" , response)
⚠️ 注意: 将 Hermes 嵌入到你自己的代码中时,请务必设置 quiet_mode=True。否则,Agent 会打印 CLI 的加载动画和进度指示器,这会扰乱你的应用输出。
3. 进阶篇:完全对话控制与多轮对话 (Full Conversation Control) 如果需要对对话有更多的控制权,请直接使用 run_conversation()。它不仅返回最终的文本回复,还会返回完整的消息历史记录和元数据字典。
3.1 获取完整上下文与自定义 System Prompt 你可以通过 run_conversation() 传入临时的 system_message,覆盖该次调用的系统提示词:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from run_agent import AIAgentagent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , quiet_mode=True , ) result = agent.run_conversation( user_message="解释一下什么是快速排序" , system_message="你是一个计算机科学导师。请使用生活中的简单比喻来解释。" , task_id="my-task-1" , ) print ("最终回复:" , result["final_response" ])print (f"总共交互的消息数: {len (result['messages' ])} " )
返回的字典包含:
final_response — Agent 的最终文本回复
messages — 完整的消息历史(包含 system, user, assistant, tool calls)
task_id — 用于虚拟机隔离的任务标识符
3.2 保持多轮对话状态与持久化机制 Hermes 的对话历史状态保存有两种模式:
模式 A:纯内存传递(适合无状态 API) 要在多个回合之间在纯内存中保持对话状态,只需将上一次返回的 messages 历史记录重新传入 conversation_history 参数即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from run_agent import AIAgentagent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , quiet_mode=True , skip_memory=True , ) result1 = agent.run_conversation("你好,我叫 Alice,我最喜欢的颜色是蓝色。" ) history = result1["messages" ] print ("第一轮回复:" , result1["final_response" ])result2 = agent.run_conversation( "你还记得我叫什么名字,喜欢什么颜色吗?" , conversation_history=history, ) print ("第二轮回复:" , result2["final_response" ])
模式 B:SQLite 自动持久化存储(适合 CLI/聊天机器人) 如果你想让对话记录持久化到本地硬盘 ,即使程序重启也能继续聊天,你只需要在初始化 AIAgent 时传入一个固定的 session_id。
Hermes 底层使用了 hermes_state.py 提供的 SessionDB。它会将所有的对话消息自动存入 ~/.hermes/state.db (SQLite 数据库) 中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from run_agent import AIAgentagent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , quiet_mode=True , session_id="my_tutorial_session" , ) res1 = agent.run_conversation("我最喜欢的水果是苹果。" ) print ("回复:" , res1["final_response" ])res2 = agent.run_conversation("我最喜欢的水果是什么?" ) print ("回复:" , res2["final_response" ])
4. 配置篇:工具权限与运行轨迹 你可以通过 enabled_toolsets(白名单)或 disabled_toolsets(黑名单)来控制 Agent 有权使用哪些工具集:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 agent_web_only = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , enabled_toolsets=["web" ], quiet_mode=True , ) agent_no_terminal = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , disabled_toolsets=["terminal" ], quiet_mode=True , )
4.2 保存对话轨迹 (Saving Trajectories)与临时人设 如果你需要收集数据用于模型微调,可以开启轨迹保存。同时,使用 ephemeral_system_prompt 可以设定专属人设,且该设定不会 污染保存的轨迹数据:
1 2 3 4 5 6 7 8 9 10 11 agent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , ephemeral_system_prompt="你是一个 SQL 专家。只回答与数据库相关的问题。" , save_trajectories=True , quiet_mode=True , ) response = agent.chat("我该怎么写一个 JOIN 查询?" )
5. 架构篇:并发场景下的多用户隔离机制 当你准备将 Hermes Agent 接入 FastAPI、Discord Bot 或 Telegram 机器人时,多用户隔离 是绕不开的话题。
Hermes 提供了两个层级的多用户隔离方案:
5.1 代码层级的软隔离 (Session ID) 在同一个 Python 进程中,如果你只是希望让模型能够分别记住不同用户的对话,你只需要为不同的用户请求分配不同的 session_id。
⚠️ 核心规则: AIAgent 实例维护着自身的对话历史、工具会话和迭代计数器,它不是线程安全的 。因此,必须为每个并发任务或每个用户请求创建一个新的 AIAgent 实例 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import concurrent.futuresfrom run_agent import AIAgentdef handle_user_message (user_id: str , message: str ): agent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , session_id=f"user_session_{user_id} " , quiet_mode=True ) return agent.chat(message) users_requests = { "u1001" : "你好,我是用户A" , "u1002" : "你好,我是用户B" } with concurrent.futures.ThreadPoolExecutor(max_workers=2 ) as executor: futures = { executor.submit(handle_user_message, uid, msg): uid for uid, msg in users_requests.items() } for future in concurrent.futures.as_completed(futures): uid = futures[future] print (f"用户 {uid} 的专属回复: {future.result()} " )
5.2 物理层级的硬隔离 (Profiles) 如果你不仅需要隔离对话历史,还需要为不同用户配置完全不同的 API Key、不同的模型、不同的系统提示词(人设)、甚至不同的可用工具集 ,你需要使用 Hermes 的 Profiles(配置文件) 功能。
每一个 Profile 都拥有独立的 ~/.hermes/profiles/<name>/ 目录。
你可以通过 CLI 预先创建 Profile:1 2 hermes profile create alice hermes profile create bob
然后在 Python 代码中,你可以在初始化 AIAgent 之前,通过修改环境变量 HERMES_HOME 来让当前进程或 Agent 绑定到特定的 Profile 目录下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import osfrom pathlib import Pathfrom run_agent import AIAgentdef run_agent_for_profile (profile_name: str , message: str ): profile_dir = Path.home() / ".hermes" / "profiles" / profile_name os.environ["HERMES_HOME" ] = str (profile_dir) agent = AIAgent( quiet_mode=True ) return agent.chat(message)
6. 实战集成示例 (Integration Examples) 6.1 FastAPI 接口端点 将 Hermes 包装成一个 HTTP API 服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from fastapi import FastAPIfrom pydantic import BaseModelfrom run_agent import AIAgentapp = FastAPI() class ChatRequest (BaseModel ): message: str model: str = "gpt-5.4-mini" @app.post("/chat" ) async def chat (request: ChatRequest ): agent = AIAgent( model=request.model, provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , quiet_mode=True , skip_context_files=True , skip_memory=True , ) response = agent.chat(request.message) return {"response" : response}
6.2 CI/CD 自动化代码审查流水线 利用 Agent 在 CI/CD 流程中自动进行 Code Review:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 """CI step: auto-review a PR diff.""" import subprocessfrom run_agent import AIAgentdiff = subprocess.check_output(["git" , "diff" , "main...HEAD" ]).decode() agent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , quiet_mode=True , skip_context_files=True , skip_memory=True , disabled_toolsets=["terminal" , "browser" ], ) review = agent.chat( f"请审查以下 PR 的代码变更,检查是否存在 bug、安全漏洞或代码风格问题:\n\n{diff} " ) print (review)
6.3 从零开发自定义工具 开发自定义工具非常简单,只需调用 tools.registry.registry.register 将其注册到全局系统中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import jsonfrom tools.registry import registry, tool_resultfrom run_agent import AIAgentdef get_weather (location: str ) -> str : data = {"location" : location, "weather" : "晴朗" , "temp" : "25°C" } return json.dumps(tool_result(success=True , data=data), ensure_ascii=False ) WEATHER_SCHEMA = { "type" : "function" , "function" : { "name" : "get_weather" , "description" : "获取指定城市的天气信息" , "parameters" : { "type" : "object" , "properties" : { "location" : {"type" : "string" , "description" : "城市名称,如:北京、上海" } }, "required" : ["location" ], }, } } registry.register( name="get_weather" , toolset="weather_tools" , schema=WEATHER_SCHEMA, handler=lambda args, **kw: get_weather(args.get("location" )), emoji="🌤️" ) agent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , enabled_toolsets=["weather_tools" ], quiet_mode=False ) print (agent.chat("今天北京的天气怎么样?" ))
7. 高阶篇:复杂任务编排与子智能体委托 (Agent-to-Agent 通信) 当面对超大型任务(例如“帮我从头开发一个贪吃蛇游戏并运行测试”)时,单线程执行往往容易遇到上下文瓶颈。Hermes 支持一种受控的 A2A (Agent-to-Agent) 协作模式——即子智能体委托机制 (Subagent Delegation) 。
当开启 delegate 工具集时,主 Agent 可以化身为“项目经理”,它会为不同的子任务创建隔离的 Child AIAgent 进行并行或串行的任务攻坚。
A2A 机制的核心特性:
上下文隔离 :子 Agent 会获得全新的对话会话和专属任务 ID,主 Agent 的庞大上下文不会拖慢子 Agent 的执行速度。
防止递归失控 :系统硬编码了最大委派深度(MAX_DEPTH = 2),即子 Agent 无法再创建孙 Agent,且被禁止向人类提问(clarify 工具被禁用),确保它们默默打工不打扰用户。
并行处理 :主 Agent 可以一次性派发多个任务,系统会自动利用线程池并发运行多个子 Agent。
1 2 3 4 5 6 7 8 9 10 11 agent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , enabled_toolsets=["delegate" , "terminal" , "file_tools" ], quiet_mode=False ) agent.chat("请帮我写一个 Python 贪吃蛇游戏,保存到 snake.py 中,然后运行并修复可能存在的 bug。" )
此外,Hermes Agent 还可以接入 auxiliary_client.py 辅助客户端来支持视觉多模态 识别,以及通过 cron/ 目录下的调度器实现自动化定时任务,这些都是其作为生产级 AI 框架的核心优势。
8. 前沿探索:支持标准 A2A Protocol (Agent2Agent) 最近,由 Linux 基金会主导的 A2A Protocol (Agent-to-Agent) 成为了跨框架智能体协作的开放标准。与前文提到的 Hermes 内部的 delegate(父子智能体委派)不同,标准的 A2A 协议允许 Hermes Agent 与完全不同的框架(如 LangGraph, CrewAI 等)构建的外部智能体进行去中心化的通信 。
虽然目前 Hermes 官方暂未原生内置 A2A 协议,但得益于其高度可扩展的工具注册表(Tool Registry)和网关(Gateway)架构,将其作为一个插件接入是非常容易的!
概念验证 1:作为 A2A 发起方 (Caller) 如果你想让 Hermes 能够调用外部支持 A2A 协议的 Agent(例如一个专门用于金融分析的 LangGraph 智能体),你可以轻松地为其编写一个自定义工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 import jsonfrom tools.registry import registry, tool_resultfrom run_agent import AIAgentdef call_external_a2a_agent (agent_address: str , task_query: str ) -> str : """通过 A2A 协议向外部智能体发送任务并等待结果""" print (f"正在通过 A2A 协议联系外部智能体 [{agent_address} ]..." ) result = f"来自 {agent_address} 的分析结果:已完成关于 '{task_query} ' 的任务。" return json.dumps(tool_result(success=True , data={"result" : result}), ensure_ascii=False ) registry.register( name="call_a2a_agent" , toolset="a2a_tools" , schema={ "type" : "function" , "function" : { "name" : "call_a2a_agent" , "description" : "通过标准 A2A 协议将特定领域的任务委派给外部智能体" , "parameters" : { "type" : "object" , "properties" : { "agent_address" : {"type" : "string" , "description" : "外部智能体的 A2A 寻址地址" }, "task_query" : {"type" : "string" , "description" : "需要外部智能体完成的任务详情" } }, "required" : ["agent_address" , "task_query" ], }, } }, handler=lambda args, **kw: call_external_a2a_agent(args.get("agent_address" ), args.get("task_query" )), emoji="📡" ) agent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , enabled_toolsets=["a2a_tools" , "web_search" ], quiet_mode=False ) agent.chat("我需要一份专业的市场分析报告。请通过 A2A 协议联系地址为 'a2a://finance-expert-agent' 的智能体,让它帮你生成报告,然后你再结合最新的网络搜索结果发给我。" )
概念验证 2:作为 A2A 接收方 (Server) 除了主动调用其他 Agent,你也可以将 Hermes 包装成一个 A2A 协议的服务端,监听并处理来自外部框架(如 CrewAI 或 AutoGen)发送的 A2A 请求。这在 Hermes 的架构中相当于构建一个自定义的 Gateway Platform 适配器。
以下是最简单的伪代码实现思路,展示了如何监听 A2A 请求、将请求内容交给 Hermes AIAgent 处理,再将结果通过 A2A 协议返回:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 from run_agent import AIAgentdef handle_incoming_a2a_task (request ): """处理外部 Agent 发送来的 A2A 请求""" print (f"收到来自 {request.sender} 的任务:{request.content['task' ]} " ) agent = AIAgent( model="gpt-5.4-mini" , provider="custom" , base_url="https://api.your-proxy.com/v1" , api_key="your-api-key-here" , quiet_mode=True , session_id=f"a2a_session_{request.sender} " ) result = agent.chat(request.content["task" ]) print (f"任务完成,回复给 {request.sender} :{result} " ) def start_a2a_server (): """启动 A2A 监听服务""" pass if __name__ == "__main__" : start_a2a_server()
正如你所见,A2A 协议(用于 Agent 间通信)与 MCP 协议(用于 Agent 访问工具资源)是完美的互补组合。随着生态的成熟,你完全可以通过上述方式将 Hermes 接入到由无数异构 AI 智能体组成的“互联网”中!
结语 通过本教程,你已经掌握了如何使用 Python 库的方式调用 hermes-agent,从单次/多轮对话控制,到安全地进行并发处理和工具定制。它既可以作为你的本地终端 Copilot,也能轻易集成到 FastAPI 后端、Discord Bot 甚至自动化 CI/CD 流水线中!