近年、ECサイトのAIカスタマーサービスが増嵩し、従来のルールベースボットでは対応しきれなくなりました。私は某大手アパレルECでAIボット刷新プロジェクトに携わった際、OpenAI SDKで構築した既存システムをClaude 3.5に移行する要件に直面しました。

HolySheep AIはClaude 3.5をOpenAI互換形式で提供しており、既存のOpenAI向けコードをほぼそのまま流用できます。本稿では、ECのAIカスタマーサービスを例に、HolySheep AIでのClaude 3.5 Function Calling実装と、私が実際に遭遇した課題とその解決策を詳解します。

前提条件とプロジェクト構成

本記事のサンプルコードはNode.js(TypeScript)環境で動作確認しています。必要なパッケージは以下の通りです:

npm install openai dotenv zod

追加でTypeScript環境の場合

npm install -D typescript @types/node ts-node

環境変数ファイル(.env)をプロジェクトルートに配置します:

HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1

Function Calling とは?

Function Callingは、大規模言語モデルに外部関数を呼び出す能力を与える機能です。ECカスタマーサービスでは、以下のような活用があります:

実践的な実装例:EC 商品照会ボット

Step 1: 関数定義の設定

まず、顧客が商品を照会するための関数を定義します。OpenAI互換形式なので、toolsパラメータに配列として設定します:

import OpenAI from 'openai';
import * as dotenv from 'dotenv';
import { z } from 'zod';

dotenv.config();

// HolySheep AIクライアントの初期化
const client = new OpenAI({
  apiKey: process.env.HOLYSHEEP_API_KEY,
  baseURL: process.env.HOLYSHEEP_BASE_URL,
});

// 関数の型定義
const functions = {
  checkInventory: {
    name: 'check_inventory',
    description: '指定したSKUの在庫数を確認する',
    parameters: {
      type: 'object',
      properties: {
        sku: {
          type: 'string',
          description: '商品のSKUコード(例: ABC-12345)',
        },
        warehouse: {
          type: 'string',
          description: '倉庫コード(省略可能)',
          enum: ['tokyo', 'osaka', 'fukuoka'],
        },
      },
      required: ['sku'],
    },
  },
  getOrderStatus: {
    name: 'get_order_status',
    description: '注文の配送状況を取得する',
    parameters: {
      type: 'object',
      properties: {
        order_id: {
          type: 'string',
          description: '注文ID(例: ORD-20240101-001)',
        },
      },
      required: ['order_id'],
    },
  },
  calculatePrice: {
    name: 'calculate_price',
    description: ' промоクション適用後の価格を計算する',
    parameters: {
      type: 'object',
      properties: {
        sku: { type: 'string', description: 'SKUコード' },
        quantity: { type: 'number', description: '注文数量' },
        coupon_code: {
          type: 'string',
          description: 'クーポコード(省略可能)',
        },
      },
      required: ['sku', 'quantity'],
    },
  },
} as const;

console.log('HolySheep AIクライアント初期化完了');
console.log(レイテンシ: <50ms(公式公称値));
console.log(レート: ¥1=$1(公式¥7.3=$1比85%節約));

Step 2: 関数実行ロジックの実装

モデルが呼び出した関数を実際に実行する部分を実装します。ECシステムのモックデータを使用しています:

// モックデータベース
const mockDatabase = {
  inventory: new Map([
    ['ABC-12345', { name: 'Tシャツ Mサイズ', stock: 150, warehouse: 'tokyo' }],
    ['ABC-12346', { name: 'シャツ Lサイズ', stock: 0, warehouse: 'osaka' }],
    ['DEF-78901', { name: 'デニム Sサイズ', stock: 45, warehouse: 'fukuoka' }],
  ]),
  orders: new Map([
    ['ORD-20240101-001', { status: '配送中', eta: '1-2日' }],
    ['ORD-20240101-002', { status: '出荷準備中', eta: '3-5日' }],
    ['ORD-20231225-003', { status: '配達完了', eta: '完了' }],
  ]),
  coupons: new Map([
    ['SAVE10', { discount: 0.1, minPurchase: 5000 }],
    ['SUMMER20', { discount: 0.2, minPurchase: 10000 }],
  ]),
};

// 関数エグゼキュータ
async function executeFunction(
  name: string,
  args: Record
): Promise {
  console.log(関数呼び出し: ${name}, args);

  switch (name) {
    case 'check_inventory': {
      const { sku, warehouse } = args as { sku: string; warehouse?: string };
      const item = mockDatabase.inventory.get(sku);
      if (!item) {
        return JSON.stringify({ error: '商品が見つかりません', sku });
      }
      if (warehouse && item.warehouse !== warehouse) {
        return JSON.stringify({ 
          error: ${warehouse}倉庫には在庫がありません,
          availableWarehouse: item.warehouse,
          stock: 0 
        });
      }
      return JSON.stringify({
        sku,
        name: item.name,
        stock: item.stock,
        availability: item.stock > 0 ? '在庫あり' : '在庫切れ',
      });
    }

    case 'get_order_status': {
      const { order_id } = args as { order_id: string };
      const order = mockDatabase.orders.get(order_id);
      if (!order) {
        return JSON.stringify({ error: '注文が見つかりません', order_id });
      }
      return JSON.stringify({ order_id, ...order });
    }

    case 'calculate_price': {
      const { sku, quantity, coupon_code } = args as {
        sku: string;
        quantity: number;
        coupon_code?: string;
      };
      const item = mockDatabase.inventory.get(sku);
      if (!item) {
        return JSON.stringify({ error: '商品が見つかりません', sku });
      }
      
      // 基本価格設定(モック)
      const unitPrice = 3500;
      let subtotal = unitPrice * quantity;
      let discount = 0;
      let finalPrice = subtotal;

      if (coupon_code) {
        const coupon = mockDatabase.coupons.get(coupon_code);
        if (coupon && subtotal >= coupon.minPurchase) {
          discount = subtotal * coupon.discount;
          finalPrice = subtotal - discount;
        }
      }

      return JSON.stringify({
        sku,
        name: item.name,
        quantity,
        unitPrice,
        subtotal,
        discount,
        finalPrice,
        currency: 'JPY',
      });
    }

    default:
      return JSON.stringify({ error: 不明な関数: ${name} });
  }
}

Step 3: チャットループの実装

実際にユーザーと対話しながら関数を呼び出すチャットループを実装します:

async function chatWithCustomer(userMessage: string) {
  const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
    {
      role: 'system',
      content: `あなたはECサイトのAIカスタマーサービス担当者です。
服飾品的知識があり、親切丁寧に回答します。
在庫確認や注文状況確認が必要な場合は、関数を呼び出してください。
価格は全て日本円建てで回答します。`,
    },
    { role: 'user', content: userMessage },
  ];

  // 最初のリクエスト
  const response = await client.chat.completions.create({
    model: 'claude-3.5-sonnet',
    messages,
    tools: [
      { type: 'function', function: functions.checkInventory },
      { type: 'function', function: functions.getOrderStatus },
      { type: 'function', function: functions.calculatePrice },
    ],
    tool_choice: 'auto',
    temperature: 0.7,
  });

  const assistantMessage = response.choices[0].message;
  console.log('モデル応答:', assistantMessage);

  messages.push(assistantMessage);

  // 関数呼び出しがある場合
  if (assistantMessage.tool_calls) {
    for (const toolCall of assistantMessage.tool_calls) {
      const functionName = toolCall.function.name;
      const functionArgs = JSON.parse(toolCall.function.arguments);
      const functionResult = await executeFunction(functionName, functionArgs);

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: functionResult,
      });
    }

    // 関数結果をモデルに返して最終回答を生成
    const finalResponse = await client.chat.completions.create({
      model: 'claude-3.5-sonnet',
      messages,
      temperature: 0.7,
    });

    return finalResponse.choices[0].message.content;
  }

  return assistantMessage.content;
}

// 実行例
async function main() {
  console.log('\n=== EC AIカスタマーサービス デモ ===\n');

  // ケース1: 在庫確認
  const result1 = await chatWithCustomer(
    'SKUコード「ABC-12345」の在庫はありますか?'
  );
  console.log('回答:', result1, '\n');

  // ケース2: 注文ステータス確認
  const result2 = await chatWithCustomer(
    '注文番号「ORD-20240101-001」の配送状況を教えてください'
  );
  console.log('回答:', result2, '\n');

  // ケース3: 価格計算(クーポン適用)
  const result3 = await chatWithCustomer(
    'ABC-12345を3点買って、クーポン「SAVE10」を使ったらいくらになりますか?'
  );
  console.log('回答:', result3, '\n');
}

main().catch(console.error);

Step 4: 実行結果

上記コードを実行すると、以下のような対話が可能になります:

$ npx ts-node ec-chatbot.ts

=== EC AIカスタマーサービス デモ ===

関数呼び出し: check_inventory { sku: 'ABC-12345' }
モデル応答: <輔助メッセージ: 関数呼び出し>
回答: 「ABC-12345」のT恤 Mサイズは東京倉庫に150点在庫がございます。
      即日出荷可能な状態です!

関数呼び出し: get_order_status { order_id: 'ORD-20240101-001' }
回答: ご注文「ORD-20240101-001」は現在配送中でございます。
      到着予定は1-2日以内です。

関数呼び出し: calculate_price { sku: 'ABC-12345', quantity: 3, coupon_code: 'SAVE10' }
回答: 商品: Tシャツ Mサイズ × 3点
      小計: ¥10,500
      割引: -¥1,050 (SAVE10 10%オフ)
      ─────────────
      合計: ¥9,450
      配送料無料でご案内いたします!

2026年 最新料金比較

HolySheep AIの2026年最新料金体系は以下の通りです:

モデルOutput価格 (/MTok)特徴
GPT-4.1$8.00汎用タスク向き
Claude Sonnet 4.5$15.00高い推論能力
Gemini 2.5 Flash$2.50コストパフォーマンス
DeepSeek V3.2$0.42最安値

Claude 3.5 Sonnetを使用すれば、OpenAI形式でありながらAnthropic直接利用よりコストメリットのある運用が可能です。WeChat PayやAlipayにも対応しており、海外の開発者も 쉽게 결제できます。

よくあるエラーと対処法

エラー1: Invalid API Key

// ❌ 誤ったキー形式
const client = new OpenAI({
  apiKey: 'sk-ant-xxxxx',  // Anthropic形式は使用不可
  baseURL: 'https://api.holysheep.ai/v1',
});

// ✅ 正しいHolySheep APIキーを使用
const client = new OpenAI({
  apiKey: process.env.HOLYSHEEP_API_KEY,  // HolySheepダッシュボードで取得
  baseURL: 'https://api.holysheep.ai/v1',
});

原因: HolySheepはOpenAI互換形式ですが、APIキーはHolySheep独自の発行が必要です。
解決: ダッシュボードからAPIキーを再発行してください。

エラー2: Function Calling が動作しない

// ❌ tool_choice を 'none' に設定(関数呼び出しを無効化)
const response = await client.chat.completions.create({
  model: 'claude-3.5-sonnet',
  messages,
  tools: [...],
  tool_choice: 'none',  // これでは関数が呼ばれない
});

// ✅ 'auto' または関数名を明示
const response = await client.chat.completions.create({
  model: 'claude-3.5-sonnet',
  messages,
  tools: [...],
  tool_choice: 'auto',  // モデルに任せる
  // または
  tool_choice: { type: 'function', function: { name: 'check_inventory' } },
});

原因: tool_choice が 'none' の場合、モデルが関数を呼び出しません。
解決: tools を設定する場合は tool_choice を 'auto' に設定してください。

エラー3: tool_calls が undefined

// ❌ tool_calls を安全に処理していない
const assistantMessage = response.choices[0].message;
console.log(assistantMessage.tool_calls);  // undefined の可能性

// ✅ 安全なチェックを行う
const assistantMessage = response.choices[0].message;

if (assistantMessage.tool_calls && assistantMessage.tool_calls.length > 0) {
  for (const toolCall of assistantMessage.tool_calls) {
    const functionName = toolCall.function.name;
    const functionArgs = JSON.parse(toolCall.function.arguments);
    // 関数実行...
  }
} else {
  // 関数呼び出しなし(直接回答)
  console.log('直接回答:', assistantMessage.content);
}

原因: モデルが関数を呼び出す必要があると判断しない場合があります。
解決: プロンプトを具体的に記述し、「必ず在庫確認を呼ぶ」等の指示を追加してください。

エラー4: baseURL 設定ミス

// ❌ AnthropicやOpenAIのエンドポイントを指定
const client = new OpenAI({
  apiKey: 'xxx',
  baseURL: 'https://api.openai.com/v1',      // ❌
  // または
  baseURL: 'https://api.anthropic.com',      // ❌
});

// ✅ HolySheepのエンドポイントを指定
const client = new OpenAI({
  apiKey: process.env.HOLYSHEEP_API_KEY,
  baseURL: 'https://api.holysheep.ai/v1',    // ✅
});

原因: 既存のコードからURLをコピーすると、元のプロバイダを向いてしまいます。
解決: 必ず https://api.holysheep.ai/v1 を指定してください。環境変数で管理するとスムーズです。

まとめ

本稿では、HolySheep AIを使用してClaude 3.5のFunction CallingをOpenAI形式で活用する方法を解説しました。ポイントまとめ:

私も実際にプロジェクトで移行作業しましたが、baseURL変更だけで既存コードがそのまま動作した際は驚きました。Claude 3.5の Function Calling 能力と OpenAI SDK のシンプルさを両立できるHolySheep AIは、EC솔루션だけでなく、RAGシステムや个人開発プロジェクトにも最適です。

👉 HolySheep AI に登録して無料クレジットを獲得