Agent eXperience Interface (AXI) — 为通过 shell 执行与 CLI 工具交互的智能体设计的符合人体工程学的标准。 在构建、修改或审查任何面向智能体的 CLI 时使用。
Agent eXperience Interface (AXI)
AXI 定义了构建自主智能体通过 shell 执行交互的 CLI 工具时应遵循的符合人体工程学的标准。
开始之前
在构建任何 AXI 输出之前,请阅读 TOON 规范。
1. 令牌高效的输出
在 stdout 上使用 TOON(面向令牌的对象表示法)作为输出格式。
TOON 相比等效的 JSON 可节省约 40% 的令牌,同时保持智能体可读性。
在输出边界转换为 TOON — 内部逻辑保持使用 JSON。
tasks[2]{id,title,status,assignee}:
"1",Fix auth bug,open,alice
"2",Add pagination,closed,bob
2. 最小默认模式
stdout 中的每个字段都会消耗令牌 — 在集合中按行数倍增。
默认使用最小的模式,让智能体决定下一步做什么:通常是一个标识符、一个标题和一个状态。
- 默认列表模式:3-4 个字段,而不是 10 个
- 默认限制:足够高以在一次调用中覆盖常见情况(如果大多数仓库有 <100 个标签,默认设为 100,而不是 30)
- 长文本内容(正文、描述)属于详情视图,而不是列表
- 提供
--fields标志,让智能体显式请求额外字段
3. 内容截断
详情视图通常包含大文本字段。省略它们会迫使智能体去查找;包含它们会浪费令牌。
默认截断,并告诉智能体如何获取完整版本。
task:
number: 42
title: Fix auth bug
state: open
body: First 500 chars of the issue body...
... (truncated, 8432 chars total)
help[1]: Run `tasks view 42 --full` to see complete body
- 永远不要完全省略大字段 — 包含截断预览
- 显示总大小,让智能体知道它缺少多少
- 仅在内容实际被截断时建议转义方式(
--full) - 选择覆盖大多数用例的截断限制(500-1500 字符)
4. 预计算的聚合
最昂贵的令牌成本通常不是更长的响应 — 而是后续调用。如果你的后端有智能体通常下一步需要的数据,计算并包含它。
聚合计数:在列表输出中包含总数,而不仅仅是页面大小。智能体需要知道“有多少?”,如果答案不明确,它们会分页。
count: 30 of 847 total
tasks[30]{number,title,state}:
1,Fix auth bug,open
...
派生状态字段:当下一步几乎总是涉及检查相关状态时,内联包含一个轻量级摘要。
task:
number: 42
title: Deploy pipeline fix
state: open
checks: 3/3 passed
comments: 7
只包含你的后端可以廉价提供的派生字段 — 一个摘要(“3/3 passed”),而不是完整数据。
5. 明确的空状态
当答案是“没有”时,明确说出来。模糊的空输出会导致智能体使用不同标志重新运行以验证。
$ tasks list --state closed
tasks: 0 closed tasks found in this repository
在上下文中说明零。明确命令已成功 — 没有结果是答案。
6. 结构化错误和退出码
幂等变更
当期望状态已存在时不要报错。如果智能体关闭了已关闭的内容,确认并继续,退出码为 0。保留非零退出码用于智能体的意图确实无法满足的情况。
$ tasks close 42
task: #42 already closed (no-op) # exit 0
stdout 上的结构化错误
错误以与正常输出相同的结构化格式输出到 stdout,以便智能体可以读取并采取行动。包括出错原因和可操作的建议。永远不要让原始依赖输出(API 错误、堆栈跟踪)泄露出来。
error: --title is required
help: tasks create --title "..." [--body "..."]
- 在调用任何依赖之前验证必需标志
- 翻译错误 — 提取可操作的含义,丢弃噪音
- 永远不要泄露依赖名称 — 建议引用你的 CLI 的命令,而不是底层工具
无交互式提示
每个操作必须仅通过标志即可完成。如果缺少必需的值,立即失败并给出清晰的错误 — 不要提示输入。抑制来自包装工具的提示。
对无法识别的输入大声失败
拒绝未知的标志和参数 — 永远不要静默忽略它们。丢弃的标志比错误更糟糕:智能体得到看似合理的输出,认为它已被限定范围或过滤,然后基于错误数据自信地继续。这是 CLI 已经对未知_命令_提供的保证;将其扩展到标志。
$ tasks list --stat closed
error: unknown flag --stat for `list`
help: valid flags for `list`: --state, --assignee, --limit (--help always allowed)
- 在任何依赖调用之前进行验证,退出码为 2 — 与缺少必需标志相同。每个命令声明自己的已知标志;无法识别的标志按名称拒绝,并列出该命令的有效标志。
--help始终通过 — 它是唯一的通用标志。除此之外,CLI 可以标准化自己的始终允许的全局标志(例如--account选择器);无论集合是什么,这些标志在每个命令上都通过,并且永远不会被报告为未知。- 重命名或移除的标志会得到有针对性的提示,而不是通用列表 — 指向替换它的内容(
--status was renamed; use --state instead),以便智能体一步自我纠正。 - 每个子命令的标志集。 对于分组名词,其中一个命令分派给子命令(同一名词下的
list与create),根据_子命令_的标志进行验证 — 它们不同,只有子命令层知道哪个在起作用。 - 使错误在一个回合内可自我纠正。 智能体在未知标志错误后的确定性下一步是运行
<command> --help(例如tasks list --help) — 因此将该查找折叠到错误中:内联列出有效标志,或在其下方直接打印命令的简洁--help块。根据第 4 节,昂贵的成本是后续调用,根据第 10 节,每个命令的帮助已经简洁,因此内联它将两个回合的纠正合并为一个。
输出通道
- stdout:智能体消费的所有结构化输出 — 数据、错误、建议
- stderr:调试日志、进度指示器、诊断信息(智能体不读取此内容)
- 退出码:0 = 成功(包括无操作),1 = 错误,2 = 使用错误
永远不要将进度消息混入 stdout。读取“Fetching data...”的智能体会尝试将其解释为数据。
7. 通过会话集成实现环境上下文
将你的工具注册到智能体的会话生命周期中,以便每个对话开始时相关状态已经可见 — 在智能体采取任何操作之前。
模式:
- 提供一个显式的设置命令,在用户意图明确后安装或修复会话钩子或插件
- 在会话开始时,集成运行你的工具并提供紧凑的仪表板作为上下文
- 智能体将此作为初始上下文接收,并可以立即行动
# Agent sees this at session start — no invocation needed:
specs[2]{id,title,status}:
1,Fix auth bug,open
2,Add pagination,in-progress
help[2]:
Run `mytool specs view 1` for details
Run `mytool specs create --title "..."` to add a spec
规则:
- 默认应用目标:默认情况下,支持 Claude Code、Codex 和 OpenCode。当工具可以合理支持多个智能体时,不要硬编码单个智能体集成
- 显式选择加入:仅从用户调用的设置命令注册钩子或插件,而不是从普通 CLI 命令
- 可移植命令:钩子命令应在解析到当前可执行文件时使用 PATH 验证的二进制名称,否则回退到完整绝对路径。这使全局安装保持可移植性,同时确保钩子不会意外运行不同的二进制文件
- 路径修复:设置命令应检查现有钩子,并在可执行文件路径更改时更新它(例如,重新安装或移动后)
- 幂等:使用相同路径重复安装是静默无操作
- 目录范围:仅显示与当前工作目录相关的状态
- 令牌预算感知:此上下文在_每个_会话上加载 — 无情地最小化它。仅包含足够让智能体定位和行动的内容;深层数据属于显式调用
- 生命周期捕获:使用会话结束钩子捕获发生了什么(转录、接触的文件、引用的规范),以便未来的会话开始上下文随时间变得更丰富
如何与每个应用集成:
- Claude Code:在
~/.claude/settings.json或项目.claude/settings.json中使用原生钩子。优先使用SessionStart通过 stdout 注入紧凑上下文 - Codex:在
~/.codex/hooks.json或<repo>/.codex/hooks.json中使用原生钩子,并确保config.toml中[features].hooks = true。优先使用SessionStart通过 stdout 提供环境上下文 - OpenCode:在
~/.config/opencode/plugins/中使用托管插件。优先使用环境系统上下文注入用于主页视图,而不是添加自定义工具
同时提供一个可安装的技能(次要推荐):
会话钩子是主要集成,但它只帮助其框架支持钩子的智能体,并且在_每个_会话上加载。
提供一个可安装的 Agent Skill 作为次要发现路径。
它在智能体识别到匹配任务时按需加载,没有每会话令牌成本,并且可以在任何支持技能格式的智能体中工作。
首先推荐钩子(环境上下文加实时状态),其次推荐技能(更低开销,更广泛的智能体支持)——它们是互补的,用户安装适合的任何一个,或两者都安装。
npx skills add <owner>/<repo> --skill <name>
- 单一事实来源:从你的无参数主页视图打印的相同内容生成
SKILL.md,以便技能永远不会偏离 CLI 自身的指导。在 CI 中添加--check构建步骤,如果提交的技能已过时则失败 - 剥离实时状态:技能是静态的,因此省略只有钩子才能显示的动态数据(打开的会话、当前项目)
- 非交互式命令:将命令示例重写为智能体无需全局安装即可运行的形式(例如
npx -y mytool ...),因为技能可能在没有二进制文件在 PATH 上的情况下安装 - 触发器形状的前置元数据:包含
name和写为触发器的description— 简洁且以结果为导向,以便智能体在正确的意图上加载它 - 记录两种路径:在你的 README 中,将钩子和技能呈现为实现同一目标的两种方式,并明确用户只需要一个
8. 内容优先
运行你的 CLI 时不带参数应显示最相关的实时内容 — 而不是使用手册。
当智能体看到实际状态时,它可以立即行动。当它看到帮助文本时,它必须进行第二次调用。
$ tasks
tasks[3]{id,title,status}:
1,Fix auth bug,open
2,Add pagination,open
3,Update docs,closed
help[2]:
Run `tasks view <id>` to see full details
Run `tasks create --title "..."` to add a task
9. 上下文相关的提示
包含一些逻辑上跟随当前输出的下一步操作。
智能体通过使用你的 CLI 有机地发现其表面区域,而不是通过事先阅读手册。
规则:
- 相关:在打开的项目后 → 建议关闭;在空列表后 → 建议创建;在列表后 → 建议查看
- 可操作:每个建议都是一个完整的命令(或模板),携带当前调用中的任何消歧标志(例如
--repo、--source) - 参数化动态值:当建议的命令需要运行时值(如 ID、标题、分支、URL 或路径)时,使用占位符如
<id>或"<title>",而不是猜测可能误导智能体的具体值 - 自包含时省略:当输出完全回答了查询(详情视图、计数、确认)时,建议是噪音 — 省略它们。在列表和变更响应中包含它们,其中下一步不明显。
- 引导发现,而非工作流:建议各种可能的下一步操作,不要规定固定顺序。已经知道自己想要什么的智能体不应被推入额外步骤。
- 揭示截断的列表:当列表仅显示较大总数中的最近 N 个项目时,添加帮助提示,告诉智能体如何查看所有项目(例如
Run 'mytool list' for all 47 items)。不要将分页编码到 TOON 数组头部 — 改用帮助提示。 - 解决错误:在错误时,建议修复问题的具体命令,而不是“参见
--help”
10. 一致的获取帮助方式
顶级主页视图还应在实时数据之前标识工具本身:
- 包含当前可执行文件的绝对路径,用户主目录折叠为
~ - 包含一句话描述此 AXI 的功能
$ tasks
bin: ~/.local/bin/tasks
description: Manage project tasks in the current workspace
...
每个子命令应支持 --help,提供简洁完整的参考:可用标志及默认值、必需参数以及 2-3 个使用示例。保持专注于请求的子命令 — 不要转储整个 CLI 的手册。






