Chat
Nuxt UI bietet eine Reihe von Komponenten, die entwickelt wurden, um KI-gestützte Chat-Interfaces zu erstellen. Sie integrieren sich nahtlos in die Vercel AI SDK für Streaming-Antworten, Argumentation, Toolcalling und mehr.
Nuxt und Vue AI Chat-Vorlagen auf GitHub für produktionsreife Implementierungen an.Komponenten
| Komponente | Description |
|---|---|
| ChatMessages | Scrollbare Nachrichtenliste mit Auto-Scroll-und Ladeanzeige. |
| ChatMessage | Individuelle Nachrichtenblase mit Avatar, Aktionen und Slots. |
| @@@ph023@@@chatprompt@@@ph024@@@@@@@ph025@@@@@@ph026 @ | Erweiterte Textarea für die Übermittlung von Prompts. |
| ChatPromptSubmit | Absenden-Button mit automatischer Status-Handhabung. |
| @@@ph031@@@ph032@@@@@@ph033@@@@@@ph034 @@ | Zusammenklappbarer Block für den KI-Reasoning/Denkprozess. |
| ChatTool | Zusammenklappbarer Block für den Aufrufstatus von AI-Tools. |
| @@@ph039@@@ph040@@@@@@ph041@@@@@@ph042 @ | Text Shimmer Animation für Streaming-Zustände. |
| @@@ph043@@@ph044@@@@@ph045@@@@@@ph046 @@ | Layout wrapper zum einbetten von chat in modals oder schubladen. |
@@ph047@installation
Die Chat-Komponenten sind für die Verwendung mit der Vercel AI SDK, insbesondere der Chat Klasse zur Verwaltung des Chat-Status und der Streaming-Antworten vorgesehen.
Installieren Sie die erforderlichen Abhängigkeiten:
Server-Einrichtung
Erstellen Sie einen Server-API-Endpunkt, um Chat-Anfragen zu bearbeiten, indem Sie . Sie können das Vercel AI Gateway verwenden, um über einen zentralen Endpunkt auf KI-Modelle zuzugreifen:
import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai'
import { gateway } from '@ai-sdk/gateway'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const result = streamText({
model: gateway('anthropic/claude-sonnet-5'),
maxOutputTokens: 10000,
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages)
})
const stream = toUIMessageStream({ stream: result.stream })
return createUIMessageStreamResponse({ stream })
})
Begründung
Um reasoning zu aktivieren, konfigurieren Sie providerOptions für Ihren Provider (,Google,)
import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai'
import { gateway } from '@ai-sdk/gateway'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const result = streamText({
model: gateway('anthropic/claude-sonnet-5'),
maxOutputTokens: 10000,
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages),
providerOptions: {
anthropic: {
thinking: {
type: 'adaptive'
},
effort: 'low'
},
google: {
thinkingConfig: {
includeThoughts: true,
thinkingLevel: 'low'
}
},
openai: {
reasoningEffort: 'low',
reasoningSummary: 'detailed'
}
}
})
const stream = toUIMessageStream({ stream: result.stream })
return createUIMessageStreamResponse({ stream })
})
@@@ph210@@web-suche
Einige Anbieter bieten integrierte Websuchwerkzeuge an: Anthropic,Google,.
import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai'
import { anthropic } from '@ai-sdk/anthropic'
import { gateway } from '@ai-sdk/gateway'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const result = streamText({
model: gateway('anthropic/claude-sonnet-5'),
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages),
tools: {
web_search: anthropic.tools.webSearch_20260209({})
}
})
const stream = toUIMessageStream({ stream: result.stream })
return createUIMessageStreamResponse({ stream })
})
import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai'
import { google } from '@ai-sdk/google'
import { gateway } from '@ai-sdk/gateway'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const result = streamText({
model: gateway('google/gemini-3-flash'),
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages),
tools: {
google_search: google.tools.googleSearch({})
}
})
const stream = toUIMessageStream({ stream: result.stream })
return createUIMessageStreamResponse({ stream })
})
import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai'
import { openai } from '@ai-sdk/openai'
import { gateway } from '@ai-sdk/gateway'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const result = streamText({
model: gateway('openai/gpt-5-nano'),
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages),
tools: {
web_search: openai.tools.webSearch({})
}
})
const stream = toUIMessageStream({ stream: result.stream })
return createUIMessageStreamResponse({ stream })
})
MCP-Client
Befähigen Sie Ihren Chatbot mit erweiterten Funktionen zum Aufrufen von Werkzeugen mithilfe des Model Context Protocol (MCP) von @ai-sdk/mcp. MCP ermöglicht es Ihrer KI, dynamische Aktionen auszuführen, z. B. das Durchsuchen Ihrer Dokumentation oder das Ausführen benutzerdefinierter Aufgaben, um relevantere und genauere Antworten zu liefern.
Um zu beginnen, installieren Sie das MCP-Paket.
npm install @ai-sdk/mcp
pnpm add @ai-sdk/mcp
yarn add @ai-sdk/mcp
Konfigurieren Sie dann Ihren Serverendpunkt für die Verwendung von MCP-Tools:
import { streamText, convertToModelMessages, isStepCount, toUIMessageStream, createUIMessageStreamResponse } from 'ai'
import { createMCPClient } from '@ai-sdk/mcp'
import { gateway } from '@ai-sdk/gateway'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const httpClient = await createMCPClient({
transport: { type: 'http', url: 'https://your-app.com/mcp' }
})
try {
const tools = await httpClient.tools()
const result = streamText({
model: gateway('anthropic/claude-sonnet-5'),
maxOutputTokens: 10000,
instructions: 'You are a helpful assistant. Use your tools to search for relevant information before answering questions.',
messages: await convertToModelMessages(messages),
stopWhen: isStepCount(6),
tools,
onEnd: async () => {
await httpClient.close()
},
onError: async (error) => {
console.error(error)
await httpClient.close()
}
})
const stream = toUIMessageStream({ stream: result.stream })
return createUIMessageStreamResponse({ stream })
} catch (error) {
// Close the MCP client if setup fails before streaming starts
await httpClient.close()
throw error
}
})
Tool-Genehmigung
Erfordern Sie eine Benutzerbestätigung, bevor ein Tool mit der Option ausgeführt wird.
import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse, tool } from 'ai'
import { gateway } from '@ai-sdk/gateway'
import { z } from 'zod'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const result = streamText({
model: gateway('anthropic/claude-sonnet-5'),
maxOutputTokens: 10000,
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages),
tools: {
deleteFile: tool({
description: 'Delete a file from the project',
inputSchema: z.object({ path: z.string() }),
execute: async ({ path }) => ({ deleted: path })
})
},
toolApproval: {
deleteFile: 'user-approval'
}
})
const stream = toUIMessageStream({ stream: result.stream })
return createUIMessageStreamResponse({ stream })
})
Client-Setup-Einstellungen
Verwenden Sie useChat composable von @ai-sdk/vue, um den Chat-Status zu verwalten und eine Verbindung zu Ihrem Serverendpunkt herzustellen:
defineMarkdownComponent, um eine benutzerdefinierte Komponente zu erstellen, anstatt jedes Mal die Props inline zu übergeben.shiki Plugin verwenden, fügen Sie Ihrem Stylesheet das folgende CSS hinzu, um den dunklen Modus zu unterstützen:html.dark .shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}