目 录CONTENT

文章目录

Hermes Agent 一键部署实战:从裸机到自进化运行

PySuper
2026-05-23 / 0 评论 / 0 点赞 / 0 阅读 / 0 字
温馨提示:
本文最后更新于2026-05-22,若内容或图片失效,请留言反馈。 所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

作者:PySuper | 来源:zhengxingtao.com

上一篇 #48 讲了 Hermes Agent 的自进化原理,部署部分点到为止。这篇是纯运维向——你拿到一台裸机,照着做,30 分钟后 Hermes 就在跑,并且能从 Telegram/Discord 跟你对话。所有脚本都可直接复制运行,不含省略号。

目录

  1. 部署前规划

  2. 方案一:Docker 一键部署(推荐)

  3. 方案二:pip/uv 安装部署

  4. 方案三:云服务器一键部署

  5. 多渠道接入配置

  6. 模型配置

  7. 自进化系统配置

  8. 执行后端配置

  9. 生产加固

  10. 一键部署脚本(完整版)

  11. 与 OpenClaw 联合部署方案

  12. 常见问题排查

1. 部署前规划

1.1 硬件需求

Hermes Agent 的资源消耗跟 OpenClaw 有本质区别——Hermes 重存储,因为 Skill、记忆、会话摘要都在本地持久化。选配置时磁盘比 CPU 更关键。

表格

配置档

CPU

内存

磁盘

GPU

月费参考

适用场景

最小

2C

4GB

40GB SSD

$5-10

个人尝鲜、CLI 模式

推荐

4C

8GB

80GB SSD

$15-25

日常使用 + 网关模式

生产

8C

16GB

200GB SSD

可选

$40-80

团队使用 + Ollama 本地推理

本地推理

8C+

32GB+

200GB SSD

16GB+ VRAM

电费

Ollama 跑 70B 模型

据《How to Set Up Hermes Agent》(https://hermes-agent.ai/blog/hermes-agent-setup-guide),Hetzner CX22(2 vCPU / 4GB RAM)约 EUR4/月,是性价比最高的入门选择。

1.2 操作系统支持

plaintext

┌─────────────────────────────────────────────────────┐
│             Hermes Agent OS 支持矩阵                 │
├─────────────┬───────────┬───────────┬───────────────┤
│   OS        │  安装脚本 │  Docker   │   备注        │
├─────────────┼───────────┼───────────┼───────────────┤
│ Ubuntu 22.04│   ✅      │   ✅      │ 官方推荐      │
│ Debian 12   │   ✅      │   ✅      │ 稳定          │
│ macOS       │   ✅      │   ✅      │ Intel/Apple   │
│ WSL2        │   ✅      │   ✅      │ Win11 必须    │
│ Termux      │   ✅      │   ❌      │ 精简版        │
│ Windows 原生│   ❌      │   ❌      │ 不支持        │
│ NixOS       │   ✅      │   ✅      │ Nix flake     │
└─────────────┴───────────┴───────────┴───────────────┘

1.3 与 OpenClaw 的部署差异

Hermes 和 OpenClaw 都能跑在 2C4G 上,但资源侧重完全不同:

plaintext

┌──────────────────────────────────────────────────────────────┐
│              资源消耗对比(同等工作负载)                       │
│                                                              │
│  OpenClaw                    Hermes Agent                    │
│  ┌──────────────┐            ┌──────────────┐                │
│  │ CPU: ★★★★☆   │            │ CPU: ★★★☆☆   │                │
│  │ 内存: ★★★☆☆  │            │ 内存: ★★★☆☆  │                │
│  │ 磁盘: ★★☆☆☆  │            │ 磁盘: ★★★★★  │                │
│  │ 网络: ★★★★★  │            │ 网络: ★★★☆☆  │                │
│  └──────────────┘            └──────────────┘                │
│                                                              │
│  OpenClaw 重 API 调用(常驻 Claude Opus)                    │
│  Hermes 重本地存储(Skill 文件 + FTS5 索引 + 记忆)          │
│                                                              │
│  ┌──────────────────────────────────────────────┐            │
│  │ 磁盘空间增长预估(6个月日常使用)            │            │
│  │                                              │            │
│  │ OpenClaw:  ~500MB  (配置+日志)               │            │
│  │ Hermes:    ~2-5GB  (Skill+记忆+会话索引)     │            │
│  │ Ollama:    +4-40GB (每个模型 4-40GB)         │            │
│  └──────────────────────────────────────────────┘            │
└──────────────────────────────────────────────────────────────┘

关键差异

  • 存储:Hermes 的 Skill 文件(~/.hermes/skills/)、FTS5 会话索引(sessions.db)、记忆文件(MEMORY.md/USER.md/SOUL.md)会持续增长。OpenClaw 的配置基本不增长。

  • 模型灵活性:Hermes 支持 19+ 提供商(含本地 Ollama、vLLM),OpenClaw 主要依赖 Anthropic。这意味着 Hermes 可以跑在便宜的模型上,日成本更低。

  • 网关开销:Hermes 的 Gateway 进程同时处理所有平台消息,内存占用比 OpenClaw 的轻量 CLI 更大。

1.4 模型选择:云 API vs 本地

表格

策略

推荐模型

月成本

延迟

质量

极省

DeepSeek V4 / Kimi K2.5

$2-5

均衡

Claude Sonnet 4.6 via OpenRouter

$15-30

本地

Ollama + Qwen3 14B

电费

顶配

Claude Opus 4.6

$50+

极优

据社区共识,Kimi K2.5 约3/天重度使用,DeepSeekV4的缓存命中仅3/天重度使用,DeepSeek V4 的缓存命中仅 0.03/M token——日常使用选这两款不会肉疼。

2. 方案一:Docker 一键部署(推荐)

Docker 是最省心的方案:环境隔离、升级方便、数据持久化有保障。生产环境优先选这个。

2.1 完整 docker-compose.yml

yaml

# docker-compose.yml — Hermes Agent 生产部署
# 用法: HERMES_UID=$(id -u) HERMES_GID=$(id -g) docker compose up -d
#
# 安全提示:
# - Dashboard 默认绑定 127.0.0.1,不对外暴露
# - API Server 默认关闭,需手动开启并设置密钥
# - .env 文件权限必须 600

version: "3.8"

services:
  # ── Hermes Agent 主服务 ──────────────────────────────────
  hermes:
    image: nousresearch/hermes-agent:latest
    container_name: hermes
    restart: unless-stopped
    command: ["gateway", "run"]
    ports:
      - "8642:8642"     # Gateway API
    volumes:
      - ~/.hermes:/opt/data
    environment:
      - HERMES_UID=${HERMES_UID:-10000}
      - HERMES_GID=${HERMES_GID:-10000}
      # API Server(默认关闭,生产环境按需开启)
      # - API_SERVER_HOST=0.0.0.0
      # - API_SERVER_KEY=${API_SERVER_KEY}
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: "2.0"
    depends_on:
      redis:
        condition: service_healthy
    networks:
      - hermes-net

  # ── Redis 记忆后端 ──────────────────────────────────────
  redis:
    image: redis:7-alpine
    container_name: hermes-redis
    restart: unless-stopped
    command: >
      redis-server
      --appendonly yes
      --appendfsync everysec
      --maxmemory 1gb
      --maxmemory-policy allkeys-lru
      --requirepass ${REDIS_PASSWORD:-}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 1536M
          cpus: "0.5"
    networks:
      - hermes-net

  # ── Dashboard Web UI ───────────────────────────────────
  dashboard:
    image: nousresearch/hermes-agent:latest
    container_name: hermes-dashboard
    restart: unless-stopped
    command: ["dashboard", "--host", "127.0.0.1", "--no-open"]
    ports:
      - "9119:9119"
    volumes:
      - ~/.hermes:/opt/data
    environment:
      - HERMES_UID=${HERMES_UID:-10000}
      - HERMES_GID=${HERMES_GID:-10000}
      - GATEWAY_HEALTH_URL=http://hermes:8642
    depends_on:
      - hermes
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "0.5"
    networks:
      - hermes-net

  # ── PostgreSQL(可选:生产级记忆后端)──────────────────
  postgres:
    image: postgres:16-alpine
    container_name: hermes-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: hermes
      POSTGRES_USER: hermes
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-hermes_local_dev}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U hermes"]
      interval: 10s
      timeout: 5s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 1G
          cpus: "0.5"
    networks:
      - hermes-net

  # ── Ollama(可选:本地模型推理)────────────────────────
  ollama:
    image: ollama/ollama:latest
    container_name: hermes-ollama
    restart: unless-stopped
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    deploy:
      resources:
        limits:
          memory: 16G
          cpus: "4.0"
    # GPU 支持(NVIDIA)
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: 1
    #           capabilities: [gpu]
    networks:
      - hermes-net

volumes:
  redis_data:
  postgres_data:
  ollama_data:

networks:
  hermes-net:
    driver: bridge

2.2 环境变量详解

创建 .env 文件:

bash

# ── LLM 提供商(至少填一个)──────────────────────────────
# OpenRouter(推荐:200+ 模型切换)
OPENROUTER_API_KEY=sk-or-v1-your-key-here

# 或 Anthropic 直连
# ANTHROPIC_API_KEY=sk-ant-api03-your-key

# 或 DeepSeek
# DEEPSEEK_API_KEY=sk-your-deepseek-key

# ── Redis 密码(生产必须设置)────────────────────────────
REDIS_PASSWORD=

# ── PostgreSQL 密码 ──────────────────────────────────────
POSTGRES_PASSWORD=your-strong-password-here

# ── API Server 密钥(开启 API 时必须设置)─────────────────
# API_SERVER_KEY=your-api-server-key

# ── Docker UID/GID(文件权限映射)────────────────────────
HERMES_UID=1000
HERMES_GID=1000

# ── 消息网关(按需填写)──────────────────────────────────
# TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
# DISCORD_BOT_TOKEN=your-discord-token
# SLACK_BOT_TOKEN=xoxb-your-slack-token

# ── 可选工具密钥 ─────────────────────────────────────────
# FIRECRAWL_API_KEY=fc-your-key
# FAL_KEY=your-fal-key

安全提醒.env 文件权限必须收紧:

bash

chmod 600 .env

2.3 数据持久化策略

plaintext

┌──────────────────────────────────────────────────────────────┐
│              Hermes 数据持久化架构                            │
│                                                              │
│  宿主机 ~/.hermes/          容器内 /opt/data/                │
│  ┌─────────────────┐        ┌─────────────────┐              │
│  │ .env            │ ◀────▶ │ .env            │              │
│  │ config.yaml     │ ◀────▶ │ config.yaml     │              │
│  │ SOUL.md         │ ◀────▶ │ memories/SOUL.md│              │
│  │ memories/       │ ◀────▶ │ memories/       │              │
│  │   MEMORY.md     │        │   MEMORY.md     │              │
│  │   USER.md       │        │   USER.md       │              │
│  │ skills/         │ ◀────▶ │ skills/         │              │
│  │   deploy-k8s/   │        │   deploy-k8s/   │              │
│  │   nginx-ssl/    │        │   nginx-ssl/    │              │
│  │ sessions/       │ ◀────▶ │ sessions/       │              │
│  │ cron/           │ ◀────▶ │ cron/           │              │
│  │ logs/           │ ◀────▶ │ logs/           │              │
│  └─────────────────┘        └─────────────────┘              │
│                                                              │
│  Docker Named Volumes:                                       │
│  ┌───────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │ redis_data    │  │ postgres_data│  │ ollama_data  │      │
│  │ 会话缓存      │  │ 结构化记忆   │  │ 模型文件     │      │
│  │ (1GB limit)   │  │ (生产推荐)   │  │ (4-40GB/模型)│      │
│  └───────────────┘  └──────────────┘  └──────────────┘      │
└──────────────────────────────────────────────────────────────┘

关键原则:容器可以删,镜像可以升级,但 ~/.hermes/ 目录和 Named Volumes 绝不能丢。所有状态都在这里。

2.4 一键启动/停止/重启

bash

# ── 启动所有服务 ─────────────────────────────────────────
docker compose up -d

# ── 查看状态 ─────────────────────────────────────────────
docker compose ps

# ── 查看日志 ─────────────────────────────────────────────
docker compose logs hermes --tail 50 -f

# ── 健康检查 ─────────────────────────────────────────────
curl http://localhost:8642/health
# 预期返回: {"status":"ok"}

# ── 重启(升级后)────────────────────────────────────────
docker compose pull
docker compose up -d

# ── 停止所有服务 ─────────────────────────────────────────
docker compose down

# ── 停止并清理(数据卷保留)──────────────────────────────
docker compose down --remove-orphans

# ── 完全清理(⚠️ 含数据卷,慎用!)───────────────────────
docker compose down -v

2.5 Docker 安全加固

据 Hermes Agent 官方 Docker 文档(https://hermes-agent.nousresearch.com/docs/user-guide/docker),最高隔离级别的运行方式:

bash

docker run -d --name hermes \
  --read-only \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --tmpfs /tmp:size=100m \
  -v ~/.hermes:/opt/data \
  -p 8642:8642 \
  nousresearch/hermes-agent gateway run

2.6 多 Profile 部署

Hermes 支持多 Profile(不同 SOUL、Skill、记忆、凭证),Docker 下的推荐做法是一个容器一个 Profile:

yaml

# docker-compose.yml — 多 Profile 示例
services:
  hermes-work:
    image: nousresearch/hermes-agent:latest
    container_name: hermes-work
    restart: unless-stopped
    command: ["gateway", "run"]
    ports:
      - "8642:8642"
    volumes:
      - ~/.hermes-work:/opt/data

  hermes-personal:
    image: nousresearch/hermes-agent:latest
    container_name: hermes-personal
    restart: unless-stopped
    command: ["gateway", "run"]
    ports:
      - "8643:8642"
    volumes:
      - ~/.hermes-personal:/opt/data

每个 Profile 独立容器、独立端口、独立数据——不会串台。

3. 方案二:pip/uv 安装部署

适合不想用 Docker 的场景:macOS 开发环境、已有多台 VPS 的老运维、或需要深度定制。

3.1 Python 环境准备

Hermes 需要 Python 3.11+。推荐用 uv 管理,它比 pip 快 10-100 倍:

bash

# ── 安装 uv ──────────────────────────────────────────────
curl -LsSf https://astral.sh/uv/install.sh | sh

# ── 验证 ─────────────────────────────────────────────────
uv --version

# ── 如果坚持用 pip ──────────────────────────────────────
python3 --version  # 需要 3.11+

3.2 一键安装脚本

据 Hermes Agent 安装文档(https://hermes-agent.ac.cn/docs/getting-started/installation),官方安装脚本最省心:

bash

# 官方一键安装(处理 Python + uv + 依赖 + PATH)
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash

# 安装选项
curl -fsSL ... | bash -s -- --skip-setup     # 跳过设置向导
curl -fsSL ... | bash -s -- --no-venv         # 不创建虚拟环境
curl -fsSL ... | bash -s -- --branch dev      # 安装开发分支
curl -fsSL ... | bash -s -- --dir /opt/hermes # 指定安装目录

3.3 手动安装(完全控制)

bash

# ── 克隆仓库 ─────────────────────────────────────────────
git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git
cd hermes-agent

# ── 创建虚拟环境 ─────────────────────────────────────────
uv venv venv --python 3.11

# ── 安装依赖 ─────────────────────────────────────────────
export VIRTUAL_ENV="$(pwd)/venv"

# 完整安装(含所有消息平台 + 语音 + Cron)
uv pip install -e ".[all]"

# 最小安装(仅核心 Agent)
# uv pip install -e "."

# 按需安装
# uv pip install -e ".[messaging]"  # Telegram/Discord/Slack
# uv pip install -e ".[cron]"       # 定时任务
# uv pip install -e ".[mcp]"        # MCP 集成
# uv pip install -e ".[voice]"      # 语音(不支持 Termux)

# ── 可选子模块 ───────────────────────────────────────────
# uv pip install -e "./tinker-atropos"  # RL 训练后端

# ── Node.js 依赖(可选:浏览器自动化 + WhatsApp)─────────
# npm install

# ── 创建配置目录 ─────────────────────────────────────────
mkdir -p ~/.hermes/{cron,sessions,logs,memories,skills,pairing,hooks,image_cache,audio_cache,whatsapp/session}

# ── 复制默认配置 ─────────────────────────────────────────
cp cli-config.yaml.example ~/.hermes/config.yaml

# ── 创建 .env ────────────────────────────────────────────
touch ~/.hermes/.env

# ── 添加到 PATH ──────────────────────────────────────────
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes

# ── 验证安装 ─────────────────────────────────────────────
hermes doctor

3.4 配置文件 config.yaml 详解

Hermes 的核心配置文件是 ~/.hermes/config.yaml,据官方示例配置(https://github.com/NousResearch/hermes-agent/blob/main/cli-config.yaml.example)整理:

yaml

# =============================================================================
# ~/.hermes/config.yaml — Hermes Agent 完整配置
# =============================================================================

# ── 模型配置 ─────────────────────────────────────────────
model:
  # 默认模型(provider:model 格式或纯模型名)
  default: "anthropic/claude-sonnet-4-6"

  # 推理提供商
  # auto | openrouter | nous | anthropic | openai-codex | copilot |
  # zai | kimi-coding | minimax | minimax-cn | deepseek | custom
  provider: "auto"

  # API 基础 URL(custom 提供商必填)
  base_url: "https://openrouter.ai/api/v1"

  # 上下文长度(一般不设,Hermes 自动检测)
  # context_length: 131072

  # 输出 token 上限(一般不设,用模型原生上限)
  # max_tokens: 8192

# ── 备用模型(主模型挂了自动切换)─────────────────────────
fallback_model:
  provider: openrouter
  model: anthropic/claude-sonnet-4

# ── 终端执行后端 ─────────────────────────────────────────
terminal:
  # local | docker | ssh | modal | daytona | vercel_sandbox | singularity
  backend: "local"
  cwd: "."
  timeout: 180
  env_passthrough: []  # 传递到沙箱的环境变量名列表

  # Docker 后端配置
  # docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
  # docker_mount_cwd_to_workspace: false
  # docker_forward_env:
  #   - GITHUB_TOKEN
  # docker_volumes:
  #   - "/host/path:/container/path"

  # SSH 后端配置
  # ssh_host: "your-server.com"
  # ssh_user: "root"
  # ssh_port: 22
  # ssh_key_path: "~/.ssh/id_rsa"

  # Modal 后端配置
  # modal_image: "nikolaik/python-nodejs:python3.11-nodejs20"

  # Daytona 后端配置
  # daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20"
  # container_cpu: 1
  # container_memory: 5120
  # container_disk: 10240
  # container_persistent: true

# ── Agent 行为 ──────────────────────────────────────────
agent:
  max_turns: 90            # 每次对话最大工具调用轮次
  reasoning_effort: "medium"  # none | low | minimal | medium | high | xhigh

# ── 记忆系统 ─────────────────────────────────────────────
memory:
  memory_enabled: true       # 启用 MEMORY.md
  user_profile_enabled: true # 启用 USER.md
  memory_char_limit: 2200    # MEMORY.md 最大字符数
  user_char_limit: 1375      # USER.md 最大字符数

# ── 上下文压缩 ──────────────────────────────────────────
compression:
  enabled: true
  threshold: 0.50            # 上下文占用超过 50% 时触发压缩
  summary_model: "google/gemini-3-flash-preview"  # 压缩用的便宜模型

# ── 审批模式 ─────────────────────────────────────────────
approvals:
  mode: "manual"   # manual(手动确认)| smart(AI 判断)| off(全自动)

# ── 工具集 ───────────────────────────────────────────────
toolsets:
  - all

# ── 显示设置 ─────────────────────────────────────────────
display:
  skin: "default"          # default | ares | mono | slate | poseidon
  tool_progress: "all"     # off | new | all | verbose
  compact: false
  show_reasoning: false
  streaming: false

# ── 辅助模型(各子任务可用不同模型省钱)─────────────────
auxiliary:
  # 视觉分析
  vision:
    provider: "auto"
    model: ""
    timeout: 120
  # 网页摘要
  web_extract:
    provider: "auto"
    model: ""
    timeout: 360
  # 危险命令审批
  approval:
    provider: "auto"
    model: ""
    timeout: 30
  # 会话搜索
  session_search:
    provider: "auto"
    model: ""
    timeout: 30
    max_concurrency: 3

# ── MCP 服务器 ──────────────────────────────────────────
# mcp:
#   servers:
#     - name: my-tools
#       command: npx my-mcp-server
#     - name: github
#       command: npx
#       args: ["-y", "@modelcontextprotocol/server-github"]
#       env:
#         GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"

# ── 提供商超时配置(可选)──────────────────────────────
# providers:
#   ollama-local:
#     request_timeout_seconds: 300
#     stale_timeout_seconds: 900
#   anthropic:
#     request_timeout_seconds: 30

3.5 Systemd 服务配置

bash

# ── 创建 systemd 服务文件 ────────────────────────────────
sudo tee /etc/systemd/system/hermes-agent.service << 'EOF'
[Unit]
Description=Hermes Agent Gateway
After=network.target redis.service
Requires=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/hermes-agent
ExecStart=/home/ubuntu/hermes-agent/venv/bin/hermes gateway run
Restart=always
RestartSec=10
Environment=HERMES_HOME=/home/ubuntu/.hermes

# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/ubuntu/.hermes

[Install]
WantedBy=multi-user.target
EOF

# ── 启用并启动 ──────────────────────────────────────────
sudo systemctl daemon-reload
sudo systemctl enable hermes-agent
sudo systemctl start hermes-agent

# ── 查看状态 ─────────────────────────────────────────────
sudo systemctl status hermes-agent

# ── 查看日志 ─────────────────────────────────────────────
journalctl -u hermes-agent -f

3.6 日志轮转

bash

# ── 创建 logrotate 配置 ─────────────────────────────────
sudo tee /etc/logrotate.d/hermes-agent << 'EOF'
/home/ubuntu/.hermes/logs/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}
EOF

# ── 验证配置 ─────────────────────────────────────────────
sudo logrotate -d /etc/logrotate.d/hermes-agent

4. 方案三:云服务器一键部署

4.1 云平台选择

表格

平台

方案

月费

亮点

腾讯云 Lighthouse

2C4G

¥50-80

官方一键镜像

Hetzner Cloud

CX22 (2C4G)

EUR4

性价比最高

DigitalOcean

Basic Droplet

$6

简单易用

阿里云 ECS

2C4G

¥60-100

国内速度快

AWS Lightsail

2C4G

$10-15

生态好

Vultr

Cloud Compute

$6

全球节点多

据腾讯云 Techpedia(https://www.tencentcloud.com/techpedia/144037),腾讯云 Lighthouse 是首个提供 Hermes Agent 官方应用镜像的云平台,90 秒从零到运行。

4.2 腾讯云 Lighthouse 一键部署

  1. 登录腾讯云控制台 → 搜索「Lighthouse」

  2. 创建实例 → 应用镜像 → AI Agent → Hermes Agent

  3. 选择 2C4G 或更高配置

  4. 完成购买,等待 90 秒

模板预装内容:

  • Ubuntu 22.04 LTS

  • Python 3.11 + 全部 Hermes 依赖

  • Redis 持久化配置

  • Nginx 反向代理

  • systemd 服务 + 防火墙规则

4.3 VPS 5 美元/月方案(Hetzner)

Hetzner CX22 是目前性价比最高的选择——2 vCPU、4GB RAM,仅 EUR4/月:

bash

# ── SSH 登录 ─────────────────────────────────────────────
ssh root@your-hetzner-ip

# ── 更新系统 ─────────────────────────────────────────────
apt update && apt upgrade -y

# ── 安装依赖 ─────────────────────────────────────────────
apt install -y \
  python3.11 python3.11-venv python3-pip \
  redis-server git curl nginx \
  build-essential libssl-dev libffi-dev

# ── 运行 Hermes 安装脚本 ────────────────────────────────
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash

# ── 配置 API Key ─────────────────────────────────────────
echo 'OPENROUTER_API_KEY=sk-or-v1-your-key' >> ~/.hermes/.env

# ── 启动 ─────────────────────────────────────────────────
hermes gateway install
hermes gateway start

# ── 验证 ─────────────────────────────────────────────────
curl http://localhost:8642/health

4.4 Modal 无服务器部署

据 Hermes Agent 配置文档(https://hermes-agent.nousresearch.com/docs/user-guide/configuration),Modal 后端适合临时任务和弹性计算:

yaml

# ~/.hermes/config.yaml
terminal:
  backend: modal
  modal_image: "nikolaik/python-nodejs:python3.11-nodejs20"

需要设置 Modal 凭证:

bash

pip install modal
modal token new  # 浏览器 OAuth 登录

4.5 Daytona 云开发环境

Daytona 适合需要持久化云开发环境的场景:

yaml

# ~/.hermes/config.yaml
terminal:
  backend: daytona
  daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20"
  container_cpu: 2
  container_memory: 4096
  container_disk: 10240
  container_persistent: true

bash

# 设置 Daytona API Key
export DAYTONA_API_KEY=your-daytona-key

5. 多渠道接入配置

据 Hermes Agent 消息网关文档(https://hermes-agent.nousresearch.com/docs/user-guide/messaging),Gateway 是一个单进程,同时连接所有已配置平台:

plaintext

┌──────────────────────────────────────────────────────────────┐
│              Hermes Gateway 架构                              │
│                                                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  Telegram    │  │  Discord    │  │   Slack     │          │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘          │
│         │                │                │                  │
│  ┌──────┴──────┐  ┌──────┴──────┐  ┌──────┴──────┐          │
│  │  WhatsApp   │  │   Signal    │  │    Email    │          │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘          │
│         │                │                │                  │
│  ┌──────┴──────┐  ┌──────┴──────┐  ┌──────┴──────┐          │
│  │  DingTalk   │  │  Feishu     │  │   WeCom     │          │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘          │
│         │                │                │                  │
│         └────────────────┼────────────────┘                  │
│                          ▼                                   │
│              ┌───────────────────────┐                       │
│              │   Gateway 进程        │                       │
│              │   (单进程多平台)       │                       │
│              │                       │                       │
│              │   ┌─ Session Store ─┐ │                       │
│              │   │  per chat 状态  │ │                       │
│              │   └─────────────────┘ │                       │
│              │   ┌─ Cron Scheduler ─┐ │                      │
│              │   │  每 60s 检查     │ │                      │
│              │   └─────────────────┘ │                       │
│              └───────────┬───────────┘                       │
│                          ▼                                   │
│              ┌───────────────────────┐                       │
│              │    AIAgent 核心       │                       │
│              │    (run_agent.py)     │                       │
│              └───────────────────────┘                       │
└──────────────────────────────────────────────────────────────┘

5.1 Telegram Bot 接入(完整步骤)

bash

# 第 1 步:创建 Bot
# 在 Telegram 中找 @BotFather
# /newbot → 输入名称 → 输入用户名 → 获得 Token

# 第 2 步:配置 Hermes
hermes gateway setup telegram
# 或手动配置:
hermes config set TELEGRAM_BOT_TOKEN "123456:ABC-DEF..."

# 第 3 步:启动网关
hermes gateway start

# 第 4 步:验证
# 在 Telegram 中给你的 Bot 发消息,应该能收到回复

可选:限制哪些用户可以使用 Bot:

bash

# 在 ~/.hermes/.env 中添加
TELEGRAM_ALLOWED_USERS=12345678,87654321

5.2 Discord Bot 接入

bash

# 第 1 步:创建 Discord Application
# https://discord.com/developers/applications → New Application
# Bot → Add Bot → 复制 Token
# OAuth2 → URL Generator → bot scope → 勾选权限

# 第 2 步:配置 Hermes
hermes gateway config --platform discord
# 或:
hermes config set DISCORD_BOT_TOKEN "your-discord-token"

# 第 3 步:启动网关
hermes gateway start

社区技巧:用 Discord 的频道做 Agent 上下文隔离——每个频道一个项目,避免上下文串台。

5.3 Slack 接入

bash

# 第 1 步:创建 Slack App
# https://api.slack.com/apps → Create New App
# Bot Token Scopes: chat:write, channels:history, groups:history
# Install to Workspace → 复制 Bot Token (xoxb-...)

# 第 2 步:启用 Socket Mode
# Basic Information → Socket Mode → Enable
# 生成 App-Level Token (xapp-...)

# 第 3 步:配置 Hermes
hermes config set SLACK_BOT_TOKEN "xoxb-your-token"
hermes config set SLACK_APP_TOKEN "xapp-your-app-token"

# 第 4 步:启动网关
hermes gateway start

5.4 CLI 模式(终端直接用)

不需要任何网关配置,直接在终端使用:

bash

# 交互式 REPL
hermes

# 单次查询
hermes chat -q "帮我检查 nginx 配置"

# 指定模型
hermes chat --provider openrouter --model anthropic/claude-sonnet-4

# 使用配置文件
hermes chat --config ~/.hermes/config.yaml

5.5 平台功能对比

表格

平台

语音

图片

文件

线程

表情

流式

Telegram

Discord

Slack

WhatsApp

Signal

Email

QQ

5.6 消息网关常用命令速查

bash

hermes gateway              # 前台运行
hermes gateway setup        # 交互式配置所有平台
hermes gateway install      # 安装为系统服务(Linux)/ launchd(macOS)
hermes gateway start        # 启动服务
hermes gateway stop         # 停止服务
hermes gateway status       # 查看服务状态

聊天内命令:

表格

命令

说明

/new/reset

开始新对话

/model provider:model

切换模型

/personality name

设置人格

/retry

重试上一条

/stop

停止当前 Agent

/approve

批准待确认的危险命令

6. 模型配置

6.1 Nous Portal(官方推荐)

Nous Portal 是 Hermes 自己的推理端点,通过 OAuth 认证:

bash

# 首次登录(浏览器 OAuth)
hermes model
# 选择 "Nous Portal" → 浏览器自动打开 → 授权

# 设置默认模型
hermes model nous:hermes-3

# 或在 config.yaml 中:
# model:
#   provider: "nous"
#   default: "hermes-3"

6.2 OpenRouter(200+ 模型切换)

OpenRouter 是最灵活的选择,一个 API Key 访问 200+ 模型:

bash

# 设置 API Key
echo 'OPENROUTER_API_KEY=sk-or-v1-your-key' >> ~/.hermes/.env

# 自动选择最便宜的模型
hermes model openrouter:auto

# 指定模型
hermes model openrouter:anthropic/claude-sonnet-4
hermes model openrouter:deepseek/deepseek-v4
hermes model openrouter:moonshotai/kimi-k2.5

# 在 config.yaml 中:
# model:
#   provider: "openrouter"
#   default: "anthropic/claude-sonnet-4"
#   base_url: "https://openrouter.ai/api/v1"

OpenRouter 提供商路由控制(省钱利器):

yaml

# config.yaml
provider_routing:
  sort: "throughput"       # price | throughput | latency
  # only: ["anthropic", "google"]  # 只用这些提供商
  # ignore: ["deepinfra"]          # 排除这些提供商

6.3 Anthropic Claude 原生 OAuth PKCE

据 Hermes Agent 中文文档(https://hermes-agent.lzw.me/docs/integrations/providers),Anthropic 支持三种认证方式:

bash

# 方式 1:API Key(按 token 计费)
export ANTHROPIC_API_KEY=sk-ant-api03-your-key
hermes chat --provider anthropic --model claude-sonnet-4-6

# 方式 2:OAuth(推荐,复用 Claude Pro/Max 订阅)
hermes model
# 选择 "Anthropic" → OAuth 浏览器登录
# Hermes 自动使用 Claude Code 的凭据存储(如果已有)
# Token 保存在 ~/.hermes/auth.json,自动刷新

# 方式 3:手动 setup-token(回退方案)
export ANTHROPIC_TOKEN=your-setup-token
hermes chat --provider anthropic

在 config.yaml 中永久设置:

yaml

model:
  provider: "anthropic"
  default: "claude-sonnet-4-6"

--provider claude--provider claude-code--provider anthropic 的别名。

6.4 OpenAI GPT 系列

bash

# API Key
echo 'OPENAI_API_KEY=sk-your-key' >> ~/.hermes/.env

# ChatGPT 订阅用户(OAuth,无需 API Key)
hermes model
# 选择 "OpenAI Codex" → 浏览器 OAuth

# 指定模型
hermes model openai:gpt-4o

6.5 本地 Ollama

bash

# 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh

# 拉取模型
ollama pull qwen3:14b
ollama pull llama3.1:8b

# 配置 Hermes
hermes model
# 选择 "Custom endpoint"
# API base URL: http://localhost:11434/v1
# API key: ollama(随便填,本地不需要)

# 或在 config.yaml 中:
# model:
#   provider: "custom"
#   default: "qwen3:14b"
#   base_url: "http://localhost:11434/v1"

6.6 DeepSeek

bash

# 设置 API Key
echo 'DEEPSEEK_API_KEY=sk-your-deepseek-key' >> ~/.hermes/.env

# 使用
hermes model deepseek:deepseek-v4

6.7 模型回退和负载均衡

当主模型挂了(限流、宕机、认证失败),Hermes 自动切换到备用模型:

yaml

# config.yaml
fallback_model:
  provider: openrouter
  model: anthropic/claude-sonnet-4

API Key 池化管理(多 Key 轮换,防限流):

bash

# 添加第二个 OpenRouter Key
hermes auth add openrouter --api-key sk-or-v1-your-second-key

# 添加 Anthropic OAuth 凭证
hermes auth add anthropic --type oauth  # 浏览器登录

# 查看所有凭证池
hermes auth list

# 交互式管理
hermes auth

据 Hermes Agent 官方认证文档,凭证池支持四种轮换策略:round_robin(轮询)、least_used(最久未用优先)、fill_first(先用完一个)、random(随机)。

7. 自进化系统配置

这是 Hermes 区别于所有其他 Agent 的核心——让它真正"越用越聪明"。

7.1 Skill 生成触发条件配置

据 Hermes Agent 源码解析(https://juejin.cn/post/7638806086187614234),Skill 创建的触发条件定义在 skill_manage 工具的 schema 中:

plaintext

┌──────────────────────────────────────────────────────────────┐
│              Skill 创建触发条件                               │
│                                                              │
│  自动创建(满足任一):                                       │
│  ┌──────────────────────────────────────────────┐            │
│  │ ✅ 工具调用超过 5 次(复杂任务)              │            │
│  │ ✅ 踩过坑并成功修复                           │            │
│  │ ✅ 用户纠正了做法                             │            │
│  │ ✅ 发现了非显而易见的工作流                    │            │
│  │ ✅ 用户主动要求记住                            │            │
│  └──────────────────────────────────────────────┘            │
│                                                              │
│  自动修补(Skill 已存在但需要更新):                         │
│  ┌──────────────────────────────────────────────┐            │
│  │ ✅ 步骤有遗漏(Pitfalls 追加)                │            │
│  │ ✅ OS 特定故障需要补充                         │            │
│  │ ✅ 新发现的边界条件                            │            │
│  │ ✅ 用户纠正了 Skill 中的做法                   │            │
│  └──────────────────────────────────────────────┘            │
│                                                              │
│  不创建(简单任务):                                         │
│  ┌──────────────────────────────────────────────┐            │
│  │ ❌ 工具调用 ≤ 5 次的一次性任务                │            │
│  │ ❌ 纯查询类(不需要执行步骤)                  │            │
│  └──────────────────────────────────────────────┘            │
└──────────────────────────────────────────────────────────────┘

配置 Skill 创建频率(Nudge 间隔):

yaml

# config.yaml
skills:
  # 每多少次工具调用后触发 Skill 审查(默认 10)
  creation_nudge_interval: 10

  # 两层索引(v2,减少 Token 消耗)
  index_v2: false  # 实验性功能,默认关闭

  # Token 预算(index_v2 开启时生效,默认 2000)
  index_token_budget: 2000

7.2 Signal-Based Nudge(信号驱动提示)

据 Hermes Agent PR #21841(https://github.com/NousResearch/hermes-agent/pull/21841),v0.11+ 引入了基于信号的 Skill 创建提示,比固定计数器更智能:

yaml

# config.yaml
skills:
  nudge_signals:
    enabled: false  # 实验性,默认关闭

    # S1: 重复工具模式(同一参数签名出现 N 次触发)
    repeated_pattern_threshold: 3

    # S2: 新 CLI 命令(30天内未出现过的外部命令)
    novel_cli_window_days: 30

    # S3: 用户明确暗示("记住"、"下次"、"以后"、"记一下")
    # 内置关键词,无需配置

    # S4: 重复错误修复(同一错误出现 N 次后修复触发)
    error_repeat_threshold: 2

7.3 Skill Curator 自动维护设置

Skill Curator 在后台定期审查 Skill 库,评分和修剪:

bash

# 查看所有 Skill
hermes skills list

# 查看特定 Skill 详情
hermes skills view deploy-k8s

# 手动触发 Skill 审查
hermes skills review

# 删除低质量 Skill
hermes skills delete deprecated-skill

系统提示词中有一句关键约束:"Skills that aren't maintained become liabilities"——通过提示词给 Agent 灌输维护责任感。

7.4 Nudge Engine 提醒策略

Nudge Engine 维护两个独立计数器:

plaintext

┌──────────────────────────────────────────────────────────────┐
│              Nudge Engine 双计数器机制                        │
│                                                              │
│  ┌───────────────────────────────┐                           │
│  │ Memory Nudge                  │                           │
│  │ 触发间隔: 10 个用户回合       │                           │
│  │ 计数方式: 按用户回合计        │                           │
│  │ 作用: 审查 MEMORY.md/USER.md │                           │
│  │ 重置: Agent 主动写入记忆时    │                           │
│  └───────────────────────────────┘                           │
│                                                              │
│  ┌───────────────────────────────┐                           │
│  │ Skill Nudge                   │                           │
│  │ 触发间隔: 10 次工具迭代       │  ← 可通过 config 调整     │
│  │ 计数方式: 按工具迭代计        │                           │
│  │ 作用: 审查是否需要创建/修补   │                           │
│  │ 重置: Agent 主动操作 Skill 时 │                           │
│  └───────────────────────────────┘                           │
│                                                              │
│  Nudge 触发 → fork 后台 Agent 审查 → 不打扰用户             │
│  审查完成 → 结果写回记忆/Skill → 下次对话生效              │
└──────────────────────────────────────────────────────────────┘

7.5 SOUL.md 初始化和进化

SOUL.md 定义了 Agent 的身份——性格、专长、沟通风格。位置:~/.hermes/memories/SOUL.md

方式 1:让 Hermes 自己写

plaintext

你: 请定义你自己的身份和性格
Hermes: (自动生成 SOUL.md)

方式 2:Token 压缩 DSL(省 Token)

markdown

# Agent Identity
Core:SelfImprove,CompoundLearning
AGENT_LOOP={CheckCtx,MapTools,Execute,Verify}
LEARN_LOOP={Observe,Pattern,Skill,Memory}
MEMORY_SYS={Short:ctx,Long:facts,Episodic:skills}

## Personality
Direct+Concise | TechFoc:Python,DevOps,AI/ML

## Rules
AlwaysVerify b4 destructive | EditOverCreate | AskIfAmbiguous

方式 3:明确人格定义

markdown

# Hermes Agent Identity

## Personality
- Direct and concise — avoid hedging
- Technical competence in: Python, DevOps, AI/ML
- Slightly informal but professional

## Response Style
- Lead with the answer, then explain
- Use code blocks liberally
- Numbered steps for procedures

## Behavioral Rules
- Always verify before destructive operations
- Prefer editing existing files over creating new
- Ask clarifying questions when ambiguous

关键原则:SOUL.md 越短越好。社区推荐压缩到 500-1000 字符——每个 session 都要注入系统提示词,太长烧 Token。

Hermes 可以通过 memory_manage 工具修改自己的 SOUL.md,实现人格进化。

7.6 记忆后端选择

表格

后端

适用场景

持久化

性能

配置复杂度

SQLite (默认)

个人使用

✅ 文件

零配置

Redis

高频访问

✅ AOF

极快

需部署 Redis

PostgreSQL

生产环境

✅ WAL

需部署 PG

Redis 配置

bash

# 安装 Redis
sudo apt install redis-server -y

# 持久化配置
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG SET appendfsync everysec
redis-cli CONFIG SET maxmemory 2gb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE

# 启动
sudo systemctl enable redis-server
sudo systemctl start redis-server

7.7 FTS5 全文搜索配置

Hermes 的情景记忆使用 SQLite FTS5 做全文搜索,无需额外配置——自动创建在 ~/.hermes/sessions/sessions.db

bash

# 验证 FTS5 索引
sqlite3 ~/.hermes/sessions/sessions.db ".schema"

# 搜索历史会话
hermes session search "部署 nginx"

8. 执行后端配置

据 Hermes Agent 配置文档(https://hermes-agent.nousresearch.com/docs/user-guide/configuration),Hermes 支持 7 种执行后端:

plaintext

┌──────────────────────────────────────────────────────────────┐
│              执行后端架构                                     │
│                                                              │
│  ┌──────────────┐                                            │
│  │ Hermes Agent │                                            │
│  │ (命令调度)   │                                            │
│  └──────┬───────┘                                            │
│         │                                                    │
│         ├──────── local ──── 本机直接执行                    │
│         │                    零隔离,开发环境用               │
│         │                                                    │
│         ├──────── docker ──── Docker 容器                    │
│         │                    完全隔离,CI/CD 用              │
│         │                                                    │
│         ├──────── ssh ─────── SSH 远程服务器                 │
│         │                    网络隔离,远端强算力             │
│         │                                                    │
│         ├──────── modal ──── Modal 云沙箱                    │
│         │                    弹性计算,临时任务               │
│         │                                                    │
│         ├──────── daytona ── Daytona 云开发环境              │
│         │                    持久化云环境,团队协作           │
│         │                                                    │
│         ├──────── vercel ─── Vercel Sandbox                  │
│         │                    microVM,快照持久化              │
│         │                                                    │
│         └──────── singularity ─ Singularity/Apptainer       │
│                              HPC 集群,共享机器               │
└──────────────────────────────────────────────────────────────┘

8.1 本地终端执行

默认后端,零配置:

yaml

# config.yaml
terminal:
  backend: "local"
  cwd: "."
  timeout: 180

8.2 Docker 沙箱隔离

yaml

# config.yaml
terminal:
  backend: "docker"
  docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
  timeout: 300
  docker_mount_cwd_to_workspace: false
  docker_forward_env:
    - GITHUB_TOKEN
    - NPM_TOKEN
  docker_volumes:
    - "/host/path:/container/path"

Hermes 自动 bind-mount Skills 目录和凭证文件到容器内(只读)。

8.3 SSH 远程执行

yaml

# config.yaml
terminal:
  backend: "ssh"
  ssh_host: "your-server.com"
  ssh_user: "root"
  ssh_port: 22
  # ssh_key_path: "~/.ssh/id_rsa"  # 或用 ssh-agent
  cwd: "/root"
  timeout: 300
  persistent_shell: true  # 保持 Shell 状态跨命令

Skills 和凭证文件通过 rsync 自动同步到远端。

8.4 Modal 无服务器

yaml

# config.yaml
terminal:
  backend: "modal"
  modal_image: "nikolaik/python-nodejs:python3.11-nodejs20"

bash

# 认证
pip install modal
modal token new

8.5 Daytona 云开发环境

yaml

# config.yaml
terminal:
  backend: "daytona"
  daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20"
  container_cpu: 2
  container_memory: 4096    # MB → 转为 GiB
  container_disk: 10240     # MB → 转为 GiB,最大 10GiB
  container_persistent: true  # 停止而非删除

Daytona 磁盘上限 10GiB,超出会被 cap 并警告。Sandbox 名称遵循 hermes-{task_id} 模式。

9. 生产加固

9.1 安全

API Key 管理

plaintext

┌──────────────────────────────────────────────────────────────┐
│              API Key 管理最佳实践                             │
│                                                              │
│  ❌ 错误做法:                                               │
│     · 直接写在 config.yaml 里                                │
│     · 提交 .env 到 Git                                      │
│     · 多人共享同一个 Key                                     │
│                                                              │
│  ✅ 正确做法:                                               │
│     · .env 文件 + chmod 600                                 │
│     · 生产环境用 Secret Manager / K8s Secret                 │
│     · 多 Key 池化轮换(hermes auth add)                     │
│     · 定期轮换高权限 Token                                   │
│                                                              │
│  ┌───────────────────────────────────────────┐               │
│  │ 凭证自动发现优先级:                      │               │
│  │ 1. ~/.hermes/.env 环境变量               │               │
│  │ 2. ~/.hermes/auth.json OAuth 令牌        │               │
│  │ 3. ~/.claude/.credentials.json           │               │
│  │ 4. config.yaml 中的 api_key 字段         │               │
│  │ 5. hermes auth add 手动添加              │               │
│  └───────────────────────────────────────────┘               │
└──────────────────────────────────────────────────────────────┘

Docker 隔离

bash

# 最高隔离级别
docker run -d --name hermes \
  --read-only \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --tmpfs /tmp:size=100m \
  -v ~/.hermes:/opt/data \
  -p 8642:8642 \
  nousresearch/hermes-agent gateway run

VPS 基础加固

bash

# SSH 密钥登录(禁用密码)
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd

# UFW 防火墙
ufw allow OpenSSH
ufw allow 8642/tcp  # Hermes Gateway(生产环境限制 IP)
ufw enable

# 限制 8642 端口只允许特定 IP
ufw allow from YOUR_IP to any port 8642

Tirith 安全模块

Hermes 内置 Tirith 安全模块,自动拦截:

  • 混淆的 Shell 管道模式

  • 记忆写入中的 Prompt 注入

  • 凭证泄露模式

  • 工具输入中的不可见 Unicode

yaml

# config.yaml
approvals:
  mode: "manual"  # manual | smart | off

注意:Tirith 可能过于激进。如果它拦截了你需要运行的命令,解决方法是在分屏终端中手动执行,而不是通过 Hermes。

9.2 备份

自动备份脚本

bash

#!/bin/bash
# hermes-backup.sh — Hermes Agent 自动备份脚本
# 使用方法: chmod +x hermes-backup.sh && ./hermes-backup.sh

set -euo pipefail

# ── 配置 ─────────────────────────────────────────────────
HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
BACKUP_DIR="${BACKUP_DIR:-$HOME/hermes-backups}"
RETENTION_DAYS=30
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/hermes-backup-$TIMESTAMP.tar.gz"

# ── 创建备份目录 ─────────────────────────────────────────
mkdir -p "$BACKUP_DIR"

# ── 检查 Hermes 是否在运行 ──────────────────────────────
if docker ps | grep -q hermes; then
    echo "[INFO] 检测到 Docker 模式,暂停容器确保数据一致性..."
    docker compose pause hermes 2>/dev/null || true
    sleep 2
fi

# ── 执行备份 ─────────────────────────────────────────────
echo "[INFO] 开始备份 $HERMES_HOME ..."

tar -czf "$BACKUP_FILE" \
    --exclude="*.log" \
    --exclude="image_cache" \
    --exclude="audio_cache" \
    --exclude="whatsapp/session" \
    -C "$(dirname "$HERMES_HOME")" \
    "$(basename "$HERMES_HOME")"

BACKUP_SIZE=$(du -sh "$BACKUP_FILE" | cut -f1)
echo "[INFO] 备份完成: $BACKUP_FILE ($BACKUP_SIZE)"

# ── 恢复容器 ─────────────────────────────────────────────
if docker ps -a | grep -q hermes; then
    docker compose unpause hermes 2>/dev/null || true
fi

# ── 清理旧备份 ───────────────────────────────────────────
DELETED=$(find "$BACKUP_DIR" -name "hermes-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete -print | wc -l)
echo "[INFO] 清理 $DELETED 个超过 $RETENTION_DAYS 天的旧备份"

# ── 可选:上传到 S3 ─────────────────────────────────────
# aws s3 cp "$BACKUP_FILE" s3://your-bucket/hermes-backups/
# echo "[INFO] 已上传到 S3"

设置定时备份:

bash

# 每天凌晨 3 点自动备份
(crontab -l 2>/dev/null; echo "0 3 * * * $HOME/hermes-backup.sh >> $HOME/hermes-backups/backup.log 2>&1") | crontab -

9.3 监控

健康检查

bash

# 基础健康检查
curl http://localhost:8642/health
# {"status":"ok"}

# 详细健康检查
curl http://localhost:8642/health/detailed

# Docker 内健康检查
docker compose exec hermes curl -s http://localhost:8642/health

Prometheus 指标

Hermes Agent 的 Rust 版(hermes-agent-rs)内置 OpenTelemetry + Prometheus 指标暴露。Python 版需要手动集成:

yaml

# config.yaml — 如果使用 hermes-agent-rs
# 指标默认暴露在 /metrics 端点

对于 Python 版,用 Prometheus Blackbox Exporter 探测 /health

yaml

# prometheus.yml
scrape_configs:
  - job_name: 'hermes-health'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
        - http://localhost:8642/health
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox-exporter:9115

日志收集

bash

# Hermes 内置日志
hermes logs
hermes logs gateway --since 10m
hermes logs errors --tail 100

# Docker 日志
docker compose logs hermes --tail 100 -f

# Systemd 日志
journalctl -u hermes-agent -f --since "10 minutes ago"

生产环境推荐用 Fluent Bit / Vector 收集 ~/.hermes/logs/*.log,对 LLM 调用链路可启用 Langfuse 做可观测。

9.4 成本控制

模型调用统计

bash

# 查看当前使用的模型
hermes model

# 查看凭证池状态
hermes auth list

预算限制

OpenRouter 支持设置使用限额:

bash

# 在 OpenRouter 控制台设置月度限额
# https://openrouter.ai/settings/limits

Kimi K2.5 社区建议:添加余额并设置限额,防止 API Key 泄露导致巨额账单。

省钱策略

plaintext

┌──────────────────────────────────────────────────────────────┐
│              省钱策略矩阵                                     │
│                                                              │
│  策略                 │ 日成本  │ 质量    │ 延迟             │
│  ─────────────────────────────────────────────────────────   │
│  全用 Opus            │ $50+   │ 极优    │ 低               │
│  Opus + Kimi 混用     │ $10-20 │ 优      │ 中               │
│  全用 DeepSeek V4     │ $2-5   │ 良      │ 中               │
│  本地 Ollama          │ 电费   │ 中      │ 高               │
│  OpenRouter auto      │ $5-15  │ 良-优   │ 中               │
│                                                              │
│  进阶省钱:                                                  │
│  · 主模型用便宜的,辅助模型(vision等)用更便宜的             │
│  · 压缩模型用 gemini-flash(几乎免费)                       │
│  · 设置 fallback_model 防主模型限流时浪费重试 Token           │
│  · 多 Key 池化轮换避免触发 rate limit                        │
└──────────────────────────────────────────────────────────────┘

yaml

# config.yaml — 省钱配置示例
model:
  default: "deepseek/deepseek-v4"
  provider: "openrouter"

fallback_model:
  provider: openrouter
  model: "anthropic/claude-sonnet-4"

# 便宜的压缩模型
compression:
  summary_model: "google/gemini-3-flash-preview"

# 便宜的辅助模型
auxiliary:
  vision:
    model: "openai/gpt-4o-mini"
  web_extract:
    model: "google/gemini-3-flash-preview"
  session_search:
    model: "deepseek/deepseek-v4"
    max_concurrency: 2

10. 一键部署脚本(完整版)

这个脚本从裸机到 Hermes 运行,全程交互式引导。支持 Ubuntu/Debian/macOS。

bash

#!/usr/bin/env bash
# =============================================================================
# hermes-setup.sh — Hermes Agent 一键部署脚本
# 版本: 1.0.0
# 兼容: Ubuntu 20.04+, Debian 12+, macOS (Intel/Apple Silicon)
#
# 使用方法:
#   chmod +x hermes-setup.sh && ./hermes-setup.sh
#
# 或远程执行:
#   curl -fsSL https://your-host/hermes-setup.sh | bash
# =============================================================================

set -euo pipefail

# ── 颜色定义 ─────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# ── 辅助函数 ─────────────────────────────────────────────
info()  { echo -e "${BLUE}[INFO]${NC} $*"; }
ok()    { echo -e "${GREEN}[OK]${NC} $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

# ── 确认函数 ─────────────────────────────────────────────
confirm() {
    local prompt="$1"
    local default="${2:-n}"
    local yn
    if [[ "$default" == "y" ]]; then
        read -rp "$prompt [Y/n] " yn
        yn="${yn:-Y}"
    else
        read -rp "$prompt [y/N] " yn
        yn="${yn:-N}"
    fi
    [[ "$yn" =~ ^[Yy] ]]
}

# ── 选择函数 ─────────────────────────────────────────────
select_option() {
    local prompt="$1"
    shift
    local options=("$@")
    echo -e "${BLUE}$prompt${NC}"
    for i in "${!options[@]}"; do
        echo "  $((i+1))) ${options[$i]}"
    done
    local choice
    read -rp "请选择 [1-${#options[@]}]: " choice
    choice=$((choice - 1))
    if [[ $choice -ge 0 && $choice -lt ${#options[@]} ]]; then
        echo "${options[$choice]}"
    else
        echo "${options[0]}"
    fi
}

# =============================================================================
# 第 1 步: 检测系统环境
# =============================================================================
info "=== 第 1 步: 检测系统环境 ==="

# 检测操作系统
OS="$(uname -s)"
case "$OS" in
    Linux)
        if [[ -f /etc/os-release ]]; then
            . /etc/os-release
            OS_NAME="$NAME"
            OS_VERSION="$VERSION_ID"
        else
            OS_NAME="Linux"
            OS_VERSION="unknown"
        fi
        ;;
    Darwin)
        OS_NAME="macOS"
        OS_VERSION="$(sw_vers -productVersion)"
        ;;
    *)
        error "不支持的操作系统: $OS。请使用 Linux 或 macOS。"
        ;;
esac
ok "操作系统: $OS_NAME $OS_VERSION"

# 检测架构
ARCH="$(uname -m)"
ok "CPU 架构: $ARCH"

# 检测内存
if [[ "$OS" == "Darwin" ]]; then
    TOTAL_MEM=$(( $(sysctl -n hw.memsize) / 1024 / 1024 / 1024 ))
else
    TOTAL_MEM=$(( $(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024 / 1024 ))
fi
ok "内存: ${TOTAL_MEM}GB"

if [[ $TOTAL_MEM -lt 3 ]]; then
    warn "内存不足 4GB,Hermes 可能运行不稳定"
fi

# 检测磁盘空间
DISK_AVAIL=$(df -h ~ | awk 'NR==2 {print $4}')
ok "可用磁盘: $DISK_AVAIL"

# =============================================================================
# 第 2 步: 安装依赖
# =============================================================================
info "=== 第 2 步: 安装依赖 ==="

# 检测 Git
if ! command -v git &>/dev/null; then
    warn "未检测到 Git,正在安装..."
    if [[ "$OS" == "Darwin" ]]; then
        xcode-select --install 2>/dev/null || true
    else
        sudo apt update && sudo apt install -y git
    fi
fi
ok "Git: $(git --version)"

# 检测 Docker
USE_DOCKER=false
if command -v docker &>/dev/null; then
    ok "Docker: $(docker --version)"
    if confirm "检测到 Docker,是否使用 Docker 部署?" "y"; then
        USE_DOCKER=true
    fi
else
    if confirm "是否安装 Docker 并使用 Docker 部署?" "y"; then
        info "正在安装 Docker..."
        curl -fsSL https://get.docker.com | sh
        sudo usermod -aG docker "$USER"
        # 激活 Docker 组(当前 session)
        newgrp docker 2>/dev/null || true
        USE_DOCKER=true
        ok "Docker 安装完成"
    fi
fi

# 检测 Docker Compose
if [[ "$USE_DOCKER" == "true" ]]; then
    if docker compose version &>/dev/null; then
        ok "Docker Compose: $(docker compose version)"
    else
        warn "Docker Compose 未安装,尝试安装..."
        sudo apt install -y docker-compose-plugin 2>/dev/null || \
            mkdir -p ~/.docker/cli-plugins && \
            curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" \
            -o ~/.docker/cli-plugins/docker-compose && \
            chmod +x ~/.docker/cli-plugins/docker-compose
    fi
fi

# 非 Docker 模式:安装 Python + uv
if [[ "$USE_DOCKER" == "false" ]]; then
    # 安装 uv
    if ! command -v uv &>/dev/null; then
        info "正在安装 uv(Python 包管理器)..."
        curl -LsSf https://astral.sh/uv/install.sh | sh
        export PATH="$HOME/.local/bin:$PATH"
    fi
    ok "uv: $(uv --version)"

    # 检测 Python
    PYTHON_CMD=""
    for cmd in python3.11 python3.12 python3 python; do
        if command -v "$cmd" &>/dev/null; then
            PY_VER=$($cmd -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
            if [[ "$(echo "$PY_VER >= 3.11" | bc -l)" -eq 1 ]]; then
                PYTHON_CMD="$cmd"
                break
            fi
        fi
    done

    if [[ -z "$PYTHON_CMD" ]]; then
        info "未找到 Python 3.11+,uv 会自动下载..."
    else
        ok "Python: $($PYTHON_CMD --version)"
    fi

    # 安装 Redis(Linux)
    if [[ "$OS" == "Linux" ]]; then
        if ! command -v redis-server &>/dev/null; then
            if confirm "是否安装 Redis(推荐用于记忆后端)?" "y"; then
                sudo apt install -y redis-server
                sudo systemctl enable redis-server
                sudo systemctl start redis-server
                # 配置持久化
                redis-cli CONFIG SET appendonly yes
                redis-cli CONFIG SET appendfsync everysec
                redis-cli CONFIG SET maxmemory 512mb
                redis-cli CONFIG SET maxmemory-policy allkeys-lru
                redis-cli CONFIG REWRITE
                ok "Redis 安装并配置完成"
            fi
        else
            ok "Redis: $(redis-server --version | head -1)"
        fi
    fi
fi

# =============================================================================
# 第 3 步: 交互式选择
# =============================================================================
info "=== 第 3 步: 交互式配置 ==="

# 选择消息渠道
CHANNEL=$(select_option "选择消息渠道(可多选,稍后配置)" \
    "Telegram" "Discord" "Slack" "仅 CLI(不接入消息平台)")
info "已选择渠道: $CHANNEL"

# 选择模型提供商
MODEL_PROVIDER=$(select_option "选择模型提供商" \
    "OpenRouter(推荐:200+ 模型)" \
    "DeepSeek(最便宜)" \
    "Anthropic Claude(高质量)" \
    "OpenAI GPT(企业级)" \
    "本地 Ollama(免费离线)" \
    "Kimi/Moonshot(长上下文)")

case "$MODEL_PROVIDER" in
    OpenRouter*)
        PROVIDER="openrouter"
        read -rp "请输入 OpenRouter API Key (sk-or-v1-...): " API_KEY
        DEFAULT_MODEL="anthropic/claude-sonnet-4"
        BASE_URL="https://openrouter.ai/api/v1"
        ;;
    DeepSeek*)
        PROVIDER="deepseek"
        read -rp "请输入 DeepSeek API Key: " API_KEY
        DEFAULT_MODEL="deepseek-v4"
        BASE_URL="https://api.deepseek.com/v1"
        ;;
    Anthropic*)
        PROVIDER="anthropic"
        read -rp "请输入 Anthropic API Key (sk-ant-...): " API_KEY
        DEFAULT_MODEL="claude-sonnet-4-6"
        BASE_URL="https://api.anthropic.com"
        ;;
    OpenAI*)
        PROVIDER="openai"
        read -rp "请输入 OpenAI API Key (sk-...): " API_KEY
        DEFAULT_MODEL="gpt-4o"
        BASE_URL="https://api.openai.com/v1"
        ;;
    *Ollama*)
        PROVIDER="custom"
        API_KEY="ollama"
        DEFAULT_MODEL="qwen3:14b"
        BASE_URL="http://localhost:11434/v1"
        # 检查 Ollama 是否运行
        if ! curl -s http://localhost:11434/api/tags &>/dev/null; then
            warn "Ollama 未运行。请先安装并启动 Ollama:"
            echo "  curl -fsSL https://ollama.com/install.sh | sh"
            echo "  ollama pull qwen3:14b"
        fi
        ;;
    Kimi*)
        PROVIDER="kimi-coding"
        read -rp "请输入 Kimi API Key: " API_KEY
        DEFAULT_MODEL="kimi-k2.5"
        BASE_URL="https://api.moonshot.cn/v1"
        ;;
esac

# 选择记忆后端
MEMORY_BACKEND=$(select_option "选择记忆后端" \
    "SQLite(默认,零配置)" \
    "Redis(高性能)" \
    "PostgreSQL(生产级)")

case "$MEMORY_BACKEND" in
    SQLite*)  MEM_BACKEND="sqlite" ;;
    Redis*)   MEM_BACKEND="redis" ;;
    PostgreSQL*) MEM_BACKEND="postgres" ;;
esac

# 选择执行后端
EXEC_BACKEND=$(select_option "选择执行后端" \
    "本地终端(默认)" \
    "Docker 沙箱(隔离)" \
    "SSH 远程(远端服务器)")

case "$EXEC_BACKEND" in
    本地*)   TERM_BACKEND="local" ;;
    Docker*) TERM_BACKEND="docker" ;;
    SSH*)    TERM_BACKEND="ssh"
        read -rp "SSH 主机: " SSH_HOST
        read -rp "SSH 用户 [root]: " SSH_USER
        SSH_USER="${SSH_USER:-root}"
        read -rp "SSH 端口 [22]: " SSH_PORT
        SSH_PORT="${SSH_PORT:-22}"
        ;;
esac

# =============================================================================
# 第 4 步: 生成配置文件
# =============================================================================
info "=== 第 4 步: 生成配置文件 ==="

HERMES_HOME="$HOME/.hermes"
mkdir -p "$HERMES_HOME"/{cron,sessions,logs,memories,skills,pairing,hooks,image_cache,audio_cache,whatsapp/session}

# ── 生成 .env ──────────────────────────────────────────
ENV_FILE="$HERMES_HOME/.env"

cat > "$ENV_FILE" << ENVEOF
# ── Hermes Agent 环境变量 ──────────────────────────────
# 自动生成于 $(date -Iseconds)

# LLM 提供商
ENVEOF

case "$PROVIDER" in
    openrouter)  echo "OPENROUTER_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
    deepseek)    echo "DEEPSEEK_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
    anthropic)   echo "ANTHROPIC_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
    openai)      echo "OPENAI_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
    kimi-coding) echo "KIMI_API_KEY=$API_KEY" >> "$ENV_FILE" ;;
esac

# 消息渠道 Token
case "$CHANNEL" in
    Telegram)
        read -rp "请输入 Telegram Bot Token: " TG_TOKEN
        echo "TELEGRAM_BOT_TOKEN=$TG_TOKEN" >> "$ENV_FILE"
        ;;
    Discord)
        read -rp "请输入 Discord Bot Token: " DC_TOKEN
        echo "DISCORD_BOT_TOKEN=$DC_TOKEN" >> "$ENV_FILE"
        ;;
    Slack)
        read -rp "请输入 Slack Bot Token (xoxb-...): " SL_TOKEN
        echo "SLACK_BOT_TOKEN=$SL_TOKEN" >> "$ENV_FILE"
        ;;
esac

chmod 600 "$ENV_FILE"
ok ".env 文件已生成: $ENV_FILE"

# ── 生成 config.yaml ──────────────────────────────────
CONFIG_FILE="$HERMES_HOME/config.yaml"

cat > "$CONFIG_FILE" << CONFEOF
# =============================================================================
# ~/.hermes/config.yaml — Hermes Agent 配置
# 自动生成于 $(date -Iseconds)
# =============================================================================

# ── 模型 ─────────────────────────────────────────────
model:
  default: "$DEFAULT_MODEL"
  provider: "$PROVIDER"
  base_url: "$BASE_URL"

# ── 备用模型 ─────────────────────────────────────────
fallback_model:
  provider: "openrouter"
  model: "anthropic/claude-sonnet-4"

# ── 终端执行后端 ─────────────────────────────────────
terminal:
  backend: "$TERM_BACKEND"
  cwd: "."
  timeout: 180
CONFEOF

# 追加终端后端配置
case "$TERM_BACKEND" in
    docker)
        cat >> "$CONFIG_FILE" << 'CONFEOF'
  docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
CONFEOF
        ;;
    ssh)
        cat >> "$CONFIG_FILE" << CONFEOF
  ssh_host: "$SSH_HOST"
  ssh_user: "$SSH_USER"
  ssh_port: $SSH_PORT
  persistent_shell: true
CONFEOF
        ;;
esac

cat >> "$CONFIG_FILE" << 'CONFEOF'

# ── Agent 行为 ───────────────────────────────────────
agent:
  max_turns: 90
  reasoning_effort: "medium"

# ── 记忆 ─────────────────────────────────────────────
memory:
  memory_enabled: true
  user_profile_enabled: true
  memory_char_limit: 2200
  user_char_limit: 1375

# ── 上下文压缩 ───────────────────────────────────────
compression:
  enabled: true
  threshold: 0.50
  summary_model: "google/gemini-3-flash-preview"

# ── 审批模式 ─────────────────────────────────────────
approvals:
  mode: "manual"

# ── 工具集 ───────────────────────────────────────────
toolsets:
  - all

# ── 显示 ─────────────────────────────────────────────
display:
  skin: "default"
  tool_progress: "all"
  compact: false
CONFEOF

ok "config.yaml 已生成: $CONFIG_FILE"

# ── 生成 docker-compose.yml(Docker 模式)───────────
if [[ "$USE_DOCKER" == "true" ]]; then
    COMPOSE_FILE="$HOME/hermes-docker/docker-compose.yml"
    mkdir -p "$HOME/hermes-docker"

    # Docker 模式的 .env
    cat > "$HOME/hermes-docker/.env" << DOCKERENVEOF
HERMES_UID=$(id -u)
HERMES_GID=$(id -g)
OPENROUTER_API_KEY=${API_KEY:-}
POSTGRES_PASSWORD=$(openssl rand -hex 16)
DOCKERENVEOF

    chmod 600 "$HOME/hermes-docker/.env"

    cat > "$COMPOSE_FILE" << 'COMPOSEEOF'
version: "3.8"
services:
  hermes:
    image: nousresearch/hermes-agent:latest
    container_name: hermes
    restart: unless-stopped
    command: ["gateway", "run"]
    ports:
      - "8642:8642"
    volumes:
      - ~/.hermes:/opt/data
    environment:
      - HERMES_UID=${HERMES_UID:-10000}
      - HERMES_GID=${HERMES_GID:-10000}
    deploy:
      resources:
        limits:
          memory: 4G
    depends_on:
      redis:
        condition: service_healthy
    networks:
      - hermes-net

  redis:
    image: redis:7-alpine
    container_name: hermes-redis
    restart: unless-stopped
    command: >
      redis-server
      --appendonly yes
      --appendfsync everysec
      --maxmemory 512mb
      --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
    networks:
      - hermes-net

  dashboard:
    image: nousresearch/hermes-agent:latest
    container_name: hermes-dashboard
    restart: unless-stopped
    command: ["dashboard", "--host", "127.0.0.1", "--no-open"]
    ports:
      - "9119:9119"
    volumes:
      - ~/.hermes:/opt/data
    environment:
      - HERMES_UID=${HERMES_UID:-10000}
      - HERMES_GID=${HERMES_GID:-10000}
    depends_on:
      - hermes
    networks:
      - hermes-net

volumes:
  redis_data:

networks:
  hermes-net:
    driver: bridge
COMPOSEEOF

    ok "docker-compose.yml 已生成: $COMPOSE_FILE"
fi

# =============================================================================
# 第 6 步: 初始化数据库
# =============================================================================
info "=== 第 6 步: 初始化 ==="

if [[ "$USE_DOCKER" == "false" ]]; then
    # 克隆 Hermes Agent
    HERMES_SRC="$HOME/.hermes/hermes-agent"
    if [[ ! -d "$HERMES_SRC" ]]; then
        info "正在克隆 Hermes Agent 仓库..."
        git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git "$HERMES_SRC"
    fi

    # 创建虚拟环境并安装
    cd "$HERMES_SRC"
    uv venv venv --python 3.11
    export VIRTUAL_ENV="$(pwd)/venv"
    uv pip install -e ".[all]"

    # 添加到 PATH
    mkdir -p ~/.local/bin
    ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes

    # 确保 PATH 包含 ~/.local/bin
    if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then
        echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
        export PATH="$HOME/.local/bin:$PATH"
    fi

    # 初始化
    hermes doctor || true

    ok "Hermes Agent 安装完成"
fi

# =============================================================================
# 第 7 步: 启动
# =============================================================================
info "=== 第 7 步: 启动 Hermes Agent ==="

if [[ "$USE_DOCKER" == "true" ]]; then
    cd "$HOME/hermes-docker"
    docker compose pull
    docker compose up -d
    info "等待服务启动..."
    sleep 10
else
    # 安装为 systemd 服务
    if [[ "$OS" == "Linux" ]]; then
        if confirm "是否安装为 systemd 服务(开机自启)?" "y"; then
            sudo tee /etc/systemd/system/hermes-agent.service << SYSEOF
[Unit]
Description=Hermes Agent Gateway
After=network.target redis.service
Requires=network.target

[Service]
Type=simple
User=$USER
WorkingDirectory=$HERMES_SRC
ExecStart=$HERMES_SRC/venv/bin/hermes gateway run
Restart=always
RestartSec=10
Environment=HERMES_HOME=$HERMES_HOME

[Install]
WantedBy=multi-user.target
SYSEOF
            sudo systemctl daemon-reload
            sudo systemctl enable hermes-agent
            sudo systemctl start hermes-agent
            ok "systemd 服务已安装并启动"
        fi
    fi

    # macOS launchd
    if [[ "$OS" == "Darwin" ]]; then
        hermes gateway install
        hermes gateway start
    fi
fi

# =============================================================================
# 第 8 步: 可选 Nginx + SSL
# =============================================================================
if [[ "$OS" == "Linux" ]]; then
    if confirm "是否配置 Nginx 反向代理 + SSL(Let's Encrypt)?" "n"; then
        read -rp "请输入域名(如 hermes.yourdomain.com): " DOMAIN

        sudo apt install -y nginx certbot python3-certbot-nginx

        sudo tee /etc/nginx/sites-available/hermes << NGINXEOF
server {
    listen 80;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:8642;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 300s;
    }
}
NGINXEOF

        sudo ln -sf /etc/nginx/sites-available/hermes /etc/nginx/sites-enabled/hermes
        sudo nginx -t && sudo systemctl reload nginx

        # SSL
        sudo certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "admin@$DOMAIN"

        ok "Nginx + SSL 配置完成: https://$DOMAIN"
    fi
fi

# =============================================================================
# 第 9 步: 健康检查和验证
# =============================================================================
info "=== 第 9 步: 健康检查 ==="

MAX_RETRIES=10
RETRY=0
HEALTH_OK=false

while [[ $RETRY -lt $MAX_RETRIES ]]; do
    RETRY=$((RETRY + 1))
    if curl -sf http://localhost:8642/health >/dev/null 2>&1; then
        HEALTH_OK=true
        break
    fi
    info "等待 Hermes 启动... ($RETRY/$MAX_RETRIES)"
    sleep 3
done

if [[ "$HEALTH_OK" == "true" ]]; then
    ok "Hermes Agent 健康检查通过!"
else
    warn "健康检查未通过,请手动检查:"
    warn "  docker compose logs hermes --tail 50"
    warn "  或: journalctl -u hermes-agent --since '5 minutes ago'"
fi

# =============================================================================
# 输出访问地址和管理命令
# =============================================================================
echo ""
echo "============================================================"
echo -e "${GREEN}  Hermes Agent 部署完成!${NC}"
echo "============================================================"
echo ""
echo "  📍 访问地址:"
echo "     API:      http://localhost:8642"
echo "     健康检查: http://localhost:8642/health"
if [[ "$USE_DOCKER" == "true" ]]; then
    echo "     Dashboard: http://localhost:9119"
fi
echo ""
echo "  🔧 管理命令:"
if [[ "$USE_DOCKER" == "true" ]]; then
    echo "     启动:     cd ~/hermes-docker && docker compose up -d"
    echo "     停止:     cd ~/hermes-docker && docker compose down"
    echo "     日志:     cd ~/hermes-docker && docker compose logs -f hermes"
    echo "     升级:     cd ~/hermes-docker && docker compose pull && docker compose up -d"
else
    echo "     启动:     sudo systemctl start hermes-agent"
    echo "     停止:     sudo systemctl stop hermes-agent"
    echo "     状态:     sudo systemctl status hermes-agent"
    echo "     日志:     journalctl -u hermes-agent -f"
    echo "     CLI:      hermes"
    echo "     模型:     hermes model"
fi
echo ""
echo "  📱 消息网关:"
echo "     配置:     hermes gateway setup"
echo "     启动:     hermes gateway start"
echo "     状态:     hermes gateway status"
echo ""
echo "  💾 备份:"
echo "     手动:     tar -czf hermes-backup-\$(date +%F).tar.gz ~/.hermes"
echo ""
echo "  📖 文档:     https://hermes-agent.nousresearch.com"
echo "============================================================"

11. 与 OpenClaw 联合部署方案

据《OpenClaw + Hermes Agent: The Two-Agent System I Run Daily》(https://www.mejba.me/blog/openclaw-hermes-multi-agent-workflow),两者天然互补——OpenClaw 擅长规划和编排,Hermes 擅长执行和持续优化。

11.1 架构

plaintext

┌──────────────────────────────────────────────────────────────┐
│              OpenClaw + Hermes 联合架构                       │
│                                                              │
│  ┌─────────────────┐       ┌─────────────────┐              │
│  │   OpenClaw       │       │   Hermes Agent   │              │
│  │   (规划/编排)    │◄─────►│   (执行/学习)    │              │
│  │                  │ A2A   │                  │              │
│  │  ┌────────────┐ │ 协议  │  ┌────────────┐ │              │
│  │  │ Claude Opus│ │       │  │ DeepSeek V4│ │              │
│  │  │ 重推理模型  │ │       │  │ 轻执行模型  │ │              │
│  │  └────────────┘ │       │  └────────────┘ │              │
│  │                  │       │                  │              │
│  │  不学新东西      │       │  越用越聪明      │              │
│  │  贵但稳          │       │  便宜且进化      │              │
│  └────────┬────────┘       └────────┬────────┘              │
│           │                         │                        │
│           └──────────┬──────────────┘                        │
│                      ▼                                       │
│           ┌──────────────────────┐                           │
│           │   共享 Ollama        │                           │
│           │   (本地推理后端)     │                           │
│           │   port: 11434       │                           │
│           └──────────────────────┘                           │
│                                                              │
│  成本效果:总 AI 支出降低约 40%,吞吐量反而提升              │
└──────────────────────────────────────────────────────────────┘

11.2 同机 docker-compose.yml

yaml

# docker-compose.yml — OpenClaw + Hermes 联合部署
version: "3.8"

services:
  # ── OpenClaw ────────────────────────────────────────────
  openclaw:
    image: anthropic/openclaw:latest
    container_name: openclaw
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ~/.openclaw:/home/user/.openclaw
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: "2.0"
    networks:
      - agents-net

  # ── Hermes Agent ────────────────────────────────────────
  hermes:
    image: nousresearch/hermes-agent:latest
    container_name: hermes
    restart: unless-stopped
    command: ["gateway", "run"]
    ports:
      - "8642:8642"
    volumes:
      - ~/.hermes:/opt/data
    environment:
      - HERMES_UID=${HERMES_UID:-10000}
      - HERMES_GID=${HERMES_GID:-10000}
      - OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: "2.0"
    depends_on:
      redis:
        condition: service_healthy
    networks:
      - agents-net

  # ── Redis(Hermes 专用)────────────────────────────────
  redis:
    image: redis:7-alpine
    container_name: hermes-redis
    restart: unless-stopped
    command: >
      redis-server
      --appendonly yes
      --appendfsync everysec
      --maxmemory 1gb
      --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
    networks:
      - agents-net

  # ── Ollama(共享推理后端)─────────────────────────────
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    restart: unless-stopped
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    deploy:
      resources:
        limits:
          memory: 16G
          cpus: "4.0"
    networks:
      - agents-net

volumes:
  redis_data:
  ollama_data:

networks:
  agents-net:
    driver: bridge

11.3 端口规划

表格

服务

端口

用途

OpenClaw

8080

OpenClaw API

Hermes Gateway

8642

Hermes API + 网关

Hermes Dashboard

9119

Web UI

Ollama

11434

本地推理

Redis

6379

记忆后端

PostgreSQL

5432

结构化记忆

11.4 资源隔离

plaintext

┌──────────────────────────────────────────────────────────────┐
│              8C16G 服务器资源分配                             │
│                                                              │
│  CPU:  ████████░░  OpenClaw (4C)                             │
│        ██████░░░░  Hermes (3C)                               │
│        ██░░░░░░░░  Ollama/Redis (1C)                         │
│                                                              │
│  内存: ████████░░  OpenClaw (4GB)                            │
│        ██████░░░░  Hermes (4GB)                              │
│        ████░░░░░░  Ollama/Redis (4GB)                        │
│        ██░░░░░░░░  系统 (2GB)                                │
│                                                              │
│  磁盘: ~/.openclaw  ~500MB                                   │
│        ~/.hermes    ~2-5GB(持续增长)                       │
│        Ollama 模型  ~4-40GB/模型                             │
└──────────────────────────────────────────────────────────────┘

11.5 A2A 协议互相发现

Hermes 和 OpenClaw 都支持 A2A(Agent-to-Agent)协议,可以通过 HTTP API 互相发现和协作:

yaml

# Hermes config.yaml — 添加 OpenClaw 为协作 Agent
# mcp:
#   servers:
#     - name: openclaw
#       url: "http://openclaw:8080/v1/mcp"
#       headers:
#         Authorization: "Bearer ${OPENCLAW_API_KEY}"

11.6 互相健康监控

参考社区实践,让两个 Agent 互相监控对方的健康状态:

yaml

# hermes-tasks/openclaw-health-check.yml
name: openclaw_health_monitor
schedule: "*/30 * * * * *"  # 每 30 秒
model: deepseek/deepseek-v4  # 便宜模型
task: |
  Check if the OpenClaw process is running and responsive.
  If unresponsive for 3+ consecutive checks:
  1. Read /var/log/openclaw/latest.log
  2. Identify the root cause
  3. Apply fix from repair-patterns library
  4. Restart openclaw service
  5. Notify via Telegram: summary of failure + fix applied
retry_on_failure: true
max_retries: 3

12. 常见问题排查

12.1 Python 版本兼容

问题python: command not found 或 Python 版本低于 3.11

bash

# 诊断
python3 --version
python3.11 --version

# 解决:用 uv 自动管理 Python 版本
uv venv venv --python 3.11  # uv 会自动下载 Python 3.11

# 或手动安装(Ubuntu)
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.11 python3.11-venv

12.2 PostgreSQL 连接失败

问题connection refusedauthentication failed

bash

# 诊断
pg_isready -h localhost -p 5432
psql -U hermes -d hermes -h localhost

# 常见原因 1:PostgreSQL 未启动
sudo systemctl start postgresql
sudo systemctl enable postgresql

# 常见原因 2:pg_hba.conf 不允许密码认证
sudo vim /etc/postgresql/16/main/pg_hba.conf
# 修改:local all all peer → local all all md5
sudo systemctl restart postgresql

# 常见原因 3:密码不对
sudo -u postgres psql -c "ALTER USER hermes WITH PASSWORD 'new-password';"

12.3 Skill 生成不触发

问题:Agent 工作了很多任务,但 Skills 目录是空的

bash

# 诊断 1:检查 Nudge 间隔配置
grep -A5 "skills:" ~/.hermes/config.yaml

# 诊断 2:检查是否手动禁用了
grep "HERMES_SKILL_NUDGE_DISABLE" ~/.hermes/.env

# 诊断 3:检查 Skill 目录权限
ls -la ~/.hermes/skills/

# 原因 1:任务太简单(工具调用 ≤ 5 次不触发)
# 解决:做更复杂的任务,或手动触发
hermes skills create "my-custom-skill"

# 原因 2:Nudge 间隔太大
# 解决:减小间隔
# skills:
#   creation_nudge_interval: 5  # 从 10 减到 5

# 原因 3:session 内被关闭
# 解决:在聊天中执行 /skills nudge on

12.4 记忆丢失

问题:重启后 Agent 忘记了之前的内容

bash

# 诊断 1:检查记忆文件是否存在
ls -la ~/.hermes/memories/
cat ~/.hermes/memories/MEMORY.md
cat ~/.hermes/memories/USER.md

# 诊断 2:检查记忆是否被禁用
grep "memory_enabled" ~/.hermes/config.yaml

# 诊断 3:Docker 模式下检查卷挂载
docker inspect hermes | grep -A5 Mounts

# 常见原因 1:Docker 容器重建但未挂载数据卷
# 解决:确保 -v ~/.hermes:/opt/data

# 常见原因 2:Redis 未持久化
# 解决:
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG SET appendfsync everysec
redis-cli CONFIG REWRITE

# 常见原因 3:会话级记忆未写回
# 解决:手动触发记忆保存
# 在对话中说 "请把刚才讨论的要点保存到记忆中"

12.5 Ollama 连接超时

问题ollama connection refusedtimeout

bash

# 诊断 1:Ollama 是否在运行
curl http://localhost:11434/api/tags

# 诊断 2:模型是否已下载
ollama list

# 诊断 3:Hermes 配置是否正确
grep -A3 "base_url" ~/.hermes/config.yaml

# 常见原因 1:Ollama 未启动
ollama serve  # 或 sudo systemctl start ollama

# 常见原因 2:模型未下载
ollama pull qwen3:14b

# 常见原因 3:Docker 容器网络不通
# 解决:使用 host 网络或正确配置桥接
# docker run --network=host ...
# 或 config.yaml 中 base_url 改为 http://host.docker.internal:11434/v1

# 常见原因 4:超时设置太短
# 解决:增加超时
# providers:
#   ollama-local:
#     request_timeout_seconds: 300
#     stale_timeout_seconds: 900

12.6 日志查看命令速查表

bash

# ── Hermes 内置日志 ─────────────────────────────────────
hermes logs                      # 所有日志
hermes logs gateway --since 10m  # 网关最近 10 分钟
hermes logs errors --tail 100    # 最近 100 条错误

# ── Docker 模式 ─────────────────────────────────────────
docker compose logs hermes --tail 50      # 最近 50 行
docker compose logs hermes -f             # 实时跟踪
docker compose logs hermes --since 1h     # 最近 1 小时
docker compose logs hermes --grep error   # 过滤错误

# ── Systemd 模式 ────────────────────────────────────────
journalctl -u hermes-agent -f                       # 实时跟踪
journalctl -u hermes-agent --since "10 minutes ago" # 最近 10 分钟
journalctl -u hermes-agent --since yesterday        # 昨天以来
journalctl -u hermes-agent -p err                   # 只看错误

# ── 原始日志文件 ────────────────────────────────────────
tail -f ~/.hermes/logs/errors.log      # 错误日志
tail -f ~/.hermes/logs/gateway.log     # 网关日志
tail -f ~/.hermes/logs/agent.log       # Agent 日志

# ── 健康检查 ────────────────────────────────────────────
curl http://localhost:8642/health          # 基础检查
curl http://localhost:8642/health/detailed  # 详细检查

# ── Redis 检查 ──────────────────────────────────────────
redis-cli ping                     # PONG = 正常
redis-cli info memory              # 内存使用
redis-cli dbsize                   # Key 数量

# ── Docker 容器健康 ─────────────────────────────────────
docker compose ps                  # 所有容器状态
docker stats hermes                # 实时资源占用
docker inspect hermes | jq '.[0].State'  # 详细状态

12.7 环境诊断一键脚本

bash

#!/bin/bash
# hermes-diagnose.sh — 一键诊断 Hermes Agent 环境

echo "=== Hermes Agent 环境诊断 ==="
echo ""

echo "--- 1. 系统信息 ---"
uname -a
echo "内存: $(free -h | awk '/Mem/{print $2}')"
echo "磁盘: $(df -h ~ | awk 'NR==2{print $4}')"

echo ""
echo "--- 2. Python ---"
python3 --version 2>/dev/null || echo "Python3: 未安装"
python3.11 --version 2>/dev/null || echo "Python3.11: 未安装"

echo ""
echo "--- 3. uv ---"
uv --version 2>/dev/null || echo "uv: 未安装"

echo ""
echo "--- 4. Docker ---"
docker --version 2>/dev/null || echo "Docker: 未安装"
docker compose version 2>/dev/null || echo "Docker Compose: 未安装"

echo ""
echo "--- 5. Hermes 命令 ---"
which hermes 2>/dev/null || echo "hermes: 未找到"
hermes doctor 2>/dev/null || echo "hermes doctor: 执行失败"

echo ""
echo "--- 6. 配置文件 ---"
[[ -f ~/.hermes/.env ]] && echo ".env: 存在 (权限: $(stat -c %a ~/.hermes/.env 2>/dev/null || stat -f %Lp ~/.hermes/.env))" || echo ".env: 不存在"
[[ -f ~/.hermes/config.yaml ]] && echo "config.yaml: 存在" || echo "config.yaml: 不存在"
[[ -f ~/.hermes/memories/SOUL.md ]] && echo "SOUL.md: 存在" || echo "SOUL.md: 不存在"

echo ""
echo "--- 7. 记忆文件 ---"
ls -la ~/.hermes/memories/ 2>/dev/null || echo "memories 目录: 不存在"

echo ""
echo "--- 8. Skills ---"
ls ~/.hermes/skills/ 2>/dev/null | head -20 || echo "skills 目录: 不存在"

echo ""
echo "--- 9. 健康检查 ---"
curl -sf http://localhost:8642/health 2>/dev/null && echo "" || echo "Gateway: 未响应"

echo ""
echo "--- 10. Redis ---"
redis-cli ping 2>/dev/null || echo "Redis: 未运行或未安装"

echo ""
echo "=== 诊断完成 ==="

附录:快速参考

部署方式选择决策树

plaintext

你有 Docker 吗?
├── 是 → 想要隔离环境吗?
│   ├── 是 → 方案一:Docker 部署 ✅(推荐)
│   └── 否 → 方案二:pip/uv 部署
└── 否 → 你是什么系统?
    ├── macOS → 方案二:pip/uv 部署
    ├── Linux → 方案三:云服务器一键脚本
    └── WSL2 → 先装 Docker,然后方案一

关键文件位置

表格

文件

路径

用途

配置

~/.hermes/config.yaml

所有设置

密钥

~/.hermes/.env

API Key

身份

~/.hermes/memories/SOUL.md

Agent 人格

记忆

~/.hermes/memories/MEMORY.md

长期事实

用户

~/.hermes/memories/USER.md

用户画像

技能

~/.hermes/skills/

自动生成的 Skill

会话

~/.hermes/sessions/

FTS5 索引

日志

~/.hermes/logs/

运行日志

OAuth

~/.hermes/auth.json

OAuth 令牌

定时

~/.hermes/cron/

Cron 任务

最小验收清单

上线前确认以下项目:

  • /health 返回 {"status":"ok"}

  • /v1/models 返回模型列表(需 API Server Key)

  • 最小 chat completions 请求成功

  • Gateway 日志无持续报错

  • Dashboard 可访问但不暴露公网

  • .env 权限 600,不在 Git 仓库中

  • API Server 前有 TLS 和访问控制

  • Docker 数据卷已持久化(非 tmpfs)

  • 日志和健康检查已接入监控

  • 自动备份脚本已配置并测试

下一篇预告:#62 将深入 Hermes Agent 的 Skill Hub 生态——如何从零构建和发布你自己的 Skill,以及 agentskills.io 的社区分发机制。

系列文章

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区