DeepAI Paper Hermes Agent 教程 Hermes zsh 补全报 _arguments: invalid argument:短选项和长选项不能这样写

Hermes zsh 补全报 _arguments: invalid argument:短选项和长选项不能这样写

命令行补全通常不会影响核心业务逻辑,但它会直接影响开发者每天的使用体验。尤其是 Zsh 用户,如果补全脚本语法错误,按 Tab 时不仅没有提示,还会抛出一串 _arguments 错误。

NousResearch/hermes-agent issue `#22686` 记录了一个具体问题:hermes completion zsh 生成的 Zsh completion script 中 _arguments 写法不符合 Zsh 语法,导致补全脚本被拒绝。

错误信息是:

_arguments:comparguments:327: invalid argument: (-h --help){-h,--help}[Show help and exit]

这类问题看起来小,但搜索价值很明确:zsh _arguments invalid argument(-h --help){-h,--help}hermes completion zsh,都是用户真实会复制搜索的错误片段。


复现:生成 zsh completion 后语法不合法

触发路径很直接:

hermes completion zsh

生成的脚本里有类似内容:

_arguments -C \
  '(-h --help){-h,--help}[Show help and exit]' \
  '(-V --version){-V,--version}[Show version and exit]' \
  '(-p --profile){-p,--profile}[Profile name]:profile:_hermes_profiles' \
  '1:command:->commands' \
  '*::arg:->args'

问题集中在这几段:

'(-h --help){-h,--help}[Show help and exit]'
'(-V --version){-V,--version}[Show version and exit]'
'(-p --profile){-p,--profile}[Profile name]:profile:_hermes_profiles'

Zsh 的 _arguments 解析器看到 (-h --help) 后会报 invalid argument。


根因:() exclusion group 不能这样放长选项

在 Zsh completion 语法中,_arguments 的 option spec 可以包含 exclusion group,用来表示互斥关系。

但 issue 指出,像下面这种写法不合法:

(-h --help)

原因有两个:

1. group 中不应该混入 --help 这类长选项; 2. -h --help 中间有空格,整体被 _arguments 当成无效 spec。

换句话说,{-h,--help} 可以用来描述短/长选项形式,但前面的 exclusion group 不是同一回事。

这两个部分不能简单拼成:

'(-h --help){-h,--help}[...]'

修正:用 (-) 或只放合法短选项

issue 中给出的目标写法是:

'(-)'{-h,--help}'[Show help and exit]'

对应替换包括:

- '(-h --help){-h,--help}[Show help and exit]'
+ '(-)'{-h,--help}'[Show help and exit]'
- '(-V --version){-V,--version}[Show version and exit]'
+ '(-)'{-V,--version}'[Show version and exit]'
- '(-p --profile){-p,--profile}[Profile name]:profile:_hermes_profiles'
+ '(-)'{-p,--profile}'[Profile name]:profile:_hermes_profiles'

后续评论中的 draft PR `#22728` 又补充了更细一点的修正:

help/version 使用 (-)
profile 使用 (-p)

并且生成结果通过:

zsh -n

验证没有语法错误。


为什么 zsh -n 很适合做回归测试?

补全脚本的 bug 很容易被忽略,因为它不一定出现在普通单元测试里。

对 Zsh completion generator 来说,至少应该做两层检查:

hermes completion zsh > /tmp/_hermes
zsh -n /tmp/_hermes

这能捕获明显语法错误。

如果要进一步验证交互效果,还可以在测试 shell 中加载:

fpath=(/tmp $fpath)
autoload -Uz compinit
compinit
compdef _hermes hermes

但对 CI 来说,zsh -n 已经能防止 _arguments spec 写坏后直接发布。


为什么 CLI completion bug 也值得修?

补全脚本不像 gateway、model adapter、tool execution 那样“核心”,但它影响的是第一层开发体验。

Zsh 用户安装 Hermes 后,通常会期待:

hermes <TAB>
hermes gateway <TAB>
hermes config <TAB>
hermes completion <TAB>

如果每次按 Tab 都看到:

_arguments:comparguments:327: invalid argument

用户很容易误以为整个 CLI 安装坏了。

对开发者工具来说,completion 是“信任感入口”。小错误会放大成对项目成熟度的怀疑。


排查清单:遇到 _arguments: invalid argument 先看什么?

如果你遇到类似错误,可以按这个顺序查。

1. 直接生成补全脚本

hermes completion zsh > /tmp/_hermes

2. 用 zsh -n 验证语法

zsh -n /tmp/_hermes

如果这里报错,说明不是你的 .zshrc 问题,而是补全脚本本身语法有问题。

3. 搜索 _arguments

grep "_arguments" -n /tmp/_hermes

重点看是否存在:

(-h --help)
(-V --version)
(-p --profile)

4. 检查短/长选项写法

短/长形式可以写成:

{-h,--help}

但 exclusion group 不应写成:

(-h --help)

5. 更新 Hermes 或套用修复后的生成器

如果上游已修复,优先更新到包含修复的版本。不要长期手改生成出来的 _hermes 文件,因为下一次生成会覆盖。


外链与进一步阅读

站内相关分析:


与 DeepAI API 中转站的关系:CLI 体验和模型路由是两条线

很多用户会把 Hermes、Cline、Cherry Studio、Dify、Open WebUI 这类工具接到 DeepAI API 中转站,统一管理 Base URL、API Key、模型路由和 OpenAI-compatible 调用。

但 CLI completion 属于本地命令行体验层:

shell → completion script → hermes command layout

而模型 API 层关注的是:

Base URL → API Key → model id → streaming/tool calling/usage/context length

两条线可以同时优化:模型入口统一,CLI 补全也要稳定。对开发者工具来说,API 能调通只是基础,命令行交互、补全、错误提示同样会影响日常效率。


FAQ

_arguments:comparguments:327: invalid argument 是什么意思?

表示 Zsh 的 _arguments 解析器遇到了不合法的 option spec。这里的问题是 (-h --help){-h,--help} 这类写法不符合 Zsh completion 语法。

为什么 {-h,--help} 可以,(-h --help) 不行?

{-h,--help} 是短/长选项形式展开;() 是 exclusion group。后者不应混入带空格的长选项组合。

我应该手动改 _hermes 文件吗?

临时可以,但不建议长期依赖。更好的方式是更新 Hermes,让 hermes completion zsh 生成正确脚本。

如何快速验证补全脚本有没有语法错误?

运行:

hermes completion zsh > /tmp/_hermes
zsh -n /tmp/_hermes

如果没有输出,说明至少语法层面通过。

这个问题会影响 Bash 或 Fish 补全吗?

issue 针对的是 Zsh _arguments 语法。Bash/Fish completion generator 是否受影响,需要分别检查生成结果。


总结

#22686 的核心很简单:

Hermes 的 zsh completion generator 把短选项和长选项错误地塞进 _arguments exclusion group,导致 Zsh 报 invalid argument。

正确方向是把:

'(-h --help){-h,--help}[Show help and exit]'

改为类似:

'(-)'{-h,--help}'[Show help and exit]'

并在 CI 或发布前用:

zsh -n

验证生成脚本。

CLI 补全不是边角料。它是用户每天触碰工具的入口,越是开发者工具,越应该把这类小而明确的体验问题修到位。

Related Post

Hermes agent deepai custom endpoint model lock.png

Hermes Agent 接入 DeepAI API 中转站:自定义端点多模型被锁定怎么排查Hermes Agent 接入 DeepAI API 中转站:自定义端点多模型被锁定怎么排查

Hermes Agent 使用自定义 OpenAI-compatible 端点接入多模型 API 中转站时,如果 hermes model 总是锁定第一次选择的模型,根因可能是 custom_providers[].model 已保存导致提前返回,不再探测 /v1/models。本文结合 Hermes Agent Issue #6862,整理 DeepAI API 中转站多模型路由场景下的排查和修复思路。

Hermes Provider 兼容性排错:reasoning_content、custom headers、上下文长度和 api_mode 继承Hermes Provider 兼容性排错:reasoning_content、custom headers、上下文长度和 api_mode 继承

OpenAI-compatible 不等于 provider 细节完全一致。本文基于 Hermes Issues 解析 reasoning_content 400、Custom Provider headers 403、上下文长度误判、delegate api_mode 继承等兼容性问题,并说明 DeepAI 接 Hermes 时该如何分层测试。

Hermes 热门 Issue #7237:Response truncated due to output length limit 怎么排查?Hermes 热门 Issue #7237:Response truncated due to output length limit 怎么排查?

Hermes 热门已关闭 Issue #7237 复盘:Response truncated due to output length limit、finish_reason=length、Truncated tool call 到底是 Hermes bug、模型输出限制,还是上下文太满?