Next.js の Server Actions を利用して Claude チャットを作成する
2024-07-23
はじめに
Next.js の Server Actions を利用して Anthropic API の Claude へ質問します。
プロジェクト作成
プロジェクトを作成します。
npx create-next-app@latest
プロジェクト名は、 claude-chat-app
を入力し、その他の質問はデフォルトを選択しました。エンター連打です。
✔ What is your project named? … claude-chat-app
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Anthropic TypeScript API インストール
cd claude-chat-app
npm install @anthropic-ai/sdk
スタイルの初期化
/app/globals.css
を以下に修正します。
@tailwind base;
@tailwind components;
@tailwind utilities;
API キーを環境変数へ設定
.env.local
へ以下を追加します。
API_KEY='{自分の API キー}'
Server Actions 作成
/app/actions.tsx
を作成します。 Form から取得した model
, message
を API のパラメータへ指定します。
'use server'
import { Anthropic } from '@anthropic-ai/sdk'
type State = {
response: string
}
export async function callAI(prevState: State, formData: FormData) {
const rawFormData = {
model: formData.get('model'),
message: formData.get('message')
}
console.log(rawFormData)
const anthropic = new Anthropic({
apiKey: process.env['API_KEY']
})
const msg = await anthropic.messages.create({
model: rawFormData.model as string,
max_tokens: 1024,
messages: [{ role: 'user', content: rawFormData.message as string }]
})
// console.log(msg)
const answer = (msg.content[0] as Anthropic.TextBlock).text
return {
response: answer
}
}
トップページ修正
/app/page.tsx
を修正します。Form のアクションへ Server Actions を指定します。
Claude からの回答は <pre>{formState.response}</pre>
の部分へ表示されます。
'use client'
import { useFormState } from 'react-dom'
import { callAI } from '../app/actions'
export default function Home() {
const model = 'claude-3-5-sonnet-20240620'
const [formState, formAction] = useFormState(callAI, {
response: 'ここへ返答が表示されます。'
})
return (
<main>
<div>
<h1 className='text-2xl'>Claude Chat App</h1>
<pre>{formState.response}</pre>
<form action={formAction}>
<div>
<input type='hidden' name='model' value={model} />
<textarea
name='message'
defaultValue=''
placeholder='メッセージを入力してください'
></textarea>
</div>
<button>送信</button>
</form>
</div>
</main>
)
}
動作確認
npm run dev