Axe 声称用 12MB 二进制文件替代庞大的 AI 框架,对性能敏感、部署受限的场景有潜在价值。
用于管理和运行 LLM 驱动的 agent 的 CLI 工具。
大多数 AI 工具假设你想要一个聊天机器人。一个长期运行的会话,拥有庞大的上下文窗口,可以一次完成所有事情。但好的软件不是这样工作的。好的软件是小的、专注的、可组合的。
Axe 像对待 Unix 程序一样对待 LLM agent。每个 agent 都做一件事做得很好。你在 TOML 文件中定义它,给它一个专注的技能,然后从命令行运行它。输入数据,得到结果。将 agent 链接在一起。从 cron、git hooks 或 CI 触发它们。使用你已经有的任何东西。没有守护程序、没有 GUI、没有需要购买的框架。只是一个二进制文件和你的配置。
Axe 编排通过 TOML 配置文件定义的 LLM 驱动的 agent。每个 agent 都有自己的系统提示、模型选择、技能文件、上下文文件、工作目录、持久化内存以及委派给子 agent 的能力。
Axe 是执行器,而不是调度器。它设计为与标准 Unix 工具组合使用——cron、git hooks、pipes、文件监视器——而不是重新发明调度或工作流编排。
多提供商支持——Anthropic、OpenAI、Ollama(本地模型)、OpenCode 和 AWS Bedrock
基于 TOML 的 agent 配置——声明式、可版本控制的 agent 定义
子 agent 委派——agent 可以通过 LLM 工具使用调用其他 agent,支持深度限制和并行执行
持久化内存——带时间戳的 markdown 日志,在运行之间传递上下文
内存垃圾回收——LLM 辅助的模式分析和修剪
技能系统——可在 agent 间共享的可复用指令集
Stdin 管道——直接将任何输出管道到 agent 中(git diff | axe run reviewer)
本地 agent 目录——从 <cwd>/axe/agents/ 自动发现 agent,或使用 --agents-dir 指向任何位置
试运行模式——检查已解决的上下文而不调用 LLM
JSON 输出——具有用于脚本编写的元数据的结构化输出
内置工具——文件操作(读、写、编辑、列表)沙箱限制在工作目录;shell 命令执行;URL 获取;web 搜索
输出白名单——限制 url_fetch 和 web_search 到特定的主机名;私有/保留 IP 始终被阻止(SSRF 保护)
Token 预算——通过 [budget] 配置或 --max-tokens 标志为每个 agent 运行限制累积 token 使用
MCP 工具支持——通过 SSE 或可流式 HTTP 传输连接到外部 MCP 服务器以获取额外工具
可配置的重试——指数、线性或固定退避,用于处理临时提供商错误(429、5xx、超时)
最小化依赖——四个直接依赖(cobra、toml、mcp-go-sdk、x/net);所有 LLM 调用都使用标准库
预构建的二进制文件(不需要 Go)可用于 Linux、macOS 和 Windows,从 GitHub Releases 页面下载。
go install github.com/jrswab/axe@latest
如果这失败并显示无效的 go 版本,你的 Go 工具链版本低于 1.25。从 go.dev/dl 升级或下载预构建的二进制文件。
或从源代码构建:
git clone https://github.com/jrswab/axe.git
cd axe
go build .
初始化配置目录:
axe config init
这在 $XDG_CONFIG_HOME/axe/ 创建目录结构,包含一个示例技能和默认的 config.toml,用于存储提供商凭证。
创建新 agent 的脚手架:
axe agents init my-agent
编辑其配置:
axe agents edit my-agent
运行 agent:
axe run my-agent
从其他工具管道输入:
git diff --cached | axe run pr-reviewer
cat error.log | axe run log-analyzer
examples/ 目录包含即用的 agent,你可以复制到你的配置中并立即使用。包括代码审查器、提交消息生成器和文本摘要器——每个都有一个专注的 SKILL.md。
# Copy an example agent into your config
cp examples/code-reviewer/code-reviewer.toml "$(axe config path)/agents/"
cp -r examples/code-reviewer/skills/ "$(axe config path)/skills/"
# Set your API key and run
export ANTHROPIC_API_KEY="your-key-here"
git diff | axe run code-reviewer
有关完整的设置说明,请参阅 examples/README.md。
Axe 提供了一个 Docker 镜像,用于在隔离、强化的容器中运行 agent。
构建镜像:
docker build -t axe .
支持通过 buildx 的多架构构建(linux/amd64、linux/arm64):
docker buildx build --platform linux/amd64,linux/arm64 -t axe:latest .
挂载你的配置目录并传递 API 密钥作为环境变量:
docker run --rm \
-v ./my-config:/home/axe/.config/axe \
-e ANTHROPIC_API_KEY \
axe run my-agent
使用 -i 标志管道 stdin:
git diff | docker run --rm -i \
-v ./my-config:/home/axe/.config/axe \
-e ANTHROPIC_API_KEY \
axe run pr-reviewer
未挂载配置卷时,axe 退出代码 2(配置错误),因为没有 agent TOML 文件存在。
上面的示例挂载整个配置目录。如果你只需要运行一个具有一个技能的 agent,只需将这些文件挂载到容器内预期的 XDG 路径。未挂载配置卷时不需要 config.toml,API 密钥通过环境变量传递。
docker run --rm -i \
-e ANTHROPIC_API_KEY \
-v ./agents/reviewer.toml:/home/axe/.config/axe/agents/reviewer.toml:ro \
-v ./skills/code-review/:/home/axe/.config/axe/skills/code-review/:ro \
axe run reviewer
agent 的技能字段会自动针对容器内的 XDG 配置路径进行解析,因此不需要 --skill 标志。
要使用与 agent TOML 中声明的不同技能,使用 --skill 标志覆盖它。在这种情况下,你只需挂载替代技能——TOML 中声明的原始技能被完全忽略:
docker run --rm -i \
-e ANTHROPIC_API_KEY \
-v ./agents/reviewer.toml:/home/axe/.config/axe/agents/reviewer.toml:ro \
-v ./alt-review.md:/home/axe/alt-review.md:ro \
axe run reviewer --skill /home/axe/alt-review.md
如果 agent 声明了 sub_agents,所有引用的 agent TOML 及其技能也必须被挂载。
当挂载数据卷时,agent 内存在运行之间持久化:
docker run --rm \
-v ./my-config:/home/axe/.config/axe \
-v axe-data:/home/axe/.local/share/axe \
-e ANTHROPIC_API_KEY \
axe run my-agent
包含了一个 docker-compose.yml,用于在本地 Ollama 实例旁运行 axe。
仅云提供商(无 Ollama):
docker compose run --rm axe run my-agent
带 Ollama:
docker compose --profile ollama up -d ollama
docker compose --profile cli run --rm axe run my-agent
拉取一个 Ollama 模型:
docker compose --profile ollama exec ollama ollama pull llama3
注意:compose axe 服务声明 depends_on: ollama。Docker Compose 将在任何时候通过 compose 启动 axe 时尝试启动 Ollama 服务,即使对于仅云端运行也是如此。要在不使用 Ollama 的情况下进行仅云端使用,请直接使用 docker run 而不是 docker compose run。
如果 Ollama 直接在主机上运行(不通过 compose),使用以下方式指向它:
Linux: --add-host=host.docker.internal:host-gateway -e AXE_OLLAMA_BASE_URL=http://host.docker.internal:11434
macOS / Windows(Docker Desktop): -e AXE_OLLAMA_BASE_URL=http://host.docker.internal:11434
容器默认运行以下强化配置(通过 compose):
非 root 用户——UID 10001
只读根文件系统——可写位置是配置挂载、数据挂载和 /tmp/axe tmpfs
删除所有能力——cap_drop: ALL
禁止权限提升——no-new-privileges:true
这些设置不会限制出站网络访问。要隔离仅与本地 Ollama 实例通话的 agent,添加 --network=none 并将其手动连接到共享 Docker 网络。
配置是可读写的,因为 axe config init 和 axe agents init 会写入配置。如果你只运行 agent,挂载为 :ro。
发送给 LLM 的用户消息按此顺序解析:
-p / --prompt 标志——如果提供了非空、非空白值,则用作用户消息。
管道化 stdin——如果 -p 不存在或为空/仅空白,则使用管道化 stdin。
内置默认值——如果 -p 或 stdin 都不提供内容,则使用默认消息"Execute the task described in your instructions."。
当 -p 与管道化 stdin 一起提供时,管道化 stdin 将被无声忽略(不发出警告)。空或仅空白 -p 值被视为不存在,并转至 stdin,然后是默认值。
axe run my-agent -p "Summarize the README"
Agent 在 $XDG_CONFIG_HOME/axe/agents/ 中定义为 TOML 文件。
name = "pr-reviewer"
description = "Reviews pull requests for issues and improvements"
model = "anthropic/claude-sonnet-4-20250514"
system_prompt = "You are a senior code reviewer. Be concise and actionable."
skill = "skills/code-review/SKILL.md"
files = ["src/**/*.go", "CONTRIBUTING.md"]
workdir = "/home/user/projects/myapp"
tools = ["read_file", "list_directory", "run_command"]
sub_agents = ["test-runner", "lint-checker"]
allowed_hosts = ["api.example.com", "docs.example.com"]
[sub_agents_config]
max_depth = 3 # maximum nesting depth (hard max: 5)
parallel = true # run sub-agents concurrently
timeout = 120 # per sub-agent timeout in seconds
[memory]
enabled = true
last_n = 10 # load last N entries into context
max_entries = 100 # warn when exceeded
[[mcp_servers]]
name = "my-tools"
url = "https://my-mcp-server.example.com/sse"
transport = "sse"
headers = { Authorization = "Bearer ${MY_TOKEN}" }
[params]
temperature = 0.3
max_tokens = 4096
# response_format = "json_object" # text, json_object, or json_schema
[budget]
max_tokens = 50000 # 0 = unlimited (default)
[retry]
max_retries = 3 # retry up to 3 times on transient errors
backoff = "exponential" # "exponential", "linear", or "fixed"
initial_delay_ms = 500 # base delay before first retry
max_delay_ms = 30000 # maximum delay cap
[[mcp_servers]]
name = "filesystem"
transport = "stdio"
command = "/usr/local/bin/mcp-server-filesystem"
args = ["--root", "/home/user/projects"]
除了 name 和 model 外,所有字段都是可选的。
Agent 可以在临时 LLM 提供商错误上重试——速率限制(429)、服务器错误(5xx)和超时。重试是选择加入的,默认禁用。
只有临时错误被重试。身份验证错误(401/403)和错误请求(400)从不重试。启用 --verbose 时,每个重试尝试都被记录到 stderr。--json 信封包括 retry_attempts 字段用于可观测性。
使用 allowed_hosts 字段,使用 url_fetch 或 web_search 的 agent 可以被限制到特定的主机名:
allowed_hosts = ["api.example.com", "docs.example.com"]
限制单次运行的累积 token 使用(输入 + 输出,跨所有轮次和子 agent 调用):
[budget]
max_tokens = 50000 # 0 = unlimited (default)
或通过标志覆盖:
axe run my-agent --max-tokens 10000
设置为大于零的值时,标志优先于 TOML。
当超出预算时,返回当前响应但不执行进一步的工具调用。进程以代码 4 退出。在超出预算的运行中不追加内存。
启用 --verbose 时,每个轮次记录累积使用到 stderr。启用 --json 时,输出信封包括 budget_max_tokens、budget_used_tokens 和 budget_exceeded 字段(无限时省略)。
通过 [params] 部分将 LLM 输出限制为特定格式。由 OpenAI 和 Ollama 提供商支持;其他提供商忽略此设置。
# String shorthand
[params]
response_format = "json_object"
# Table form (required for json_schema)
[params.response_format]
type = "json_schema"
[params.response_format.schema]
name = "my_schema"
type = "object"
Agent 可以使用内置工具与文件系统交互和运行命令。启用工具后,agent 进入对话循环——LLM 可以进行工具调用、接收结果并继续推理,最多 50 个轮次。
通过将工具添加到 agent 的 tools 字段来启用工具:
tools = ["read_file", "list_directory", "run_command"]
call_agent 工具未在工具中列出——当配置了 sub_agents 且未达到深度限制时自动可用。
所有文件工具(list_directory、read_file、write_file、edit_file)都沙箱限制在 agent 的工作目录。绝对路径、.. 遍历和符号链接转义被拒绝。
当 LLM 在单个轮次中返回多个工具调用时,默认并行运行。这适用于内置工具和子 agent 调用。使用 [sub_agents_config] 中的 parallel = false 禁用。
Agent 可以使用来自外部 MCP 服务器的工具。在 agent TOML 中声明服务器,具有 [[mcp_servers]]:
[[mcp_servers]]
name = "my-tools"
url = "https://my-mcp-server.example.com/sse"
transport = "sse"
headers = { Authorization = "Bearer ${MY_TOKEN}" }
启动时,axe 连接到每个声明的服务器,通过 tools/list 发现可用工具,并将它们与内置工具一起提供给 LLM。
MCP 工具完全由 [[mcp_servers]] 控制——它们不在 tools 字段中列出。如果 MCP 工具与启用的内置工具同名,内置工具优先。
技能是可复用的指令集,为 agent 提供特定领域的知识和工作流程。它们被定义为遵循社区 SKILL.md 格式的 SKILL.md 文件。
agent TOML 中的 skill 字段按顺序解析:
绝对路径——按原样使用(如 /home/user/skills/SKILL.md)
相对于配置目录——如 skills/code-review/SKILL.md 解析为 $XDG_CONFIG_HOME/axe/skills/code-review/SKILL.md
裸名称——如 code-review 解析为 $XDG_CONFIG_HOME/axe/skills/code-review/SKILL.md
技能通常引用辅助脚本。由于 run_command 在 agent 的 workdir 中执行(不是技能目录),SKILL.md 中的脚本路径必须是绝对路径。相对路径将失败,因为脚本在 agent 的工作目录中不存在。
# Correct — absolute path
/home/user/.config/axe/skills/my-skill/scripts/fetch.sh <args>
# Wrong — relative path won't resolve from the agent's workdir
scripts/fetch.sh <args>
$XDG_CONFIG_HOME/axe/
├── config.toml
├── agents/
│ └── my-agent.toml
└── skills/
└── my-skill/
├── SKILL.md
└── scripts/
└── fetch.sh
默认情况下,agent 从 $XDG_CONFIG_HOME/axe/agents/ 加载。Axe 也支持项目本地 agent 目录,用于按仓库的 agent 定义。
如果 <cwd>/axe/agents/ 存在,axe 在全局配置目录之前搜索它。与全局 agent 同名的本地 agent 会覆盖全局 agent。
my-project/
└── axe/
└── agents/
└── my-agent.toml ← found automatically
使用 --agents-dir 指向任何目录:
axe run my-agent --agents-dir ./custom/agents
此标志在所有命令上可用:run、agents list、agents show、agents init、agents edit 和 gc。
搜索顺序:
--agents-dir(如果提供)
<cwd>/axe/agents/(自动发现)
$XDG_CONFIG_HOME/axe/agents/(全局备选)
第一个包含匹配 <name>.toml 的目录将获胜。
axe agents init <name> 如果 <cwd>/axe/agents/ 已存在则写到它,否则回退到全局配置目录。
区域:通过 AWS_REGION 环境变量或 config.toml 中的 [providers.bedrock] region = "us-east-1" 设置
凭证:使用环境变量(AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN)或 ~/.aws/credentials 文件(支持 AWS_PROFILE 和 AWS_SHARED_CREDENTIALS_FILE)
模型 ID:使用完整 Bedrock 模型 ID(如 bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0)
基础 URL 可以通过 AXE_<PROVIDER>_BASE_URL 环境变量或 config.toml 覆盖。
Apache-2.0。见 LICENSE。