요약
AI 에이전트 파일 하나를 3단계로 10개 IDE에 변환: (1) get_field(), get_body(), to_kebab() bash 함수를 사용하여 YAML 프런트매터 구문 분석, (2) convert.sh로 도구별 형식 변환 (Claude Code .md, Cursor .mdc, Aider CONVENTIONS.md, Windsurf .windsurfrules 등), (3) install.sh로 올바른 경로에 설치. 한 번 작성하면 자동 변환 및 배포가 가능합니다.
에이전트 파일 하나로 10개 IDE를 지원하세요. The Agency 프로젝트는 단일 마크다운 파일을 Claude Code, Cursor, Aider, Windsurf, GitHub Copilot 및 그 외 여러 도구에서 사용할 수 있도록 자동 변환합니다.
AI 에이전트를 작성했다면, 아래 도구에서 바로 사용할 수 있습니다:
- Claude Code (
~/.claude/agents/내.md) - Cursor (
.cursor/rules/내.mdc) - Aider (프로젝트 루트
CONVENTIONS.md) - Windsurf (
.windsurfrules) - GitHub Copilot (
~/.github/agents/내.md) - 기타 5개 이상 도구
10가지 버전을 직접 작성할 필요 없습니다. 한 번 작성 후 스크립트로 자동 변환하세요.
The Agency는 두 개의 bash 스크립트로 이 문제를 해결합니다:
-
convert.sh— 에이전트 파일을 도구별 형식으로 변환 -
install.sh— 변환된 파일을 각 도구의 경로에 설치
이 튜토리얼에서는 두 스크립트를 리버스 엔지니어링하여 YAML 프런트매터를 파싱하고, 본문을 추출하며, 변환 파이프라인을 구축하는 방법을 단계별로 설명합니다.
💡 Apidog 통합을 통해 API 개발 워크플로를 위한 에이전트 배포, 특수 테스트 에이전트 생성 등 모든 팀이 선호하는 IDE에서 작동하도록 보장할 수 있습니다.
에이전트 형식
The Agency의 모든 에이전트는 동일한 구조를 사용합니다:
---
name: API Tester
description: "Specialized in API testing with Apidog, Postman, and automated validation"
color: purple
emoji: 🧪
vibe: Breaks APIs before users do.
---
# API Tester Agent Personality
You are **API Tester**, an expert in API validation...
## Identity & Memory
- Role: API testing specialist
- Personality: Thorough, skeptical, evidence-focused
...
파일은 두 부분으로 구성됩니다:
-
프런트매터 —
---사이의 YAML 메타데이터 -
본문 — 두 번째
---뒤의 마크다운 내용
변환의 핵심: 프런트매터 필드 추출 → 본문 변환 → 올바른 경로에 생성
1단계: YAML 프런트매터 구문 분석
파싱 스크립트 parse-frontmatter.sh 작성:
#!/usr/bin/env bash
set -euo pipefail
get_field() {
local field="$1" file="$2"
awk -v f="$field" '
/^---$/ { fm++; next }
fm == 1 && $0 ~ "^" f ": " {
sub("^" f ": ", "");
print;
exit
}
' "$file"
}
get_body() {
awk 'BEGIN{fm=0} /^---$/{fm++; next} fm>=2{print}' "$1"
}
to_kebab() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g'
}
if [[ "${1:-}" == "--demo" ]]; then
AGENT_FILE="${2:-test-agent.md}"
echo "File: $AGENT_FILE"
echo "Name: $(get_field 'name' "$AGENT_FILE")"
echo "Description: $(get_field 'description' "$AGENT_FILE")"
echo "Slug: $(to_kebab "$(get_field 'name' "$AGENT_FILE")")"
echo "---"
echo "Body preview:"
get_body "$AGENT_FILE" | head -10
fi
테스트:
chmod +x parse-frontmatter.sh
./parse-frontmatter.sh --demo engineering-backend-architect.md
예상 출력:
File: engineering-backend-architect.md
Name: Backend Architect
Description: Senior backend architect specializing in scalable system design...
Slug: backend-architect
---
Body preview:
# Backend Architect Agent Personality
You are **Backend Architect**, a senior backend architect...
2단계: Claude Code 형식으로 변환
Claude Code는 원본 .md 파일을 그대로 사용합니다. 복사만 하면 됩니다:
convert_claude_code() {
local agent_file="$1"
local dest="$HOME/.claude/agents/"
mkdir -p "$dest"
cp "$agent_file" "$dest/"
echo " Claude Code: $(basename "$agent_file")"
}
3단계: Cursor 형식으로 변환
Cursor는 description 필드가 포함된 .mdc 파일을 사용합니다:
convert_cursor() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local description=$(get_field 'description' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
local output=".cursor/rules/agency-${slug}.mdc"
mkdir -p "$(dirname "$output")"
cat > "$output" << EOF
---
description: Agency agent: $description
---
$body
EOF
echo " Cursor: agency-${slug}.mdc"
}
입력 예시:
---
name: API Tester
description: Specialized in API testing...
---
# API Tester Agent...
출력 예시 (.mdc):
---
description: Agency agent: Specialized in API testing...
---
# API Tester Agent...
4단계: Aider 형식으로 변환
Aider는 모든 에이전트를 포함하는 단일 CONVENTIONS.md 파일을 사용:
convert_aider() {
local agent_file="$1"
local output="CONVENTIONS.md"
echo "" >> "$output"
echo "---" >> "$output"
echo "" >> "$output"
cat "$agent_file" >> "$output"
echo " Aider: appended to $output"
}
전체 파일 빌드 예시:
build_aider() {
local output="CONVENTIONS.md"
echo "# Agency Agents for Aider" > "$output"
echo "" >> "$output"
echo "This file contains all Agency agents for Aider integration." >> "$output"
echo "" >> "$output"
for agent_file in engineering/*.md design/*.md testing/*.md; do
convert_aider "$agent_file"
done
}
5단계: Windsurf 형식으로 변환
Windsurf도 단일 .windsurfrules 파일 사용:
convert_windsurf() {
local agent_file="$1"
local output=".windsurfrules"
echo "" >> "$output"
echo "---" >> "$output"
echo "" >> "$output"
cat "$agent_file" >> "$output"
echo " Windsurf: appended to $output"
}
6단계: Antigravity 형식으로 변환
Antigravity (Gemini)는 하위 디렉토리에 SKILL.md를 사용:
convert_antigravity() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local slug=$(to_kebab "$name")
local output="integrations/antigravity/skills/agency-${slug}/SKILL.md"
mkdir -p "$(dirname "$output")"
cat > "$output" << EOF
# Agency Agent: $name
$(get_body "$agent_file")
EOF
echo " Antigravity: agency-${slug}/SKILL.md"
}
7단계: OpenClaw 형식으로 변환
OpenClaw는 에이전트당 3개 파일(SOUL.md, AGENTS.md, IDENTITY.md) 사용:
convert_openclaw() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local description=$(get_field 'description' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
local output_dir="integrations/openclaw/agency-${slug}"
mkdir -p "$output_dir"
cat > "$output_dir/SOUL.md" << EOF
# $name
$description
---
$body
EOF
cat > "$output_dir/AGENTS.md" << EOF
# Agent Capabilities: $name
- Specialized expertise in domain
- Deliverable-focused output
- Success metrics defined
See SOUL.md for full definition.
EOF
cat > "$output_dir/IDENTITY.md" << EOF
# Identity: $name
- Name: $name
- Description: $description
- Source: The Agency (agency-agents repo)
EOF
echo " OpenClaw: agency-${slug}/"
}
8단계: 전체 convert.sh 스크립트
간소화된 전체 변환 스크립트 예시:
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
OUT_DIR="$REPO_ROOT/integrations"
get_field() {
local field="$1" file="$2"
awk -v f="$field" '
/^---$/ { fm++; next }
fm == 1 && $0 ~ "^" f ": " { sub("^" f ": ", ""); print; exit }
' "$file"
}
get_body() {
awk 'BEGIN{fm=0} /^---$/{fm++; next} fm>=2{print}' "$1"
}
to_kebab() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g'
}
convert_claude_code() {
local agent_file="$1"
local dest="$OUT_DIR/claude-code/"
mkdir -p "$dest"
cp "$agent_file" "$dest/"
}
convert_cursor() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
mkdir -p "$OUT_DIR/cursor/.cursor/rules/"
cat > "$OUT_DIR/cursor/.cursor/rules/agency-${slug}.mdc" << EOF
---
description: Agency agent: $(get_field 'description' "$agent_file")
---
$body
EOF
}
convert_aider() {
local output="$OUT_DIR/aider/CONVENTIONS.md"
echo "" >> "$output"
echo "---" >> "$output"
cat "$agent_file" >> "$output"
}
convert_windsurf() {
local output="$OUT_DIR/windsurf/.windsurfrules"
echo "" >> "$output"
echo "---" >> "$output"
cat "$agent_file" >> "$output"
}
echo "Converting Agency agents..."
AGENT_DIRS=(engineering design testing marketing sales)
for dir in "${AGENT_DIRS[@]}"; do
for agent_file in "$REPO_ROOT/$dir"/*.md; do
[[ -f "$agent_file" ]] || continue
name=$(get_field 'name' "$agent_file")
echo "Processing: $name"
convert_claude_code "$agent_file"
convert_cursor "$agent_file"
done
done
echo "# Agency Agents for Aider" > "$OUT_DIR/aider/CONVENTIONS.md"
for dir in "${AGENT_DIRS[@]}"; do
for agent_file in "$REPO_ROOT/$dir"/*.md; do
[[ -f "$agent_file" ]] || continue
convert_aider "$agent_file"
done
done
echo "# Agency Agents for Windsurf" > "$OUT_DIR/windsurf/.windsurfrules"
for dir in "${AGENT_DIRS[@]}"; do
for agent_file in "$REPO_ROOT/$dir"/*.md; do
[[ -f "$agent_file" ]] || continue
convert_windsurf "$agent_file"
done
done
echo "Conversion complete!"
echo " Claude Code: $OUT_DIR/claude-code/"
echo " Cursor: $OUT_DIR/cursor/.cursor/rules/"
echo " Aider: $OUT_DIR/aider/CONVENTIONS.md"
echo " Windsurf: $OUT_DIR/windsurf/.windsurfrules"
실행:
chmod +x convert.sh
./convert.sh
9단계: 각 도구에 설치
변환 후, 도구별로 파일을 복사합니다:
#!/usr/bin/env bash
set -euo pipefail
install_claude_code() {
local src="$REPO_ROOT/integrations/claude-code/"
local dest="$HOME/.claude/agents/"
mkdir -p "$dest"
cp "$src"/*.md "$dest/"
echo "Claude Code: $(find "$dest" -name '*.md' | wc -l) agents installed"
}
install_cursor() {
local src="$REPO_ROOT/integrations/cursor/.cursor/rules/"
local dest="./.cursor/rules/"
mkdir -p "$dest"
cp "$src"/*.mdc "$dest/"
echo "Cursor: $(find "$dest" -name '*.mdc' | wc -l) rules installed"
}
install_aider() {
local src="$REPO_ROOT/integrations/aider/CONVENTIONS.md"
local dest="./CONVENTIONS.md"
cp "$src" "$dest"
echo "Aider: CONVENTIONS.md installed"
}
install_windsurf() {
local src="$REPO_ROOT/integrations/windsurf/.windsurfrules"
local dest="./.windsurfrules"
cp "$src" "$dest"
echo "Windsurf: .windsurfrules installed"
}
install_all() {
if [[ -d "$HOME/.claude/agents/" ]]; then
install_claude_code
fi
if command -v cursor &>/dev/null || [[ -d "./.cursor/" ]]; then
install_cursor
fi
if command -v aider &>/dev/null; then
install_aider
fi
}
install_all
형식 비교
| 도구 | 형식 | 범위 | 변환 방식 |
|---|---|---|---|
| Claude Code | .md |
사용자 전체 | 그대로 복사 |
| Cursor | .mdc |
프로젝트 | 설명 프런트매터 추가 |
| Aider | CONVENTIONS.md |
프로젝트 루트 | 모든 에이전트 연결 |
| Windsurf | .windsurfrules |
프로젝트 루트 | 모든 에이전트 연결 |
| GitHub Copilot | .md |
사용자 전체 | 그대로 복사 |
| Antigravity | SKILL.md |
사용자 전체 | 스킬 디렉토리로 묶기 |
| OpenClaw |
SOUL.md 외 2 |
사용자 전체 | 3개 파일로 분할 |
| Gemini CLI | 확장 | 사용자 전체 | 매니페스트+스킬 생성 |
| OpenCode | .md |
프로젝트 | 그대로 복사 |
| Qwen Code | .md |
프로젝트 | SubAgent로 복사 |
자신만의 변환 스크립트 구축
새 도구 추가를 위한 템플릿:
#!/usr/bin/env bash
convert_your_tool() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local description=$(get_field 'description' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
local output="path/to/your/tool/agency-${slug}.ext"
mkdir -p "$(dirname "$output")"
cat > "$output" << EOF
# Your tool-specific format
# Use: $name, $description, $body
EOF
echo " YourTool: agency-${slug}.ext"
}
for agent_file in engineering/*.md; do
convert_your_tool "$agent_file"
done
구축한 내용
| 구성 요소 | 목적 |
|---|---|
get_field() |
YAML 프런트매터 값 추출 |
get_body() |
프런트매터 제거, 본문 반환 |
to_kebab() |
이름을 URL-safe 슬러그로 변환 |
convert_cursor() |
.mdc로 변환 |
convert_aider() |
단일 파일로 연결 |
convert_windsurf() |
단일 파일로 연결 |
convert_antigravity() |
스킬 디렉토리 생성 |
convert_openclaw() |
에이전트당 3개 파일로 분할 |
install.sh |
도구별 경로로 복사 |
다음 단계
스크립트 확장:
-
xargs -P또는 GNU parallel로 병렬 변환 - 유효성 검사(필수 프런트매터 필드 확인)
- 드라이런 모드(
--dry-run플래그)
더 많은 도구 추가:
- VS Code 확장
- JetBrains IDE
- 내부 도구 등
대규모 저장소 최적화:
- 프런트매터 캐시
-
find -print0로 안전한 파일 처리 - 100개 이상 에이전트용 진행률 표시줄
일반적인 문제 해결
“bad substitution” 오류:
- bash로 실행 (
#!/usr/bin/env bash확인) - bash 버전 4.0 이상 확인:
bash --version - bash로 명시적 실행:
bash convert.sh - Windows 줄 끝 문자 제거:
sed -i 's/\r$//' convert.sh
프런트매터 추출 오류:
- YAML에
:(콜론+공백) 사용 확인 - 필드명 앞 공백 주의
-
---구분자 정확히 3개 확인 - 수동 테스트:
./parse-frontmatter.sh --demo agent.md
슬러그 깨짐:
-
to_kebab()예외 케이스 테스트 - 특수 문자 처리:
iconv활용 - 빈 슬러그 대체:
[[ -z "$slug" ]] && slug="unknown-agent" - 원본 이름도 로그 남기기
Cursor 규칙 미적용:
-
.mdc에description프런트매터 존재 확인 -
.cursor/mcp.json구성 확인 -
.cursor/rules/폴더에 파일이 있는지 재확인 - 규칙 추가 후 Cursor 재시작
Aider CONVENTIONS.md 너무 클 때:
- 카테고리별 분할(
CONVENTIONS-engineering.md등) - 자동 정리 스크립트 구현
- 목차 추가
- include 지시문 활용 고려
대규모 변환을 위한 성능 최적화
병렬 처리:
GNU parallel 예시:
#!/usr/bin/env bash
export OUT_DIR="$REPO_ROOT/integrations"
export -f get_field get_body to_kebab convert_cursor convert_claude_code
find "$REPO_ROOT" -name "*.md" -type f | \
parallel -j 8 --progress '
name=$(get_field "name" {})
slug=$(to_kebab "$name")
echo "Converting: $name"
convert_cursor "{}"
convert_claude_code "{}"
'
echo "Parallel conversion complete!"
증분 변환:
변경된 파일만 변환:
#!/usr/bin/env bash
CACHE_FILE="$REPO_ROOT/.conversion-cache"
declare -A PREV_HASHES
if [[ -f "$CACHE_FILE" ]]; then
while IFS='=' read -r file hash; do
PREV_HASHES["$file"]="$hash"
done < "$CACHE_FILE"
fi
for agent_file in engineering/*.md; do
CURRENT_HASH=$(md5sum "$agent_file" | cut -d' ' -f1)
PREV_HASH="${PREV_HASHES[$agent_file]:-}"
if [[ "$CURRENT_HASH" != "$PREV_HASH" ]]; then
echo "Changed: $agent_file"
convert_cursor "$agent_file"
convert_claude_code "$agent_file"
NEW_HASHES["$agent_file"]="$CURRENT_HASH"
else
echo "Unchanged: $agent_file"
fi
done
for file in "${!NEW_HASHES[@]}"; do
echo "$file=${NEW_HASHES[$file]}"
done > "$CACHE_FILE"
진행 상황 추적:
#!/usr/bin/env bash
total_files=$(find "$REPO_ROOT" -name "*.md" -type f | wc -l)
current=0
for agent_file in "$REPO_ROOT"/**/*.md; do
((current++))
percent=$((current * 100 / total_files))
filled=$((percent / 5))
empty=$((20 - filled))
bar=$(printf '%*s' "$filled" | tr ' ' '#')
spaces=$(printf '%*s' "$empty" | tr ' ' ' ')
name=$(get_field 'name' "$agent_file")
echo -ne "\r[${bar}${spaces}] ${percent}% - $name"
convert_cursor "$agent_file"
done
echo -ne "\n"
공유 에이전트 보안 고려 사항
에이전트 소스 유효성 검사:
#!/usr/bin/env bash
validate_agent() {
local file="$1"
local name=$(get_field 'name' "$file")
local description=$(get_field 'description' "$file")
if [[ -z "$name" ]]; then
echo "ERROR: Missing 'name' field in $file"
return 1
fi
if [[ -z "$description" ]]; then
echo "WARNING: Missing 'description' field in $file"
fi
local body=$(get_body "$file")
if echo "$body" | grep -q 'rm -rf\|curl.*\|wget.*\|eval\|exec'; then
echo "WARNING: Potentially dangerous patterns in $file"
return 1
fi
echo "VALID: $name"
return 0
}
에이전트 실행 샌드박싱:
- Docker로 격리 실행
- 읽기 전용 파일시스템 마운트
- 네트워크 접근 제한
- 감사 추적 로그 기록
에이전트 파일 하나, 10개 IDE, 2개의 bash 스크립트로 자동화하세요. 한 번 작성, 자동 변환, 어디든 설치.
이제 여러분이 직접 변환 스크립트를 확장해보고, 에이전트를 더 많은 AI 도구에서 활용해보세요.
핵심 요약
- 한 번 작성하고 10개 이상 형식으로 변환 — YAML 프런트매터가 있는 단일 마크다운 파일을 다양한 도구용으로 자동 변환
-
Bash 구문 분석으로 프런트매터 추출 —
get_field()로 YAML 값 추출,get_body()로 본문 추출,to_kebab()로 슬러그 생성 - 도구별 맞춤 변환 — Claude Code는 그대로 복사, Cursor는 설명 프런트매터 추가, Aider/Windsurf는 연결 파일 생성
-
설치 스크립트로 자동 배포 — 사용자 전체 도구는
~/.claude/agents/, 프로젝트 도구는.cursor/rules/등 위치 사용 -
새 도구 확장도 간단 —
convert_your_tool()함수 정의 후 메인 루프에 추가
자주 묻는 질문
convert.sh는 무엇이며 어떻게 작동합니까?
에이전트 마크다운 파일에서 YAML 프런트매터를 파싱하고, 본문을 추출하여 각 도구별 파일로 변환하는 bash 스크립트입니다. awk/sed/heredoc으로 구현됩니다.
bash에서 프런트매터 파싱은 어떻게?
get_field()가 awk로 프런트매터 블록을 찾아 필드값을 추출, get_body()는 두 번째 --- 뒤 전체를 출력합니다.
어떤 IDE/도구를 지원합니까?
Claude Code(.md), Cursor(.mdc), Aider(CONVENTIONS.md), Windsurf(.windsurfrules), GitHub Copilot, Antigravity, OpenClaw, Gemini CLI, OpenCode, Qwen Code 등
새 도구 변환 지원은 어떻게 추가합니까?
convert_yourtool() 함수에서 프런트매터 추출 및 포맷 후, 메인 루프에 추가하세요.
병렬 변환 가능한가요?
가능합니다. xargs -P나 GNU parallel로 수십~수백 개 에이전트도 빠르게 변환할 수 있습니다.
프런트매터 필드 존재 확인은?
[[ -z "$name" ]] && echo "Missing name field" && exit 1 등으로 유효성 검사 추가
변환 실패시 대처법?
set -euo pipefail로 빠른 실패, || continue로 오류 파일 건너뛰기, 실패 로그 기록 등
빠르고 이식성 높은 에이전트 자동 변환 시스템을 직접 구현해보세요.
Top comments (0)