230 lines
8.0 KiB
Markdown
230 lines
8.0 KiB
Markdown
---
|
||
title: Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
|
||
type: reference
|
||
namespace: work
|
||
tags:
|
||
- hermes
|
||
- mac
|
||
- eagle
|
||
- claude-proxy
|
||
- zulip
|
||
- pitfalls
|
||
created: '2026-05-21'
|
||
updated: '2026-05-22'
|
||
last_synced: '2026-05-22'
|
||
confidence: 0.9
|
||
---
|
||
# Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
|
||
|
||
Hermes работает нативно (не в Docker) на Mac через `hermes gateway`.
|
||
Транспорт — Zulip (запущен в Docker). Провайдер модели — openclaw-claude-proxy
|
||
(см. ниже).
|
||
|
||
## Компоненты
|
||
|
||
| Компонент | Расположение | Запуск |
|
||
|-----------|-------------|--------|
|
||
| Hermes config | `~/.hermes/config.yaml` | — |
|
||
| claude-proxy (Claude proxy) | `/opt/homebrew/bin/claude-proxy` | launchd `ai.claude-proxy` |
|
||
| Zulip stack | `~/Developer/zulip/docker-compose.yml` | `docker compose up -d` |
|
||
| Obsidian MCP | mcpvault | встроен в Hermes toolset |
|
||
|
||
---
|
||
|
||
## openclaw-claude-proxy — обход rate limit Claude API
|
||
|
||
### Проблема
|
||
|
||
`provider: claude-code` в Hermes использует OAuth-токен напрямую через
|
||
API Anthropic — и упирается в rate limit подписки. Лимиты сбрасываются
|
||
раз в час. API-ключа нет (политика организации).
|
||
|
||
### Почему не cmappy
|
||
|
||
cmappy (`claude-max-proxy-py`) молча выбрасывает поле `tools` из запроса —
|
||
передаёт только текст в `claude --print`. Результат: Hermes не может
|
||
использовать **ни один инструмент** (скиллы, MCP, терминал). Только голый
|
||
чат.
|
||
|
||
### Решение: openclaw-claude-proxy
|
||
|
||
[mehdic/claude-proxy](https://github.com/mehdic/claude-proxy) (npm:
|
||
`openclaw-claude-proxy`) — Node.js сервер, запускает `claude --print` как
|
||
subprocess и предоставляет OpenAI-совместимый `/v1/chat/completions` на
|
||
порту 3456. **Поддерживает tool_use** — инжектирует схемы инструментов в
|
||
системный промпт, парсит JSON tool_call из ответа, возвращает стандартный
|
||
OpenAI `tool_calls`. Caller (Hermes) сам выполняет инструменты.
|
||
|
||
**Важно:** `CLAUDE_PROXY_TOOLS_TRANSLATION=1` НЕ включать — этот режим
|
||
выполняет MCP инструменты внутри CLI и Hermes ничего не получает.
|
||
|
||
### Установка
|
||
|
||
```bash
|
||
npm install -g openclaw-claude-proxy
|
||
```
|
||
|
||
### Wrapper-скрипт (обязателен для launchd)
|
||
|
||
`~/.local/bin/claude-proxy-start.sh`:
|
||
```bash
|
||
#!/bin/zsh
|
||
# launchd не наследует среду login-сессии — токен нужно загружать явно
|
||
set -a
|
||
source /Users/admin/.hermes/.env 2>/dev/null
|
||
set +a
|
||
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||
exec /opt/homebrew/bin/claude-proxy 3456
|
||
```
|
||
|
||
**Pitfall:** без явного `source ~/.hermes/.env` claude-proxy не видит
|
||
`CLAUDE_CODE_OAUTH_TOKEN` и прогревочные процессы падают с "Not logged in".
|
||
|
||
**Pitfall:** без явного PATH Claude CLI не найден (`/opt/homebrew/bin/claude`
|
||
не в launchd PATH).
|
||
|
||
### launchd сервис
|
||
|
||
`~/Library/LaunchAgents/ai.claude-proxy.plist`:
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>Label</key><string>ai.claude-proxy</string>
|
||
<key>ProgramArguments</key>
|
||
<array>
|
||
<string>/Users/admin/.local/bin/claude-proxy-start.sh</string>
|
||
</array>
|
||
<key>EnvironmentVariables</key>
|
||
<dict>
|
||
<key>HOME</key><string>/Users/admin</string>
|
||
</dict>
|
||
<key>RunAtLoad</key><true/>
|
||
<key>KeepAlive</key><true/>
|
||
<key>StandardOutPath</key>
|
||
<string>/Users/admin/.hermes/logs/claude-proxy.log</string>
|
||
<key>StandardErrorPath</key>
|
||
<string>/Users/admin/.hermes/logs/claude-proxy.log</string>
|
||
</dict>
|
||
</plist>
|
||
```
|
||
|
||
```bash
|
||
launchctl load ~/Library/LaunchAgents/ai.claude-proxy.plist
|
||
```
|
||
|
||
**Pitfall при перезагрузке:** если старый процесс ещё держит порт 3456:
|
||
```bash
|
||
lsof -ti :3456 | xargs kill -9
|
||
launchctl unload ~/Library/LaunchAgents/ai.claude-proxy.plist
|
||
launchctl load ~/Library/LaunchAgents/ai.claude-proxy.plist
|
||
```
|
||
|
||
### Конфигурация Hermes
|
||
|
||
`~/.hermes/config.yaml` (секция model):
|
||
```yaml
|
||
model:
|
||
default: claude-sonnet-4-6
|
||
# provider: claude-code # отключён — упирается в rate limit OAuth API
|
||
provider: custom
|
||
base_url: 'http://localhost:3456/v1'
|
||
```
|
||
|
||
**Pitfall:** `provider: openai` не существует в Hermes — нужно `custom`.
|
||
|
||
**Pitfall:** `base_url` должен включать `/v1` (Hermes дописывает
|
||
`/chat/completions`). Без `/v1` → 404.
|
||
|
||
---
|
||
|
||
## Zulip Docker — подводные камни
|
||
|
||
### RabbitMQ: пользователи сбрасываются после перезапуска
|
||
|
||
**Симптом:** Zulip отдаёт 500 на `/api/v1/register`. В логах RabbitMQ —
|
||
паника Khepri (Raft WAL). Пользователи в RabbitMQ исчезают.
|
||
|
||
**Причина:** RabbitMQ 4.x использует Khepri вместо Mnesia. При переполнении
|
||
диска WAL не может записаться → Khepri сбрасывает состояние → пользователи
|
||
исчезают. `RABBITMQ_DEFAULT_USER/PASS` применяются только при **первом
|
||
старте** с пустым volume — повторный запуск их не восстанавливает.
|
||
|
||
**Решение:**
|
||
|
||
1. `docker system prune` — освободить место на диске (Docker VM sparse disk
|
||
не освобождает место автоматически).
|
||
2. Добавить `RABBITMQ_ERLANG_COOKIE` в env rabbitmq (стабилизирует cookie
|
||
через перезапуски).
|
||
3. При повреждённом volume — стереть и пересоздать:
|
||
```bash
|
||
docker compose down
|
||
docker volume rm zulip_zulip-rabbitmq
|
||
docker compose up -d
|
||
```
|
||
|
||
### Log rotation (обязательно!)
|
||
|
||
Без ротации логи заполняют Docker VM (~6 ГБ за несколько месяцев).
|
||
|
||
`docker-compose.yml` — добавить к каждому сервису:
|
||
```yaml
|
||
# zulip:
|
||
logging:
|
||
driver: json-file
|
||
options:
|
||
max-size: "50m"
|
||
max-file: "5"
|
||
|
||
# rabbitmq, memcached, redis:
|
||
logging:
|
||
driver: json-file
|
||
options:
|
||
max-size: "20m"
|
||
max-file: "3"
|
||
```
|
||
|
||
### Docker VM sparse disk
|
||
|
||
Mac Docker Desktop использует sparse virtual disk. Место, освобождённое
|
||
внутри VM, не возвращается хосту автоматически. `docker system prune`
|
||
запускает compaction.
|
||
|
||
---
|
||
|
||
## Obsidian MCP
|
||
|
||
Везде используется `mcpvault` (не `obsidian-mcp`).
|
||
|
||
| Конфиг | Путь |
|
||
|--------|------|
|
||
| Claude Code CLI | `~/.claude/.mcp.json` |
|
||
| Claude Desktop App | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
||
| Hermes | встроен через toolset |
|
||
|
||
Пример конфига (одинаковый для обоих):
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"obsidian": {
|
||
"command": "mcpvault",
|
||
"args": ["/Users/admin/obsidian"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Pitfall:** `obsidian-mcp` (npm) был удалён — если остался в конфиге,
|
||
Claude падает с "Failed to spawn process". Проверить логи:
|
||
`~/Library/Logs/Claude/mcp-server-obsidian.log`.
|
||
|
||
---
|
||
|
||
## Связанные страницы
|
||
|
||
- [[tech/hermes-docker-kraken]] — Hermes на Кракене (Docker)
|
||
- [[tech/kraken-network]] — сетевая топология
|
||
- [[concepts/hermes-deployment-patterns]] — сравнение трёх моделей деплоя Hermes
|