ANTIGRAVITY LABEN
記事一覧/Agents & Manager
Agents & Manager/2026-05-05中級

Antigravity AI エージェントが動かない時の診断手順

Antigravity の AI エージェントが期待通りに動かない時の原因を効率よく絞り込む診断手順を解説。ツール呼び出しエラー・無限ループ・コンテキスト管理の問題など、よくある詰まりポイントと対処法をまとめました。

antigravity435agents90troubleshooting88debug2agentic

「エージェントが途中で止まる」「同じツールを何度も呼び出してループする」「期待していたアクションをとらない」——AI エージェントを実際に動かすと、こういうトラブルが必ず出てきます。

エージェントのデバッグが難しいのは、モデルの判断プロセスが完全にはわからないからです。でも、詰まるポイントにはある程度のパターンがあります。よくある原因と、効率よく絞り込む診断の手順を整理しました。

まず確認すること: エラーの種類を特定する

エージェントが「動かない」と一口に言っても、状況は大きく異なります。最初にどのカテゴリの問題かを特定することが大切です。

カテゴリ1: エージェントが起動しない

  • ツールの設定が間違っている
  • 認証エラー
  • プロンプトの形式が正しくない

カテゴリ2: エージェントが途中で止まる

  • ツール呼び出しが失敗している
  • 入力データの形式がツールと合っていない
  • タイムアウト

カテゴリ3: エージェントがループする

  • タスクの完了条件が不明確
  • ツールのレスポンスが次のアクションの判断に使えていない
  • メモリ/コンテキストの管理の問題

カテゴリ4: エージェントが間違った行動をとる

  • システムプロンプトが不明確
  • ツールの説明(description)が曖昧
  • Few-shot 例が逆効果になっている

この分類をするだけで、デバッグの方向性がかなり絞れます。

カテゴリ1の診断: エージェントが起動しない

Antigravity でエージェントを設定する際の典型的なミスを確認します。

# まずシンプルな疎通確認から始める
import os
from google import genai
from google.genai import types
 
client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))
 
# ✅ Step 1: ツールなしで基本的な疎通を確認する
response = client.models.generate_content(
    model="gemini-2.5-pro",
    contents="こんにちは。テストメッセージです。"
)
print("疎通確認:", response.text[:50])
 
# ✅ Step 2: ツールを1つだけ追加して確認する
def get_current_time() -> str:
    """現在の時刻を返します"""
    from datetime import datetime
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S JST")
 
response = client.models.generate_content(
    model="gemini-2.5-pro",
    contents="現在の時刻を教えてください",
    config=types.GenerateContentConfig(
        tools=[get_current_time],  # 1つのツールだけ
        system_instruction="ユーザーのリクエストに応じてツールを使用してください。"
    )
)
print("ツール呼び出し確認:", response.candidates[0].content)

疎通確認からシンプルなツール追加へと段階的に試すことで、どの段階で問題が起きているかがわかります。

カテゴリ2の診断: ツール呼び出しの失敗

ツールが呼び出されているのに結果が正しくない場合は、ツールの入出力をロギングして確認します。

import json
import logging
from datetime import datetime
from typing import Any
 
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
 
def debug_tool_wrapper(tool_func):
    """ツール呼び出しのデバッグログを記録するデコレータ"""
    def wrapper(*args, **kwargs):
        call_id = datetime.now().strftime("%H:%M:%S.%f")
        logger.debug(f"[{call_id}] ツール呼び出し: {tool_func.__name__}")
        logger.debug(f"[{call_id}] 引数: args={args}, kwargs={kwargs}")
        
        try:
            result = tool_func(*args, **kwargs)
            logger.debug(f"[{call_id}] 成功: {str(result)[:200]}")
            return result
        except Exception as e:
            logger.error(f"[{call_id}] エラー: {type(e).__name__}: {e}")
            # エラーをそのまま投げると エージェントが止まるので、エラー情報を返す
            return f"エラーが発生しました: {type(e).__name__}: {str(e)}"
    
    wrapper.__name__ = tool_func.__name__
    wrapper.__doc__ = tool_func.__doc__
    return wrapper
 
# 実際のツールにデバッグラッパーを適用
@debug_tool_wrapper
def search_database(query: str, limit: int = 10) -> str:
    """データベースを検索して結果を返します。
    
    Args:
        query: 検索クエリ
        limit: 返す結果の最大件数(デフォルト: 10)
    
    Returns:
        JSON形式の検索結果
    """
    # 実際の検索処理
    results = perform_actual_search(query, limit)
    return json.dumps(results, ensure_ascii=False)

ツールのエラーハンドリングで特に重要なのは、例外をそのまま投げないことです。エージェントはツールからのレスポンスを次の判断に使うため、エラー情報を文字列として返してあげることで、エージェントが状況を理解して次の行動を選べるようになります。

カテゴリ3の診断: ループの検出と対処

エージェントがループに入っている場合、コールバックでステップを記録して原因を特定します。

from google import genai
from google.genai import types
import os
 
class AgentLoopDetector:
    """エージェントのループを検出するクラス"""
    
    def __init__(self, max_repetitions: int = 3, max_steps: int = 20):
        self.tool_call_history: list[tuple[str, str]] = []  # (ツール名, 引数ハッシュ)
        self.step_count = 0
        self.max_repetitions = max_repetitions
        self.max_steps = max_steps
    
    def record_tool_call(self, tool_name: str, args: dict) -> bool:
        """ツール呼び出しを記録し、ループを検出した場合は True を返す"""
        self.step_count += 1
        
        # ステップ数の上限チェック
        if self.step_count > self.max_steps:
            print(f"⚠️ 最大ステップ数 ({self.max_steps}) に達しました")
            return True
        
        # 同じツールに同じ引数を繰り返し呼んでいるか確認
        call_signature = (tool_name, str(sorted(args.items()) if args else []))
        recent_calls = self.tool_call_history[-self.max_repetitions * 2:]
        repetition_count = recent_calls.count(call_signature)
        
        self.tool_call_history.append(call_signature)
        
        if repetition_count >= self.max_repetitions - 1:
            print(f"⚠️ ループ検出: {tool_name}{repetition_count + 1} 回繰り返されています")
            print(f"   直近の呼び出し履歴: {recent_calls[-6:]}")
            return True
        
        return False
 
# 使用例
detector = AgentLoopDetector(max_repetitions=3, max_steps=15)
 
# エージェントのステップ実行前にループチェック
def safe_execute_agent_step(tool_name: str, args: dict):
    if detector.record_tool_call(tool_name, args):
        raise RuntimeError(f"エージェントループを検出しました。処理を中断します。ステップ: {detector.step_count}")
    # 実際のツール実行
    return execute_tool(tool_name, args)

ループが起きる根本原因の多くは、タスクの完了条件が曖昧なことです。システムプロンプトに「タスクが完了したと判断する基準」を明示しましょう。

# ❌ ループが起きやすいシステムプロンプト
bad_system = """
ユーザーの質問に答えてください。
必要に応じてツールを使用してください。
"""
 
# ✅ 完了条件を明示したシステムプロンプト
good_system = """
あなたはリサーチエージェントです。
 
## タスク
ユーザーの質問に対して、ツールを使って情報を収集し、回答を生成します。
 
## 完了条件
以下のいずれかの条件を満たしたら、ツールの使用を停止して最終回答を生成してください:
1. 質問に答えるために必要な情報がすべて揃った
2. 検索ツールを3回使用したが情報が見つからなかった
3. 同じ検索を2回実行した
 
## 重要なルール
- 同じ検索クエリを2回以上実行しない
- 情報が不足していても、得られた情報の範囲で最善の回答を提供する
- 「情報が見つかりませんでした」で終わらず、代替案や次のステップを提案する
"""

カテゴリ4の診断: 間違った行動の原因を特定する

エージェントが意図しない行動をとる場合、ツールの description が問題のことがよくあります。

# ❌ 曖昧なツール説明(エージェントが誤用しやすい)
def search_knowledge_base(query: str) -> str:
    """ナレッジベースを検索する"""
    # ...
 
# ✅ 具体的なツール説明(いつ使うべきか・何を返すかが明確)
def search_knowledge_base(query: str, search_type: str = "semantic") -> str:
    """社内のナレッジベースを検索して関連ドキュメントを返します。
    
    このツールは、以下の場合に使用してください:
    - ユーザーが製品仕様・マニュアル・FAQ に関する質問をしている
    - 過去のトラブル対応事例を調べたい
    
    このツールは、以下には使用しないでください:
    - リアルタイムの外部情報が必要な場合(web_search を使ってください)
    - データベースのレコードを取得する場合(query_database を使ってください)
    
    Args:
        query: 検索キーワードまたは自然言語による質問
        search_type: "semantic"(意味的検索)または "keyword"(キーワード検索)
    
    Returns:
        関連ドキュメントの内容を含むJSON文字列。各ドキュメントには
        title・content・relevance_score・last_updated が含まれます。
        結果が見つからない場合は空のリストを返します。
    """
    # ...

ツールの description に「いつ使うべきか・使うべきでないか」を書くことで、エージェントが適切なツールを選べるようになります。


エージェントのデバッグは試行錯誤が必要ですが、まずカテゴリを絞り込んでから原因を探ると効率よく進められます。ログとループ検出の仕組みを最初から入れておくことで、本番で問題が起きた時の調査時間を大幅に短縮できます。

最初は safe_execute_agent_step の実装から始めてみてください。ループを検出できるようになるだけで、エージェントのデバッグがずいぶん楽になります。

個人開発12年とアーティスト活動から見るエージェント設計

線引きするときの3つの判断軸

  • 失敗時の影響が金銭やユーザー体験にどれだけ波及するか
  • 復旧オペレーションが明文化されているか
  • 観測ログから人間が再現できる粒度に整っているか

まとめ — 検証ステップの推奨

  1. 観測メトリクスとアラートを設置
  2. 限定ロールアウトで本番検証
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Agents & Manager2026-07-15
ls には見えるのに、エージェントが開けない — 日本語ファイル名が macOS と Linux で別物になるとき
エージェントが「そのファイルは存在しません」と言い、ターミナルの ls には確かに写っている。三日かけて同期を疑った末に辿り着いたのは、濁点が一文字ではなかったという事実でした。検出スクリプトと三層ゲートまで残します。
Agents & Manager2026-05-30
Antigravity のエージェントが node や python を『command not found』にするときの原因と対処
自分のターミナルでは動くのに、Antigravity のエージェントがコマンドを実行すると command not found になる。PATH 継承の仕組みから、nvm・pyenv・Homebrew・WSL 環境ごとの具体的な解決手順と、直ったかどうかの確かめ方までまとめます。
Agents & Manager2026-05-26
Antigravity の Browser Sub-Agent が SPA を空ページと誤認する原因と待機戦略
Antigravity の Browser Sub-Agent に SPA ダッシュボードを読ませると、本文が描画される前に get_page_text が返ってきて空ページ扱いされる。原因と、私の運用で安定した3つの待機パターンを整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →