日期: 2026-05-17
作者: toy
最近一次远端节点升级让我意识到一件事——OAuth 在 SSH 远端场景下其实有一套可复用的范式。过去每次撞到都靠现场拼凑,这一次顺着 Hermes Agent 升级 + 接入 xAI Grok 走了一遍,把它写成步骤了。
这篇是写给 AI agent 看的部署 SOP。我希望读完它的 agent,能在另一台远端节点上独立完成同样的接入,不需要再来问我。
xAI 在 2026-05-15 上线了 Grok 与 Hermes 的 OAuth 集成。一套 OAuth 凭证,覆盖四类能力:聊天、推特实时搜索、图像生成、视频生成。SuperGrok 订阅者不需要单独申请 API Key。
下面按顺序走。
前置条件
agent 执行前,自查这三项:
- 能 ssh 进目标远端节点,且远端已经装有 hermes-agent(版本不限,下面会升级)。
- 本机能开 SSH 本地端口转发(普通用户权限即可)。
- SuperGrok 账号已经登录过浏览器,OAuth 授权页能直接确认。
第一步:升级 Hermes Agent
hermes 自带升级器,自带 pre-update 快照和依赖同步。不要手工 git pull。
ssh <node> 'hermes update'
升级器会做:备份当前版本、清 __pycache__、同步 Python 与 Node 依赖、重建 web UI、增量更新 bundled skills(用户改过的会保留)、drain gateway 最多 195 秒后自动重启。
确认结果:
ssh <node> 'hermes --version'
# 期望看到 v0.14.0 或更新
第二步:接入 xAI OAuth
v0.14.0 把旧的 hermes login 替换成 hermes auth 子命令族。OAuth 类型选 oauth(PKCE + loopback callback),不是 device code。
hermes auth {add,list,remove,reset,status,logout}
远端执行 hermes auth add 时有两个麻烦事:一是远端没有 TTY,hermes 在非交互终端下会跳过引导;二是 loopback 回调监听在远端 127.0.0.1,本地浏览器够不着。
在远端拿到授权 URL
用 script(1) 强制分配 PTY,setsid 脱离 SSH 会话,输出落日志再读出来:
ssh <node> '
rm -f /tmp/xai-oauth.log
setsid script -q -f -c "hermes auth add xai-oauth --type oauth --no-browser" \
/tmp/xai-oauth.log </dev/null >/dev/null 2>&1 &
sleep 6
cat /tmp/xai-oauth.log
'
日志里会有两条关键信息:授权 URL(带 state 参数)和 loopback 监听端口(随机端口,每次不同,下面用 <PORT> 代指)。
把远端端口拽到本机
ssh -N -L <PORT>:127.0.0.1:<PORT> <node>
让这个 ssh 留着不要退出。本机打开授权 URL,在 SuperGrok 账号下点确认。
理想情况:浏览器跳回 http://127.0.0.1:<PORT>/callback?...,hermes 收到 code 自动换 token,落库完成。
当 loopback 探测失败时:curl 兜底
跨大洋链路上 RTT 容易撞 xAI 的 loopback 探测超时。浏览器侧会显示 "We couldn't reach your app",但同时会给一段 fallback authorization code。
不要慌。hermes 那边的监听器还在跑,自己拼回调 URL 灌进去就行:
curl -sS -o /dev/null -w "HTTP %{http_code}\n" \
"http://127.0.0.1:<PORT>/callback?code=<CODE>&state=<STATE>"
# 期望 HTTP 200
state 从一开始那个授权 URL 里抠出来(PKCE 防 CSRF,必须严格一致)。看到下面这两行就是成功了:
Added xai-oauth OAuth credential #1: "xai-oauth-oauth-1"
xai-oauth: logged in
第三步:列出真实模型清单
不要凭记忆填 model ID。每个 provider 接入前先 list 一次。
ssh <node> 'TOKEN=$(python3 -c "import json;
d=json.load(open(\"/root/.hermes/auth.json\"));
print(d[\"credential_pool\"][\"xai-oauth\"][0][\"access_token\"])");
curl -sS https://api.x.ai/v1/models -H "Authorization: Bearer $TOKEN" |
python3 -c "import json,sys;
[print(m[\"id\"]) for m in json.load(sys.stdin)[\"data\"]]"'
注意 auth.json 的结构是 credential_pool[<provider>][0]["access_token"],不是 providers[<provider>](后者是预留空对象)。
当前 (2026-05) 应该看到这些:
grok-4.20-0309-non-reasoning
grok-4.20-0309-reasoning
grok-4.20-multi-agent-0309
grok-4.3 ← 当前旗舰
grok-imagine-image ← 图,快
grok-imagine-image-quality ← 图,慢但质量高
grok-imagine-video ← 视频
下面的配置基于这份清单。如果 xAI 改了 ID,以 list 输出为准。
第四步:配置模型与工具
四类能力一次配齐。
# 默认聊天模型
hermes config set model.default grok-4.3
hermes config set model.provider xai-oauth
# 推特实时搜索(三平台分别启用)
hermes tools enable x_search --platform cli
hermes tools enable x_search --platform telegram
hermes tools enable x_search --platform discord
# 图像生成
hermes config set image_gen.provider xai
hermes config set image_gen.xai.model grok-imagine-image-quality
# 视频生成(插件默认未启用,需要先 enable)
hermes plugins enable video_gen/xai
hermes tools enable video_gen --platform cli
hermes tools enable video_gen --platform telegram
hermes tools enable video_gen --platform discord
hermes config set video_gen.provider xai
hermes config set video_gen.xai.model grok-imagine-video
两个配置选型说明:
- image_gen 选 quality 不选 fast。图像生成本来就低频高价值,慢几秒换显著质量提升是好交易。如果业务侧抱怨延迟,一行 config 切回
grok-imagine-image。 - x_search 不动 model。它默认用
grok-4.20-reasoning,这是 xAI 专门为工具调用 + 长思考链调优的版本,不要改。
最终 ~/.hermes/config.yaml 关键段应该是这样:
model:
default: grok-4.3
provider: xai-oauth
x_search:
model: grok-4.20-reasoning
timeout_seconds: 180
retries: 2
image_gen:
provider: xai
xai:
model: grok-imagine-image-quality
video_gen:
provider: xai
xai:
model: grok-imagine-video
plugins:
enabled:
- image_gen/xai
- video_gen/xai
第五步:重启并验活
升级后必须重启一次 gateway,原因下一节会讲。
ssh <node> 'systemctl restart hermes-gateway'
# 等 drain 完成,约 3 分钟
最简单的验活:
ssh <node> 'hermes -z "用一句话告诉我你的模型版本号"'
# 我的模型版本号是 grok-4.3。
到这里聊天通路就通了。image_gen / video_gen / x_search 各跑一次真实请求确认端到端。
已知坑(重要)
下面三个坑都是这次踩过的,agent 部署完务必照表自检。
1. 升级后第一条消息会被吞
v0.14.0 首次启动会弹一次性提示,问"以后 /clear /reset /undo 要不要每次都确认"。如果 Telegram / Discord 用户在这之后第一时间发消息,这条消息会被当成对提示的回答(解读为 opted out),并触发一次 session_reset。结果就是:模型其实算出了 35 字符的回复,但被新 generation 标记为 stale,丢掉。
外部表现:发消息没回应,看似集成失败。
预防做法:升级后先 systemctl restart hermes-gateway(强制把一次性提示落库),再让 agent 自己发一条无关紧要的探活消息确认通路,再让真实用户发消息。
排查关键字(日志里出现就是这个坑):User opted out、session_reset、Discarding stale agent result。
2. 跨大洋 loopback 大概率失败
xAI 那边的 loopback 探测有较紧的超时,跨太平洋 200ms+ RTT 容易撞线。表现是浏览器报 "We couldn't reach your app",但远端 hermes 的监听器其实是活的。
按第二步里 curl 兜底处理即可。这条不是 bug,是 xAI 的设计取舍。
3. hermes login 已彻底废弃
如果远端 hermes 版本特别老的脚本里还在调 hermes login,会直接报错 "The 'hermes login' command has been removed."。换成 hermes auth add。
操作可逆性
这次涉及的所有操作都可回滚,agent 可以放心执行:
操作
回滚方式
hermes update
自动生成的 pre-update snapshot 可恢复
hermes auth add
hermes auth remove <name>
hermes config set <key>
重新 set 回旧值
hermes plugins enable / tools enable
对应 disable
systemctl restart hermes-gateway
drain 期间用户被通知,3 分钟内恢复
部署完后建议把 hermes auth list 和 hermes config list 的输出存档,方便下次对照。
收尾
整套流程跑下来,单台节点接入耗时大约 15 分钟(不含 OAuth loopback 探测失败时人工 curl 那 2 分钟)。一份 OAuth 凭证撑起四种能力,是这次升级最值得复制的地方。
如果你是 AI agent,照着上面跑就行。如果遇到不在已知坑里的现象,先 grep 远端日志看有没有 session_reset / stale / opted out,再决定要不要回滚到 pre-update snapshot。
script + setsid + ssh -L 这套组合,下次再遇到任何远端 OAuth 场景都能照搬,不只是 xAI。