AIエージェントを1つ作って10個のIDEで動かす方法

Ashley Innocent

Ashley Innocent

19 3月 2026

AIエージェントを1つ作って10個のIDEで動かす方法

Apidog エンタープライズ

オンプレミスデプロイ

SSO & RBAC

SOC 2 準拠

Apidog Enterpriseを見る

要点

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`を使って正しいパスにインストール。一度書けば、自動的に変換され、どこにでもデプロイできます。

1つのエージェントファイルで10種類のIDEに対応。The Agencyプロジェクトが単一のMarkdownファイルをClaude Code、Cursor、Aider、Windsurf、GitHub Copilot、その他6つ以上のツールで動作するように変換する方法を学びましょう。

AIエージェントを作成したとします。それを以下の場所で利用可能にしたい場合:

10種類のバージョンを作成しますか?いいえ。一度書けば、自動的に変換できます。

The Agencyプロジェクトは、この問題を2つのbashスクリプトで解決します:

このチュートリアルでは、両方のスクリプトをリバースエンジニアリングします。YAMLフロントマターの解析方法、本文コンテンツの抽出方法、あらゆるツールに対応する変換パイプラインの構築方法を学びます。

💡
API開発ワークフローのためにApidog統合を伴うエージェントをデプロイする場合でも、専門的なテストエージェントを作成する場合でも、この変換システムは、それらがチームのすべての好みのIDEで動作することを保証します。
button

エージェントフォーマット

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
...

ファイルは2つの部分から構成されています:

  1. フロントマター — `---`区切り文字で囲まれたYAMLメタデータ
  2. 本文 — 2番目の`---`以降のMarkdownコンテンツ

変換とは:フロントマターのフィールドを抽出し、本文をターゲットフォーマットに変換し、正しいパスに書き込むことです。

ステップ1:YAMLフロントマターの解析

`parse-frontmatter.sh`を作成します:

#!/usr/bin/env bash
#
# parse-frontmatter.sh — Extract YAML frontmatter fields from agent files
#

set -euo pipefail

# Extract a single field value from YAML frontmatter
# Usage: get_field <field> <file>
get_field() {
  local field="$1" file="$2"
  awk -v f="$field" '
    /^---$/ { fm++; next }
    fm == 1 && $0 ~ "^" f ": " {
      sub("^" f ": ", "");
      print;
      exit
    }
  ' "$file"
}

# Strip frontmatter, return only body
# Usage: get_body <file>
get_body() {
  awk 'BEGIN{fm=0} /^---$/{fm++; next} fm>=2{print}' "$1"
}

# Convert name to kebab-case slug
# Usage: to_kebab "API Tester" → api-tester
to_kebab() {
  echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g'
}

# Demo
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"

  # Append with separator
  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`ファイルを使用します(Aiderと同様):

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"

  # SOUL.md - Main agent definition
  cat > "$output_dir/SOUL.md" << EOF
# $name

$description

---

$body
EOF

  # AGENTS.md - Agent capabilities
  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

  # IDENTITY.md - Agent identity
  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
#
# convert.sh — Convert all Agency agents to tool-specific formats
#

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
OUT_DIR="$REPO_ROOT/integrations"

# Frontmatter helpers
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'
}

# Conversion functions
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"
}

# Main conversion loop
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

# Build combined files
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
#
# install.sh — Install converted agents to your local tools
#

set -euo pipefail

# Claude Code
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"
}

# Cursor
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"
}

# Aider
install_aider() {
  local src="$REPO_ROOT/integrations/aider/CONVENTIONS.md"
  local dest="./CONVENTIONS.md"
  cp "$src" "$dest"
  echo "Aider: CONVENTIONS.md installed"
}

# Windsurf
install_windsurf() {
  local src="$REPO_ROOT/integrations/windsurf/.windsurfrules"
  local dest="./.windsurfrules"
  cp "$src" "$dest"
  echo "Windsurf: .windsurfrules installed"
}

# Install all detected tools
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 ユーザー全体 (~/.claude/agents/) そのままコピー
Cursor .mdc プロジェクト (.cursor/rules/) descriptionフロントマターを追加
Aider CONVENTIONS.md プロジェクトルート すべてのエージェントを連結
Windsurf .windsurfrules プロジェクトルート すべてのエージェントを連結
GitHub Copilot .md ユーザー全体 (~/.github/agents/) そのままコピー
Antigravity SKILL.md ユーザー全体 (~/.gemini/antigravity/) スキルディレクトリにラッピング
OpenClaw SOUL.md + その他 ユーザー全体 (~/.openclaw/) 3つのファイルに分割
Gemini CLI 拡張機能 ユーザー全体 (~/.gemini/extensions/) マニフェスト + スキルを生成
OpenCode .md プロジェクト (.opencode/agents/) そのままコピー
Qwen Code .md プロジェクト (.qwen/agents/) SubAgentとしてコピー

独自の変換スクリプトを構築する

新しいツールを追加するためのテンプレート:

#!/usr/bin/env bash

# 1. Define conversion function
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")

  # 2. Create output path
  local output="path/to/your/tool/agency-${slug}.ext"
  mkdir -p "$(dirname "$output")"

  # 3. Write converted content
  cat > "$output" << EOF
# Your tool-specific format
# Use: $name, $description, $body
EOF

  echo "  YourTool: agency-${slug}.ext"
}

# 4. Add to main loop
for agent_file in engineering/*.md; do
  convert_your_tool "$agent_file"
done

構築したもの

コンポーネント 目的
get_field() YAMLフロントマターの値を抽出
get_body() フロントマターを削除し、Markdown本文を返す
to_kebab() 名前をURLセーフなスラッグに変換
convert_cursor() .mdcフォーマットに変換
convert_aider() 単一ファイルに連結
convert_windsurf() 単一ファイルに連結
convert_antigravity() スキルディレクトリを作成
convert_openclaw() エージェントごとに3つのファイルに分割
install.sh ツール固有のパスにコピー

次のステップ

スクリプトを拡張する:

さらにツールを追加する:

大規模なリポジトリ向けに最適化する:

一般的な問題のトラブルシューティング

変換スクリプトが「bad substitution」で失敗する:

フロントマターフィールドが抽出されない:

スラッグ生成で壊れた名前が作成される:

Cursorルールがロードされない:

AiderのCONVENTIONS.mdが大きくなりすぎる:

大規模変換のためのパフォーマンス最適化

並列処理:

100以上のエージェントを持つリポジトリでは、GNU parallelを使用します:

#!/usr/bin/env bash
# convert-parallel.sh

export OUT_DIR="$REPO_ROOT/integrations"

# Export functions for parallel use
export -f get_field get_body to_kebab convert_cursor convert_claude_code

# Find all agent files and process in parallel
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
# convert-incremental.sh

CACHE_FILE="$REPO_ROOT/.conversion-cache"

# Load previous state
declare -A PREV_HASHES
if [[ -f "$CACHE_FILE" ]]; then
  while IFS='=' read -r file hash; do
    PREV_HASHES["$file"]="$hash"
  done < "$CACHE_FILE"
fi

# Process each agent
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

# Save cache
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))

  # Progress bar
  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.sh

validate_agent() {
  local file="$1"

  # Check required frontmatter fields
  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

  # Check for malicious patterns in body
  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
}

エージェント実行のサンドボックス化:

信頼できないエージェントについては、隔離された環境で実行します:

1つのエージェントファイル。10のIDE。2つのbashスクリプト。

これが変換自動化の力です。一度書けば、自動的に変換され、どこにでもインストールできます。

次はあなたの番です:お気に入りのAIツールに変換サポートを追加しましょう。スクリプトを共有し、エージェントをポータブルにしましょう。

主要なポイント

button

よくある質問

convert.shとは何ですか?どのように機能しますか?convert.shは、エージェントのMarkdownファイルからYAMLフロントマターを解析し、本文コンテンツを抽出し、各エージェントをツール固有のフォーマットに変換するbashスクリプトです。解析にはawkを、スラッグ変換にはsedを、出力生成にはヒアドキュメントを使用します。

bashでのフロントマター解析はどのように行われますか?`get_field()`関数は、awkを使用してフロントマターの区切り文字(`---`)を追跡し、フィールド名と一致する行を見つけて値を抽出します。`get_body()`は、2番目の`---`区切り文字以降のすべての行を出力します。

どのIDEとツールがサポートされていますか?Claude Code (`.md`)、Cursor (`.mdc`)、Aider (`CONVENTIONS.md`)、Windsurf (`.windsurfrules`)、GitHub Copilot (`.md`)、Antigravity (`SKILL.md`)、OpenClaw (`SOUL.md` + 2ファイル)、Gemini CLI拡張機能、OpenCode、Qwen Codeです。

新しいツールの変換サポートを追加するにはどうすればよいですか?フロントマターフィールドを抽出し、本文をツールのフォーマットに変換し、正しいパスに書き込む`convert_yourtool()`関数を作成します。その関数呼び出しをメインの変換ループに追加します。

より高速な処理のために並列で変換を実行できますか?はい。`xargs -P`またはGNU parallelを使用して、複数のエージェントファイルを同時に処理できます。100以上のエージェントの場合、並列変換により実行時間を数分から数秒に短縮できます。

フロントマターフィールドが存在することを確認するにはどうすればよいですか?変換関数に検証チェックを追加します:`[[ -z "$name" ]] && echo "Missing name field" && exit 1`。出力ファイルを書き込む前に検証を実行してください。

一部のエージェントで変換が失敗した場合はどうなりますか?エラー時にすぐに失敗させるために`set -euo pipefail`を使用します。壊れたファイルをスキップするには`|| continue`でエラー処理を追加します。デバッグのために失敗を別のファイルにログとして記録します。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる

AIエージェントを1つ作って10個のIDEで動かす方法