# AIチャットアシスタントを作成しよう
1960年代の『スター・トレック』で、乗組員が船のコンピュータと気軽に会話し、複雑な質問をして思慮深い回答を得ていたシーンを覚えていますか?当時は純粋なSFのように思えたものが、今ではあなたが既に知っているウェブ技術を使って構築できるものになっています。
このレッスンでは、HTML、CSS、JavaScript、そしてバックエンド統合を使用してAIチャットアシスタントを作成します。これまで学んできたスキルが、文脈を理解し、意味のある回答を生成する強力なAIサービスとどのように接続できるかを発見することができます。
AIは、膨大な情報を検索するだけでなく、それを統合して特定の質問に合わせた一貫した回答を提供する広大な図書館にアクセスするようなものだと考えてください。何千ものページを検索する代わりに、直接的で文脈に沿った回答を得ることができます。
統合は、馴染みのあるウェブ技術が連携することで実現します。HTMLはチャットインターフェースを作成し、CSSは視覚デザインを担当し、JavaScriptはユーザーとのやり取りを管理し、バックエンドAPIがすべてをAIサービスに接続します。これは、オーケストラの異なるセクションが協力して交響曲を作り上げるようなものです。
私たちは、自然な人間のコミュニケーションと機械処理の間に橋を架けることを目指しています。AIサービス統合の技術的な実装と、直感的に感じられるインタラクションを実現するデザインパターンの両方を学びます。
このレッスンの終わりまでには、AI統合が神秘的なプロセスではなく、扱いやすいAPIの一つとして感じられるようになります。ChatGPTやClaudeのようなアプリケーションを支える基礎的なパターンを理解し、これまで学んできたウェブ開発の原則を活用していきます。
完成したプロジェクトは以下のようになります:

## AIを理解する:謎から習得へ
コードに取り掛かる前に、まず何を扱っているのかを理解しましょう。APIを使用したことがあるなら、基本的なパターンはご存じでしょう:リクエストを送信し、レスポンスを受け取る。
AI APIも同様の構造を持っていますが、データベースから事前に保存されたデータを取得する代わりに、膨大なテキストから学んだパターンに基づいて新しい回答を生成します。これは、図書館のカタログシステムと、複数の情報源から情報を統合できる知識豊富な司書との違いのようなものです。
### 「生成AI」とは何か?
ロゼッタストーンが知られている言語と未知の言語の間のパターンを見つけることで学者がエジプトの象形文字を理解できるようになったように、AIモデルも同様に膨大なテキストのパターンを見つけて言語の仕組みを理解し、新しい質問に対して適切な回答を生成します。
**簡単な比較で説明します:**
- **従来のデータベース**:出生証明書を求めるようなもの。同じ文書を毎回取得します。
- **検索エンジン**:司書に猫に関する本を探してもらうようなもの。利用可能なものを見せてくれます。
- **生成AI**:知識豊富な友人に猫について尋ねるようなもの。あなたが知りたいことに合わせて自分の言葉で面白いことを教えてくれます。
```mermaid
graph LR
A[Your Question] --> B[AI Model]
B --> C[Pattern Recognition]
C --> D[Content Generation]
D --> E[Contextual Response]
F[Training Data
Books, Articles, Web] --> B
```
### AIモデルの学習方法(簡単版)
AIモデルは、書籍、記事、会話などの膨大なデータセットに触れることで学習します。このプロセスを通じて以下のパターンを特定します:
- 書かれたコミュニケーションで思考がどのように構成されているか
- どの単語が一般的に一緒に現れるか
- 会話が通常どのように進行するか
- フォーマルなコミュニケーションとインフォーマルなコミュニケーションの文脈的な違い
**これは考古学者が古代の言語を解読する方法に似ています**:文法、語彙、文化的文脈を理解するために何千もの例を分析し、学んだパターンを使って新しいテキストを解釈できるようになります。
### GitHub Modelsを選ぶ理由
GitHub Modelsを使用する理由は非常に実用的です。自分でAIインフラを構築する必要がなく、エンタープライズレベルのAIにアクセスできるからです(今すぐ自分で構築するのはお勧めしません!)。これは天気APIを使うのと同じで、全国に気象観測所を設置して天気を予測しようとする代わりに利用するようなものです。
これは基本的に「AI-as-a-Service」であり、最良の部分は無料で始められることです。実験をしても高額な請求を心配する必要がありません。
```mermaid
graph LR
A[Frontend Chat UI] --> B[Your Backend API]
B --> C[GitHub Models API]
C --> D[AI Model Processing]
D --> C
C --> B
B --> A
```
GitHub Modelsをバックエンド統合に使用します。これにより、開発者に優しいインターフェースを通じてプロフェッショナルなAI機能にアクセスできます。[GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground)は、異なるAIモデルを試し、その能力を理解してコードに実装する前に実験できるテスト環境として機能します。

**Playgroundが便利な理由:**
- **異なるAIモデルを試す**:GPT-4o-mini、Claudeなど(すべて無料!)
- **アイデアやプロンプトをテストする**:コードを書く前に試せます
- **お気に入りのプログラミング言語で使えるコードスニペットを取得する**
- **設定を調整する**:創造性レベルや応答の長さを変更して出力にどのように影響するか確認できます
少し試してみたら、「Code」タブをクリックしてプログラミング言語を選択し、必要な実装コードを取得します。

## Pythonバックエンド統合のセットアップ
次に、Pythonを使用してAI統合を実装します。Pythonはその簡潔な構文と強力なライブラリのため、AIアプリケーションに最適です。GitHub Models Playgroundからコードを取得し、それを再利用可能で本番環境対応の関数にリファクタリングします。
### 基本的な実装を理解する
PlaygroundからPythonコードを取得すると、以下のようなものが得られます。最初は多く感じるかもしれませんが、部分ごとに説明していきます:
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
```python
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
**このコードで何が行われているか:**
- **必要なツールをインポート**:環境変数を読み取るための`os`とAIと通信するための`OpenAI`
- **OpenAIクライアントを設定**:GitHubのAIサーバーを直接OpenAIではなく指すように設定
- **認証を行う**:特別なGitHubトークンを使用(これについては後ほど詳しく説明します!)
- **会話を構成する**:異なる「役割」を設定することで、舞台のシーンを作るようなもの
- **リクエストをAIに送信**:微調整パラメータを含めて送信
- **戻ってきたデータから実際の応答テキストを抽出**
**FastAPIが私たちのプロジェクトに最適な理由:**
- **デフォルトで非同期**: 複数のAIリクエストを同時に処理し、詰まることがない
- **自動ドキュメント生成**: `/docs`にアクセスするだけで、美しいインタラクティブなAPIドキュメントページが無料で手に入る
- **組み込みのバリデーション**: 問題を引き起こす前にエラーをキャッチ
- **超高速**: Pythonフレームワークの中でも最速の一つ
- **モダンなPython**: 最新かつ最高のPython機能を活用
**なぜバックエンドが必要なのか:**
**セキュリティ**: AI APIキーはパスワードのようなものです。フロントエンドのJavaScriptにキーを埋め込むと、ウェブサイトのソースコードを閲覧した誰でもそれを盗んでAIクレジットを使用できてしまいます。バックエンドは機密情報を安全に保ちます。
**リクエスト制限と管理**: バックエンドを使用することで、ユーザーがリクエストを送信する頻度を制御したり、ユーザー認証を実装したり、使用状況を追跡するためのログを追加したりできます。
**データ処理**: 会話を保存したり、不適切なコンテンツをフィルタリングしたり、複数のAIサービスを組み合わせたりする場合があります。これらのロジックはバックエンドで処理されます。
**アーキテクチャはクライアントサーバーモデルに似ています:**
- **フロントエンド**: ユーザーインターフェース層
- **バックエンドAPI**: リクエスト処理とルーティング層
- **AIサービス**: 外部計算と応答生成
- **環境変数**: 安全な設定と資格情報の保存
### リクエストとレスポンスの流れを理解する
ユーザーがメッセージを送信したときに何が起こるかを追跡してみましょう:
```mermaid
sequenceDiagram
participant User as 👤 User
participant Frontend as 🌐 Frontend
participant API as 🔧 FastAPI Server
participant AI as 🤖 AI Service
User->>Frontend: Types "Hello AI!"
Frontend->>API: POST /hello {"message": "Hello AI!"}
Note over API: Validates request
Adds system prompt
API->>AI: Sends formatted request
AI->>API: Returns AI response
Note over API: Processes response
Logs conversation
API->>Frontend: {"response": "Hello! How can I help?"}
Frontend->>User: Displays AI message
```
**各ステップの理解:**
1. **ユーザーの操作**: チャットインターフェースに入力
2. **フロントエンド処理**: JavaScriptが入力をキャプチャし、JSON形式にフォーマット
3. **APIバリデーション**: FastAPIがPydanticモデルを使用してリクエストを自動的に検証
4. **AI統合**: バックエンドがコンテキスト(システムプロンプト)を追加し、AIサービスを呼び出す
5. **レスポンス処理**: APIがAIの応答を受け取り、必要に応じて修正
6. **フロントエンド表示**: JavaScriptがチャットインターフェースに応答を表示
### APIアーキテクチャの理解
```mermaid
sequenceDiagram
participant Frontend
participant FastAPI
participant AI Function
participant GitHub Models
Frontend->>FastAPI: POST /hello {"message": "Hello AI!"}
FastAPI->>AI Function: call_llm(message, system_prompt)
AI Function->>GitHub Models: API request
GitHub Models->>AI Function: AI response
AI Function->>FastAPI: response text
FastAPI->>Frontend: {"response": "Hello! How can I help?"}
```
### FastAPIアプリケーションの作成
APIを段階的に構築していきましょう。`api.py`というファイルを作成し、以下のFastAPIコードを記述します:
```python
# api.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from llm import call_llm
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Create FastAPI application
app = FastAPI(
title="AI Chat API",
description="A high-performance API for AI-powered chat applications",
version="1.0.0"
)
# Configure CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Configure appropriately for production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Pydantic models for request/response validation
class ChatMessage(BaseModel):
message: str
class ChatResponse(BaseModel):
response: str
@app.get("/")
async def root():
"""Root endpoint providing API information."""
return {
"message": "Welcome to the AI Chat API",
"docs": "/docs",
"health": "/health"
}
@app.get("/health")
async def health_check():
"""Health check endpoint."""
return {"status": "healthy", "service": "ai-chat-api"}
@app.post("/hello", response_model=ChatResponse)
async def chat_endpoint(chat_message: ChatMessage):
"""Main chat endpoint that processes messages and returns AI responses."""
try:
# Extract and validate message
message = chat_message.message.strip()
if not message:
raise HTTPException(status_code=400, detail="Message cannot be empty")
logger.info(f"Processing message: {message[:50]}...")
# Call AI service (note: call_llm should be made async for better performance)
ai_response = await call_llm_async(message, "You are a helpful and friendly assistant.")
logger.info("AI response generated successfully")
return ChatResponse(response=ai_response)
except HTTPException:
raise
except Exception as e:
logger.error(f"Error processing chat message: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=5000, reload=True)
```
**FastAPI実装の理解:**
- **インポート**: FastAPIのモダンなウェブフレームワーク機能とPydanticのデータ検証機能
- **自動APIドキュメント生成**: サーバー実行時に`/docs`で利用可能
- **CORSミドルウェアの有効化**: 異なるオリジンからのフロントエンドリクエストを許可
- **Pydanticモデルの定義**: 自動リクエスト/レスポンス検証とドキュメント化
- **非同期エンドポイントの使用**: 同時リクエスト処理のパフォーマンス向上
- **適切なHTTPステータスコードとエラーハンドリングの実装**: HTTPExceptionを使用
- **構造化されたログの追加**: モニタリングとデバッグのため
- **ヘルスチェックエンドポイントの提供**: サービス状態のモニタリング
**従来のフレームワークに対するFastAPIの主な利点:**
- **自動バリデーション**: Pydanticモデルが処理前にデータの整合性を保証
- **インタラクティブなドキュメント**: `/docs`で自動生成されたテスト可能なAPIドキュメントを利用可能
- **型安全性**: Pythonの型ヒントがランタイムエラーを防ぎ、コード品質を向上
- **非同期サポート**: 複数のAIリクエストを同時に処理可能
- **パフォーマンス**: リアルタイムアプリケーション向けの高速なリクエスト処理
### CORS: ウェブのセキュリティガードを理解する
CORS(クロスオリジンリソース共有)は、建物のセキュリティガードのようなもので、訪問者が許可されているかどうかを確認します。この重要性とアプリケーションへの影響を理解しましょう。
#### CORSとは何か、なぜ存在するのか
**問題点**: もしどんなウェブサイトでもあなたの銀行のウェブサイトに許可なくリクエストを送れるとしたら、それはセキュリティの悪夢です!ブラウザはデフォルトでこれを防ぐために「同一オリジンポリシー」を使用します。
**同一オリジンポリシー**: ブラウザは、読み込まれたドメイン、ポート、プロトコルと同じオリジンに対してのみリクエストを許可します。
**現実世界の例え**: アパートのセキュリティのようなもので、居住者(同一オリジン)のみがデフォルトで建物にアクセスできます。友人(異なるオリジン)を訪問させたい場合は、セキュリティに明示的に許可を伝える必要があります。
#### 開発環境でのCORS
開発中、フロントエンドとバックエンドは異なるポートで動作します:
- フロントエンド: `http://localhost:3000`(またはHTMLを直接開く場合はfile://)
- バックエンド: `http://localhost:5000`
これらは同じコンピュータ上にあっても「異なるオリジン」と見なされます!
```python
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(__name__)
CORS(app) # This tells browsers: "It's okay for other origins to make requests to this API"
```
**CORS設定が実際に行うこと:**
- **特別なHTTPヘッダーを追加**: APIレスポンスに「このクロスオリジンリクエストは許可されている」とブラウザに伝える
- **「プリフライト」リクエストを処理**: ブラウザが実際のリクエストを送る前に許可を確認する場合がある
- **ブラウザコンソールでの「CORSポリシーによるブロック」エラーを防止**
#### CORSセキュリティ: 開発と本番環境の違い
```python
# 🚨 Development: Allows ALL origins (convenient but insecure)
CORS(app)
# ✅ Production: Only allow your specific frontend domain
CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"])
# 🔒 Advanced: Different origins for different environments
if app.debug: # Development mode
CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"])
else: # Production mode
CORS(app, origins=["https://yourdomain.com"])
```
**重要性**: 開発中は`CORS(app)`がフロントドアを開けっぱなしにするようなもので、便利ですが安全ではありません。本番環境では、APIと通信できるウェブサイトを正確に指定する必要があります。
#### 一般的なCORSシナリオと解決策
| シナリオ | 問題 | 解決策 |
|----------|---------|----------|
| **ローカル開発** | フロントエンドがバックエンドに到達できない | FastAPIにCORSMiddlewareを追加 |
| **GitHub Pages + Heroku** | デプロイされたフロントエンドがAPIに到達できない | GitHub PagesのURLをCORSオリジンに追加 |
| **カスタムドメイン** | 本番環境でのCORSエラー | CORSオリジンをドメインに合わせて更新 |
| **モバイルアプリ** | アプリがウェブAPIに到達できない | アプリのドメインを追加するか、慎重に`*`を使用 |
**プロのヒント**: ブラウザの開発者ツールのネットワークタブでCORSヘッダーを確認できます。レスポンス内の`Access-Control-Allow-Origin`などのヘッダーを探してください。
### エラーハンドリングとバリデーション
APIが適切なエラーハンドリングを含んでいることに注目してください:
```python
# Validate that we received a message
if not message:
return jsonify({"error": "Message field is required"}), 400
```
**バリデーションの重要な原則:**
- **必須フィールドをチェック**: リクエストを処理する前に
- **意味のあるエラーメッセージをJSON形式で返す**
- **適切なHTTPステータスコードを使用**: (400は不正なリクエスト用)
- **フロントエンド開発者が問題をデバッグしやすいように明確なフィードバックを提供**
## バックエンドのセットアップと実行
AI統合とFastAPIサーバーが準備できたので、すべてを実行してみましょう。セットアッププロセスには、Python依存関係のインストール、環境変数の設定、開発サーバーの起動が含まれます。
### Python環境のセットアップ
Python開発環境をセットアップしましょう。仮想環境はマンハッタン計画の区分化されたアプローチのようなもので、各プロジェクトが特定のツールと依存関係を持つ独自の空間を得ることで、異なるプロジェクト間の競合を防ぎます。
```bash
# Navigate to your backend directory
cd backend
# Create a virtual environment (like creating a clean room for your project)
python -m venv venv
# Activate it (Linux/Mac)
source ./venv/bin/activate
# On Windows, use:
# venv\Scripts\activate
# Install the good stuff
pip install openai fastapi uvicorn python-dotenv
```
**今行ったこと:**
- **独自のPythonバブルを作成**: パッケージをインストールしても他のものに影響を与えない
- **アクティブ化**: ターミナルがこの特定の環境を使用するように設定
- **必須項目をインストール**: OpenAI(AIマジック用)、FastAPI(ウェブAPI用)、Uvicorn(実行用)、python-dotenv(安全な秘密管理用)
**主要な依存関係の説明:**
- **FastAPI**: モダンで高速なウェブフレームワーク、自動APIドキュメント付き
- **Uvicorn**: FastAPIアプリケーションを実行する超高速ASGIサーバー
- **OpenAI**: GitHubモデルとOpenAI API統合用の公式ライブラリ
- **python-dotenv**: `.env`ファイルから安全に環境変数を読み込む
### 環境設定: 秘密を安全に保つ
APIを開始する前に、ウェブ開発で最も重要な教訓の一つについて話しましょう: 秘密を本当に秘密に保つ方法。環境変数は、アプリケーションだけがアクセスできる安全な金庫のようなものです。
#### 環境変数とは何か?
**環境変数は金庫のようなもの**です。貴重品をそこに入れておけば、あなただけ(とアプリ)が鍵を持ってアクセスできます。コードに直接機密情報を書き込む(誰でも見られる場所に置く)のではなく、安全に環境に保存します。
**違いは次の通りです:**
- **間違った方法**: パスワードを付箋に書いてモニターに貼る
- **正しい方法**: パスワードを安全なパスワードマネージャーに保存し、あなただけがアクセスできるようにする
#### 環境変数が重要な理由
```python
# 🚨 NEVER DO THIS - API key visible to everyone
client = OpenAI(
api_key="ghp_1234567890abcdef...", # Anyone can steal this!
base_url="https://models.github.ai/inference"
)
# ✅ DO THIS - API key stored securely
client = OpenAI(
api_key=os.environ["GITHUB_TOKEN"], # Only your app can access this
base_url="https://models.github.ai/inference"
)
```
**秘密をハードコードするとどうなるか:**
1. **バージョン管理の露出**: Gitリポジトリにアクセスできる人は誰でもAPIキーを確認できる
2. **公開リポジトリ**: GitHubにプッシュすると、キーがインターネット全体に公開される
3. **チーム共有**: プロジェクトに取り組む他の開発者が個人のAPIキーにアクセスできる
4. **セキュリティ侵害**: 誰かがAPIキーを盗むと、AIクレジットを使用される可能性がある
#### 環境ファイルの設定
バックエンドディレクトリに`.env`ファイルを作成します。このファイルは秘密をローカルに保存します:
```bash
# .env file - This should NEVER be committed to Git
GITHUB_TOKEN=your_github_personal_access_token_here
FASTAPI_DEBUG=True
ENVIRONMENT=development
```
**.envファイルの理解:**
- **1行に1つの秘密**: `KEY=value`形式
- **等号の周りにスペースなし**
- **通常は値に引用符不要**
- **コメント**は`#`で始まる
#### GitHubの個人アクセストークンの作成
GitHubトークンは、アプリケーションにGitHubのAIサービスを使用する権限を与える特別なパスワードのようなものです:
**トークン作成の手順:**
1. **GitHub設定に移動** → Developer settings → Personal access tokens → Tokens (classic)
2. **「Generate new token (classic)」をクリック**
3. **有効期限を設定**(テスト用に30日、運用用に長期間)
4. **スコープを選択**: 「repo」と必要な権限をチェック
5. **トークンを生成**し、すぐにコピー(後で確認できません!)
6. **.envファイルに貼り付け**
```bash
# Example of what your token looks like (this is fake!)
GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R
```
#### Pythonで環境変数を読み込む
```python
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Now you can access them securely
api_key = os.environ.get("GITHUB_TOKEN")
if not api_key:
raise ValueError("GITHUB_TOKEN not found in environment variables!")
client = OpenAI(
api_key=api_key,
base_url="https://models.github.ai/inference"
)
```
**このコードが行うこと:**
- **.envファイルを読み込み**: 変数をPythonで利用可能にする
- **必要なトークンが存在するか確認**: (良いエラーハンドリング!)
- **トークンがない場合は明確なエラーを発生**
- **コード内でトークンを安全に使用**: 露出を防ぐ
#### Gitのセキュリティ: .gitignoreファイル
`.gitignore`ファイルは、Gitに追跡やアップロードをしないファイルを指示します:
```bash
# .gitignore - Add these lines
.env
*.env
.env.local
.env.production
__pycache__/
venv/
.vscode/
```
**これが重要な理由**: `.env`を`.gitignore`に追加すると、Gitが環境ファイルを無視し、秘密をGitHubに誤ってアップロードするのを防ぎます。
#### 異なる環境、異なる秘密
プロフェッショナルなアプリケーションは、異なる環境に異なるAPIキーを使用します:
```bash
# .env.development
GITHUB_TOKEN=your_development_token
DEBUG=True
# .env.production
GITHUB_TOKEN=your_production_token
DEBUG=False
```
**これが重要な理由**: 開発中の実験が本番環境のAI使用量に影響を与えないようにし、異なる環境に異なるセキュリティレベルを設定します。
### 開発サーバーの起動: FastAPIを稼働させる
いよいよエキサイティングな瞬間です – FastAPI開発サーバーを起動し、AI統合が動作する様子を確認しましょう!FastAPIは、非同期Pythonアプリケーション専用に設計された超高速ASGIサーバーであるUvicornを使用します。
#### FastAPIサーバー起動プロセスの理解
```bash
# Method 1: Direct Python execution (includes auto-reload)
python api.py
# Method 2: Using Uvicorn directly (more control)
uvicorn api:app --host 0.0.0.0 --port 5000 --reload
```
このコマンドを実行すると、以下のことが舞台裏で行われます:
**1. PythonがFastAPIアプリケーションを読み込む**:
- 必要なライブラリ(FastAPI、Pydantic、OpenAIなど)をインポート
- `.env`ファイルから環境変数を読み込む
- 自動ドキュメント付きのFastAPIアプリケーションインスタンスを作成
**2. UvicornがASGIサーバーを設定**:
- 非同期リクエスト処理機能を備えたポート5000にバインド
- 自動バリデーション付きのリクエストルーティングを設定
- 開発用ホットリロードを有効化(ファイル変更時に再起動)
- インタラクティブなAPIドキュメントを生成
**3. サーバーがリスニングを開始**:
- ターミナルに`INFO: Uvicorn running on http://0.0.0.0:5000`と表示
- サーバーが複数の同時AIリクエストを処理可能
- APIが`http://localhost:5000/docs`で自動ドキュメント付きで準備完了
#### すべてが正常に動作した場合に見るべきもの
```bash
$ python api.py
INFO: Will watch for changes in these directories: ['/your/project/path']
INFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)
INFO: Started reloader process [12345] using WatchFiles
INFO: Started server process [12346]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
**FastAPI出力の理解:**
- **変更を監視**: 開発用の自動リロードが有効
- **Uvicornが稼働中**: 高性能ASGIサーバ
```python
# test_api.py - Create this file to test your API
import requests
import json
# Test the API endpoint
url = "http://localhost:5000/hello"
data = {"message": "Tell me a joke about programming"}
response = requests.post(url, json=data)
if response.status_code == 200:
result = response.json()
print("AI Response:", result['response'])
else:
print("Error:", response.status_code, response.text)
```
#### よくある起動時の問題のトラブルシューティング
| エラーメッセージ | 意味 | 修正方法 |
|------------------|------|----------|
| `ModuleNotFoundError: No module named 'fastapi'` | FastAPIがインストールされていない | 仮想環境で`pip install fastapi uvicorn`を実行してください |
| `ModuleNotFoundError: No module named 'uvicorn'` | ASGIサーバーがインストールされていない | 仮想環境で`pip install uvicorn`を実行してください |
| `KeyError: 'GITHUB_TOKEN'` | 環境変数が見つからない | `.env`ファイルと`load_dotenv()`の呼び出しを確認してください |
| `Address already in use` | ポート5000が使用中 | ポート5000を使用している他のプロセスを終了するか、ポートを変更してください |
| `ValidationError` | リクエストデータがPydanticモデルと一致しない | リクエスト形式が期待されるスキーマと一致しているか確認してください |
| `HTTPException 422` | 処理できないエンティティ | リクエストの検証に失敗しました。正しい形式については`/docs`を確認してください |
| `OpenAI API error` | AIサービスの認証に失敗 | GitHubトークンが正しく、適切な権限を持っていることを確認してください |
#### 開発のベストプラクティス
**ホットリロード**: FastAPIとUvicornを使用すると、Pythonファイルを保存するたびに自動的にリロードされます。これにより、コードを変更してすぐにテストでき、手動で再起動する必要がありません。
```python
# Enable hot reloading explicitly
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True) # debug=True enables hot reload
```
**開発用のログ記録**: ログを追加して、何が起きているかを把握しましょう:
```python
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.route("/hello", methods=["POST"])
def hello():
data = request.get_json()
message = data.get("message", "")
logger.info(f"Received message: {message}")
if not message:
logger.warning("Empty message received")
return jsonify({"error": "Message field is required"}), 400
try:
response = call_llm(message, "You are a helpful and friendly assistant.")
logger.info(f"AI response generated successfully")
return jsonify({"response": response})
except Exception as e:
logger.error(f"AI API error: {str(e)}")
return jsonify({"error": "AI service temporarily unavailable"}), 500
```
**ログが役立つ理由**: 開発中に、どのリクエストが来ているのか、AIが何を返しているのか、エラーがどこで発生しているのかを正確に確認できます。これによりデバッグが非常に迅速になります。
### GitHub Codespacesの設定: クラウド開発を簡単に
GitHub Codespacesは、ブラウザからアクセスできるクラウド上の強力な開発環境のようなものです。Codespacesで作業する場合、バックエンドをフロントエンドにアクセス可能にするためにいくつか追加の手順が必要です。
#### Codespacesネットワークの理解
ローカル開発環境では、すべてが同じコンピュータ上で動作します:
- バックエンド: `http://localhost:5000`
- フロントエンド: `http://localhost:3000` (またはfile://)
Codespacesでは、開発環境がGitHubのサーバー上で動作するため、「localhost」の意味が異なります。GitHubはサービス用の公開URLを自動的に作成しますが、適切に設定する必要があります。
#### Codespaces設定の手順
**1. バックエンドサーバーを起動する**:
```bash
cd backend
python api.py
```
Codespace環境内でFastAPI/Uvicornの起動メッセージが表示されます。
**2. ポートの可視性を設定する**:
- VS Codeの下部パネルにある「Ports」タブを探します
- リスト内のポート5000を見つけます
- ポート5000を右クリックします
- 「Port Visibility」→「Public」を選択します
**公開にする理由**: デフォルトでは、Codespaceのポートはプライベート(自分だけがアクセス可能)です。公開にすることで、ブラウザで動作するフロントエンドがバックエンドと通信できるようになります。
**3. 公開URLを取得する**:
ポートを公開にした後、次のようなURLが表示されます:
```
https://your-codespace-name-5000.app.github.dev
```
**4. フロントエンド設定を更新する**:
```javascript
// In your frontend app.js, update the BASE_URL:
this.BASE_URL = "https://your-codespace-name-5000.app.github.dev";
```
#### Codespace URLの理解
Codespace URLは予測可能なパターンに従います:
```
https://[codespace-name]-[port].app.github.dev
```
**これを分解すると**:
- `codespace-name`: Codespaceの一意の識別子(通常はユーザー名を含む)
- `port`: サービスが動作しているポート番号(FastAPIアプリの場合は5000)
- `app.github.dev`: Codespaceアプリケーション用のGitHubドメイン
#### Codespace設定のテスト
**1. バックエンドを直接テストする**:
公開URLを新しいブラウザタブで開きます。次のような画面が表示されるはずです:
```
Welcome to the AI Chat API. Send POST requests to /hello with JSON payload containing 'message' field.
```
**2. ブラウザの開発者ツールでテストする**:
```javascript
// Open browser console and test your API
fetch('https://your-codespace-name-5000.app.github.dev/hello', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message: 'Hello from Codespaces!'})
})
.then(response => response.json())
.then(data => console.log(data));
```
#### Codespacesとローカル開発の比較
| 項目 | ローカル開発 | GitHub Codespaces |
|------|-------------|-------------------|
| **セットアップ時間** | 長い(Pythonや依存関係のインストール) | 即時(事前設定済み環境) |
| **URLアクセス** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` |
| **ポート設定** | 自動 | 手動(ポートを公開にする必要あり) |
| **ファイルの永続性** | ローカルマシン | GitHubリポジトリ |
| **コラボレーション** | 環境の共有が難しい | Codespaceリンクの共有が簡単 |
| **インターネット依存性** | AI API呼び出しのみ | すべてに必要 |
#### Codespace開発のヒント
**Codespacesでの環境変数**:
Codespacesでは`.env`ファイルが同じように機能しますが、環境変数を直接設定することもできます:
```bash
# Set environment variable for the current session
export GITHUB_TOKEN="your_token_here"
# Or add to your .bashrc for persistence
echo 'export GITHUB_TOKEN="your_token_here"' >> ~/.bashrc
```
**ポート管理**:
- Codespacesはアプリケーションがポートでリスニングを開始すると自動的に検出します
- 複数のポートを同時に転送可能(後でデータベースを追加する場合に便利)
- Codespaceが動作している限りポートはアクセス可能です
**開発ワークフロー**:
1. VS Codeでコードを変更
2. FastAPIが自動リロード(Uvicornのリロードモードのおかげ)
3. 公開URLを通じてすぐに変更をテスト
4. 準備が整ったらコミットしてプッシュ
> 💡 **プロのヒント**: 開発中にCodespaceバックエンドURLをブックマークしてください。同じCodespaceを使用している限り、URLは変更されません。
## フロントエンドチャットインターフェースの作成: 人間とAIの接点
次に、ユーザーインターフェースを構築します。これは、人々がAIアシスタントとどのようにやり取りするかを決定する部分です。オリジナルのiPhoneインターフェースのデザインのように、複雑な技術を直感的で自然に使えるようにすることに焦点を当てます。
### モダンなフロントエンドアーキテクチャの理解
私たちのチャットインターフェースは「シングルページアプリケーション(SPA)」と呼ばれるものになります。古い方法では、クリックするたびに新しいページが読み込まれますが、私たちのアプリはスムーズかつ瞬時に更新されます。
**古いウェブサイト**: 紙の本を読むようなもの – 完全に新しいページに移動します
**私たちのチャットアプリ**: スマートフォンを使うようなもの – すべてが流れるように更新されます
```mermaid
graph TD
A[User Types Message] --> B[JavaScript Captures Input]
B --> C[Validate & Format Data]
C --> D[Send to Backend API]
D --> E[Display Loading State]
E --> F[Receive AI Response]
F --> G[Update Chat Interface]
G --> H[Ready for Next Message]
```
### フロントエンド開発の3つの柱
すべてのフロントエンドアプリケーション – シンプルなウェブサイトからDiscordやSlackのような複雑なアプリまで – は3つのコア技術で構築されています。これらはウェブ上で見たり操作したりするすべての基盤です。
**HTML(構造)**: 基盤となる部分
- 存在する要素を決定(ボタン、テキストエリア、コンテナなど)
- コンテンツに意味を与える(これはヘッダー、これはフォームなど)
- すべてが構築される基本構造を作成
**CSS(見た目)**: インテリアデザイナーのような役割
- すべてを美しくする(色、フォント、レイアウト)
- 異なる画面サイズに対応(スマホ、ラップトップ、タブレット)
- スムーズなアニメーションや視覚的なフィードバックを作成
**JavaScript(動作)**: 頭脳の役割
- ユーザーの操作に応答(クリック、入力、スクロール)
- バックエンドと通信してページを更新
- すべてをインタラクティブで動的にする
**建築設計のように考える**:
- **HTML**: 構造設計図(空間と関係を定義)
- **CSS**: 美的および環境デザイン(視覚スタイルとユーザー体験)
- **JavaScript**: 機械システム(機能性とインタラクティブ性)
### モダンなJavaScriptアーキテクチャが重要な理由
私たちのチャットアプリケーションでは、プロフェッショナルなアプリケーションで見られるモダンなJavaScriptパターンを使用します。これらの概念を理解することで、開発者として成長する際に役立ちます。
**クラスベースのアーキテクチャ**: コードをクラスに整理します。これはオブジェクトの設計図を作成するようなものです
**Async/Await**: 時間がかかる操作(API呼び出しなど)を処理するモダンな方法
**イベント駆動型プログラミング**: アプリがユーザーの操作(クリック、キー入力)に応答する
**DOM操作**: ユーザーの操作やAPIの応答に基づいてウェブページのコンテンツを動的に更新
### プロジェクト構造のセットアップ
以下のような整理された構造でフロントエンドディレクトリを作成します:
```text
frontend/
├── index.html # Main HTML structure
├── app.js # JavaScript functionality
└── styles.css # Visual styling
```
**アーキテクチャの理解**:
- **構造(HTML)**、**動作(JavaScript)**、**見た目(CSS)**の間で関心を分離
- **簡単にナビゲート**および変更可能なシンプルなファイル構造を維持
- **ウェブ開発のベストプラクティス**に従った組織化と保守性
### HTMLの基盤を構築する: アクセシビリティのためのセマンティック構造
まずHTML構造から始めましょう。モダンなウェブ開発では「セマンティックHTML」が重視されます。これは、外観だけでなくその目的を明確に説明するHTML要素を使用することを意味します。これにより、アプリケーションがスクリーンリーダー、検索エンジン、その他のツールにアクセス可能になります。
**セマンティックHTMLが重要な理由**: チャットアプリを電話で誰かに説明すると想像してください。「タイトルがあるヘッダー、会話が表示されるメインエリア、メッセージを入力するためのフォームが下部にある」と言うでしょう。セマンティックHTMLは、この自然な説明に一致する要素を使用します。
`index.html`を以下のように構造化されたマークアップで作成します:
```html
Ask me anything!