Rork でアプリを作るとき、AI 機能を組み込みたいと思ったことはありませんか?「Gemini 連携の記事はよく見るけど、Claude は難しそう」という印象を持つ方もいるかもしれません。でも実は、Claude API は非常にシンプルで、Rork との相性も抜群です。
今回は Claude claude-sonnet-4-6(Anthropic の最新モデル)を使ったAIアシスタントアプリを、Rork で実際に作りながら解説します。単なる「チャット画面」ではなく、ストリーミングレスポンス・会話履歴の管理・トークンコストの最適化まで、実用的な実装を一通り扱います。
Claude claude-sonnet-4-6 を選ぶ理由
2026年5月時点で、Claude claude-sonnet-4-6 は Anthropic の最新ミッドレンジモデルです。モバイルアプリに組み込む際の観点から見ると、このモデルには明確な強みがあります。
まず、応答品質とコストのバランスが優れています。Opus 4.6 は最高性能ですが、会話型アシスタントには claude-sonnet-4-6 で十分なケースがほとんどです。API コストは Opus の約3分の1程度に抑えられます。
次に、コンテキストウィンドウが大きい点があります。長い会話履歴や、ドキュメントを渡してのQ&Aにも対応できます。「過去の会話を覚えているAI」という体験は、ユーザー満足度に直結します。
そして、日本語の精度が高いです。Rork で日本語アプリを開発している方にとって、Claude は特に強力な選択肢です。
作るもの:パーソナルAIメモアシスタント
ここでは以下の機能を持つアプリを作ります。
- ユーザーが話しかけると、Claude が応答する
- 会話履歴が保持され、文脈を踏まえた返答ができる
- レスポンスがストリーミングで表示される(文字が流れる演出)
- 過去の会話をローカルに保存・再読み込みできる
シンプルに見えますが、この実装パターンを理解しておくと、料理アシスタント・学習サポート・日記AI など、あらゆるAIアプリに応用できます。
下準備:Claude API キーの取得
まず Anthropic のコンソール(console.anthropic.com)でAPIキーを取得します。Rork のプロジェクト設定でキーを環境変数として管理するのがベストプラクティスです。
Rork に以下のプロンプトを入力して、プロジェクトの基本構造を作ります。
AIメモアシスタントアプリを作ってください。
- チャット形式のUI(吹き出し)
- 画面下部にテキスト入力とSendボタン
- Claude APIを呼び出す(モデル: claude-sonnet-4-6)
- 会話履歴を管理して文脈を引き継ぐ
- 送信中はLoadingインジケーターを表示
デザインはシンプルで落ち着いた配色にしてください。
Rork がベースとなるチャット画面を生成したら、次のステップで API 連携を実装していきます。
Step 1:Claude API との接続
Rork が生成したコードに、Claude API の呼び出し処理を追加します。services/claude.ts という新しいファイルを作って、API ロジックを分離するのがおすすめです。
// services/claude.ts
// Claude claude-sonnet-4-6 API呼び出しサービス
const CLAUDE_API_URL = 'https://api.anthropic.com/v1/messages';
// メッセージの型定義
export interface Message {
role: 'user' | 'assistant';
content: string;
}
// Claude に送るリクエストの型
interface ClaudeRequest {
model: string;
max_tokens: number;
messages: Message[];
system?: string;
}
/**
* Claude API を呼び出してレスポンスを返す
* @param messages 会話履歴(ユーザーとアシスタントのメッセージ配列)
* @param systemPrompt AIの役割・振る舞いを定義するシステムプロンプト
*/
export async function callClaude(
messages: Message[],
systemPrompt?: string
): Promise<string> {
const apiKey = process.env.EXPO_PUBLIC_ANTHROPIC_API_KEY;
if (!apiKey) {
throw new Error('Anthropic API key is not configured');
}
const requestBody: ClaudeRequest = {
model: 'claude-sonnet-4-6', // 最新のclaude-sonnet-4-6を使用
max_tokens: 1024,
messages,
system: systemPrompt,
};
const response = await fetch(CLAUDE_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
'anthropic-version': '2023-06-01',
},
body: JSON.stringify(requestBody),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Claude API error: ${error.error?.message || 'Unknown error'}`);
}
const data = await response.json();
// レスポンスからテキストを取得
return data.content[0]?.text ?? '';
}このコードで重要な点が2つあります。
エラーハンドリングを省略しないこと。API キーが未設定、ネットワークエラー、レート制限超過——モバイルアプリは様々な環境で動くため、エラーを無視すると本番でのクラッシュにつながります。
EXPO_PUBLIC_ プレフィックスを使うこと。Rork(Expo ベース)では、このプレフィックスがある環境変数のみクライアントサイドで参照できます。API キーは直接コードに書かず、必ず環境変数で管理してください。
Step 2:会話履歴の管理
「AIが文脈を覚えている」体験を作るために、会話履歴の管理は核心部分です。チャット画面のコンポーネントに以下のロジックを追加します。
// hooks/useChat.ts
// 会話管理カスタムフック
import { useState, useCallback } from 'react';
import { callClaude, Message } from '../services/claude';
const SYSTEM_PROMPT = `あなたは親切なパーソナルアシスタントです。
ユーザーのメモや考えを整理するお手伝いをしてください。
返答は簡潔に、かつ温かみのある日本語で行ってください。`;
// トークン消費を抑えるため、直近10件のメッセージのみ送信する
const MAX_HISTORY = 10;
export function useChat() {
const [messages, setMessages] = useState<Message[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const sendMessage = useCallback(async (userText: string) => {
if (!userText.trim() || isLoading) return;
// ユーザーメッセージを追加
const userMessage: Message = { role: 'user', content: userText };
const updatedMessages = [...messages, userMessage];
setMessages(updatedMessages);
setIsLoading(true);
setError(null);
try {
// 直近MAX_HISTORY件のみAPIに送信(コスト最適化)
const recentMessages = updatedMessages.slice(-MAX_HISTORY);
const assistantText = await callClaude(recentMessages, SYSTEM_PROMPT);
// アシスタントの返答を追加
const assistantMessage: Message = {
role: 'assistant',
content: assistantText,
};
setMessages(prev => [...prev, assistantMessage]);
} catch (err) {
const errorMessage = err instanceof Error
? err.message
: 'メッセージの送信中にエラーが発生しました';
setError(errorMessage);
// エラー時はユーザーメッセージも削除して、再送できるようにする
setMessages(messages);
} finally {
setIsLoading(false);
}
}, [messages, isLoading]);
const clearHistory = useCallback(() => {
setMessages([]);
setError(null);
}, []);
return { messages, isLoading, error, sendMessage, clearHistory };
}MAX_HISTORY = 10 という定数に注目してください。会話が長くなると、すべての履歴を毎回 API に送るのはコストの無駄です。「直近10件だけ送る」というシンプルなルールを設けることで、長い会話でもコストを一定範囲に抑えられます。実際の開発では、アプリの用途に応じてこの数値を調整してください。
Step 3:ストリーミング表示の実装
「AIがリアルタイムで文字を打っている」ような演出は、ユーザー体験を大きく向上させます。Claude API はストリーミングレスポンスに対応しているので、これを実装しましょう。
// services/claude.ts に追加
// ストリーミング版の Claude 呼び出し
export async function callClaudeStreaming(
messages: Message[],
onChunk: (text: string) => void, // テキストの断片を受け取るコールバック
onComplete: () => void,
systemPrompt?: string
): Promise<void> {
const apiKey = process.env.EXPO_PUBLIC_ANTHROPIC_API_KEY;
if (!apiKey) {
throw new Error('Anthropic API key is not configured');
}
const response = await fetch(CLAUDE_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
'anthropic-version': '2023-06-01',
},
body: JSON.stringify({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
stream: true, // ストリーミングを有効化
messages,
system: systemPrompt,
}),
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
// ストリームのテキストを読み取る
const reader = response.body?.getReader();
const decoder = new TextDecoder();
if (!reader) {
throw new Error('Failed to get response stream reader');
}
let buffer = '';
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() ?? '';
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') continue;
try {
const parsed = JSON.parse(data);
const text = parsed.delta?.text ?? '';
if (text) {
onChunk(text); // テキストの断片をUIに渡す
}
} catch {
// JSONパース失敗は無視(不完全なチャンクの場合がある)
}
}
}
}
} finally {
reader.releaseLock();
onComplete();
}
}ストリーミングの実装で特に注意したいのは、finally ブロックで必ず reader.releaseLock() を呼ぶこと。エラーが発生した場合でも Reader のロックを解放しないと、その後のリクエストが詰まる原因になります。
Step 4:チャット UI への組み込み
ここまで作った機能を、Rork が生成したチャット画面に組み込みます。Rork に対して以下のプロンプトで UI を更新してもらいましょう。
チャット画面を以下のように改善してください。
1. メッセージ送信中はSendボタンを無効化(isLoading=true の間)
2. AIの返答は文字が1文字ずつ表示されるアニメーション
3. エラー時は赤いバナーでメッセージを表示(再送ボタン付き)
4. 画面上部に「会話をリセット」ボタンを追加
5. メッセージリストは新しいメッセージが届いたら自動スクロール
useChat フックは既に作成済みです。それを使って実装してください。
Rork が生成したコードを確認したら、sendMessage・clearHistory・isLoading・error をそれぞれ適切なUIコンポーネントに接続します。細かい調整はプロンプトで依頼するか、Rork Max であれば直接コードを編集できます。
コスト管理:個人開発者が知っておくべき数字
Claude API の費用は、送受信したトークン数に応じて発生します。claude-sonnet-4-6 の場合、1回の会話(ユーザー発言 + AI返答 = 約500トークン)で発生するコストは非常に小さいです。
私が実際に作ったアシスタントアプリでの実感ですが、1日10〜20回チャットするアクティブユーザーで、月の API 費用は数十円程度に収まりました。ユーザー数が増えるまでは気にしすぎなくてよいと思います。
ただし、アプリが伸びてきたら「1ユーザーあたりの月次API費用」を計算して、サブスクリプション価格が採算に合うかを確認することをおすすめします。
まずは動かしてみることが大切です
Claude claude-sonnet-4-6 と Rork の組み合わせは、AIアシスタントアプリの開発ハードルを大きく下げてくれます。この記事で作ったものは「最低限動く状態」ですが、そこから始めてユーザーの反応を見ながら改善するのが、個人開発でうまくいくやり方だと思います。
まずは Rork でベースを作り、自分が実際に使いながら「ここが不便」を見つけていく——そのサイクルが、最終的に使いやすいアプリに育っていきます。
関連記事として、プロンプトエンジニアリングを深掘りしたい方はこちら、Claude API をさらに活用した応用実装はこちらを参考にしてください。