はじめに
Claude 3.5 Sonnet が先月公開されました。
Claude 3.5 Sonnetは、Anthropic社が開発した最新の大規模言語モデルです。前バージョンと比較して、大幅な性能向上が見られます。
注目なのはArtifactsという機能です。LLMが生成したコードを右側の実行環境でプレビューしつつ、対話形式で修正を依頼することができます。従来のチャットベースのやり取りに加え、より視覚的で直感的な開発体験を提供します。
今回はこのArtifacts機能を使った例をご紹介します。
アプリのフロントを作成し、プレビューしながら修正する
Reactで作成されたコードをpreviewしつつ修正できます。
次のようなアプリを生成してください
1. 英語の入力ボックスに英文を入力する
2. 入力した英文は、クリック可能なUIとなる
上記のように指示を出すと、Claude 3.5 Sonnetはリアルタイムにコードを生成し、右側のプレビューエリアに反映してくれます。
一発では狙い通り完成しませんが、プレビューを見ながら具体的な指示をチャットで伝えることで、コードを修正していくことができます。
何度か対話を続けることで、以下のようなところまで作成できました。
このコードをローカルの環境にコピーし、裏側で翻訳APIを繋げます。
今回はGoogle Cloud のCloud Translation APIを使用しました。
バックエンド部分は非同期処理で同期的に待ってしまったりと、ところどころ実装が不十分でしたが、
フロントの知識が皆無でも、Claude 3.5 Sonnetの力を借りることで、以下のような英語学習アプリが作成できました。
具体的なコードは以下のようになりました。
import React, { useState, useCallback } from 'react';
import axios from 'axios';
// Mock translation dictionaries
let wordTranslations = {
'Hello': 'こんにちは',
'world': '世界',
'This': 'これは',
'is': 'です',
'a': '1つの',
'test': 'テスト',
'sentence': '文',
'for': 'のための',
'translation': '翻訳',
'I': '私は',
'love': '愛します',
'programming': 'プログラミング',
'in': 'で',
'JavaScript': 'ジャバスクリプト',
};
let fullTextTranslations = {
'Hello world': 'こんにちは、世界',
'This is a test sentence for translation': 'これは翻訳のためのテスト文です',
'I love programming in JavaScript': '私はJavaScriptでのプログラミングが大好きです',
};
// Google Cloud Translation APIを使用した翻訳関数
const translateTextWithAPI = async (text) => {
const apiKey = ''; // ここに取得したAPIキーを入力してください
const url = `https://translation.googleapis.com/language/translate/v2?key=${apiKey}`;
try {
const response = await axios.post(url, {
q: text,
target: 'ja'
});
console.log("text: %s, translated: %s", text, response.data.data.translations[0].translatedText);
return response.data.data.translations[0].translatedText;
} catch (error) {
console.error('Error translating text:', error);
return '翻訳に失敗しました';
}
};
const translateTextWithAPIbyword = async (word) => {
const translatedText = await translateTextWithAPI(word);
wordTranslations[word.toLowerCase()] = translatedText;
}
// Simulated API call for word translation
const translateWord = async (word) => {
return new Promise((resolve) => {
setTimeout(() => {
console.log("keyとなるword: %s", word);
const translation = wordTranslations[word.toLowerCase()] || `[${word}の訳]`;
wordTranslations[word.toLowerCase()] = translation;
resolve(translation);
}, 100);
});
};
// Simulated API call for full text translation
const translateFullText = async (text) => {
return new Promise((resolve) => {
setTimeout(() => {
const translation = fullTextTranslations[text] || text.split(' ').map(word => wordTranslations[word.toLowerCase()] || `[${word}の訳]`).join(' ');
fullTextTranslations[text.toLowerCase()] = translation;
resolve(translation);
}, 500);
});
};
const Word = ({ word }) => {
const [showTranslation, setShowTranslation] = useState(false);
const handleClick = () => {
setShowTranslation(!showTranslation);
};
return (
<span className="inline-block mr-1 mb-2">
<span
onClick={handleClick}
className="cursor-pointer hover:bg-blue-100 p-1 rounded"
>
{word}
</span>
{showTranslation && (
<span className="block text-sm text-gray-600">
{wordTranslations[word.toLowerCase()] || `[${word}の訳]`}
</span>
)}
</span>
);
};
const InteractiveTranslatorApp = () => {
const [inputText, setInputText] = useState('');
const [displayText, setDisplayText] = useState('');
const [fullTranslation, setFullTranslation] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleInputChange = useCallback((e) => {
setInputText(e.target.value);
}, []);
const handleSubmit = useCallback(async (e) => {
e.preventDefault();
setIsLoading(true);
console.log('送信ボタンがクリックされました');
console.log('入力テキスト:', inputText);
const words = inputText.split(' ');
let results = [];
for (let word of words) {
results.push(translateTextWithAPIbyword(word));
}
await Promise.all(results);
results = [];
for (let word of words) {
results.push(translateWord(word));
}
await Promise.all(results);
setDisplayText(inputText);
setIsLoading(false);
}, [inputText]);
const handleButtonClick = useCallback(() => {
console.log('ボタンが直接クリックされました');
}, []);
const handleFullTranslation = useCallback(async () => {
setIsLoading(true);
const translatedText = await translateTextWithAPI(displayText);
// const translatedText = await translateFullText(displayText);
setFullTranslation(translatedText);
setIsLoading(false);
}, [displayText]);
return (
<div className="p-4 max-w-2xl mx-auto">
<h1 className="text-2xl font-bold mb-4">インタラクティブ英語翻訳アプリ</h1>
<form onSubmit={handleSubmit} className="mb-4">
<textarea
value={inputText}
onChange={handleInputChange}
placeholder="英語の文章を入力してください"
className="w-full p-2 border border-gray-300 rounded"
rows="4"
/>
<button
type="submit"
onClick={handleButtonClick}
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
disabled={isLoading}
>
{isLoading ? '処理中...' : '送信'}
</button>
</form>
{displayText && (
<div className="mt-4">
<div className="p-4 bg-gray-100 rounded">
{displayText.split(' ').map((word, index) => (
<Word key={`${word}-${index}`} word={word} />
))}
</div>
<button
onClick={handleFullTranslation}
className="mt-2 px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"
disabled={isLoading}
>
{isLoading ? '処理中...' : '全体翻訳'}
</button>
{fullTranslation && (
<div className="mt-2 p-4 bg-yellow-100 rounded">
<h2 className="font-bold mb-2">全体翻訳:</h2>
<p>{fullTranslation}</p>
</div>
)}
</div>
)}
<div className="mt-4">
<p>デバッグ情報:</p>
<p>入力テキスト: {inputText}</p>
<p>表示テキスト: {displayText}</p>
<p>全体翻訳: {fullTranslation}</p>
</div>
</div>
);
};
export default InteractiveTranslatorApp;
svg形式で図を作成し、プレビューを閲覧しながら調整
diffusionモデルを使った画像生成はできませんが、svg形式で画像を作成しプレビューすることができます。
svgで、会社のロゴを作成してください
Claude 3.5 Sonnetは、抽象的な指示に対しても、具体的なアウトプットを生成することができます。もちろん、ロゴのデザインも調整可能です。
次に、JKKのロゴを作ってもらいます。
Create the logo of Juncture Keeps Key Technologies, Inc (JKK Technologies) in svg
会社名を与えることで、それを反映したロゴを作成してくれます。
もう少し会社情報を入れてみましょう。
JKK Technologies is a company that specializes in data analysis, so please create a logo that will make that feature easily recognizable!
会社の特徴を伝えることで、ロゴにそれを象徴する要素を加えることも可能です。
なかなかかわいいロゴが作成できました。
終わりに
Claude 3.5 Sonnetは、Artifacts機能によって、従来のLLMよりもさらにインタラクティブで直感的な開発体験を提供します。今回の例を通じて、その可能性を感じていただけたのではないでしょうか。今後、Claude 3.5 Sonnetがどのように活用されていくのか、非常に楽しみです。