Skip to content

08 — Hermes-aligned File Structure

Status: 📐 Architecture proposal · 2026-05-07 Source: Hermes Agent docs (skills, mcp, configuration, context-files, tools) Goal: Single source-of-truth deployment dir + agent-readable reference docs; align repo with Hermes canonical layout to make P1.1 provisioner sync trivial

Hermes 已经定义了一套约定俗成的目录结构;让我们的 repo 长得跟它"一模一样",省掉将来 sync 时的翻译成本

目标 (Goal)

回应用户三件事:

  1. 整洁的单源部署目录:一个目录就是一个完整可部署的 profile,rsync 即可
  2. 本地可读的 reference 文档:sessions / context / tool 用法集中存放,agent 能加载
  3. MCP-first 数据源整合:未来外部数据源走 MCP server + config.yaml,本地代码走 skills/ + scripts/

Hermes 官方约定(fetch 自 docs)

全局 + per-profile 文件树

~/.hermes/                         # global, OR ~/.hermes/profiles/<name>/ for per-profile
├── config.yaml                    # provider/model/agent/mcp_servers/skills/...
├── .env                           # secrets
├── auth.json                      # OAuth (auto-managed)
├── SOUL.md                        # agent identity (always slot #1)
├── memories/                      # MEMORY.md, USER.md
├── skills/                        # both human-authored and agent-created live here
│   └── <category>/<skill>/
│       ├── SKILL.md               # required: name, description (+ optional metadata)
│       ├── scripts/               # helper scripts callable from skill
│       ├── references/            # additional docs
│       ├── templates/             # output formats
│       └── assets/                # supplementary
├── cron/                          # scheduled jobs
├── sessions/                      # gateway session DB
└── logs/                          # auto-redacted runtime logs

Context-file 加载顺序(at session start)

  • SOUL.md:always loads, slot #1(只在 ~/.hermes/SOUL.md在 working dir 探测)
  • Project context:working dir 走 .hermes.mdAGENTS.mdCLAUDE.md.cursorrules(first-match wins,progressive discovery in subdirectories)
  • profile 模式 下,profile 目录被当作 working dir,所以 ~/.hermes/profiles/<name>/AGENTS.md 会被加载

SKILL.md frontmatter(Hermes 格式)

yaml
---
name: my-skill
description: Brief description
version: 1.0.0
platforms: [macos, linux]
metadata:
  hermes:
    tags: [python, automation]
    category: devops
    config:
      - key: my.setting
        description: "What this controls"
        default: "value"
        prompt: "Prompt for setup"
required_environment_variables:
  - name: TOKEN_X
    prompt: Token for X
    help: Get it from https://...
    required_for: full functionality
---

config.yaml 顶层 keys(最常用)

Key用途
modelPrimary LLM provider/model
auxiliarySide-task models (vision, compression)
agentmax_turns, reasoning_effort, tool_use_enforcement
terminalShell backend (local/docker/ssh)
mcp_serversMCP server declarations + tools include/exclude
skillsSkill config + agent-write guards
webWeb search backend (firecrawl/searxng/...)
compression, display, voice, streaming, security, approvals, delegation, quick_commands, checkpoints各种行为参数

MCP server 声明示例

yaml
mcp_servers:
  filesystem:                  # stdio + npx
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]

  github:                      # stdio + env-passed token
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
    tools:
      include: [create_issue, list_issues]    # whitelist 优先于 exclude

  company_api:                 # remote HTTP
    url: "https://mcp.internal.example.com"
    headers:
      Authorization: "Bearer ${COMPANY_API_KEY}"

Hermes 不会盲目透传整个 shell env;只有 env 块里显式列出的变量 + 一个 safe baseline 才会下发。

/opt/hermes-agent/
├── config.yaml
├── .env.production           # gitignored
├── SOUL.md
└── skills/
    └── ...

现状(Twilight Drive v0.1.1)

twilight-drive/
├── core/                              # Python lib(citation/verifier/data 适配器)
│   ├── core/{citation,verifier,competences,model_router,runtime,skills,tools}.py
│   └── core/data/{tushare,akshare,_market,schemas}.py
├── skill/stock-research/              # ⚠️ 缺 category 层级
│   ├── SKILL.md                       # ⚠️ frontmatter 字段是 top-level 而非 metadata.hermes
│   ├── scripts/{_client,fetch_price,fetch_fundamentals,search_reports}.py
│   ├── references/chinese-a-share-data-sources.md
│   └── templates/operation-strategy.md
├── profile/template-stock-research-pro/
│   ├── AGENTS.md
│   ├── SOUL.md
│   ├── README.md
│   └── legacy/                        # 历史 trading-bot 模板归档
├── scripts/{install-skill.sh, with-hermes-secrets.sh, with-cf-token.sh}
├── docs/                              # VitePress 站
└── install.sh

现状对照 Hermes 约定

维度现状Hermes 期望差距
Skill 路径层级skill/stock-research/skills/<category>/<skill>/⚠️ 缺 research/ category 子层(install-skill.sh 部署时会加)
SKILL.md frontmattertop-level category, required_environment_variablesmetadata.hermes.{tags,category,config} + required_environment_variables⚠️ category 应嵌进 metadata.hermes
Skill 子目录scripts/ ✅ + references/ ✅ + templates/ ✅同上 + 可选 assets/✅ 对齐
部署 profile 模板profile/template-stock-research-pro/ 含 AGENTS.md + SOUL.md同上 + config.yaml + .env❌ 缺 config.yaml.template + .env.example
secrets.schema.json不存在provisioner clone 时按 schema 植入❌ 缺,P1.1 必备
MCP 集成mcp_servers: 块(推荐用于外部数据源)❌ P2 范围;现在先在 spec 里规划
单源部署profile 模板与 skill 分两处,install-skill.sh 拼装一个完整 profile dir 直接 rsync 即可⚠️ 拼装步骤可保留,但 profile 模板应完整可见(见下文方案)
Reference docsreferences/chinese-a-share-data-sources.md 一份references/ 里是 agent 实际加载的 context 文档⚠️ 应补 tool-usage.md + session-context.md

提议的目标结构

仓库根(source of truth)

twilight-drive/
├── core/                                  # 不变(citation/verifier/data lib)
├── skill/stock-research/                  # skill 源代码(不带 category 前缀;install-skill.sh 加 research/)
│   ├── SKILL.md                           # 调整 frontmatter → metadata.hermes
│   ├── scripts/...                        # 不变
│   ├── references/
│   │   ├── chinese-a-share-data-sources.md  # 现有
│   │   ├── tool-usage.md                  # 🆕 fetch_price / fetch_fundamentals / search_reports 用法
│   │   ├── session-context.md             # 🆕 典型问询形态、输出预期、回退策略
│   │   └── price-freshness.md             # 🆕 served_by/metric 解读(已在 SKILL.md,抽到独立文档便于 LLM 检索)
│   └── templates/operation-strategy.md    # 不变
├── profile/template-stock-research-pro/   # 完整 profile 模板(rsync-ready)
│   ├── AGENTS.md                          # 现有
│   ├── SOUL.md                            # 现有
│   ├── config.yaml.template               # 🆕 含 mcp_servers 占位 + model 配置
│   ├── .env.example                       # 🆕 列出所需 env keys(注释解释每一项)
│   ├── secrets.schema.json                # 🆕 P1.1 provisioner 用
│   ├── README.md                          # 现有,更新 install 说明
│   └── legacy/                            # 不变(trading-bot 历史归档)
├── scripts/                               # 不变
├── docs/                                  # 不变
└── install.sh                             # 不变

部署后的 profile(运行时)

~/.hermes/profiles/stock-research-agent/
├── config.yaml          ← 由 config.yaml.template 实例化
├── .env                 ← 由 .env.example 复制 + secrets.schema.json 植入填充
├── auth.json            ← Hermes 自管
├── SOUL.md              ← profile/template/SOUL.md 复制
├── AGENTS.md            ← profile/template/AGENTS.md 复制
├── memories/            ← Hermes runtime 维护
├── skills/
│   └── research/
│       └── stock-research/   ← rsync skill/stock-research/ + shebang 重写
├── cron/, sessions/, logs/, ...      ← Hermes runtime 维护

与 Hermes 文档对齐的关键变化:

  1. category 层(research/)由 install-skill.sh 注入:源仓库不带 category 前缀以保持灵活,部署时统一加 research/
  2. SKILL.md frontmatter 改为 metadata.hermes.category:跟 Hermes 文档示例一致
  3. profile 模板含完整 4 件套:AGENTS.md + SOUL.md + config.yaml.template + .env.example(+ secrets.schema.json for P1.1)
  4. References 拓展:从单一数据源指南扩到 tool-usage / session-context / price-freshness 三份,agent 在跑 skill 时按需加载
  5. MCP 占位:config.yaml.template 已留 mcp_servers: 块(含注释说明),P2-A 数据仓库上线时直接填

與 MCP / skills / scripts 的关系决策

用户引用:"最'洁净'的方式是把外部数据源包装成 MCP Server 并在 config.yaml 中声明;如果必须使用本地代码,则放进 skills/ 目录并通过 skill_manage 加载后再加入 toolsets.py"

我们现在的 stock-research 走的是第二条路径(本地 skill scripts)。两个原因合理:

  • 数据访问需要带 cite 信封(served_bytool_call_id),MCP server 包装一层后我们对协议的控制变松
  • core 包内含 Verifier,要求每个数据点能被确定性校验,与 cite 一一对应

长期方向(P2 之后):

路径适合什么现在未来
Skill scripts (skill/stock-research/scripts/)需要 cite 强制 + Verifier 闭环的核心数据✅ Tushare/akshare/get_price保留
MCP server第三方原生协议(GitHub、filesystem、SearXNG 等)❌ 无P2-C:SearXNG MCP server 替换 web 搜索;考虑把 Tushare API 包装成 MCP server 让外部 agent 也能用
Twilight backend HTTP(P1.0)跨 profile 共享、需要鉴权/计费/缓存⏳ P1.0profile config.yaml 把 backend URL 注入;skill _client.py 自动切到 Service 模式

所以:现阶段 skill scripts + scripts/install-skill.sh 是对的,不是技术债。MCP 上线后 config.yaml.template 加 mcp_servers 块即可,不重写 skill。

關鍵決策點 (Open Questions)

Q1. SKILL.md frontmatter 是否破坏性升级?

  • A) 直接改成 Hermes 标准 metadata.hermes.category(破坏性)
  • B) 同时保留 top-level + 嵌套 metadata.hermes(兼容)
  • C) 不动(Hermes 当前能解析 top-level)

建議 A(直接改):现在只有一个 skill,破坏性升级成本最低;保留兼容字段反而是技术债。

Q2. profile/template 是否包含 skills/ 子目录(rsync 即完整 profile)?

  • A) 包含:profile/template-stock-research-pro/skills/research/stock-research/ 通过 symlink 指向 skill/stock-research/
  • B) 不包含:profile 模板只放 AGENTS.md/SOUL.md/config.yaml.template/.env.example;skill 由 install-skill.sh 单独装入
  • C) 不包含但仓库 build 时把 skill 拷贝/打包进 template

建議 B(不包含 skill):保持当前 install-skill.sh 的拼装逻辑(已经稳定且测试过);profile 模板专注做"非 skill 部分"的 source of truth。代价是 profile 模板看起来不像"完整 profile",README 解释清楚即可。

Q3. config.yaml.template 模板化策略?

  • A) Jinja-like {{PLACEHOLDER}} (Initiative B 已有此约定)
  • B) Hermes 原生 ${ENV_VAR} 替换
  • C) 两者结合:硬编码常量 + ${ENV_VAR} 引用 secrets

建議 C(两者结合){{PLACEHOLDER}} 给 provisioner-time 替换的字段(用户名、profile 名、bot ID 等元数据),${ENV_VAR} 给 Hermes runtime 解析的 secrets。两套语义清晰。

Q4. agent runtime 真要加载 references/*.md 吗?

  • A) 是,写明在 SKILL.md 触发条件里"调用 fetch_price 前先读 references/tool-usage.md 中相应段"
  • B) 否,references 是给操作员看的,agent 走 SKILL.md 即可
  • C) 半量:agent 不主动读,但 SKILL.md 可以引用具体段落(cite tool 路径回 references)

建議 C:references 主要是 SKILL.md 的"详细参考章节" + 操作员阅读;当 agent 在跑步骤里遇到边角问题(如解释 served_by 含义)时,SKILL.md 内置 link 让它去读 specific reference file。这跟 Hermes 文档对 references/ 的定位 ("Additional docs") 一致。

與其他層的關係

  • 00-multi-tenancy:本结构让 multi-profile 部署的 sync/clone 路径变得直接(rsync template → fill placeholders → done)
  • 06-v0.1.1-hotfix-and-p1:v0.1.1 已 ship 的 SKILL.md "价格新鲜度语义" 拆出独立 reference 文件
  • 07-aigc-monetization:profile template 是 P1.1 provisioner 的核心原料,决定 user 体验起点
  • superpowers/specs/phase1:P1.0 backend 上线后 config.yaml.template 把 model: 指向 New-API endpoint(P2-C 之前先指向 SiliconFlow 直连)
  • superpowers/specs/phase2 Initiative B:profile registry 自动 push/pull 这套模板(hermes-profile-manager

下一步 (Next Steps)

详见 plans/2026-05-07-hermes-restructure.md。Highlights:

  1. SKILL.md frontmatter migrate(破坏性升级,1 commit)
  2. profile/template 加 config.yaml.template + .env.example + secrets.schema.json(1 commit)
  3. references 拆分 + 新增 tool-usage / session-context / price-freshness(1 commit)
  4. README 更新 + planning index + VitePress sidebar(1 commit)
  5. 部署到运行 profile 验证(手动)

进一步阅读

团队内部文档