# Vercel AI SDK

Source: https://aiand-docs-staging.pages.dev/ja/integrations/vercel-ai/

Vercel AI SDK は `@ai-sdk/openai-compatible` で ai& に接続します。

## セットアップ

```bash
npm install ai @ai-sdk/openai-compatible
```

```ts
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";

export const aiand = createOpenAICompatible({
  name: "aiand",
  baseURL: "https://api.aiand.com/v1",
  apiKey: process.env.AIAND_API_KEY,
  includeUsage: true,
});
```

API キーは [ai& コンソール](https://console.aiand.com) で発行し、`AIAND_API_KEY` に設定します。

## テキスト生成

```ts
import { generateText } from "ai";
import { aiand } from "./client";

const { text } = await generateText({
  model: aiand("google/gemma-4-31b-it"),
  prompt: "Tell me a haiku about Tokyo.",
});

console.log(text);
```

システムプロンプトは `{ role: "system" }` メッセージではなく `instructions` に置きます。

## ブラウザにストリーム (Next.js App Router)

```bash
npm install @ai-sdk/react
```

```ts
// app/api/chat/route.ts
import { convertToModelMessages, createUIMessageStreamResponse, streamText, toUIMessageStream, type UIMessage } from "ai";
import { aiand } from "@/lib/aiand";

export async function POST(req: Request) {
  const { messages }: { messages: UIMessage[] } = await req.json();
  const result = streamText({
    model: aiand("google/gemma-4-31b-it"),
    messages: await convertToModelMessages(messages),
  });
  return createUIMessageStreamResponse({
    stream: toUIMessageStream({ stream: result.stream }),
  });
}
```

```tsx
// app/page.tsx
"use client";
import { useChat } from "@ai-sdk/react";
import { useState } from "react";

export default function Page() {
  const { messages, sendMessage } = useChat();
  const [input, setInput] = useState("");
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        sendMessage({ text: input });
        setInput("");
      }}
    >
      {messages.map((m) => (
        <div key={m.id}>
          {m.role}:{" "}
          {m.parts.map((part, i) => (part.type === "text" ? <span key={i}>{part.text}</span> : null))}
        </div>
      ))}
      <input value={input} onChange={(e) => setInput(e.target.value)} />
    </form>
  );
}
```

## ツール

```ts
import { generateText, tool } from "ai";
import { z } from "zod";
import { aiand } from "./client";

const result = await generateText({
  model: aiand("google/gemma-4-31b-it"),
  tools: {
    getWeather: tool({
      description: "Get current weather",
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => `Sunny in ${city}, 22°C`,
    }),
  },
  prompt: "What's the weather in Tokyo?",
});
```

## 推論 (reasoning)

推論モデルは `providerOptions` でレベルを受け取ります。モデルごとの対応レベルは [モデルカタログ](https://api.aiand.com/v1/models) の `reasoning_efforts` にあります。

```ts
const { text } = await generateText({
  model: aiand("moonshotai/kimi-k3"),
  prompt: "Solve this step by step: What is 15 * 23?",
  providerOptions: {
    aiand: {
      reasoningEffort: "high",
    },
  },
});
```

<Aside type="tip">
  React Server Components 用の `useUIState` / `streamUI` でも同じ `aiand` プロバイダがそのまま動作します。
</Aside>
