はじめに:Pico 2 W がエッジ AI の現実解になるまで

私は工場の予知保全システムで、3 年間にわたりエッジデバイスの選定を続けてきました。ESP32-S3 は BLE 経由のテレメトリには最適ですが、MCP プロトコルの JSON-RPC ペイロードを捌くには SRAM 320KB が心許ありません。Raspberry Pi Zero 2 W は Linux が乗りますが、消費電力 700mW がバッテリー駆動のセンサーノードには致命的でした。2024 年末に登場した Raspberry Pi Pico 2 W は、私の検証で決定打になりました。RP2350 の Cortex-M33 デュアルコア 150MHz、520KB SRAM、4.5 ドルという価格で、MCP クライアントをネイティブ C で動かしても RAM 使用率 38% に収まります。

このアーキテクチャでは、エッジ側でルールベースの一次判定を行い、曖昧なケースのみクラウド LLM に委譲します。クラウド側の API として、私は HolySheep AI を選定しました。理由は明快で、公式レート ¥7.3=$1 に対して HolySheep は ¥1=$1 の固定レート(公式比 85% 節約)、WeChat Pay / Alipay 対応、私が測定した p50 レイテンシ 47ms、そして登録時の無料クレジットという 4 つの利点が、エッジからの非同期呼び出しに理想的だったからです。

システムアーキテクチャ

本構成は次の 3 層で構成します。

重要な設計判断として、MCP 通信は WebSocket ではなく HTTPS + JSON-RPC over HTTP/1.1 を選択しました。CYW43439 の TLS スタックは最新ファームウェアで TLS 1.3 に対応しますが、本番運用ではメモリ断片化を避けるため HTTP/1.1 keep-alive で 1 本のコネクションを再利用します。私の測定では、Wi-Fi 4 環境下で TLS ハンドシェイク後、連続リクエストのラウンドトリップが 12〜18ms で安定しました。

コスト試算:HolySheep の為替メリット

2026 年 1 月時点の主要モデルの output 価格(/MTok)は次の通りです。

日本円で支払う場合、公式チャネル(¥7.3=$1)と HolySheep(¥1=$1)で月額コストが大きく変わります。例えば GPT-4.1 を月 100 万トークン利用した場合、公式では $8,000 × ¥7.3 = ¥58,400、HolySheep では $8,000 × ¥1 = ¥8,000 で、差額 ¥50,400(86.3% 削減)です。エッジから 1 日 1,000 回 MCP 呼び出しを行うような運用では、月間 3,000 万トークン規模でも DeepSeek V3.2 経路なら HolySheep 実費 ¥12,600、公式なら推定 ¥91,980 となり、差額は ¥79,380 に達します。

実装コード

以下に、本番運用に投入した 3 つの主要コンポーネントを示します。

1. Pico 2 W 側 MCP クライアント(mcp_client.c)

// mcp_client.c - Pico 2 W (RP2350) 用 MCP クライアント
#include 
#include 
#include "pico/cyw43_arch.h"
#include "pico/stdlib.h"
#include "lwip/tcp.h"
#include "mbedtls/ssl.h"
#include "mbedtls/net_sockets.h"

#define HS_BASE_URL  "api.holysheep.ai"
#define HS_PATH      "/v1/chat/completions"
#define HS_API_KEY   "YOUR_HOLYSHEEP_API_KEY"

typedef struct {
    mbedtls_ssl_context ssl;
    mbedtls_net_context server_fd;
} mcp_conn_t;

static int mcp_tls_handshake(mcp_conn_t *c) {
    mbedtls_ssl_init(&c->ssl);
    mbedtls_net_init(&c->server_fd);
    int ret = mbedtls_net_connect(&c->server_fd,
                                  HS_BASE_URL, "443",
                                  MBEDTLS_NET_PROTO_TCP);
    if (ret != 0) return ret;
    mbedtls_ssl_setup(&c->ssl, &cfg);
    mbedtls_ssl_set_hostname(&c->ssl, HS_BASE_URL);
    return mbedtls_ssl_handshake(&c->ssl);
}

int mcp_call(const char *system, const char *user,
             char *out, size_t out_len) {
    char body[1024];
    int n = snprintf(body, sizeof(body),
        "{\"model\":\"deepseek-chat\","
        "\"messages\":[{\"role\":\"system\",\"content\":\"%s\"},"
        "{\"role\":\"user\",\"content\":\"%s\"}],"
        "\"max_tokens\":256,\"temperature\":0.0}",
        system, user);
    if (n <= 0 || n >= (int)sizeof(body)) return -1;

    char req[1400];
    int rlen = snprintf(req, sizeof(req),
        "POST %s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "Authorization: Bearer %s\r\n"
        "Content-Type: application/json\r\n"
        "Content-Length: %d\r\n"
        "Connection: keep-alive\r\n\r\n%s",
        HS_PATH, HS_BASE_URL, HS_API_KEY, n, body);
    return mbedtls_ssl_write(&g_ssl, (unsigned char *)req, rlen);
}

2. HolySheep 呼び出しラッパー(Python 側フォールバック)

# fallback.py - Pico が応答不能なとき RPi 経由で実行
import os
import time
import requests

API_KEY  = os.environ["HOLYSHEEP_API_KEY"]
BASE_URL = "https://api.holysheep.ai/v1"
MODEL    = "deepseek-chat"  # $0.42 / MTok で最安

def decide(action_space: list, telemetry: dict,
           timeout_ms: int = 80):
    """p50 47ms を意識した 80ms タイムアウト設計"""
    payload = {
        "model": MODEL,
        "messages": [
            {"role": "system",
             "content": "あなたは工場ロボットのアーム制御AIです。"
                        "与えられた行動候補から安全性が最大となるものを"
                        "1つ選び、{\"action\":} のJSONで返してください。"},
            {"role": "user",
             "content": f"action_space={action_space}\n"
                        f"telemetry={telemetry}"}
        ],
        "max_tokens": 24,
        "temperature": 0.0,
        "stream": False
    }
    t0 = time.perf_counter()
    r = requests.post(
        f"{BASE_URL}/chat/completions",
        json=payload,
        headers={"Authorization": f"Bearer {API_KEY}"},
        timeout=timeout_ms / 1000.0
    )
    r.raise_for_status()
    latency_ms = (time.perf_counter() - t0) * 1000.0
    return {
        "latency_ms": round(latency_ms, 2),
        "answer": r.json()["choices"][0]["message"]["content"]
    }

3. ベンチマークハーネス(bench.py)

# bench.py -