jrswab/axe
요약
Axe는 LLM 기반 에이전트를 Unix 철학에 따라 작고 조합 가능한 단위로 관리하고 실행하는 CLI 도구입니다. TOML 설정을 통해 에이전트를 정의하며, 파이프라인과 표준 Unix 도구들과 결합하여 워크플로우를 구축할 수 있습니다.
핵심 포인트
- Unix 철학을 계승한 작고 집중된 에이전트 설계
- TOML 기반의 선언적 에이전트 정의 및 버전 관리
- Anthropic, OpenAI, Ollama 등 멀티 프로바이더 지원
- 서브 에이전트 위임 및 영구 메모리 기능 제공
- Stdin 파이핑을 통한 기존 도구와의 높은 결합성
LLM 기반 에이전트 (LLM-powered agents)를 관리하고 실행하기 위한 CLI 도구입니다.
대부분의 AI 도구들은 사용자가 챗봇 (chatbot)을 원한다고 가정합니다. 즉, 거대한 컨텍스트 윈도우 (context window)를 가진 긴 세션이 한꺼번에 모든 것을 처리하는 방식입니다. 하지만 좋은 소프트웨어는 그렇게 작동하지 않습니다. 좋은 소프트웨어는 작고, 집중되어 있으며, 조합 가능 (composable) 해야 합니다.
Axe는 Unix가 프로그램을 다루는 방식과 동일하게 LLM 에이전트 (LLM agents)를 다룹니다. 각 에이전트는 한 가지 일을 잘 수행합니다. TOML 파일에 에이전트를 정의하고, 집중된 기술 (skill)을 부여한 뒤, 커맨드 라인 (command line)에서 실행하면 됩니다. 데이터를 파이프 (pipe)로 입력하고, 결과를 출력합니다. 에이전트들을 서로 연결하십시오. cron, git hooks, 또는 CI 등 여러분이 이미 사용 중인 무엇으로든 에이전트를 트리거할 수 있습니다. 데몬 (daemon), GUI, 혹은 가입해야 하는 프레임워크도 필요 없습니다. 오직 바이너리 (binary)와 설정 파일 (configs)만 있으면 됩니다.
Axe는 TOML 설정 파일을 통해 정의된 LLM 기반 에이전트들을 오케스트레이션 (orchestrate) 합니다. 각 에이전트는 고유의 시스템 프롬프트 (system prompt), 모델 선택 (model selection), 기술 파일 (skill files), 컨텍스트 파일 (context files), 작업 디렉토리 (working directory), 영구 메모리 (persistent memory), 그리고 서브 에이전트 (sub-agents)에게 권한을 위임할 수 있는 능력을 가집니다.
Axe는 스케줄러 (scheduler)가 아니라 실행기 (executor)입니다. 스케줄링이나 워크플로우 오케스트레이션 (workflow orchestration)을 새로 만드는 대신, cron, git hooks, 파이프 (pipes), 파일 와처 (file watchers)와 같은 표준 Unix 도구들과 조합될 수 있도록 설계되었습니다.
멀티 프로바이더 지원 (Multi-provider support)— Anthropic, OpenAI, Ollama (로컬 모델), OpenCode, AWS Bedrock
TOML 기반 에이전트 설정 (TOML-based agent configuration)— 선언적이고 버전 관리가 가능한 에이전트 정의
서브 에이전트 위임 (Sub-agent delegation)— 에이전트는 LLM 도구 사용 (tool use)을 통해 다른 에이전트를 호출할 수 있으며, 호출 깊이 제한 및 병렬 실행을 지원합니다
영구 메모리 (Persistent memory)— 실행 간에 컨텍스트를 전달하는 타임스탬프가 찍힌 마크다운 (markdown) 로그
메모리 가비지 컬렉션 (Memory garbage collection)— LLM 지원 패턴 분석 및 트리밍 (trimming)
기술 시스템 (Skill system)— 에이전트 간에 공유할 수 있는 재사용 가능한 지침 세트
Stdin 파이핑 (Stdin piping)— 어떤 출력이라도 에이전트로 직접 파이프 연결 가능 (git diff | axe run reviewer)
로컬 에이전트 디렉토리 (Local agent directories)— 글로벌 설정 이전에 <cwd>/axe/agents/에서 에이전트를 자동 검색하거나, --agents-dir을 사용하십시오.
어디로든 지정할 수 있습니다.Dry-run 모드 (Dry-run mode)— LLM을 호출하지 않고 해결된 컨텍스트 (context)를 검사합니다.JSON 출력 (JSON output)— 스크립팅을 위한 메타데이터가 포함된 구조화된 출력내장 도구 (Built-in tools)— 작업 디렉토리로 샌드박스 처리된 파일 작업 (읽기, 쓰기, 편집, 목록); 셸 명령 실행; URL 가져오기; 웹 검색출력 허용 목록 (Output allowlist)— url_fetch 및 web_search를 특정 호스트 이름으로 제한; 개인/예약된 IP는 항상 차단됨 (SSRF 보호)토큰 예산 (Token budgets)— [budget] 설정 또는 --max-tokens 플래그를 통해 에이전트 실행당 누적 토큰 사용량을 제한MCP 도구 지원 (MCP tool support)— SSE 또는 streamable-HTTP 전송을 통해 추가 도구를 위해 외부 MCP 서버에 연결구성 가능한 재시도 (Configurable retry)— 일시적인 제공자 오류 (429, 5xx, 타임아웃)에 대해 지수 (exponential), 선형 (linear) 또는 고정 (fixed) 백오프 적용최소한의 의존성 (Minimal dependencies)— 4개의 직접 의존성 (cobra, toml, mcp-go-sdk, x/net); 모든 LLM 호출은 표준 라이브러리 사용
Go 1.25 이상이 필요합니다.
사전 빌드된 바이너리 (Pre-built binaries) (Go 불필요)는 GitHub Releases 페이지에서 Linux, macOS 및 Windows용으로 제공됩니다.
Go를 통해 설치:
go install github.com/jrswab/axe@latest
만약 다음과 같은 오류가 발생하면:
invalid go version
사용자의 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/에 샘플 스킬 (skill)과 제공자 자격 증명을 위한 기본 config.toml이 포함된 디렉토리 구조를 생성합니다.
새 에이전트 스캐폴딩 (Scaffold):
axe agents init my-agent
에이전트 설정 편집:
axe agents edit my-agent
에이전트 실행:
axe run my-agent
다른 도구로부터 입력 파이프 연결:
git diff --cached | axe run pr-reviewer
cat error.log | axe run log-analyzer
examples/ 디렉토리에는 설정으로 복사하여 즉시 사용할 수 있는 바로 실행 가능한 에이전트들이 포함되어 있습니다. 코드 리뷰어, 커밋 메시지 생성기, 텍스트 요약기가 포함되어 있으며, 각 에이전트는 집중된 SKILL.md를 가지고 있습니다.
# 예시 에이전트를 설정 파일로 복사합니다
cp examples/code-reviewer/code-reviewer.toml "$(axe config path)/agents/"
cp -r examples/code-reviewer/skills/ "$(axe config path)/skills/"
...
전체 설정 지침은 examples/README.md를 참조하세요.
Axe는 격리되고 강화된 컨테이너(hardened container)에서 에이전트를 실행할 수 있도록 Docker 이미지를 제공합니다.
docker build -t axe .
buildx를 통해 멀티 아키텍처 빌드(linux/amd64, linux/arm64)를 지원합니다:
docker buildx build --platform linux/amd64,linux/arm64 -t axe:latest .
설정 디렉토리를 마운트(mount)하고 API 키를 환경 변수(environment variables)로 전달하세요:
docker run --rm \
-v ./my-config:/home/axe/.config/axe \
-e ANTHROPIC_API_KEY \
...
-i 플래그를 사용하여 stdin을 파이프(pipe)로 연결하세요:
git diff | docker run --rm -i \
-v ./my-config:/home/axe/.config/axe \
-e ANTHROPIC_API_KEY \
...
설정 볼륨(config volume)이 마운트되지 않으면, 에이전트 TOML 파일이 존재하지 않기 때문에 axe는 코드 2(설정 오류)와 함께 종료됩니다.
위의 예시들은 전체 설정 디렉토리를 마운트합니다. 만약 하나의 스킬을 가진 하나의 에이전트만 실행해야 한다면, 해당 파일들만 컨테이너 내부의 예상되는 XDG 경로에 마운트하세요. API 키가 환경 변수를 통해 전달될 때는 config.toml이 필요하지 않습니다.
docker run --rm -i \
-e ANTHROPIC_API_KEY \
-v ./agents/reviewer.toml:/home/axe/.config/axe/agents/reviewer.toml:ro \
...
에이전트의 skill 필드는 컨테이너 내부의 XDG 설정 경로를 기준으로 자동 확인(resolve)되므로, --skill 플래그가 필요하지 않습니다.
에이전트의 TOML에 선언된 것과 다른 스킬을 사용하려면, --skill 플래그를 사용하여 이를 재정의(override)하세요. 이 경우 교체할 스킬만 마운트하면 됩니다. TOML에 선언된 원래 스킬은 완전히 무시됩니다:
docker run --rm -i \
-e ANTHROPIC_API_KEY \
-v ./agents/reviewer.toml:/home/axe/.config/axe/agents/reviewer.toml:ro \
...
만약 에이전트가 sub_agents를 선언했다면, 참조된 모든 에이전트 TOML 파일과 그들의 스킬 또한 반드시 마운트되어야 합니다.
데이터 볼륨을 마운트하면 에이전트 메모리(Agent memory)가 실행 간에 유지됩니다:
docker run --rm \
-v ./my-config:/home/axe/.config/axe \
-v axe-data:/home/axe/.local/share/axe \
...
로컬 Ollama 인스턴스와 함께 axe를 실행하기 위한 docker-compose.yml이 포함되어 있습니다.
클라우드 제공업체 전용 (Ollama 미사용):
docker compose run --rm axe run my-agent
Ollama 사이드카(sidecar) 사용 시:
docker compose --profile ollama up -d ollama
docker compose --profile cli run --rm axe run my-agent
Ollama 모델 풀(Pull) 하기:
docker compose --profile ollama exec ollama ollama pull llama3
참고: compose의 axe 서비스는 depends_on: ollama를 선언합니다. Docker Compose는 클라우드 전용 실행 시에도 compose를 통해 axe가 시작될 때마다 Ollama 서비스를 시작하려고 시도합니다. Ollama 없이 클라우드 전용으로 사용하려면 docker compose run 대신 docker 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
컨테이너는 기본적으로 다음과 같은 보안 강화(hardening) 설정이 적용되어 실행됩니다 (compose를 통해):
비루트 사용자 (Non-root user) — UID 10001
읽기 전용 루트 파일 시스템 (Read-only root filesystem) — 쓰기 가능한 위치는 설정 마운트, 데이터 마운트 및 /tmp/axe tmpfs입니다.
모든 권한 제거 (All capabilities dropped) — cap_drop: ALL
권한 상승 방지 (No privilege escalation) — no-new-privileges:true
이 설정들은 외부 네트워크 액세스를 제한하지 않습니다. 로컬 Ollama 인스턴스와만 통신하는 에이전트를 격리하려면 --network=none을 추가하고 수동으로 공유 Docker 네트워크에 연결하십시오.
| 컨테이너 경로 | 용도 | 기본 액세스 권한 |
|---|---|---|
/home/axe/.config/axe/ | 에이전트 TOML 파일, 스킬, config.toml | 읽기-쓰기 (Read-write) |
/home/axe/.local/share/axe/ | 영구 메모리 (Persistent memory) 파일 | 읽기-쓰기 (Read-write) |
axe config init 및 axe agents init 명령어가 해당 경로에 내용을 작성하기 때문에 설정(Config)은 읽기-쓰기 권한을 가집니다. 에이전트만 실행하는 경우에는 :ro (읽기 전용)로 마운트하십시오.
| 변수 (Variable) | 필수 여부 (Required) | 목적 (Purpose) |
|---|---|---|
ANTHROPIC_API_KEY | Anthropic 사용 시 | API 인증 (API authentication) |
OPENAI_API_KEY | OpenAI 사용 시 | API 인증 (API authentication) |
AXE_OLLAMA_BASE_URL | Ollama 사용 시 | Ollama 엔드포인트 (compose 기본값: http://ollama:11434) |
AXE_ANTHROPIC_BASE_URL | 아니오 | Anthropic API 엔드포인트 재정의 (Override) |
AXE_OPENAI_BASE_URL | 아니오 | OpenAI API 엔드포인트 재정의 (Override) |
AXE_OPENCODE_BASE_URL | 아니오 | OpenCode API 엔드포인트 재정의 (Override) |
TAVILY_API_KEY | web_search 사용 시 | Tavily 웹 검색 (web search) API 키 |
AXE_WEB_SEARCH_BASE_URL | 아니오 | 웹 검색 엔드포인트 재정의 (Override) |
| 명령 (Command) | 설명 (Description) |
|---|---|
axe run <agent> | 에이전트 실행 |
axe agents list | 설정된 모든 에이전트 목록 표시 |
axe agents show <agent> | 에이전트의 전체 설정 표시 |
axe agents init <agent> | 새로운 에이전트 TOML 파일 스캐폴딩 (Scaffold) |
axe agents edit <agent> | $EDITOR에서 에이전트 TOML 파일 열기 |
axe config path | 설정 디렉터리 경로 출력 |
axe config init | 기본값으로 설정 디렉터리 초기화 |
axe gc <agent> | 에이전트에 대한 메모리 가비지 컬렉션 (Garbage Collection) 실행 |
axe gc --all | 메모리가 활성화된 모든 에이전트에 대해 GC 실행 |
axe version | 현재 버전 출력 |
| 플래그 (Flag) | 기본값 (Default) | 설명 (Description) |
|---|---|---|
--model <provider/model> | TOML에서 가져옴 | 모델을 재정의합니다 (예: anthropic/claude-sonnet-4-20250514) |
--skill <path> | TOML에서 가져옴 | 스킬 (skill) 파일 경로를 재정의합니다 |
--workdir <path> | TOML 또는 현재 작업 디렉토리 (cwd)에서 가져옴 | 작업 디렉토리 (working directory)를 재정의합니다 |
--timeout <seconds> | 120 | 요청 제한 시간 (timeout) |
--max-tokens <int> | 0 (무제한) | 실행 중 누적 토큰 사용량의 상한을 설정합니다 (초과 시 종료 코드 4 발생) |
--dry-run | false | LLM을 호출하지 않고 해결된 컨텍스트 (context)를 보여줍니다 |
--verbose / -v | false | 디버그 정보 (모델, 타이밍, 토큰, 재시도)를 stderr에 출력합니다 |
--json | false | 메타데이터와 함께 출력을 JSON 엔벨로프 (envelope)로 감쌉니다 |
-p / --prompt <string> | (없음) | 사용자 메시지로 사용되는 인라인 프롬프트 (prompt); 표준 입력 (stdin)보다 우선순위가 높습니다 |
--agents-dir <path> | (자동 검색) | 에이전트 검색 디렉토리를 재정의합니다 |
LLM에 전송되는 사용자 메시지는 다음 순서로 결정됩니다:
— -p / --prompt 플래그: 비어 있지 않고 공백만 포함되지 않은 값이 제공되면, 이를 사용자 메시지로 사용합니다.
— 파이프 표준 입력 (Piped stdin): -p 플래그가 없거나 비어 있는 경우(공백만 있는 경우 포함), 파이프된 표준 입력 (stdin)을 사용합니다.
— 내장 기본값 (Built-in default): -p 플래그와 표준 입력 모두 콘텐츠를 제공하지 않으면, 기본 메시지인 "Execute the task described in your instructions."를 사용합니다.
파이프된 표준 입력과 함께 -p가 제공되면, 파이프된 표준 입력은 조용히 무시됩니다 (경고가 발생하지 않음). 비어 있거나 공백만 있는 -p 값은 플래그가 없는 것으로 간주되어 표준 입력으로 넘어가며, 그 다음 기본값으로 넘어갑니다.
예시:
axe run my-agent -p "Summarize the README"
| 코드 (Code) | 의미 (Meaning) |
|---|---|
| 0 | 성공 (Success) |
| ... |
에이전트는 $XDG_CONFIG_HOME/axe/agents/ 내의 TOML 파일로 정의됩니다.
name = "pr-reviewer"
description = "Reviews pull requests for issues and improvements"
model = "anthropic/claude-sonnet-4-20250514"
...
name과 model을 제외한 모든 필드는 선택 사항입니다.
에이전트는 일시적인 LLM 제공자 오류 — 속도 제한 (rate limits, 429), 서버 오류 (server errors, 5xx), 그리고 타임아웃 (timeouts)에 대해 재시도할 수 있습니다. 재시도는 선택 사항이며 기본적으로는 비활성화되어 있습니다.
| 필드 (Field) | 기본값 (Default) | 설명 (Description) |
|---|---|---|
max_retries | 0 | 초기 요청 이후의 재시도 횟수. 0은 재시도를 비활성화합니다. |
backoff | "exponential" | 전략: "exponential" (지터 (jitter) 포함), "linear", 또는 "fixed" |
initial_delay_ms | 500 | 첫 번째 재시도 전의 기본 지연 시간 (밀리초) |
max_delay_ms | 30000 | 최대 지연 시간 상한 (밀리초) |
일시적인 오류 (transient errors)만 재시도됩니다. 인증 오류 (401/403) 및 잘못된 요청 (400)은 절대 재시도되지 않습니다. --verbose가 활성화되면, 각 재시도 시도가 stderr에 로그로 기록됩니다. --json 엔벨로프 (envelope)에는 관찰 가능성 (observability)을 위한 retry_attempts 필드가 포함됩니다.
url_fetch 또는 web_search를 사용하는 에이전트는 allowed_hosts 필드를 통해 특정 호스트 이름으로 제한할 수 있습니다:
allowed_hosts = ["api.example.com", "docs.example.com"]
| 동작 (Behavior) | 상세 내용 (Detail) |
|---|---|
| 비어 있거나 없는 경우 | 모든 공개 호스트 이름 허용 |
| ... |
단일 실행에 대해 누적 토큰 사용량(모든 턴 및 서브 에이전트 호출에 걸친 입력 + 출력)을 제한합니다:
[budget]
max_tokens = 50000 # 0 = 무제한 (기본값)
또는 플래그 (flag)를 통해 재정의할 수 있습니다:
axe run my-agent --max-tokens 10000
플래그가 0보다 큰 값으로 설정되면 TOML보다 우선순위를 가집니다.
예산을 초과하면 현재 응답이 반환되지만, 더 이상의 도구 호출 (tool calls)은 실행되지 않습니다. 프로세스는 **코드 4 (code 4)**로 종료됩니다. 예산 초과 실행 시 메모리는 추가되지 않습니다.
--verbose를 사용하면 각 턴의 누적 사용량이 stderr에 로그로 기록됩니다. --json을 사용하면 출력 엔벨로프에 budget_max_tokens, budget_used_tokens, 그리고 budget_exceeded가 포함됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub AI Coding Assistants의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기