1分でできるNuxtとTanStack AIで作るJevのWebサイト

NuxtとTanStack AIをインストール

手軽に環境構築するためにNuxtとTanStack AIでWebサイトを構築します。

以下のコマンドでVue → Nuxtを選択しますが、Jevの結果を処理するファイルは別ファイルにするのでNext.jsなどにしても問題ありません。

npm create vite@latest jev-site

Viteのインストールが完了したら、TanStack AIもインストールします。

Jevを使用するために「@tanstack/ai-typesafe」もインストールします。

npm i @tanstack/ai @tanstack/ai-typesafe

これらのインストールが完了したら、まずバックエンド側のserver/api/jev.tsを用意して、質問に対して応答する簡単な処理を作ります。

今回は入力したテキストが動物かどうかを判定するboolean(Noul)の処理を作成してみます。

server/api/jev.ts
import { decide, boolean } from '@tanstack/ai'
import { typesafeDecider } from '@tanstack/ai-typesafe'
import { defineEventHandler, readBody, createError } from 'h3'

export default defineEventHandler(async (event) => {
  const body = await readBody<{ text: string }>(event)
  const text = body?.text

  const result = await decide({
    adapter: typesafeDecider('jev-latest'),
    state: { text },
    questions: {
      isProblematic: boolean({
        instructions: '動物か判定してください'
      })
    }
  })

  return {
    flagged: result.isProblematic.value
  }
})

app.vueは以下のようにテキストを入力して、判定ボタンを押したらAPIで結果を取得して判定できるようにします。

app.vue
<script setup lang="ts">
import { ref } from 'vue'

const text = ref('')
const loading = ref(false)
const flagged = ref<boolean | null>(null)

const handleCheck = async () => {
  if (!text.value.trim()) return

  loading.value = true
  flagged.value = null

  try {
    const res = await $fetch<{ flagged: boolean }>('/api/jev', {
      method: 'POST',
      body: { text: text.value }
    })
    flagged.value = res.flagged
  } finally {
    loading.value = false
  }
}
</script>

<template>
  <div>
    <h1>動物判定デモ</h1>
    <input
      v-model="text"
      type="text"
      placeholder="テキストを入力"
      @keyup.enter="() => handleCheck()"
    >
    <button type="button" :disabled="loading" @click="() => handleCheck()">
      {{ loading ? '判定中...' : '判定' }}
    </button>

    <div v-if="flagged !== null">
      <p>判定結果: {{ flagged ? '動物です ✅' : '動物ではない ❌️' }}</p>
    </div>
  </div>
</template>

最後に.envにTypeSafeのAPI Keyを追加すれば完成です。

API KeyはTypeSafe AIの公式サイトにて、5ドル支払えば利用できます。

.env
TYPESAFE_API_KEY=apikey_12a34b56c78d90

3択以上の場合はchoiceを使用

「動物かどうか」の2択だけならboolean(Noul)を使用しますが、3択以上の場合はchoiceを使用します。

server/api/jev.ts
import { choice, decide } from '@tanstack/ai'
import { typesafeDecider } from '@tanstack/ai-typesafe'
import { createError, defineEventHandler, readBody } from 'h3'

export default defineEventHandler(async (event) => {
  const body = await readBody<{ text: string }>(event)
  const text = body?.text

  const result = await decide({
    adapter: typesafeDecider('jev-latest'),
    state: { text },
    questions: {
      type: choice({
        instructions: '入力されたテキストが何に該当するか判定してください',
        options: {
          animal: '動物',
          plant: '植物',
          person: '人間',
          object: '物体',
          other: 'その他'
        }
      })
    }
  })

  return {
    type: result.type.value
  }
})

順序のある評価の場合はscoreを使用

「低・中・高」のような順序のある評価の場合はscoreを使用します。

server/api/jev.ts
import { decide, score } from '@tanstack/ai'
import { typesafeDecider } from '@tanstack/ai-typesafe'
import { createError, defineEventHandler, readBody } from 'h3'

export default defineEventHandler(async (event) => {
  const body = await readBody<{ text: string }>(event)
  const text = body?.text

  const result = await decide({
    adapter: typesafeDecider('jev-latest'),
    state: { text },
    questions: {
      severity: score({
        instructions: 'このテキストの問題の深刻度を判定してください',
        levels: ['low', 'medium', 'high']
      })
    }
  })

  return {
    severity: result.severity.value
  }
})

まとめ

現在のTanStack AIのdecide()では、質問タイプは主にboolean・choice・scoreの3種類があります。

  • boolean:Yes / Noのような2択で判定したい場合
  • choice:複数の選択肢から1つを選んで分類したい場合
  • score:順序や段階のある評価をしたい場合

なお、TypeSafe側のwire形式では、booleanはnoulという名前で扱われます。

これらを使用することで、1分でJevによるAIを利用した安価で高速な判定が利用できるので、WebサイトにAIを導入したい場合は、こちらを使用することをオススメします。