配置文件与 Profile 体系
本教程共 25 篇 · 第 4 篇 · 更新于 2026-07-26 · 约 12 分钟阅读
4. 配置文件与 Profile 体系
本节目标:搞懂
~/.hermes/目录里都有什么、配置怎么存怎么改、Profile 怎么用一套配置跑多个独立智能体。学完你能自己管理配置和多 Profile 环境。
~/.hermes/ 目录全景
所有设置都存在 ~/.hermes/ 目录里。先看清这个目录长什么样:
~/.hermes/
├── config.yaml # 设置(模型、终端、TTS、压缩等)
├── .env # API Key 和密钥
├── auth.json # OAuth 提供商凭据(Nous Portal 等)
├── SOUL.md # 智能体人格身份(系统提示词的第一个槽位)
├── memories/ # 持久记忆(MEMORY.md, USER.md)
├── skills/ # 智能体创建的技能
├── cron/ # 定时任务
├── sessions/ # 会话记录
└── logs/ # 日志(errors.log, gateway.log,密钥自动脱敏)
记住一个原则:备份这个目录,就等于备份了你的整个智能体。
两个配置文件:config.yaml 和 .env
Hermes 把配置分成两类文件存放,这点设计得很清楚:
config.yaml:非敏感设置—模型、终端后端、压缩参数、记忆限制、工具集开关等。.env:敏感信息—API Key、Bot Token、密码。必须放这里。
配置优先级
设置按以下顺序解析(优先级从高到低):
- 命令行参数—比如
hermes chat --model anthropic/claude-sonnet-4,单次覆盖 ~/.hermes/config.yaml—非敏感设置的主配置文件~/.hermes/.env—环境变量兜底,敏感信息的必选项- 内置默认值—什么都没设时的安全默认
Note简单记:密钥放
.env,其他放config.yaml。两者都设了的时候,非敏感设置以config.yaml为准。
用命令管理配置
别手动编辑文件,用命令更安全—它会自动把值写到正确的文件里:
hermes config # 查看当前配置
hermes config edit # 用编辑器打开 config.yaml
hermes config get KEY # 打印某个值
hermes config set KEY VAL # 设置某个值
hermes config unset KEY # 删除某个值
hermes config check # 检查缺失项(更新后常用)
hermes config migrate # 交互式补充缺失项
# 示例:
hermes config set model anthropic/claude-opus-4
hermes config set terminal.backend docker
hermes config set OPENROUTER_API_KEY sk-or-... # 自动存到 .env
Tip
hermes config set会自动判断值该去哪—API Key 存到.env,其他存到config.yaml。不用你操心放错文件。
环境变量替换
config.yaml 里可以用 ${VAR_NAME} 语法引用环境变量:
auxiliary:
vision:
api_key: ${GOOGLE_API_KEY}
base_url: ${CUSTOM_VISION_URL}
delegation:
api_key: ${DELEGATION_KEY}
一个值里可以引用多个变量:url: "${HOST}:${PORT}"。如果引用的变量没设,占位符原样保留。注意只支持 ${VAR} 语法,裸写的 $VAR 不会展开。
SOUL.md:智能体的人格
SOUL.md 控制智能体的性格、语气和沟通风格。它放在 ~/.hermes/SOUL.md(或 $HERMES_HOME/SOUL.md)。
几个要点:
- Hermes 会在
SOUL.md不存在时自动种一个默认的 - 只从
HERMES_HOME加载,不会去工作目录找 - 文件为空则不加任何内容到提示词
- 有内容则原样注入(经过安全扫描和截断后)
SOUL.md 是系统提示词的第一个槽位,优先级最高。你可以把它理解成「这个智能体是谁」的定义。
Note
SOUL.md的改动在新会话生效。已有会话可能还在用旧的提示词状态。
Context Files:项目上下文注入
除了 SOUL.md 这种全局人格配置,Hermes 还会自动发现并加载项目级的上下文文件,让智能体理解你当前在做什么项目。
支持的上下文文件
| 文件 | 用途 | 发现方式 |
|---|---|---|
.hermes.md / HERMES.md | 项目指令(优先级最高) | 向上走到 git 根目录 |
AGENTS.md | 项目指令、规范、架构 | 启动时 CWD + 子目录渐进式 |
CLAUDE.md | Claude Code 上下文文件(兼容检测) | 启动时 CWD + 子目录渐进式 |
SOUL.md | 全局人格(独立加载) | 仅 HERMES_HOME |
.cursorrules | Cursor IDE 编码规范 | 仅 CWD |
.cursor/rules/*.mdc | Cursor IDE 规则模块 | 仅 CWD |
Note一个会话只加载一种项目上下文类型(先匹配的优先):
.hermes.md→AGENTS.md→CLAUDE.md→.cursorrules。SOUL.md始终独立加载,不受这个优先级影响。
渐进式子目录发现
这是 Hermes 一个很巧妙的设计。以 AGENTS.md 为例:
my-project/
├── AGENTS.md ← 启动时加载(进系统提示词)
├── frontend/
│ └── AGENTS.md ← 智能体读 frontend/ 文件时发现
├── backend/
│ └── AGENTS.md ← 智能体读 backend/ 文件时发现
└── shared/
└── AGENTS.md ← 智能体读 shared/ 文件时发现
启动时只加载根目录的 AGENTS.md。当智能体在会话中通过 read_file、terminal、search_files 等工具进入子目录时,才会渐进式地发现并注入那个子目录的上下文文件。
这样做有两个好处:
- 不撑爆系统提示词—子目录的提示只在需要时才出现
- 保护提示词缓存—系统提示词在多轮对话中保持稳定,省 token
安全:提示词注入防护
所有上下文文件在加载前都会扫描潜在的提示词注入。扫描器检查:
- 指令覆盖尝试(「忽略之前的指令」)
- 欺骗模式(「不要告诉用户」)
- 系统提示词覆盖
- 隐藏的 HTML 注释和 div 元素
- 凭据外泄模式(
curl ... $API_KEY) - 敏感文件访问(
cat .env) - 不可见字符(零宽空格、双向覆盖等)
检测到威胁模式时,文件会被阻止加载:
[BLOCKED: AGENTS.md contained potential prompt injection. Content not loaded.]
Warning这个扫描器防的是常见注入模式,不能替代你审查共享仓库里的上下文文件。在不是你自己写的项目里,一定要检查
AGENTS.md内容。
Profile:一台机器跑多个智能体
Profile 是 Hermes 里我最喜欢的功能之一。简单说:一个 Profile 就是一个独立的 Hermes 主目录。
为什么需要 Profile
假设你想要一个编码助手、一个研究助手、一个运维监控—如果都塞在一个配置里,记忆会混、技能会混、人格会混。
Profile 解决这个问题:每个 Profile 有自己独立的 config.yaml、.env、SOUL.md、记忆、会话、技能、定时任务和状态数据库。互不干扰。
创建和使用 Profile
hermes profile create coder # 创建 profile + "coder" 命令别名
coder setup # 配置 API Key 和模型
coder chat # 开始聊天
创建完 coder 这个 Profile,你立刻就有了 coder 这个命令—它本质上是 hermes -p coder 的别名。
三种创建方式
# 空白 profile,需要完整配置
hermes profile create mybot
# 只克隆配置(config.yaml、.env、SOUL.md、技能),会话和记忆是全新的
hermes profile create work --clone
# 克隆一切(配置、密钥、人格、记忆、技能、定时任务、插件)
hermes profile create backup --clone-all
# 从指定 profile 克隆
hermes profile create work2 --clone-from work
Tip
--clone适合「同样的能力,不同的用途」—比如用同一个 API Key 但不同人格。--clone-all适合做完整快照备份。注意--clone-all不包含会话历史(那属于源 Profile,可能几十 GB),完整备份用hermes profile export。
切换 Profile 的三种方式
- 命令别名(最直观):
coder chat # 用 coder 聊天
coder gateway start # 启动 coder 的网关
coder config set model.default anthropic/claude-sonnet-4
-p参数(临时指定):
hermes -p coder chat
hermes --profile=coder doctor
hermes chat -p coder -q "hello"
- 粘性默认(设一次,后续都走它):
hermes profile use coder
hermes chat # 现在默认用 coder
hermes tools # 配置 coder 的工具
hermes profile use default # 切回默认
这类似 kubectl config use-context 的逻辑。
怎么知道当前在哪个 Profile
CLI 会一直显示当前 Profile:
- 提示符:
coder ❯而不是❯ - 横幅:启动时显示
Profile: coder - 命令:
hermes profile显示当前 Profile 名、路径、模型、网关状态
Profile 不是沙箱
这点容易搞混:
- Profile 给 Hermes 自己的状态目录做隔离—配置、密钥、会话、记忆、技能。
- 工作目录是终端命令的起始位置,由
terminal.cwd控制。 - 沙箱限制文件系统访问。Profile 不做沙箱隔离。
在默认的 local 终端后端上,智能体仍然有你用户账号的完整文件系统访问权限。Profile 不会阻止它访问 Profile 目录之外的文件夹。
Warning如果你想要某个 Profile 固定在某个项目目录工作,在那个 Profile 的
config.yaml里设绝对路径的terminal.cwd。用cwd: "."在 local 后端上意思是「Hermes 启动时的目录」,不是「Profile 目录」。
Profile 命令速查
| 命令 | 作用 |
|---|---|
hermes profile list | 列出所有 Profile(* 标记当前) |
hermes profile use <name> | 设为默认 Profile |
hermes profile create <name> | 创建新 Profile |
hermes profile show <name> | 查看详情(路径、模型、网关状态、技能数) |
hermes profile rename <old> <new> | 重命名(更新目录和别名) |
hermes profile export <name> | 导出为 tar.gz |
hermes profile import <archive> | 从 tar.gz 导入 |
hermes profile delete <name> | 删除(需确认,不能删当前激活的) |
hermes profile describe <name> | 读/设描述(供 Kanban 编排器路由用) |
Note每个 Profile 运行自己的网关进程,用自己的 Bot Token。如果两个 Profile 不小心用了同一个 Token,第二个会被明确报错拦截。支持 Telegram、Discord、Slack、WhatsApp、Signal。
Profile 分发:把整个智能体分享给别人
Profile 还能打包成 git 仓库,别人一行命令就能装:
# 从 git 仓库安装一个完整的智能体
hermes profile install github.com/you/research-bot --alias
# 作者发新版后更新(保留你的记忆和 .env)
hermes profile update research-bot
分享包包含 SOUL、配置、技能、定时任务、MCP 连接。凭据、记忆和会话留在各自机器上,不随分发走。
Tip这意味着你可以把精心调教好的智能体(人格 + 技能 + 配置)发布到 GitHub,别人 clone 下来填上自己的 API Key 就能用。
auth.json和.env永远不会进入分发包。
下一章我们聊模型配置—怎么在 10+ 个提供商之间切换。