# 在 Pixel 上编译安装 hermes-agent + 配置 Kimi Coding Plan > 目标设备:Pixel 8 Pro (husky),Android 16,已 root(Magisk)+ Termux。 > hermes-agent = **NousResearch 的自改进 AI agent**(github.com/NousResearch/hermes-agent,Python 3.11+/Node),提供 `hermes` CLI(`hermes` 聊天 / `hermes gateway` 消息网关 / `hermes setup` 配置)。本文记录从 Mac 经 adb 把它装到 Pixel Termux,并接 Kimi Coding Plan 作为 LLM 后端的完整流程。 > > 相关记忆:`~/.claude/.../memory/hermes-agent-termux-install.md`、`magisk-su-android-inet-group.md`、`termux-path-convention.md`。 --- ## 0. 前置 - 设备已 root,Termux 已装(GitHub/F-Droid 版,非 Play 商店)。Termux 重装/设备 restore 后 **uid 会变**,先取当前 uid: ```bash adb shell 'su -c "stat -c %u /data/data/com.termux"' # 例:10302(low3 = 302) ``` - 所有「以 Termux 用户身份联网」的命令必须带 inet 等 supplementary group,否则 DNS/网络全断。统一模板(uid=10302 为例): ``` su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c "" ``` 其中 `3003=inet 9997=everybody 20=cache 50=all_aN`。详见 memory `magisk-su-android-inet-group`。 - Termux 环境变量(脚本里统一 export): ```bash export PREFIX=/data/data/com.termux/files/usr export HOME=/data/data/com.termux/files/home export PATH=$PREFIX/bin:$PATH export LD_LIBRARY_PATH=$PREFIX/lib export TMPDIR=$PREFIX/tmp export TERMUX_VERSION=0.118.3 ``` --- ## 1. 编译安装 hermes-agent 官方安装器原生支持 Termux:检测到 Termux 后用 stdlib venv+pip(不用 uv),自动 `pkg install` python/git/nodejs/clang/rust/ffmpeg/ripgrep,从源码编译 native wheel(maturin / pydantic-core / jiter…),装到 `~/.hermes/hermes-agent/venv`,并在 `$PREFIX/bin/hermes` 建 wrapper。**整机编译约 25–30 分钟**。 ### 1.1 ⚠️ 必做:先升级 Termux 全量包(否则 node 坏) 全新 bootstrap 过期时,`pkg install nodejs` 装上的 node 链不上旧 openssl: ``` node: CANNOT LINK EXECUTABLE "node": cannot locate symbol "OSSL_PROVIDER_add_conf_parameter" ``` install.sh 因 `set -e` 在 Node 步骤 `rc=1` 退出。**先升级再装**: ```bash export DEBIAN_FRONTEND=noninteractive apt-get update -y apt-get upgrade -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef node --version # 应能正常打印版本(不再 CANNOT LINK) ``` ### 1.2 跑安装器(脱离 + 日志,扛 adb 掉线/doze) 把下面脚本 push 到 `/sdcard`,再以 Termux 用户 `setsid nohup` 脱离运行: ```bash #!/data/data/com.termux/files/usr/bin/bash # 见上方 export 块…… export DEBIAN_FRONTEND=noninteractive cd "$HOME"; termux-wake-lock 2>/dev/null || true echo "=== UPGRADE START $(date) ===" apt-get update -y; apt-get upgrade -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef node --version || { echo "NODE BROKEN"; exit 2; } echo "=== HERMES INSTALL $(date) ===" curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --non-interactive echo "=== HERMES INSTALL END rc=$? $(date) ===" ``` ```bash adb push install.sh /sdcard/install.sh LOG=/data/data/com.termux/files/home/hermes-install.log adb shell "su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c \ 'setsid nohup /data/data/com.termux/files/usr/bin/bash /sdcard/install.sh >$LOG 2>&1 注意:`hermes update` 会重新生成 wrapper、把 shebang 改回 `/usr/bin/env`,**每次更新后需重修**。 > `venv/bin/hermes` 的 shebang 是绝对 venv python,本就没问题,可用它绕过 wrapper 验证。 ### 1.4 验证 ```bash adb shell 'su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c " export PREFIX=/data/data/com.termux/files/usr HOME=/data/data/com.termux/files/home export PATH=\$PREFIX/bin:\$PATH LD_LIBRARY_PATH=\$PREFIX/lib TMPDIR=\$PREFIX/tmp hermes --version"' # → Hermes Agent v0.15.1 (2026.5.29) · Python 3.13.13 ``` 产物位置:代码 `~/.hermes/hermes-agent/`,配置 `~/.hermes/config.yaml` + `~/.hermes/.env`,skills `~/.hermes/skills/`。 --- ## 2. 配置 Kimi Coding Plan(sk-kimi- key) hermes **原生支持** Kimi Coding Plan,**不要**用 `provider=anthropic`+`ANTHROPIC_BASE_URL` 绕路。 ### 2.1 源码逻辑(为什么这么配) | 文件 | 逻辑 | |---|---| | `hermes_cli/auth.py:248` | `kimi-coding` provider:`api_key_env_vars=("KIMI_API_KEY","KIMI_CODING_API_KEY")` | | `hermes_cli/auth.py:515` | `KIMI_CODE_BASE_URL = "https://api.kimi.com/coding"`;`_resolve_kimi_base_url()` 把 `sk-kimi-` 前缀 key 自动重定向到这里 | | `agent/anthropic_adapter.py:385` | `_is_kimi_coding_endpoint(base_url)` 检测到 `api.kimi.com/coding` → **自动切 Anthropic Messages 协议 + 注入 claude-code User-Agent** | | `hermes_cli/main.py` `_model_flow_kimi()` | setup 向导:写 `model.provider/base_url/default`,清空 `KIMI_BASE_URL` override | **关键坑**:Kimi `/coding` 端点的 OpenAI 路径 `/coding/v1/chat/completions` 返回 **403** `access_terminated_error`("only available for Coding Agents such as Kimi CLI, Claude Code, Roo Code…");只有 Anthropic 路径 `/coding/v1/messages` 通(200)。hermes 通过上面的 UA 伪装自动绕过,所以**必须走 kimi-coding provider(anthropic 协议),不能用 OpenAI 协议**。 ### 2.2 落地配置(等价于 `hermes model` 选 Kimi) **`~/.hermes/.env`**:只放 key,**不要**设 `KIMI_BASE_URL`,也别留 `ANTHROPIC_*`(否则 `provider: auto` 会误判): ``` KIMI_API_KEY=sk-kimi-XXXXXXXX... ``` > 用 `cat /sdcard/x >> .env`(root 追加不改属主)或 `su -c 'sed ...'`(Termux 用户改,保属主)避免把 key 写进命令行/ps。 **`~/.hermes/config.yaml`**(用 CLI 设,非交互): ```bash hermes config set model.provider kimi-coding hermes config set model.base_url https://api.kimi.com/coding hermes config set model.default kimi-for-coding ``` 可用模型:`kimi-k2.6 / kimi-k2.5 / kimi-for-coding / kimi-k2-thinking / kimi-k2-thinking-turbo`。 ### 2.3 验证 ```bash # -z/--oneshot = 一次性 prompt,免 TTY hermes -z "用中文只回答一个数字: 1+1=?" # → 2 ``` 裸 `hermes`(不带 `-m/--provider`)直接走 Kimi 即配置成功。 ### 2.4 排错速查 | 现象 | 原因 / 处理 | |---|---| | `HTTP 404 resource not found` | base_url 漏了协议路径或用了 `provider=anthropic`+错 base;改用 `kimi-coding` + `https://api.kimi.com/coding` | | `HTTP 403 access_terminated_error` | 走了 OpenAI `/chat/completions` 路径;必须 kimi-coding(anthropic 协议,hermes 自动加 claude-code UA) | | `no final response was produced` | config 残留错的 `model.base_url`(如 openrouter)或 provider 不对;按 2.2 重设三项 | | `curl: Could not resolve host` | `su` 切 uid 时漏了 `-G 3003`(inet 组) | | `APIConnectionError / Connection error`(api_server 返回 200 但内容报错) | 出口被掐:VPN(ClashMeta) 死节点把 TCP 全断,或 WiFi 没真连上(`UnderlyingNetworks: []`)。停 VPN / 修网即恢复 | --- ## 3. 作为 lifelog 纪要后端:开 api_server + 省 token + 自启 hermes gateway 内建一个 OpenAI 兼容的 **api_server**,lifelog 的 SummaryWorker 用它跑纪要 (`POST http://127.0.0.1:8642/v1/chat/completions`)。2026-06-04 实测打通。 ### 3.1 开 api_server `~/.hermes/.env` 追加(`API_SERVER_KEY` **必须**等于 lifelog `keys.properties` 的 `hermes.apiKey`): ``` API_SERVER_ENABLED=true API_SERVER_HOST=127.0.0.1 API_SERVER_PORT=8642 API_SERVER_KEY=<与 lifelog hermes.apiKey 一致> API_SERVER_MODEL_NAME=kimi-for-coding ``` 启动:`hermes gateway run`(前台);常驻用 `~/start_gw.sh`(`setsid hermes gateway run` + disown, 先 `set -a; . ~/.hermes/.env; set +a`)。监听后日志:`[Api_Server] API server listening on http://127.0.0.1:8642`。 ### 3.2 ⚠️ 必做:精简 token(12,500 → 399) api_server 默认走**完整 agent**:每请求注入 tools(37.8KB/17工具) + skills index(9.1KB) ≈ **12,500 token**, 纯总结根本用不上。只对 api_server 关掉(不影响 CLI / 微信 bot): ```yaml # ~/.hermes/config.yaml platform_toolsets: api_server: [] skills: platform_disabled: api_server: [<~/.hermes/skills 下所有 skill 名>] ``` > 用 hermes 的 `load_config`/`save_config` 改最稳(保留其余配置)。源码依据:`gateway/platforms/api_server.py` > 的 `enabled_toolsets = _get_platform_tools(config, "api_server")`;skills 走 `skills.platform_disabled`。 > 改完重启 gateway,实测 **prompt 399 token**。 ### 3.3 开机自启(Magisk service.d) Termux:Boot 未装;已 root → 用 `/data/adb/service.d/start-hermes-gw.sh`(root, 755): ```sh #!/system/bin/sh LOG=/data/adb/hermes-boot.log { echo "=== $(date) ===" i=0; while [ "$(getprop sys.boot_completed)" != "1" ] && [ "$i" -lt 60 ]; do sleep 3; i=$((i+1)); done sleep 25 T=/data/data/com.termux; GW=$T/files/home/start_gw.sh; [ -f "$GW" ] || exit 0 SU=$(command -v su); [ -x "$SU" ] || for p in /system_ext/bin/su /system/bin/su /debug_ramdisk/su; do [ -x "$p" ] && SU=$p && break; done U=$(stat -c %u "$T"); L=$((U-10000)) "$SU" -g "$U" -G 3003 -G 9997 -G "20$L" -G "50$L" "$U" -c "/data/data/com.termux/files/usr/bin/bash $GW" } >> "$LOG" 2>&1 ``` **坑**:这台机 Magisk 的 su 在 **`/system_ext/bin/su`**(`/system/bin/su` 不存在)→ 必须 `command -v su` 动态解析。 uid 动态推导(Termux 重装会变)。gateway 以 Termux 用户跑(保属主),冷启动慢 ~3–5 分钟(连被墙 metadata 超时)。 ### 3.4 验证端到端 - 直打:`hermes` venv python POST `/v1/chat/completions`(Bearer=API_SERVER_KEY, model=kimi-for-coding)→ 200 + 纪要。 - 整链:lifelog 纪要 tab「现在跑一次」(需最近 1h ≥60s 语音)→ logcat `SummaryWorker: summary saved` → 纪要入库。 - **坑**:api_server 收到请求会回 200,但若上游连不上(VPN/断网)正文是 `API call failed ... Connection error`——查 `~/.hermes/logs/gateway.log`。 --- ## 附:一次性自检脚本 ```bash adb shell 'su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c " export PREFIX=/data/data/com.termux/files/usr HOME=/data/data/com.termux/files/home export PATH=\$PREFIX/bin:\$PATH LD_LIBRARY_PATH=\$PREFIX/lib TMPDIR=\$PREFIX/tmp hermes --version hermes config show | grep -iE \"provider|default|base_url\" hermes -z \"ping, reply PONG\" "' ```