第5章:実践プロジェクト

実世界のアプリケーション:ビジョン、キャッシング、本番デプロイメント

読了時間:25-30分 プロジェクト:4 コード例:12 難易度:中級-上級
言語:日本語 | English

はじめに

この最終章では、学んだすべてを実世界のアプリケーション構築にまとめます。ビジョンプロンプティングプロンプトキャッシング本番デプロイメント戦略など、最新のプロンプトエンジニアリング技術を実践する4つのプロジェクトを扱います。

この章を終えると、以下のものが完成します:

プロジェクト1:ドキュメント分析システム

プロジェクト概要

目標:ビジネスドキュメント(請求書、契約書、レポート)を分析し、構造化情報を抽出するシステムを構築

使用技術:構造化出力、プロンプトチェーン、エラーハンドリング

難易度:中級

システムアーキテクチャ

graph LR A[ドキュメント入力] --> B[分類] B --> C{ドキュメントタイプ} C -->|請求書| D[請求書抽出器] C -->|契約書| E[契約書分析器] C -->|レポート| F[レポート要約器] D --> G[構造化出力] E --> G F --> G G --> H[検証] H --> I[データベース/API]

実装

ドキュメント分類

from openai import OpenAI
from pydantic import BaseModel
from typing import Literal

client = OpenAI()

class DocumentClassification(BaseModel):
    document_type: Literal["invoice", "contract", "report", "other"]
    confidence: float
    language: str
    page_count_estimate: int

def classify_document(text: str) -> DocumentClassification:
    """ドキュメントを分類し、構造化メタデータを返す"""

    response = client.beta.chat.completions.parse(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": """ドキュメントタイプを分類し、メタデータを抽出してください。
                ドキュメントタイプ:
                - invoice:請求書、領収書、支払い要求
                - contract:契約書、利用規約、NDA
                - report:分析、要約、研究文書
                - other:その他"""
            },
            {"role": "user", "content": text[:4000]}
        ],
        response_format=DocumentClassification
    )

    return response.choices[0].message.parsed

請求書抽出

from pydantic import BaseModel
from typing import Optional
from datetime import date

class LineItem(BaseModel):
    description: str
    quantity: float
    unit_price: float
    total: float

class InvoiceData(BaseModel):
    invoice_number: str
    vendor_name: str
    customer_name: str
    invoice_date: date
    line_items: list[LineItem]
    subtotal: float
    tax_amount: float = 0
    total_amount: float
    currency: str = "JPY"

def extract_invoice(text: str) -> InvoiceData:
    """請求書テキストから構造化データを抽出"""

    response = client.beta.chat.completions.parse(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": """すべての請求書情報を構造化フォーマットに抽出してください。
                - 日付はISO形式(YYYY-MM-DD)でパース
                - 明示されていない場合は合計を計算
                - ドキュメントの通貨を使用
                - 数量と価格を含むすべての明細を抽出"""
            },
            {"role": "user", "content": text}
        ],
        response_format=InvoiceData
    )

    return response.choices[0].message.parsed

プロジェクト2:ビジョンプロンプティングアプリケーション

プロジェクト概要

目標:製品品質検査のために画像を分析するマルチモーダルアプリケーションを構築

使用技術:ビジョンプロンプティング、構造化出力、画像付きFew-shot

難易度:中級

ビジョンプロンプティングの基礎

最新のLLM(GPT-4V、Claude 3.5、Gemini)はテキストと一緒に画像入力をサポートしています。これにより強力な視覚理解アプリケーションが可能になります。

基本的な画像分析

import base64
from openai import OpenAI

client = OpenAI()

def encode_image(image_path: str) -> str:
    """画像をbase64にエンコード"""
    with open(image_path, "rb") as f:
        return base64.standard_b64encode(f.read()).decode("utf-8")

def analyze_image(image_path: str, prompt: str) -> str:
    """カスタムプロンプトで画像を分析"""

    base64_image = encode_image(image_path)

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": prompt},
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": f"data:image/jpeg;base64,{base64_image}",
                            "detail": "high"  # 詳細分析用
                        }
                    }
                ]
            }
        ],
        max_tokens=1000
    )

    return response.choices[0].message.content

# 使用例
result = analyze_image(
    "product.jpg",
    "この製品画像で見える欠陥や品質問題を説明してください。"
)

品質検査システム

製品品質検査器

from pydantic import BaseModel
from typing import Literal
from enum import Enum

class DefectType(str, Enum):
    SCRATCH = "傷"
    DENT = "へこみ"
    DISCOLORATION = "変色"
    CRACK = "ひび"
    MISSING_PART = "部品欠損"
    CONTAMINATION = "汚染"
    OTHER = "その他"

class Defect(BaseModel):
    type: DefectType
    location: str  # 例:"左上隅", "中央"
    severity: Literal["軽微", "中程度", "重大"]
    description: str

class QualityInspection(BaseModel):
    product_identified: str
    overall_quality: Literal["合格", "不合格", "要レビュー"]
    confidence: float
    defects_found: list[Defect]
    recommendations: list[str]

def inspect_product(image_path: str, product_type: str) -> QualityInspection:
    """製品画像の品質検査を実行"""

    base64_image = encode_image(image_path)

    response = client.beta.chat.completions.parse(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": f"""あなたは{product_type}製品の品質管理検査員です。
                画像を分析し、欠陥や品質問題を検出してください。

                品質基準:
                - 軽微な欠陥:機能に影響しない見た目の問題
                - 中程度の欠陥:顧客満足に影響する可能性のある目に見える問題
                - 重大な欠陥:機能問題または安全上の懸念

                合格基準:重大な欠陥なし、軽微な欠陥は最大2つ
                不合格基準:重大な欠陥あり、または中程度の欠陥が3つ以上
                要レビュー:人間の判断が必要なエッジケース"""
            },
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": "この製品画像を検査し、詳細な品質評価を提供してください。"},
                    {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
                ]
            }
        ],
        response_format=QualityInspection
    )

    return response.choices[0].message.parsed

プロジェクト3:コスト最適化のためのプロンプトキャッシング

プロジェクト概要

目標:APIコストを50-90%削減するプロンプトキャッシング戦略を実装

使用技術:プロンプトキャッシング、トークン最適化、バッチ処理

難易度:中級

プロンプトキャッシングの理解

プロンプトキャッシング(Anthropic ClaudeとOpenAIで利用可能)により、頻繁に再利用されるプロンプトのプレフィックスをキャッシュできます。キャッシュされたトークンは後続のリクエストで大幅にコストが削減されます。

graph TD A[長いシステムプロンプト] -->|初回リクエスト| B[フル処理] A -->|キャッシュ済み| C[後続リクエスト] B -->|コスト: ¥X| D[応答1] C -->|コスト: ¥0.1X| E[応答2-N] style C fill:#e8f5e9 style E fill:#e8f5e9

Anthropicプロンプトキャッシング

Claudeプロンプトキャッシング

import anthropic

client = anthropic.Anthropic()

# キャッシュされる大きなシステムプロンプト
SYSTEM_PROMPT = """あなたは深い知識を持つ専門法務アシスタントです:

[5000トークン以上の法的コンテキスト、判例参照、
管轄固有のルール、ドキュメントテンプレートなどを含む]

あなたの役割は、弁護士のドキュメント作成、契約レビュー、
法的調査の支援です。
"""  # これは10Kトークン以上になる可能性がある

def query_legal_assistant(user_query: str):
    """プロンプトキャッシングを有効にしてクエリ"""

    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1024,
        system=[
            {
                "type": "text",
                "text": SYSTEM_PROMPT,
                "cache_control": {"type": "ephemeral"}  # キャッシングを有効化
            }
        ],
        messages=[
            {"role": "user", "content": user_query}
        ]
    )

    # 応答でキャッシュ使用状況を確認
    print(f"入力トークン: {response.usage.input_tokens}")
    print(f"キャッシュ読み取りトークン: {response.usage.cache_read_input_tokens}")
    print(f"キャッシュ作成トークン: {response.usage.cache_creation_input_tokens}")

    return response.content[0].text

# 初回呼び出し:キャッシュを作成(高コスト)
result1 = query_legal_assistant("このNDA条項をレビューしてください...")

# 後続呼び出し:キャッシュを使用(キャッシュされたトークンで90%コスト削減)
result2 = query_legal_assistant("機密保持契約を作成してください...")
result3 = query_legal_assistant("要件は何ですか...")

コスト比較

シナリオ キャッシングなし キャッシングあり 節約
10Kトークンシステムプロンプト、100リクエスト ¥450 ¥50 89%
8Kコンテキスト付きRAG、50リクエスト ¥180 ¥23 87%
コードレビュー(フルコードベース)、20リクエスト ¥300 ¥38 87%

プロジェクト4:本番デプロイメント

プロジェクト概要

目標:適切なモニタリング、エラーハンドリング、スケーリングを備えたプロンプトベースアプリケーションをデプロイ

使用技術:オブザーバビリティ、レート制限、フォールバック戦略

難易度:上級

本番アーキテクチャ

graph TD A[クライアント] --> B[APIゲートウェイ] B --> C[レートリミッター] C --> D[リクエストルーター] D --> E[プライマリLLM] D --> F[フォールバックLLM] E --> G[レスポンスキャッシュ] F --> G G --> H[モニタリング] H --> I[ロギング] H --> J[メトリクス] H --> K[アラート]

堅牢なLLMクライアント

本番対応クライアント

import time
from openai import OpenAI
from anthropic import Anthropic
from tenacity import retry, stop_after_attempt, wait_exponential
import logging

logger = logging.getLogger(__name__)

class ProductionLLMClient:
    """フォールバックとモニタリングを備えた本番対応LLMクライアント"""

    def __init__(self):
        self.openai = OpenAI()
        self.anthropic = Anthropic()
        self.metrics = MetricsCollector()

    @retry(
        stop=stop_after_attempt(3),
        wait=wait_exponential(multiplier=1, min=4, max=60)
    )
    def _call_openai(self, messages: list, **kwargs) -> str:
        """リトライロジック付きでOpenAIを呼び出す"""
        start = time.time()
        try:
            response = self.openai.chat.completions.create(
                model=kwargs.get("model", "gpt-4o"),
                messages=messages,
                **kwargs
            )
            self.metrics.record("openai_success", time.time() - start)
            return response.choices[0].message.content
        except Exception as e:
            self.metrics.record("openai_error", time.time() - start)
            logger.error(f"OpenAIエラー: {e}")
            raise

    def complete(self, messages: list, primary: str = "openai", **kwargs) -> str:
        """自動フォールバック付きで完了"""
        try:
            if primary == "openai":
                return self._call_openai(messages, **kwargs)
            else:
                return self._call_anthropic(messages, **kwargs)
        except Exception as e:
            logger.warning(f"プライマリプロバイダーが失敗、フォールバックを試行: {e}")
            # 他のプロバイダーにフォールバック
            try:
                if primary == "openai":
                    return self._call_anthropic(messages, **kwargs)
                else:
                    return self._call_openai(messages, **kwargs)
            except Exception as e2:
                logger.error(f"すべてのプロバイダーが失敗: {e2}")
                raise RuntimeError("すべてのLLMプロバイダーが利用不可")

本番チェックリスト

デプロイメントチェックリスト

最終演習

演習1:ドキュメントプロセッサ拡張(難易度:中)

課題:ドキュメント分析システムを拡張して以下を処理:

演習2:ビジョンアプリケーション(難易度:中)

課題:以下ができるレシートスキャナーを構築:

演習3:キャッシング実装(難易度:中)

課題:以下を行うチャットボットのキャッシングレイヤーを実装:

演習4:本番API(難易度:上級)

課題:以下を備えた本番対応APIエンドポイントを構築:

演習5:完全プロジェクト(難易度:上級)

課題:すべての技術を組み合わせて「スマート会議ノート」アプリケーションを構築:

シリーズまとめ

このシリーズの重要ポイント

次のステップ

プロンプトエンジニアリング入門シリーズの完了おめでとうございます!推奨される次のステップ:


参考文献


更新履歴

免責事項