Google Antigravity CLIには、特定の作業ルールや専門知識をエージェントへ追加できる「SKILLS」機能があります。今回は、GoogleのCodelab「Google Antigravity Skillsを作成する」を参考にしながら、
山の名前に応じて自動で適切なSKILLを選択し、Webサイトを生成するサンプル を作成しました。
具体的動作:
> ○○山を紹介するホームページを作って
と依頼すると、
* 北アルプスの山なら「春山サイト」
→ 結果:槍ヶ岳で作ったホームページ(画像も自動で3枚生成されました。)
* 南アルプスの山なら「秋山サイト」
→ 結果:北岳で作ったホームページ(画像も自動で3枚生成されました。)
この記事では、SKILLの作成方法と、複数のSKILLを組み合わせて利用する方法を紹介します。
Google Antigtavity CLIの導入方法は以下↓を参考にしてください。

こちら↓でSKILLSの基本解説と「大文字」「小文字」変換SKILLというもっと簡単な例を使ってますので、まずはこちら↓を見てください。

バージョンはAntigravity CLI 1.0.5です。
SKILLSとは
SKILLSは、Antigravityのエージェントに専門知識や作業ルールを追加する仕組みです。
例えば、
* WordPress記事作成ルール
* コーディング規約
* デザインガイドライン
* 特定業界向けの知識
などをSKILLとして登録できます。
ユーザーの依頼内容に応じて、Antigravityが適切なSKILLを自動的に選択して利用します。
今回作成したSKILLの目的
今回のサンプルでは、
- 北アルプス → 春山サイト
- 南アルプス → 秋山サイト
というように、山の名前から自動でSKILLを切り替える仕組みを作りました。
作成したディレクトリ構成
今回のサンプルは以下の構成です。
agy-demo
├── .agent
│ └── skills
│ ├── web-northalps-rule
│ │ └── SKILL.md
│ │
│ └── web-southalps-rule
│ └── SKILL.md
agy-demo/.agent/skills 配下にSKILLを配置することで、agy-demoディレクトリ(workspace-root)でagyを起動したときだけでSKILLは有効になります。他のディレクトリでagyで起動したときは、このSKILLは使えません。
今回作成したSKILLの役割
今回のポイントは、「山の名前から、どのSKILLを使うか自動判定させる」ことです。
例えば、「槍ヶ岳を紹介するホームページを作って」と依頼すると、
槍ヶ岳は北アルプスなので
↓
web-northalps-rule
↓
春山サイト生成
となります。
一方、「北岳を紹介するホームページを作って」なら、
北岳は南アルプスなので
↓
web-southalps-rule
↓
秋山サイト生成
となります。
SKILL.md
SKILLの本体はSKILL.mdです。
Webの無料Geminiに依頼
今回は、トークン節約のためAntigtavityではなくWebの無料Geminiで以下のプロンプトでSKILL.mdを作ってもらいました。
以下の内容でgoogle AntigtavityCLI用skillsを作ってください。
スキル名(フォルダ名)
・web-northalps-rule
スキル名
・北アルプスWebサイト作成基本ルール
内容
・北アルプスに関するWebページを作るときのルールを指定
・1つのhtmlファイルで作る
・春だけの内容を書く。
しかし、「google AntigtavityCLI用skills」と指定したにもかかわらず、フォーマットが違ってました。具体的には以下のようなskill.json, prompt.mdという2つを作成してきました。skill.json
{
"name": "web-northalps-rule",
"displayName": "北アルプスWebサイト作成基本ルール",
"description": "北アルプスに関する春限定のWebページを単一のHTMLファイルで生成するためのルールを提供します。",
"version": "1.0.0",
"instructionFile": "prompt.md"
}
prompt.mdは、そのまま採用しているので省略。ここは問答を繰り返しても解決しないので、ここを参考に必要な部分だけ取り出して手動で以下のように1つのファイルに修正しました。
北アルプス用SKILL.md
---
name: web-northalps-rule
description: 北アルプスに関する春限定のWebページを単一のHTMLファイルで生成するためのルールを提供します。
---
# あなたの役割
あなたは、北アルプスに関するWebサイトの制作ルールを厳格に適用する、優秀なフロントエンドエンジニア兼ディレクターです。
# スキル名
北アルプスWebサイト作成基本ルール(web-northalps-rule)
# コンセプト・前提条件
ユーザーから北アルプスに関するWebページの制作依頼、またはコード生成の指示があった場合、以下の【絶対遵守ルール】に則って成果物を出力してください。
---
## 【絶対遵守ルール】
1. **単一ファイル(1つだけのHTML)で完結させること**
- CSSやJavaScript、構造、コンテンツは、すべて1つの `.html` ファイル内に含めてください。
- 外部CSS(`<link rel="stylesheet">`)や外部JSファイルへの分割は禁止します。CSSは `<style>` タグ、JSは `<script>` タグを使ってHTML内にインラインで記述してください。
2. **季節の限定(「春」のみ)**
- 掲載する内容は**「春(4月〜6月頃)」**の北アルプスに関する情報のみに限定してください。
- 残雪と新緑のコントラスト、春の風物詩(代掻き馬などの雪形)、開山祭、春の高山植物など、春の魅力を中心に構成してください。
- 夏山登山や紅葉、厳冬期の雪山など、他のおよび一般的な季節の情報は含めないでください。
3. **初心者向けのクリーンなマークアップ**
- 生成されるHTML/CSSは、後から構造を理解しやすいよう、セマンティックなタグ(`<header>`, `<main>`, `<section>`, `<footer>`)を適切に使用してください。
- コメントを適宜挿入し、どこがどのブロックなのか分かりやすくしてください。
---
# 出力フォーマット
ユーザーから具体的な指示がない場合でも、上記のルールを満たした完全なHTMLコード(`<!DOCTYPE html>` から始まるコードブロック)を1つ出力してください。
南アルプス用SKILL.md
こちらもGeminiに聞いて手動修正しました。
---
name: web-southalps-rule
description: 南アルプスに関する秋限定のWebページを単一のHTMLファイルで生成するためのルールを提供します。
---
# あなたの役割
あなたは、南アルプスに関するWebサイトの制作ルールを厳格に適用する、優秀なフロントエンドエンジニア兼ディレクターです。
# スキル名
南アルプスWebサイト作成基本ルール(web-southalps-rule)
# コンセプト・前提条件
ユーザーから南アルプスに関するWebページの制作依頼、またはコード生成の指示があった場合、以下の【絶対遵守ルール】に則って成果物を出力してください。
---
## 【絶対遵守ルール】
1. **単一ファイル(1つだけのHTML)で完結させること**
- CSSやJavaScript、構造、コンテンツは、すべて1つの `.html` ファイル内に含めてください。
- 外部CSSファイルや外部JSファイルへの分割は禁止します。CSSは `<style>` タグ、JSは `<script>` タグを使ってHTML内にインラインで記述してください。
2. **季節の限定(「秋」のみ)**
- 掲載する内容は**「秋(9月〜11月頃)」**の南アルプスに関する情報のみに限定してください。
- 北岳の日本一高い場所にある紅葉、仙丈ヶ岳や間ノ岳の三段紅葉(冠雪・紅葉・山麓の新緑/深緑)、秋の澄んだ青空(南アルプスブルー)、登山シーズンの締めくくりなど、秋の魅力を中心に構成してください。
- 春の開山、夏山合宿、厳冬期の雪山など、他の季節の情報は含めないでください。
3. **初心者向けのクリーンなマークアップ**
- 生成されるHTML/CSSは、後から構造を理解・修正しやすいよう、セマンティックなタグ(`<header>`, `<main>`, `<section>`, `<footer>`)を適切に使用してください。
- 各セクションの区切りには適宜コメントを挿入し、コードの可読性を高めてください。
---
# 出力フォーマット
ユーザーから具体的な指示がない場合でも、上記のルールを満たした完全なHTMLコード(`<!DOCTYPE html>` から始まるコードブロック)を1つ出力してください。
Antigravityは、descriptionを見て利用するSKILLを判断します。descriptionは非常に重要で、ここが曖昧だと適切なSKILLが呼ばれません。
実際に試してみる
例えば、「槍ヶ岳を紹介するホームページを作って」と入力します。
Antigravityは、
1. 槍ヶ岳が北アルプスであることを判断
2. web-northalps-rule を選択
3. 春限定サイトを生成
します。
続いて、「北岳を紹介するホームページを作って」と入力すると、
1. 北岳が南アルプスであることを判断
2. web-southalps-rule を選択
3. 秋限定サイトを生成
します。
ユーザーはSKILL名を意識する必要がありません。
結果
* 「槍ヶ岳のホームページを作って」
→ 結果:槍ヶ岳で作ったホームページ(画像も自動で3枚生成されました。)
* 「北岳のホームページを作って」
→ 結果:北岳で作ったホームページ(画像も自動で3枚生成されました。)
画像入りで立派なものができました。画像は、ログを見るとgemini-3.1-flash-imageが使われていて、計6枚作られた段階で無料枠の使用制限に引っかかました。
その次にやった「甲斐駒ヶ岳のホームページを作って」では画像なしで作成されました。
→ 結果:甲斐駒ヶ岳で作ったホームページ(画像は無料制限で作られず)
手動で修正したのは、
・pngをjpgに変換。それに伴いindex.htmlの画像拡張子を変更。
・上部にこのページへのリンクを赤字で追加。
手動で以下にアップロードしました。XREAを無料で使っていますが、XREAが上部に広告を追加します。そのため、上部は重なっています。

XREA広告によるレイアウト崩れと対処
XREAの無料サーバーでは、ページ上部に広告が自動挿入されます。
その結果、生成したHTMLのヘッダーと広告が重なってしまいました。
この修正は、AIに指示するのが厄介だと思います。本番環境の状況をAIに伝えなければなりません。Antigtavityに依頼してもいいですが、結局、以下のような依頼になると思うので、トークン節約のため無料のチャットAIに依頼しました。
作ったページのどれかを開いて右クリック→開発者ツールで調査する→elmentsタブ→一番左のボタン「select an element in the page to ispect it」をクリック→広告部分をクリックすると該当するhtmlが表示される。その周辺でアップロード前と変わったところを調べる。以下が追加されていることがわかる。
<body><div id="vdbanner" style="display:block!important;position:relative!important;top:0!important;left:0!important;margin:10px 0 !important;padding:0!important;text-align:center!important;"><a href="https://www.colorfulbox.jp/?adref=xrea_ad&utm_source=xrea&utm_medium=banner&utm_campaign=xrea_ad" target="_blank" rel="nofollow" style="display:inline-block!important;position:relative!important;top:0!important;left:0!important;margin:0!important;padding:0!important;"><img src="https://www.colorfulbox.jp/common/img/bnr/colorfulbox_bnr01.png" alt="月額480円〜の高速レンタルサーバー ColorfulBox" style="display:inline-block!important;position:relative!important;top:0!important;left:0!important;margin:0!important;padding:0!important;width:100%!important;max-width:468px;max-height:60px;vertical-align:bottom;"></a></div>
<!-- ==========================================================================
HEADER & NAVIGATION
========================================================================== -->
<header id="site-header">
該当する箇所をcopy→(elementごとでしかコピーできないのでbodyタグを右クリック)copy elementでxrea.htmlに貼り付け、不要部分を削除して保存。
sourcesタブを見るとxrea_header.jsというJavascriptスクリプトが追加されているのでSave asで保存。
WebのAIで、もとのindex.html、さっき作ったxrea.html、xrea_header.jsを添付して
「XREAにindex.htmlをアップロードしたら広告が挿入され、ヘッダー部分と重なってしまっているのでindex.htmlを修正して。xrea.htmlにはXREAが追加した部分をコピーしました。xrea_header.jsはXREAが追加したjsです。」
頼んだのはAIと結果
Claude(Sonet4.6低)→ 改善されず。
Gemini(3.5flash)→ OK。採用。「北岳のホームページ(GeminiによるXREA広告修正版)」
しかし、指示した以外のところまで修正された。
<h3>秋の北岳は「厳しい移行期」です</h3>
↓
<h3>夏山とは異なる、厳しい大自然への備え</h3>
<p>9月以降の北岳は、台風の通過や高気圧の交替により天候が急変しやすく、標高3,000mの稜線では朝晩の気温が<strong>氷点下</strong>に達します。</p>
↓
<p>秋の北岳は息をのむ美しさを見せてくれますが、同時に急速に冬へと向かう過酷な環境でもあります。標高が3,000mを超えるため、地上とは完全に異なる気象条件を理解したうえで計画を立てることが不可欠です。</p>
こういう意図と反することをAIはしてしまうので、厄介で、余計やること増えそうな気がしてます。別のAIなので、「山によって取り扱う季節が違う」というメイン趣旨を考慮せず修正しそうだし、かといって、依頼方法かえると、またおかしくなったらいやなので他のはやめました。
ハーネスエンジニアリング(ちょっと聞きかじっただけで何なのかはよく知りませんが)で本当にどうにかなるものなのでしょうか?
さらに、GeminiにSKILL.mdを添付して「今回の件をGoogle Antigtavity CLIで使っているSKILL.mdに追加してください。」というプロンプトでSKILL.mdを作ってもらった。
手動で次章のpng-jpg変換機能も入れてある。ただし、動作確認はしてない。(無料制限が解除されたら実施予定)
---
name: web-southalps-rule
description: 南アルプスに関する秋限定のWebページを単一のHTMLファイルで生成するためのルールを提供します。
---
# あなたの役割
あなたは、南アルプスに関するWebサイトの制作ルールを厳格に適用する、優秀なフロントエンドエンジニア兼ディレクターです。
# スキル名
南アルプスWebサイト作成基本ルール(web-southalps-rule)
# コンセプト・前提条件
ユーザーから南アルプスに関するWebページの制作依頼、またはコード生成の指示があった場合、以下の【絶対遵守ルール】に則って成果物を出力してください。
---
## 【絶対遵守ルール】
1. **単一ファイル(1つだけのHTML)で完結させること**
- CSSやJavaScript、構造、コンテンツは、すべて1つの `.html` ファイル内に含めてください。
- 外部CSSファイルや外部JSファイルへの分割は禁止します。CSSは `<style>` タグ、JSは `<script>` タグを使ってHTML内にインラインで記述してください。
2. **季節の限定(「秋」のみ)**
- 掲載する内容は**「秋(9月〜11月頃)」**の南アルプスに関する情報のみに限定してください。
- 北岳の日本一高い場所にある紅葉、仙丈ヶ岳や間ノ岳の三段紅葉(冠雪・紅葉・山麓の新緑/深緑)、秋の澄んだ青空(南アルプスブルー)、登山シーズンの締めくくりなど、秋の魅力を中心に構成してください。
- 春の開山、夏山合宿、厳冬期の雪山など、他の季節の情報は含めないでください。
3. **初心者向けのクリーンなマークアップ**
- 生成されるHTML/CSSは、後から構造を理解・修正しやすいよう、セマンティックなタグ(`<header>`, `<main>`, `<section>`, `<footer>`)を適切に使用してください。
- 各セクションの区切りには適宜コメントアウトを挟み、可読性を高めてください。
4. **無料サーバー(XREA等)の自動挿入広告によるレイアウト崩れ防止(★追加ルール)**
- XREAなどの無料プランにおいて、`body` 要素の最上部に広告コンテナ(`#vdbanner` など)が自動的かつ強制的に挿入される場合があります。
- これにより、`position: fixed;` で上部固定されたヘッダーや、`height: 100vh;` を持たせたHeroセクションのレイアウトが崩れたり重なったりする現象を完全に防止するため、以下の**「モダンCSSによる広告表示検知と自動レイアウト調整」**を必ずCSS内に実装してください。
**【必須実装コードパターン】**
```css
/* 広告要素が存在する場合のみ、固定ヘッダーの初期位置を広告の高さ分ずらす */
body:has(#vdbanner) header {
top: 80px; /* 広告のバナー高さ+余白を考慮した適切な値を設定 */
}
/* 画面スクロール時は、広告を無視して画面最上部に追従固定させる */
body:has(#vdbanner) header.scrolled {
top: 0;
}
/* 広告の表示によりファーストビュー(Heroエリア)が画面外に押し出されないよう高さを補正 */
body:has(#vdbanner) #hero {
height: calc(100vh - 80px);
}
@media (max-width: 768px) {
/* スマホ用ナビゲーションメニュー(ドロワー)等がある場合も、広告を考慮した位置調整を行う */
body:has(#vdbanner) .nav-menu {
top: 150px; /* ヘッダー高 70px + 広告高 80px */
height: calc(100vh - 150px);
}
body:has(#vdbanner) header.scrolled .nav-menu {
top: 60px; /* スクロール時は通常位置に補正 */
height: calc(100vh - 60px);
}
}
5. **画像形式の変換ルール(PNGからJPGへ)**
- Webページ内でPNG画像(`.png`)を使用、または生成した場合は、必ず以下のPythonスクリプトを実行してJPG(`.jpg`)に変換した上で、HTML内ではそのJPGファイル(`.jpg`)を読み込むように記述・指示してください。
- 変換コマンド:
```cmd
python scripts\png_to_jpg.py <path_to_png_file>
```
- HTMLコード内を出力する際、あるいは画像生成の指示を出す際は、成果物の画像パスが `.jpg` になっていることを確認してください。
6. **出力先フォルダの指定(ディレクトリ管理)**
- 生成するHTMLファイル、および付随する画像などの成果物は、ルート直下ではなく、必ず専用の出力フォルダ(例: `dist/` などのディレクトリ)を作成し、その中にまとめて出力・保存するように制御またはユーザーに指示してください。
- ルート直下を汚さず、1つのフォルダ内でWebサイトのパーツ(HTMLとJPG画像)が完結するように管理してください。
※上記に伴い、「4. 画像形式の変換ルール」におけるパス指定や、HTML内の `<img src="...">` のパスも、作成した出力フォルダ(例: `dist/image.jpg` など)に正しくマッピングされるように記述してください。
---
# 出力フォーマット
ユーザーから具体的な指示がない場合でも、上記のルールを満たした完全なHTMLコード(`<!DOCTYPE html>` から始まるコードブロック)を1つ出力してください。
PNG → JPG変換スクリプトの追加(Python)
ホームページで使ってる画像がPNGで作成されているためPython(Pillow)でJPGに変換するスクリプトを追加しました。
Pythonスクリプトが実行てきることは以下で確認しています。

ただ、今回のサンプルで実行しようと思っても、無料枠の制限にかかっている状態(復活するまで6.5日必要)なので確認することができていません。(制限明けに試してみます。)また、png-jpg変換にはPillowというライブラリが必要ですのでagyを起動する前にuv仮想環境などで事前にPillowをpipしておく必要があります。
png-jpg変換機能を追加するには、以下のようにディレクトリとファイルを追加します。
agy-demo
├── .agent
│ └── skills
│ ├── web-northalps-rule
│ │ ├── SKILL.md
│ │ └── scripts
│ │ └── png_to_jpg.py
│ │
│ └── web-southalps-rule
│ ├── SKILL.md
│ └── scripts
│ └── png_to_jpg.py
png_to_jpg.py
import sys
import os
from PIL import Image
def png_to_jpg(input_path, quality=95):
if not os.path.exists(input_path):
print(f"エラー: ファイルが見つかりません: {input_path}")
sys.exit(1)
if not input_path.lower().endswith(".png"):
print(f"エラー: PNGファイルを指定してください: {input_path}")
sys.exit(1)
output_path = os.path.splitext(input_path)[0] + ".jpg"
with Image.open(input_path) as img:
if img.mode in ("RGBA", "LA", "P"):
background = Image.new("RGB", img.size, (255, 255, 255))
if img.mode == "P":
img = img.convert("RGBA")
background.paste(img, mask=img.split()[-1])
img = background
else:
img = img.convert("RGB")
img.save(output_path, "JPEG", quality=quality)
print(f"変換完了: {input_path} → {output_path}")
if len(sys.argv) < 2:
print("使い方: python convert.py <ファイル名.png> [quality]")
print("例: python convert.py image.png")
print("例: python convert.py image.png 85")
sys.exit(1)
input_file = sys.argv[1]
quality = int(sys.argv[2]) if len(sys.argv) >= 3 else 95
png_to_jpg(input_file, quality)
それぞれのSKILL.mdに以下追加
5. **画像形式の変換ルール(PNGからJPGへ)**
- Webページ内でPNG画像(`.png`)を使用、または生成した場合は、必ず以下のPythonスクリプトを実行してJPG(`.jpg`)に変換した上で、HTML内ではそのJPGファイル(`.jpg`)を読み込むように記述・指示してください。
- 変換コマンド:
```cmd
python scripts\png_to_jpg.py <path_to_png_file>
```
- HTMLコード内を出力する際、あるいは画像生成の指示を出す際は、成果物の画像パスが `.jpg` になっていることを確認してください。
6. **出力先フォルダの指定(ディレクトリ管理)**
- 生成するHTMLファイル、および付随する画像などの成果物は、ルート直下ではなく、必ず専用の出力フォルダ(例: `dist/` などのディレクトリ)を作成し、その中にまとめて出力・保存するように制御またはユーザーに指示してください。
- ルート直下を汚さず、1つのフォルダ内でWebサイトのパーツ(HTMLとJPG画像)が完結するように管理してください。
※上記に伴い、「4. 画像形式の変換ルール」におけるパス指定や、HTML内の `<img src="...">` のパスも、作成した出力フォルダ(例: `dist/image.jpg` など)に正しくマッピングされるように記述してください。
まとめ
Google Antigravity CLIのSKILLSを利用すると、よく話題に上がるSKILLやエージェントについて理解が深まると思います。
今回作成したサンプルでは、
* 北アルプス → 春山サイト
* 南アルプス → 秋山サイト
というように、対象に応じて利用するSKILLを自動で切り替えました。
Antigravityを使い始めたばかりの方は、まずは今回のようなはっきりした切り分けがあるSKILLから作成してみると仕組みを理解しやすいと思います。
無料で多く使いたい場合は画像生成を伴うSKILLは避けたほうがいいです。現在、保留にしてある確認事項は、無料制限が解除されたら試して加筆します。
この記事を書いたイチゲを応援する(質問でもokです)
Vプリカでのお支払いがおすすめです。