HERMES_AGENT_PIXEL_SETUP.md 11 KB

在 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 "<cmd>" 其中 3003=inet 9997=everybody 20<low3>=cache 50<low3>=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 退出。先升级再装:

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 脱离运行:

#!/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) ==="
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 </dev/null & echo pid \$!'"
# 轮询:grep 'HERMES INSTALL END rc=0' $LOG

--non-interactive 跳过 setup 向导(无 TTY 也能跑)。

1.3 ⚠️ 必做:修 wrapper shebang

installer 生成的 $PREFIX/bin/hermes 首行是 #!/usr/bin/env bash。Termux 没 /usr/bin/env,交互会话靠 termux-exec 动态改写,但用 su -c 驱动(无 termux-exec)会报 No such file or directory(指解释器)。改成绝对路径(以 Termux 用户改,保留属主):

adb shell "su 10302 -c 'sed -i \"1s|#!/usr/bin/env bash|#!/data/data/com.termux/files/usr/bin/bash|\" /data/data/com.termux/files/usr/bin/hermes'"

注意:hermes update 会重新生成 wrapper、把 shebang 改回 /usr/bin/env,每次更新后需重修。 venv/bin/hermes 的 shebang 是绝对 venv python,本就没问题,可用它绕过 wrapper 验证。

1.4 验证

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 <uid> -c 'sed ...'(Termux 用户改,保属主)避免把 key 写进命令行/ps。

~/.hermes/config.yaml(用 CLI 设,非交互):

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 验证

# -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):

# ~/.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):

#!/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。

附:一次性自检脚本

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\"
"'