カスタムエージェント開発ガイド

MixSeek-Coreでは、標準バンドル以外にカスタムMember Agentを開発して動的にロードできます。この機能により、独自のドメイン知識やツールを統合したエージェントを作成できます(FR-020-FR-022)。

動的ロード方式

カスタムエージェントは2つの方法でロードできます

  1. agent_module(推奨): pip インストール可能なPythonパッケージからロード(本番環境向け)

  2. path(代替): スタンドアロンPythonファイルからロード(開発・プロトタイピング向け)

優先順位処理(FR-021)

  • agent_moduleが指定されている場合、優先的に試行

  • agent_moduleが失敗または未指定の場合、pathにフォールバック

カスタムエージェントクラスの実装

すべてのカスタムエージェントはBaseMemberAgentを継承する必要があります

from typing import Any

from mixseek.agents.member.base import BaseMemberAgent
from mixseek.models.member_agent import MemberAgentConfig, MemberAgentResult

class DataAnalystAgent(BaseMemberAgent):
    """データ分析専門カスタムエージェント"""

    def __init__(self, config: MemberAgentConfig):
        super().__init__(config)
        # カスタム初期化処理

    async def execute(self, task: str, context: dict[str, Any] | None = None, **kwargs: Any) -> MemberAgentResult:
        """
        エージェント実行のメインエントリポイント

        Args:
            task: タスク説明
            context: 実行コンテキスト
            **kwargs: 追加パラメータ

        Returns:
            MemberAgentResult: 実行結果
        """
        # カスタムロジックの実装
        # self._agent(Pydantic AI Agent)を使用して推論実行
        result = await self._agent.run(task)

        return MemberAgentResult.success(
            content=result.data,
            agent_name=self.config.name,
            agent_type=self.config.type,
        )

TOML設定

agent_module方式(推奨)

pipインストール可能なパッケージからロードする方式

[agent]
name = "data-analyst"
type = "custom"
model = "google-gla:gemini-2.5-flash-lite"
system_instruction = "You are a data analyst with expertise in pandas and numpy. Analyze data and provide insights based on statistical methods."
description = "Pandas/NumPyを使ったデータ分析専門エージェント"

[agent.plugin]
agent_module = "my_analytics_package.agents.data_analyst"
agent_class = "DataAnalystAgent"

パッケージのインストール

pip install my_analytics_package

path方式(代替)

開発環境でスタンドアロンファイルからロードする方式

Warning

セキュリティ警告: path方式は指定されたファイルからPythonコードを実行します。 信頼できるソースからのファイルのみを使用してください。 本番環境ではagent_module方式の使用を強く推奨します。

[agent]
name = "data-analyst"
type = "custom"
model = "google-gla:gemini-2.5-flash-lite"
system_instruction = "You are a data analyst with expertise in pandas and numpy. Analyze data and provide insights based on statistical methods."
description = "Pandas/NumPyを使ったデータ分析専門エージェント"

[agent.plugin]
path = "/path/to/custom_agent.py"
agent_class = "DataAnalystAgent"

両方指定(フォールバック)

本番環境ではagent_moduleを使い、開発環境ではpathにフォールバックする構成

[agent]
name = "data-analyst"
type = "custom"
model = "google-gla:gemini-2.5-flash-lite"
system_instruction = "You are a data analyst with expertise in pandas and numpy. Analyze data and provide insights based on statistical methods."
description = "Pandas/NumPyを使ったデータ分析専門エージェント"

[agent.plugin]
agent_module = "my_analytics_package.agents.data_analyst"  # 優先
path = "/path/to/custom_agent.py"                          # フォールバック
agent_class = "DataAnalystAgent"

エラーハンドリング

カスタムエージェントのロードに失敗した場合、詳細なエラーメッセージが表示されます(FR-022)

agent_module方式のエラー例

Error: Failed to load custom agent from module 'my_package.agents.custom'.
ModuleNotFoundError: No module named 'my_package'.
Install package: pip install <package-name>

path方式のエラー例

Error: Failed to load custom agent from path '/path/to/custom_agent.py'.
FileNotFoundError: File not found.
Check file path in TOML config.

クラス名エラー例

Error: Custom agent class 'WrongClassName' not found in module 'my_package.agents'.
Check agent_class in TOML config.

使用方法

カスタムエージェントは標準エージェントと同じ方法で使用できます

# CLIで実行
mixseek member "Analyze this dataset" --config custom_agent.toml

# 出力形式指定
mixseek member "Analyze sales trends" \
  --config custom_agent.toml \
  --output-format json

実装例: bitbank API統合

実際の外部API統合を通じて、カスタムエージェントの実装方法を学びます。

概要

bitbank Public APIと統合し、暗号通貨の財務指標分析を行うカスタムエージェントです。

機能:

  • リアルタイム価格取得(ティッカーデータ)

  • ローソク足データ分析(OHLCV)

  • 財務指標計算(シャープレシオ、ソルティノレシオ、最大ドローダウン、歪度、尖度)

学べること:

  • 外部API統合(httpx、リトライロジック、レート制限)

  • Pydantic AIツール登録(複数ツールの管理)

  • 非同期処理(async/await)

  • エラーハンドリング(明示的なエラー伝播)

  • TOML設定管理(すべての定数値を外部化)

ファイル構成

examples/custom_agents/bitbank/
├── agent.py                   # エージェントクラス(BitbankAPIAgent)
├── models.py                  # Pydanticモデル(FinancialSummary, BitbankAPIConfig等)
├── client.py                  # 非同期HTTPクライアント(BitbankAPIClient)
├── tools.py                   # ツール関数(ticker取得、財務指標計算)
├── bitbank_agent.toml         # TOML設定ファイル
└── README.md                  # 詳細な使用方法

実装手順

ステップ1: Pydanticモデル定義

財務指標とAPI設定のモデルを定義します。すべてのデータ構造はPydanticでバリデーションします

Listing 1 examples/custom_agents/bitbank/models.py - FinancialSummaryモデル(抜粋)
    @property
    def volumes(self) -> np.ndarray:
        """Array of volumes (numpy)."""
        return np.array([entry.volume for entry in self.ohlcv])

    @property
    def timestamps(self) -> np.ndarray:
        """Array of timestamps (numpy)."""
        return np.array([entry.timestamp for entry in self.ohlcv])

    model_config = ConfigDict(
        json_schema_extra={
            "examples": [
                {
                    "pair": "btc_jpy",

ポイント:

  • Fieldでバリデーションルールを定義(ge=0, le=0等)

  • docstringで各フィールドの意味を明記

  • 財務指標の計算に必要なすべてのパラメータをモデル化

ステップ2: APIクライアント実装

非同期HTTPクライアントとリトライロジックを実装します

Listing 2 examples/custom_agents/bitbank/client.py - リトライロジック(抜粋)
        """Execute HTTP request with exponential backoff retry.

        Args:
            url: Full API endpoint URL.

        Returns:
            JSON response as dictionary.

        Raises:
            RuntimeError: On network errors, timeouts, or HTTP errors.
        """
        for attempt in range(self.config.max_retries):
            try:
                await self._enforce_rate_limit()

                async with httpx.AsyncClient(timeout=self.config.timeout_seconds) as client:
                    response = await client.get(url)

                    # Handle rate limiting (HTTP 429)
                    if response.status_code == 429:
                        if attempt < self.config.max_retries - 1:
                            wait_time = self.config.retry_delay_seconds * (2**attempt)
                            await asyncio.sleep(wait_time)
                            continue
                        else:
                            raise RuntimeError(f"Rate limit exceeded after {self.config.max_retries} retries")

                    # Raise for other HTTP errors
                    response.raise_for_status()

                    # Parse and return JSON
                    try:
                        return cast(dict[str, Any], response.json())

ポイント:

  • 指数バックオフでリトライ(2**attempt

  • 429 Rate Limitエラーの自動処理

  • レート制限遵守(_enforce_rate_limit

ステップ3: ツール関数実装

API統合と財務指標計算の関数を実装します

Listing 3 examples/custom_agents/bitbank/tools.py - 財務指標計算(抜粋)
    Args:
        candlestick_data: Candlestick data.
        config: bitbank API configuration (contains risk_free_rate, etc.).

    Returns:
        FinancialSummary model.

    Raises:
        ValueError: If data is empty or invalid.
    """
    if len(candlestick_data.ohlcv) == 0:
        raise ValueError("Candlestick data is empty")

    # Extract closing prices
    closes = np.array([entry.close for entry in candlestick_data.ohlcv])

    # Validate finite values
    if not np.all(np.isfinite(closes)):
        raise ValueError("Price data contains NaN or Inf values")

    # Validate no zero prices (to prevent division by zero)
    if np.any(closes == 0):
        raise ValueError("Price data contains zero values")

    # Calculate daily returns (safe from division by zero after validation)
    daily_returns = np.diff(closes) / closes[:-1]

    # Additional safety check for finite returns
    if not np.all(np.isfinite(daily_returns)):
        raise ValueError("Calculated daily returns contain NaN or Inf values")

    # Annualized return (compound)
    daily_mean_return = np.mean(daily_returns)
    annualized_return = (1 + daily_mean_return) ** config.financial_metrics.trading_days_per_year - 1

    # Annualized volatility

ポイント:

  • NumPyで効率的な統計計算

  • すべての定数(risk_free_rate等)は設定から取得

  • NaN/Inf値の明示的なチェック

ステップ4: エージェントクラス実装

BaseMemberAgentを継承し、Pydantic AIツールを登録します

Listing 4 examples/custom_agents/bitbank/agent.py - エージェント初期化(抜粋)
        """
        super().__init__(config)

        # Build BitbankAPIConfig from MemberAgentConfig.metadata
        # The [agent.tool_settings.bitbank_api] section from TOML is stored in metadata
        bitbank_settings = config.metadata.get("tool_settings", {}).get("bitbank_api", {})
        if not bitbank_settings:
            raise ValueError(
                "Missing [agent.tool_settings.bitbank_api] configuration in TOML. "
                "Please ensure the TOML file contains bitbank API settings."
            )

        self.bitbank_config = BitbankAPIConfig.model_validate(bitbank_settings)

        # Initialize Pydantic AI Agent
        self.agent: Agent[BitbankAPIConfig, str] = Agent(
            model=self.config.model,
            deps_type=BitbankAPIConfig,
            system_prompt=(
                "You are a cryptocurrency market data analyst specializing in bitbank exchange. "
                "You have access to real-time ticker data, historical candlestick data, "
                "and financial metrics analysis tools. Provide clear, concise analysis in Markdown format.\n\n"
                "IMPORTANT: When using candlestick tools, candle_type parameter MUST be one of:\n"
                "- 4hour (for 4時間/4時間足)\n"
                "- 8hour (for 8時間/8時間足)\n"
                "- 12hour (for 12時間/12時間足)\n"
                "- 1day (for 1日/日足/日次)\n"
                "- 1week (for 1週間/週足)\n"
                "- 1month (for 1ヶ月/月足)\n"
                "Do NOT use abbreviations like '12h' or '1d'. Use the exact format specified above."
            ),
        )

重要なポイント:

  • config.metadata.get("tool_settings", {}).get("bitbank_api", {})で設定取得

  • 設定が存在しない場合は明示的なエラー

  • Pydantic AIのAgentを初期化し、deps_typeで依存関係を指定

ツール登録の例

Listing 5 examples/custom_agents/bitbank/agent.py - ツール登録(抜粋)
        # Register tools
        @self.agent.tool
        async def fetch_ticker(ctx: RunContext[BitbankAPIConfig], pair: str) -> str:
            """Fetch current ticker data for a currency pair."""
            ticker = await get_ticker_data(pair, ctx.deps)
            return (
                f"# {pair.upper()} Ticker Data\n\n"
                f"- **Buy**: {ticker.buy_float:,.0f} JPY\n"
                f"- **Sell**: {ticker.sell_float:,.0f} JPY\n"
                f"- **Last**: {ticker.last_float:,.0f} JPY\n"
                f"- **High (24h)**: {float(ticker.high):,.0f} JPY\n"
                f"- **Low (24h)**: {float(ticker.low):,.0f} JPY\n"
                f"- **Volume (24h)**: {ticker.vol_float:,.4f}\n"
            )

        @self.agent.tool

ツール実装のポイント:

  • @self.agent.toolデコレータでツールとして登録

  • ctx: RunContext[BitbankAPIConfig]型アノテーション必須

  • async defで定義(イベントループの入れ子を回避)

  • Markdown形式で結果を返す(LLMが解釈しやすい)

ステップ5: TOML設定

エージェント設定とAPI設定を定義します

Listing 6 examples/custom_agents/bitbank/bitbank_agent.toml - 基本設定(抜粋)
[agent]
type = "custom"
name = "bitbank-api-agent"
model = "google-gla:gemini-2.5-flash"
temperature = 0.0
max_tokens = 4096
tool_description = "Sample agent for bitbank Public API integration"
capabilities = ["data_retrieval", "financial_metrics_analysis"]

[agent.system_instruction]
text = """You are a cryptocurrency market data analyst specializing in bitbank exchange.

Capabilities:
- Real-time ticker data retrieval for BTC, XRP, ETH
- Historical candlestick data analysis
- Financial metrics calculation (Sharpe ratio, Sortino ratio, maximum drawdown, etc.)
- Investment risk assessment

Guidelines:
- Provide clear, data-driven analysis

注意:

  • [agent.metadata.tool_settings.bitbank_api]にAPI設定を配置

  • すべての定数値(risk_free_rate等)は設定ファイルで管理

  • [agent.plugin]pathまたはagent_moduleを指定

財務指標設定

Listing 7 examples/custom_agents/bitbank/bitbank_agent.toml - 財務指標設定
[agent.metadata.tool_settings.bitbank_api.financial_metrics]
risk_free_rate = 0.001  # 年率0.1%(日本10年国債利回り)
trading_days_per_year = 365  # 暗号通貨は365日取引
minimum_acceptable_return = 0.0  # ソルティーノレシオMAR(ゼロリターン)

Warning

本サンプルはpath方式を使用しています。 本番環境ではagent_module方式に変更してください

[agent.plugin]
agent_module = "your_package.agents.bitbank"
agent_class = "BitbankAPIAgent"

path方式は開発・プロトタイピング用です。信頼できるソースからのファイルのみを使用してください。

実行方法

# 環境変数設定
export GOOGLE_API_KEY="your-api-key"
export MIXSEEK_WORKSPACE=/tmp

# 実行
mixseek member "btc_jpyの2024年のパフォーマンスを日足で分析してください" \
  --config examples/custom_agents/bitbank/bitbank_agent.toml

出力例:

Status: SUCCESS
Agent: bitbank-api-agent (custom)

### BTC_JPY 2024年 日次パフォーマンス分析

#### リターン
*   **年率リターン**: 170.06%
*   **トータルリターン**: 136.15%

#### リスク指標
*   **年率ボラティリティ**: 52.19%
*   **最大ドローダウン**: -30.66%

#### リスク調整後リターン
*   **シャープ・レシオ**: 3.256
*   **ソルティノ・レシオ**: 5.333

Tip

ベストプラクティス:

  • すべての定数値はTOMLファイルで管理

  • エラーは明示的に伝播

  • ツール関数はasync defで定義

  • 型アノテーションを徹底(mypy strict mode推奨)

詳細情報

完全な実装とドキュメントは以下を参照

  • サンプルコード: examples/custom_agents/bitbank/

  • 日本語README: examples/custom_agents/bitbank/README.md

  • 仕様書: specs/019-custom-member-api/spec.md

  • 実装計画: specs/019-custom-member-api/plan.md

  • データモデル: specs/019-custom-member-api/data-model.md