Chuyển tới nội dung chính

Thiết lập Nix & NixOS

Hermes Agent vận chuyển một mảnh Nix với ba cấp độ tích hợp:

Cấp độNó dành cho aiNhững gì bạn nhận được
nix run / nix profile installBất kỳ người dùng Nix nào (macOS, Linux)Tệp nhị phân dựng sẵn với tất cả các chi tiết — sau đó sử dụng quy trình làm việc CLI tiêu chuẩn
Mô-đun NixOS (bản địa)Triển khai máy chủ NixOSCấu hình khai báo, dịch vụ systemd cứng cáp, bí mật được quản lý
Mô-đun NixOS (vùng chứa)Agent cần tự sửa đổiMọi thứ ở trên, cộng với một bộ chứa Ubuntu ổn định nơi tác nhân có thể apt/pip/npm install
What's different from the standard install

Trình cài đặt curl | bash tự quản lý Python, Node và các phần phụ thuộc. Flake Nix thay thế tất cả những thứ đó — mọi phần phụ thuộc Python đều là dẫn xuất Nix được xây dựng bởi uv2nix và các công cụ thời gian chạy (Node.js, git, ripgrep, ffmpeg) được gói vào PATH của tệp nhị phân. Không có pip thời gian chạy, không có kích hoạt venv, không có npm install.

Đối với người dùng không sử dụng NixOS, điều này chỉ thay đổi bước cài đặt. Mọi thứ sau (hermes setup, hermes gateway install, chỉnh sửa cấu hình) hoạt động giống hệt với cài đặt tiêu chuẩn.

Đối với người dùng mô-đun NixOS, toàn bộ vòng đời sẽ khác: cấu hình tồn tại trong configuration.nix, bí mật đi qua sops-nix/agenix, dịch vụ là đơn vị systemd và các lệnh cấu hình CLI bị chặn. Bạn quản lý Hermes giống như cách bạn quản lý bất kỳ dịch vụ NixOS nào khác.

Điều kiện tiên quyết

  • Nix đã bật vảy — Khuyến nghị Determinate Nix (bật vảy theo mặc định)
  • Khóa API cho các dịch vụ bạn muốn sử dụng (tối thiểu: khóa OpenRouter hoặc Anthropic)

Bắt đầu nhanh (Bất kỳ người dùng Nix nào)

Không cần bản sao. Nix tìm nạp, xây dựng và chạy mọi thứ:

# Run directly (builds on first use, cached after)
nix run github:NousResearch/hermes-agent -- setup
nix run github:NousResearch/hermes-agent -- chat

# Or install persistently
nix profile install github:NousResearch/hermes-agent
hermes setup
hermes chat

Sau nix profile install, hermes, hermes-agenthermes-acp đều có trên PATH của bạn. Từ đây, quy trình làm việc giống hệt với standard installationhermes setup hướng dẫn bạn lựa chọn nhà cung cấp, hermes gateway install thiết lập dịch vụ người dùng launchd (macOS) hoặc systemd và cấu hình tồn tại trong ~/.hermes/.

Xây dựng từ bản sao cục bộ
git clone https://github.com/NousResearch/hermes-agent.git
cd hermes-agent
nix build
./result/bin/hermes setup

Mô-đun NixOS

Flake xuất nixosModules.default - một mô-đun dịch vụ NixOS đầy đủ quản lý khai báo việc tạo, thư mục, tạo cấu hình, bí mật, tài liệu và vòng đời dịch vụ.

ghi chú

Mô-đun này yêu cầu NixOS. Đối với các hệ thống không phải NixOS (macOS, các bản phân phối Linux khác), hãy sử dụng nix profile install và quy trình làm việc CLI tiêu chuẩn ở trên.

Thêm đầu vào Flake

# /etc/nixos/flake.nix (or your system flake)
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
hermes-agent.url = "github:NousResearch/hermes-agent";
};

outputs = { nixpkgs, hermes-agent, ... }: {
nixosConfigurations.your-host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
hermes-agent.nixosModules.default
./configuration.nix
];
};
};
}

Cấu hình tối thiểu

# configuration.nix
{ config, ... }: {
services.hermes-agent = {
enable = true;
settings.model.default = "anthropic/claude-sonnet-4";
environmentFiles = [ config.sops.secrets."hermes-env".path ];
addToSystemPackages = true;
};
}

Thế thôi. nixos-rebuild switch tạo người dùng hermes, tạo config.yaml, kết nối bí mật và khởi động cổng — một dịch vụ chạy dài kết nối tác nhân với các nền tảng nhắn tin (Telegram, Discord, v.v.) và lắng nghe tin nhắn đến.

Secrets are required

Dòng environmentFiles ở trên giả sử bạn đã định cấu hình sops-nix hoặc agenix. Tệp phải chứa ít nhất một khóa nhà cung cấp LLM (ví dụ: OPENROUTER_API_KEY=sk-or-...). Xem Secrets Management để biết thiết lập đầy đủ. Nếu chưa có trình quản lý bí mật, bạn có thể sử dụng một tệp đơn giản làm điểm bắt đầu — chỉ cần đảm bảo rằng nó không thể đọc được trên thế giới:

echo "OPENROUTER_API_KEY=sk-or-your-key" | sudo install -m 0600 -o hermes /dev/stdin /var/lib/hermes/env
services.hermes-agent.environmentFiles = [ "/var/lib/hermes/env" ];
addToSystemPackages

Việc đặt addToSystemPackages = true thực hiện hai việc: đặt hermes CLI trên hệ thống của bạn PATH đặt HERMES_HOME trên toàn hệ thống để CLI tương tác chia sẻ trạng thái (phiên, kỹ năng, cron) với dịch vụ cổng. Nếu không có nó, việc chạy hermes trong shell của bạn sẽ tạo ra một thư mục ~/.hermes/ riêng.

Container-aware CLI

Khi container.enable = trueaddToSystemPackages = true, mọi lệnh hermes trên máy chủ sẽ tự động định tuyến vào vùng chứa được quản lý. Điều này có nghĩa là phiên CLI tương tác của bạn chạy trong cùng môi trường với dịch vụ cổng — với quyền truy cập vào tất cả các gói và công cụ được cài đặt trong vùng chứa.

  • Định tuyến minh bạch: hermes chat, hermes sessions list, hermes version, v.v. tất cả đều được thực thi vào vùng chứa dưới mui xe
  • Tất cả các cờ CLI đều được chuyển tiếp nguyên trạng
  • Nếu vùng chứa không chạy, CLI sẽ thử lại trong thời gian ngắn (5 giây với vòng quay để sử dụng tương tác, 10 giây im lặng đối với tập lệnh) rồi thất bại với một lỗi rõ ràng — không có dự phòng im lặng
  • Đối với các nhà phát triển làm việc trên cơ sở mã Hermes, hãy đặt HERMES_DEV=1 để bỏ qua định tuyến vùng chứa và trực tiếp chạy thanh toán cục bộ

Đặt container.hostUsers để tạo liên kết tượng trưng ~/.hermes tới thư mục trạng thái dịch vụ, do đó CLI máy chủ và các phiên, cấu hình và bộ nhớ chia sẻ vùng chứa:

services.hermes-agent = {
container.enable = true;
container.hostUsers = [ "your-username" ];
addToSystemPackages = true;
};

Người dùng được liệt kê trong hostUsers sẽ tự động được thêm vào nhóm hermes để truy cập quyền truy cập tệp.

Người dùng Podman: Dịch vụ NixOS chạy vùng chứa dưới dạng root. Người dùng Docker có quyền truy cập thông qua ổ cắm nhóm docker, nhưng các vùng chứa gốc của Podman yêu cầu sudo. Cấp sudo không cần mật khẩu cho thời gian chạy vùng chứa của bạn:

security.sudo.extraRules = [{
users = [ "your-username" ];
commands = [{
command = "/run/current-system/sw/bin/podman";
options = [ "NOPASSWD" ];
}];
}];

CLI tự động phát hiện khi cần sudo và sử dụng nó một cách minh bạch. Nếu không có điều này, bạn sẽ cần chạy sudo hermes chat theo cách thủ công.

Xác minh nó hoạt động

Sau nixos-rebuild switch, hãy kiểm tra xem dịch vụ có đang chạy không:

# Check service status
systemctl status hermes-agent

# Watch logs (Ctrl+C to stop)
journalctl -u hermes-agent -f

# If addToSystemPackages is true, test the CLI
hermes version
hermes config # shows the generated config

Chọn Chế độ Triển khai

Mô-đun hỗ trợ hai chế độ, được điều khiển bởi container.enable:

Gốc (mặc định)Bình chứa
Nó chạy như thế nàoDịch vụ systemd cứng trên máy chủBộ chứa Ubuntu liên tục được gắn liên kết /nix/store
An ninhNoNewPrivileges, ProtectSystem=strict, PrivateTmpCách ly vùng chứa, chạy với tư cách người dùng không có đặc quyền bên trong
Agent có thể tự cài đặt góiKhông - chỉ các công cụ trên PATH do Nix cung cấpCó — Các lượt cài đặt apt, pip, npm vẫn tồn tại sau mỗi lần khởi động lại
Bề mặt cấu hìnhTương tựTương tự
Khi nào nên chọnTriển khai tiêu chuẩn, bảo mật tối đa, khả năng tái tạoTác nhân cần cài đặt gói thời gian chạy, môi trường có thể thay đổi, công cụ thử nghiệm

Để bật chế độ vùng chứa, hãy thêm một dòng:

{
services.hermes-agent = {
enable = true;
container.enable = true;
# ... rest of config is identical
};
}
thông tin

Chế độ vùng chứa tự động kích hoạt virtualisation.docker.enable thông qua mkDefault. Nếu bạn sử dụng Podman thay thế, hãy đặt container.backend = "podman"virtualisation.docker.enable = false.


Cấu hình

Cài đặt khai báo

Tùy chọn settings chấp nhận tập hợp tùy ý được hiển thị dưới dạng config.yaml. Nó hỗ trợ hợp nhất sâu trên nhiều định nghĩa mô-đun (thông qua lib.recursiveUpdate), do đó bạn có thể chia cấu hình trên các tệp:

# base.nix
services.hermes-agent.settings = {
model.default = "anthropic/claude-sonnet-4";
toolsets = [ "all" ];
terminal = { backend = "local"; timeout = 180; };
};

# personality.nix
services.hermes-agent.settings = {
display = { compact = false; personality = "kawaii"; };
memory = { memory_enabled = true; user_profile_enabled = true; };
};

Cả hai đều được hợp nhất sâu tại thời điểm đánh giá. Các khóa do Nix khai báo luôn giành được các khóa trong config.yaml hiện có trên đĩa, nhưng các khóa do người dùng thêm mà Nix không chạm vào vẫn được giữ nguyên. Điều này có nghĩa là nếu tác nhân hoặc chỉnh sửa thủ công thêm các khóa như skills.disabled hoặc streaming.enabled, chúng vẫn tồn tại nixos-rebuild switch.

Model naming

settings.model.default sử dụng mã nhận dạng mẫu mà nhà cung cấp của bạn mong đợi. Với OpenRouter (mặc định), chúng trông giống như "anthropic/claude-sonnet-4" hoặc "google/gemini-3-flash". Nếu bạn đang sử dụng trực tiếp một nhà cung cấp (Anthropic, OpenAI), hãy đặt settings.model.base_url để trỏ đến API của họ và sử dụng ID mô hình gốc của họ (ví dụ: "claude-sonnet-4-20250514"). Khi không đặt base_url, Hermes mặc định là OpenRouter.

Discovering available config keys

Chạy nix build .#configKeys && cat result để xem mọi khóa cấu hình lá được trích xuất từ DEFAULT_CONFIG của Python. Bạn có thể dán config.yaml hiện có của mình vào tập hợp settings — bản đồ cấu trúc 1:1.

Ví dụ đầy đủ: tất cả các cài đặt được tùy chỉnh phổ biến
{ config, ... }: {
services.hermes-agent = {
enable = true;
container.enable = true;

# ── Model ──────────────────────────────────────────────────────────
settings = {
model = {
base_url = "https://openrouter.ai/api/v1";
default = "anthropic/claude-opus-4.6";
};
toolsets = [ "all" ];
max_turns = 100;
terminal = { backend = "local"; cwd = "."; timeout = 180; };
compression = {
enabled = true;
threshold = 0.85;
summary_model = "google/gemini-3-flash-preview";
};
memory = { memory_enabled = true; user_profile_enabled = true; };
display = { compact = false; personality = "kawaii"; };
agent = { max_turns = 60; verbose = false; };
};

# ── Secrets ────────────────────────────────────────────────────────
environmentFiles = [ config.sops.secrets."hermes-env".path ];

# ── Documents ──────────────────────────────────────────────────────
documents = {
"SOUL.md" = builtins.readFile /home/user/.hermes/SOUL.md;
"USER.md" = ./documents/USER.md;
};

# ── MCP Servers ────────────────────────────────────────────────────
mcpServers.filesystem = {
command = "npx";
args = [ "-y" "@modelcontextprotocol/server-filesystem" "/data/workspace" ];
};

# ── Container options ──────────────────────────────────────────────
container = {
image = "ubuntu:24.04";
backend = "docker";
hostUsers = [ "your-username" ];
extraVolumes = [ "/home/user/projects:/projects:rw" ];
extraOptions = [ "--gpus" "all" ];
};

# ── Service tuning ─────────────────────────────────────────────────
addToSystemPackages = true;
extraArgs = [ "--verbose" ];
restart = "always";
restartSec = 5;
};
}

Escape Hatch: Mang theo cấu hình của riêng bạn

Nếu bạn muốn quản lý config.yaml hoàn toàn bên ngoài Nix, hãy sử dụng configFile:

services.hermes-agent.configFile = /etc/hermes/config.yaml;

Điều này bỏ qua hoàn toàn settings — không hợp nhất, không tạo. Tệp được sao chép nguyên trạng sang $HERMES_HOME/config.yaml mỗi lần kích hoạt.

Bảng tính tùy chỉnh

Tham khảo nhanh về những điều phổ biến nhất mà người dùng Nix muốn tùy chỉnh:

Tôi muốn...Tùy chọnVí dụ
Thay đổi mô hình LLMsettings.model.default"anthropic/claude-sonnet-4"
Sử dụng điểm cuối của nhà cung cấp khácsettings.model.base_url"https://openrouter.ai/api/v1"
Thêm khóa APIenvironmentFiles[ config.sops.secrets."hermes-env".path ]
Tạo cá tính cho Agentdocuments."SOUL.md"builtins.readFile ./my-soul.md
Thêm máy chủ công cụ MCPmcpServers.<name>Xem MCP Servers
Gắn thư mục máy chủ vào vùng chứacontainer.extraVolumes[ "/data:/data:rw" ]
Truyền quyền truy cập GPU vào vùng chứacontainer.extraOptions[ "--gpus" "all" ]
Sử dụng Podman thay vì Dockercontainer.backend"podman"
Chia sẻ trạng thái giữa máy chủ CLI và vùng chứacontainer.hostUsers[ "sidbin" ]
Thêm công cụ vào dịch vụ PATH (chỉ bản địa)extraPackages[ pkgs.pandoc pkgs.imagemagick ]
Sử dụng hình ảnh cơ sở tùy chỉnhcontainer.image"ubuntu:24.04"
Ghi đè gói hermespackageinputs.hermes-agent.packages.${system}.default.override { ... }
Thay đổi thư mục trạng tháistateDir"/opt/hermes"
Đặt thư mục làm việc của AgentworkingDirectory"/home/user/projects"

Quản lý bí mật

Never put API keys in XPROT138XPROT or XPROT139XPROT

Các giá trị trong biểu thức Nix kết thúc bằng /nix/store, có thể đọc được trên thế giới. Luôn sử dụng environmentFiles với trình quản lý bí mật.

Cả environment (vars không bí mật) và environmentFiles (tệp bí mật) đều được hợp nhất vào $HERMES_HOME/.env tại thời điểm kích hoạt (nixos-rebuild switch). Hermes đọc tệp này mỗi lần khởi động, vì vậy các thay đổi sẽ có hiệu lực với systemctl restart hermes-agent — không cần tái tạo vùng chứa.

sops-nix

{
sops = {
defaultSopsFile = ./secrets/hermes.yaml;
age.keyFile = "/home/user/.config/sops/age/keys.txt";
secrets."hermes-env" = { format = "yaml"; };
};

services.hermes-agent.environmentFiles = [
config.sops.secrets."hermes-env".path
];
}

Tệp bí mật chứa các cặp khóa-giá trị:

# secrets/hermes.yaml (encrypted with sops)
hermes-env: |
OPENROUTER_API_KEY=sk-or-...
TELEGRAM_BOT_TOKEN=123456:ABC...
ANTHROPIC_API_KEY=sk-ant-...

agenix

{
age.secrets.hermes-env.file = ./secrets/hermes-env.age;

services.hermes-agent.environmentFiles = [
config.age.secrets.hermes-env.path
];
}

OAuth / Auth Seeding

Đối với các nền tảng yêu cầu OAuth (ví dụ: Discord), hãy sử dụng authFile để tạo thông tin xác thực trong lần triển khai đầu tiên:

{
services.hermes-agent = {
authFile = config.sops.secrets."hermes/auth.json".path;
# authFileForceOverwrite = true; # overwrite on every activation
};
}

Tệp chỉ được sao chép nếu auth.json chưa tồn tại (trừ khi authFileForceOverwrite = true). Việc làm mới mã thông báo OAuth trong thời gian chạy được ghi vào thư mục trạng thái và được giữ nguyên trong quá trình xây dựng lại.


Tài liệu

Tùy chọn documents cài đặt các tệp vào thư mục làm việc của tác nhân (workingDirectory, mà tác nhân đọc là không gian làm việc của nó). Hermes tìm kiếm tên tập tin cụ thể theo quy ước:

  • SOUL.md — lời nhắc/tính cách hệ thống của Agent. Hermes đọc điều này khi khởi động và sử dụng nó như những hướng dẫn liên tục định hình hành vi của nó trong tất cả các cuộc trò chuyện.
  • USER.md — bối cảnh về người dùng mà tác nhân đang tương tác.
  • Bất kỳ tệp nào khác bạn đặt ở đây đều hiển thị với tác nhân dưới dạng tệp không gian làm việc.
{
services.hermes-agent.documents = {
"SOUL.md" = ''
You are a helpful research assistant specializing in NixOS packaging.
Always cite sources and prefer reproducible solutions.
'';
"USER.md" = ./documents/USER.md; # path reference, copied from Nix store
};
}

Giá trị có thể là chuỗi nội tuyến hoặc tham chiếu đường dẫn. Các tệp được cài đặt trên mọi nixos-rebuild switch.


Máy chủ MCP

Tùy chọn mcpServers khai báo cấu hình máy chủ MCP (Model Context Protocol). Mỗi máy chủ sử dụng truyền tải stdio (lệnh cục bộ) hoặc HTTP (URL từ xa).

Stdio Transport (Máy chủ cục bộ)

{
services.hermes-agent.mcpServers = {
filesystem = {
command = "npx";
args = [ "-y" "@modelcontextprotocol/server-filesystem" "/data/workspace" ];
};
github = {
command = "npx";
args = [ "-y" "@modelcontextprotocol/server-github" ];
env.GITHUB_PERSONAL_ACCESS_TOKEN = "\${GITHUB_TOKEN}"; # resolved from .env
};
};
}
mẹo

Các biến môi trường trong giá trị env được phân giải từ $HERMES_HOME/.env khi chạy. Sử dụng environmentFiles để chèn bí mật - không bao giờ đặt mã thông báo trực tiếp vào cấu hình Nix.

Truyền tải HTTP (Máy chủ từ xa)

{
services.hermes-agent.mcpServers.remote-api = {
url = "https://mcp.example.com/v1/mcp";
headers.Authorization = "Bearer \${MCP_REMOTE_API_KEY}";
timeout = 180;
};
}

Truyền tải HTTP với OAuth

Đặt auth = "oauth" cho máy chủ sử dụng OAuth 2.1. Hermes triển khai toàn bộ luồng PKCE — khám phá siêu dữ liệu, đăng ký khách hàng động, trao đổi mã thông báo và làm mới tự động.

{
services.hermes-agent.mcpServers.my-oauth-server = {
url = "https://mcp.example.com/mcp";
auth = "oauth";
};
}

Mã thông báo được lưu trữ trong $HERMES_HOME/mcp-tokens/<server-name>.json và tồn tại trong suốt quá trình khởi động lại và xây dựng lại.

Ủy quyền OAuth ban đầu trên máy chủ không đầu

Ủy quyền OAuth đầu tiên yêu cầu luồng chấp thuận dựa trên trình duyệt. Trong triển khai không có đầu, Hermes in URL ủy quyền tới thiết bị xuất chuẩn/nhật ký thay vì mở trình duyệt.

Tùy chọn A: Khởi động tương tác — chạy luồng một lần qua docker exec (vùng chứa) hoặc sudo -u hermes (gốc):

# Container mode
docker exec -it hermes-agent \
hermes mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth

# Native mode
sudo -u hermes HERMES_HOME=/var/lib/hermes/.hermes \
hermes mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth

Vùng chứa sử dụng --network=host, do đó, trình nghe gọi lại OAuth trên 127.0.0.1 có thể truy cập được từ trình duyệt máy chủ.

Tùy chọn B: Chuẩn bị sẵn mã thông báo — hoàn thành quy trình trên máy trạm, sau đó sao chép mã thông báo:

hermes mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth
scp ~/.hermes/mcp-tokens/my-oauth-server{,.client}.json \
server:/var/lib/hermes/.hermes/mcp-tokens/
# Ensure: chown hermes:hermes, chmod 0600

Lấy mẫu (Yêu cầu LLM do máy chủ khởi tạo)

Một số máy chủ MCP có thể yêu cầu hoàn thành LLM từ tác nhân:

{
services.hermes-agent.mcpServers.analysis = {
command = "npx";
args = [ "-y" "analysis-server" ];
sampling = {
enabled = true;
model = "google/gemini-3-flash";
max_tokens_cap = 4096;
timeout = 30;
max_rpm = 10;
};
};
}

Chế độ quản lý

Khi hermes chạy qua mô-đun NixOS, các lệnh CLI sau sẽ bị chặn kèm theo lỗi mô tả hướng bạn đến configuration.nix:

Lệnh bị chặnTại sao
hermes setupCấu hình mang tính khai báo - chỉnh sửa settings trong cấu hình Nix của bạn
hermes config editCấu hình được tạo từ settings
hermes config set <key> <value>Cấu hình được tạo từ settings
hermes gateway installDịch vụ systemd được quản lý bởi NixOS
hermes gateway uninstallDịch vụ systemd được quản lý bởi NixOS

Điều này ngăn cản sự trôi dạt giữa những gì Nix khai báo và những gì có trên đĩa. Phát hiện sử dụng hai Signal:

  1. HERMES_MANAGED=true biến môi trường - được đặt bởi dịch vụ systemd, hiển thị với quy trình cổng
  2. Tệp đánh dấu .managed trong HERMES_HOME — được đặt bởi tập lệnh kích hoạt, hiển thị với các shell tương tác (ví dụ: docker exec -it hermes-agent hermes config set ... cũng bị chặn)

Để thay đổi cấu hình, hãy chỉnh sửa cấu hình Nix của bạn và chạy sudo nixos-rebuild switch.


Kiến trúc vùng chứa

thông tin

Phần này chỉ phù hợp nếu bạn đang sử dụng container.enable = true. Bỏ qua nó để triển khai chế độ gốc.

Khi chế độ vùng chứa được bật, Hermes chạy bên trong vùng chứa Ubuntu liên tục với chế độ chỉ đọc được gắn liên kết nhị phân do Nix xây dựng từ máy chủ:

Host                                    Container
──── ─────────
/nix/store/...-hermes-agent-0.1.0 ──► /nix/store/... (ro)
~/.hermes -> /var/lib/hermes/.hermes (symlink bridge, per hostUsers)
/var/lib/hermes/ ──► /data/ (rw)
├── current-package -> /nix/store/... (symlink, updated each rebuild)
├── .gc-root -> /nix/store/... (prevents nix-collect-garbage)
├── .container-identity (sha256 hash, triggers recreation)
├── .hermes/ (HERMES_HOME)
│ ├── .env (merged from environment + environmentFiles)
│ ├── config.yaml (Nix-generated, deep-merged by activation)
│ ├── .managed (marker file)
│ ├── .container-mode (routing metadata: backend, exec_user, etc.)
│ ├── state.db, sessions/, memories/ (runtime state)
│ └── mcp-tokens/ (OAuth tokens for MCP servers)
├── home/ ──► /home/hermes (rw)
└── workspace/ (MESSAGING_CWD)
├── SOUL.md (from documents option)
└── (agent-created files)

Container writable layer (apt/pip/npm): /usr, /usr/local, /tmp

Tệp nhị phân do Nix xây dựng hoạt động bên trong bộ chứa Ubuntu vì /nix/store được gắn kết - nó mang theo trình thông dịch riêng và tất cả các phần phụ thuộc, do đó không phụ thuộc vào thư viện hệ thống của bộ chứa. Điểm vào vùng chứa được giải quyết thông qua liên kết tượng trưng current-package: /data/current-package/bin/hermes gateway run --replace. Trên nixos-rebuild switch, chỉ liên kết tượng trưng được cập nhật - vùng chứa tiếp tục chạy.

Điều gì tồn tại xuyên suốt điều gì

Sự kiệnVùng chứa được tạo lại?/data (trạng thái)/home/hermesLớp có thể ghi (apt/pip/npm)
systemctl restart hermes-agentKhôngKiên trìKiên trìKiên trì
nixos-rebuild switch (đổi mã)Không (cập nhật liên kết tượng trưng)Kiên trìKiên trìKiên trì
Khởi động lại máy chủKhôngKiên trìKiên trìKiên trì
nix-collect-garbageKhông (gốc GC)Kiên trìKiên trìKiên trì
Thay đổi hình ảnh (container.image)Kiên trìKiên trìMất
Thay đổi âm lượng/tùy chọnKiên trìKiên trìMất
Thay đổi environment/environmentFilesKhôngKiên trìKiên trìKiên trì

Vùng chứa chỉ được tạo lại khi băm nhận dạng của nó thay đổi. Hàm băm bao gồm: phiên bản lược đồ, hình ảnh, extraVolumes, extraOptions và tập lệnh điểm nhập. Những thay đổi đối với các biến môi trường, cài đặt, tài liệu hoặc bản thân gói hermes không kích hoạt hoạt động giải trí.

Writable layer loss

Khi hàm băm nhận dạng thay đổi (nâng cấp hình ảnh, khối lượng mới, tùy chọn vùng chứa mới), vùng chứa sẽ bị hủy và được tạo lại từ một lần kéo container.image mới. Mọi gói apt install, pip install hoặc npm install trong lớp có thể ghi đều bị mất. Trạng thái trong /data/home/hermes được giữ nguyên (đây là các giá trị gắn kết).

Nếu tác nhân dựa vào các gói cụ thể, hãy cân nhắc việc đưa chúng vào một hình ảnh tùy chỉnh (container.image = "my-registry/hermes-base:latest") hoặc viết kịch bản cài đặt của chúng trong SOUL.md của tác nhân.

Bảo vệ gốc GC

Tập lệnh preStart tạo gốc GC tại ${stateDir}/.gc-root trỏ tới gói hermes hiện tại. Điều này ngăn nix-collect-garbage xóa tệp nhị phân đang chạy. Nếu root GC bằng cách nào đó bị hỏng, việc khởi động lại dịch vụ sẽ tạo lại nó.


Phát triển

Dev Shell

Flake cung cấp trình bao phát triển với Python 3.11, uv, Node.js và tất cả các công cụ thời gian chạy:

cd hermes-agent
nix develop

# Shell provides:
# - Python 3.11 + uv (deps installed into .venv on first entry)
# - Node.js 20, ripgrep, git, openssh, ffmpeg on PATH
# - Stamp-file optimization: re-entry is near-instant if deps haven't changed

hermes setup
hermes chat

direnv (Được khuyến nghị)

.envrc đi kèm sẽ tự động kích hoạt dev shell:

cd hermes-agent
direnv allow # one-time
# Subsequent entries are near-instant (stamp file skips dep install)

Kiểm tra vảy

Phần mềm này bao gồm xác minh tại thời điểm xây dựng chạy trong CI và cục bộ:

# Run all checks
nix flake check

# Individual checks
nix build .#checks.x86_64-linux.package-contents # binaries exist + version
nix build .#checks.x86_64-linux.entry-points-sync # pyproject.toml ↔ Nix package sync
nix build .#checks.x86_64-linux.cli-commands # gateway/config subcommands
nix build .#checks.x86_64-linux.managed-guard # HERMES_MANAGED blocks mutation
nix build .#checks.x86_64-linux.bundled-skills # skills present in package
nix build .#checks.x86_64-linux.config-roundtrip # merge script preserves user keys
Mỗi lần kiểm tra xác minh điều gì
Kiểm traNó kiểm tra cái gì
package-contentsCác tệp nhị phân hermeshermes-agent tồn tại và hermes version chạy
entry-points-syncMỗi mục [project.scripts] trong pyproject.toml đều có tệp nhị phân được gói trong gói Nix
cli-commandshermes --help hiển thị các lệnh phụ gatewayconfig
managed-guardHERMES_MANAGED=true hermes config set ... in lỗi NixOS
bundled-skillsThư mục kỹ năng tồn tại, chứa các tệp SKILL.md, HERMES_BUNDLED_SKILLS được đặt trong trình bao bọc
config-roundtrip7 kịch bản hợp nhất: cài đặt mới, ghi đè Nix, bảo toàn khóa người dùng, hợp nhất hỗn hợp, hợp nhất phụ gia MCP, hợp nhất sâu lồng nhau, idempotency

Tùy chọn Tham khảo

Cốt lõi

Tùy chọnLoạiMặc địnhMô tả
enableboolfalseKích hoạt dịch vụ Hermes Agent
packagepackagehermes-agentGói Hermes-agent để sử dụng
userstr"hermes"Người dùng hệ thống
groupstr"hermes"Nhóm hệ thống
createUserbooltrueTự động tạo người dùng/nhóm
stateDirstr"/var/lib/hermes"Thư mục trạng thái (mẹ HERMES_HOME)
workingDirectorystr"${stateDir}/workspace"Thư mục làm việc của Agent (MESSAGING_CWD)
addToSystemPackagesboolfalseThêm hermes CLI vào PATH hệ thống và đặt HERMES_HOME trên toàn hệ thống

Cấu hình

Tùy chọnLoạiMặc địnhMô tả
settingsattrs (được hợp nhất sâu){}Cấu hình khai báo được hiển thị dưới dạng config.yaml. Hỗ trợ lồng tùy ý; nhiều định nghĩa được hợp nhất thông qua lib.recursiveUpdate
configFilenull hoặc pathnullĐường dẫn đến config.yaml hiện có. Ghi đè hoàn toàn settings nếu được đặt

Bí mật & Môi trường

Tùy chọnLoạiMặc địnhMô tả
environmentFileslistOf str[]Đường dẫn đến tệp env có bí mật. Đã sáp nhập vào $HERMES_HOME/.env tại thời điểm kích hoạt
environmentattrsOf str{}Các loại env không bí mật. Hiển thị trong cửa hàng Nix — không đặt bí mật ở đây
authFilenull hoặc pathnullHạt giống thông tin xác thực OAuth. Chỉ được sao chép trong lần triển khai đầu tiên
authFileForceOverwriteboolfalseLuôn ghi đè auth.json từ authFile khi kích hoạt

Tài liệu

Tùy chọnLoạiMặc địnhMô tả
documentsattrsOf (either str path){}Các tập tin không gian làm việc. Khóa là tên tệp, giá trị là chuỗi nội tuyến hoặc đường dẫn. Đã cài đặt vào workingDirectory khi kích hoạt

Máy chủ MCP

Tùy chọnLoạiMặc địnhMô tả
mcpServersattrsOf submodule{}Định nghĩa máy chủ MCP, được sáp nhập vào settings.mcp_servers
mcpServers.<name>.commandnull hoặc strnullLệnh máy chủ (stdio Transport)
mcpServers.<name>.argslistOf str[]Đối số lệnh
mcpServers.<name>.envattrsOf str{}Biến môi trường cho tiến trình máy chủ
mcpServers.<name>.urlnull hoặc strnullURL điểm cuối của máy chủ (truyền tải HTTP/StreamableHTTP)
mcpServers.<name>.headersattrsOf str{}Tiêu đề HTTP, ví dụ: Authorization
mcpServers.<name>.authnull hoặc "oauth"nullPhương pháp xác thực. "oauth" kích hoạt OAuth 2.1 PKCE
mcpServers.<name>.enabledbooltrueBật hoặc tắt máy chủ này
mcpServers.<name>.timeoutnull hoặc intnullThời gian chờ cuộc gọi công cụ tính bằng giây (mặc định: 120)
mcpServers.<name>.connect_timeoutnull hoặc intnullThời gian chờ kết nối tính bằng giây (mặc định: 60)
mcpServers.<name>.toolsnull hoặc submodulenullLọc công cụ (danh sách include/exclude)
mcpServers.<name>.samplingnull hoặc submodulenullCấu hình lấy mẫu cho các yêu cầu LLM do máy chủ khởi tạo

Hành vi phục vụ

Tùy chọnLoạiMặc địnhMô tả
extraArgslistOf str[]Đối số bổ sung cho hermes gateway
extraPackageslistOf package[]Các gói bổ sung trên dịch vụ PATH (chỉ ở chế độ gốc)
restartstr"always"chính sách systemd Restart=
restartSecint5giá trị systemd RestartSec=

Thùng chứa

Tùy chọnLoạiMặc địnhMô tả
container.enableboolfalseKích hoạt chế độ vùng chứa OCI
container.backendenum ["docker" "podman"]"docker"Thời gian chạy vùng chứa
container.imagestr"ubuntu:24.04"Hình ảnh cơ sở (được kéo khi chạy)
container.extraVolumeslistOf str[]Giá đỡ âm lượng bổ sung (host:container:mode)
container.extraOptionslistOf str[]Các đối số bổ sung được chuyển tới docker create
container.hostUserslistOf str[]Người dùng tương tác nhận được liên kết tượng trưng ~/.hermes đến dịch vụ stateDir và được tự động thêm vào nhóm hermes

Bố cục thư mục

Chế độ gốc

/var/lib/hermes/                     # stateDir (owned by hermes:hermes, 0750)
├── .hermes/ # HERMES_HOME
│ ├── config.yaml # Nix-generated (deep-merged each rebuild)
│ ├── .managed # Marker: CLI config mutation blocked
│ ├── .env # Merged from environment + environmentFiles
│ ├── auth.json # OAuth credentials (seeded, then self-managed)
│ ├── gateway.pid
│ ├── state.db
│ ├── mcp-tokens/ # OAuth tokens for MCP servers
│ ├── sessions/
│ ├── memories/
│ ├── skills/
│ ├── cron/
│ └── logs/
├── home/ # Agent HOME
└── workspace/ # MESSAGING_CWD
├── SOUL.md # From documents option
└── (agent-created files)

Chế độ vùng chứa

Bố cục tương tự, được gắn vào thùng chứa:

Đường dẫn containerĐường dẫn máy chủChế độGhi chú
/nix/store/nix/storeroHệ nhị phân Hermes + tất cả các chi tiết Nix
/data/var/lib/hermesrwTất cả trạng thái, cấu hình, không gian làm việc
/home/hermes${stateDir}/homerwTrang chủ Agent liên tục — pip install --user, bộ đệm công cụ
/usr, /usr/local, /tmp(lớp có thể ghi)rwSố lượt cài đặt apt/pip/npm — vẫn tồn tại sau khi khởi động lại, bị mất khi giải trí

Đang cập nhật

# Update the flake input
nix flake update hermes-agent --flake /etc/nixos

# Rebuild
sudo nixos-rebuild switch

Ở chế độ vùng chứa, liên kết tượng trưng current-package được cập nhật và tác nhân chọn tệp nhị phân mới khi khởi động lại. Không giải trí container, không mất gói đã cài đặt.


Khắc phục sự cố

Podman users

Tất cả các lệnh docker bên dưới đều hoạt động tương tự với podman. Thay thế tương ứng nếu bạn đặt container.backend = "podman".

Nhật ký dịch vụ

# Both modes use the same systemd unit
journalctl -u hermes-agent -f

# Container mode: also available directly
docker logs -f hermes-agent

Kiểm tra container

systemctl status hermes-agent
docker ps -a --filter name=hermes-agent
docker inspect hermes-agent --format='{{.State.Status}}'
docker exec -it hermes-agent bash
docker exec hermes-agent readlink /data/current-package
docker exec hermes-agent cat /data/.container-identity

Giải trí Force Container

Nếu bạn cần đặt lại lớp có thể ghi (Ubuntu mới):

sudo systemctl stop hermes-agent
docker rm -f hermes-agent
sudo rm /var/lib/hermes/.container-identity
sudo systemctl start hermes-agent

Xác minh bí mật đã được tải

Nếu tác nhân khởi động nhưng không thể xác thực với nhà cung cấp LLM, hãy kiểm tra xem tệp .env đã được hợp nhất chính xác chưa:

# Native mode
sudo -u hermes cat /var/lib/hermes/.hermes/.env

# Container mode
docker exec hermes-agent cat /data/.hermes/.env

Xác minh gốc GC

nix-store --query --roots $(docker exec hermes-agent readlink /data/current-package)

Các vấn đề thường gặp

Triệu chứngNguyên nhânSửa chữa
Cannot save configuration: managed by NixOSBảo vệ CLI đang hoạt độngChỉnh sửa configuration.nixnixos-rebuild switch
Container được tạo lại bất ngờextraVolumes, extraOptions hoặc image đã thay đổiDự kiến ​​- đặt lại lớp có thể ghi. Cài đặt lại các gói hoặc sử dụng hình ảnh tùy chỉnh
hermes version hiển thị phiên bản cũVùng chứa chưa được khởi động lạisystemctl restart hermes-agent
Quyền bị từ chối trên /var/lib/hermesThư mục trạng thái là 0750 hermes:hermesSử dụng docker exec hoặc sudo -u hermes
nix-collect-garbage đã loại bỏ HermesThiếu gốc GCKhởi động lại dịch vụ (preStart tạo lại gốc GC)
no container with name or ID "hermes-agent" (Podman)Vùng chứa gốc của Podman không hiển thị với người dùng thông thườngThêm sudo không mật khẩu cho podman (xem phần Container-aware CLI)
unable to find user hermesVùng chứa vẫn đang bắt đầu (điểm vào chưa tạo người dùng)Đợi vài giây và thử lại - CLI tự động thử lại