内置 AI 聊天助手
概述
一个提供基于 MCP(模型上下文协议)工具的 AI 聊天界面的 Nuxt 模块。

快速开始
Movk Nuxt Docs 已内置 AI Chat 模块。要启用该模块,请进行以下配置:
在 nuxt.config.ts 中添加模块配置:
export default defineNuxtConfig({
extends: ['@movk/nuxt-docs'],
aiChat: {
model: 'zai/glm-4.7',
models: [
'zai/glm-4.7',
'anthropic/claude-sonnet-4.6',
'google/gemini-2.5-flash'
],
}
})
模块配置选项:
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
apiPath | string | /api/ai-chat | 聊天 API 端点路径 |
mcpPath | string | /mcp | MCP 服务器连接路径 |
model | string | - | 模型标识符 |
models | string[] | [] | 可用模型列表(格式为 "provider/model" 或 "model") |
在 app/app.config.ts 中配置 AI Chat 功能:
export default defineAppConfig({
aiChat: {
floatingInput: true,
explainWithAi: true,
faqQuestions: [
{
category: '快速开始',
items: ['如何安装?', '如何配置?'],
},
{
category: '进阶使用',
items: ['如何自定义?'],
},
],
shortcuts: {
focusInput: 'meta_i'
},
texts: {
title: 'AI 助手',
placeholder: '输入你的问题...',
// ... 更多文本配置
}
}
})
faqQuestions 可改为按 locale 分组的对象(如 { 'zh-CN': [...], 'en': [...] }),面板会随当前语言切换。将您的 API 密钥设置为环境变量:
# AI Gateway:单 key 代理多家(推荐)
AI_GATEWAY_API_KEY=your-gateway-key
# 或直连内置提供商:按需配置,对应前缀绕过 Gateway 直连官方 SDK
DEEPSEEK_API_KEY=your-deepseek-key
ALIBABA_API_KEY=your-alibaba-key
ZHIPU_API_KEY=your-zhipu-key
AI_GATEWAY_API_KEY 或任一内置提供商密钥(见下表)存在即可启用 AI Chat;全部缺失则模块禁用并在控制台记录一条消息。自动集成
默认情况下,以下功能会自动启用:
- AI Chat 触发按钮:在页面右侧显示,点击打开 AI 助手面板
- 浮动输入框:在文档页面底部显示(可通过
appConfig.aiChat.floatingInput控制) - AI 解释按钮:在文档侧边栏显示(可通过
appConfig.aiChat.explainWithAi控制)
手动集成(可选)
如果需要在自定义页面中使用 AI Chat 组件:
<template>
<div>
<AiChat />
<AiChatPanel />
</div>
</template>
app/app.config.ts 中配置,无需在组件中传递 props。浮动输入框
浮动输入框默认已集成在文档页面底部。如需在自定义页面中使用:
<template>
<div>
<Teleport to="body">
<ClientOnly>
<AiChatPanel />
<AiChatFloatingInput />
</ClientOnly>
</Teleport>
</div>
</template>
Teleport 将浮动输入渲染到 body 级别,确保它无论在组件层次结构中如何变化都能固定在底部编程式控制
使用 useAIChat 组合式函数来控制聊天:
<script setup>
const {
isEnabled,
isOpen,
messages,
toggleChat,
open
} = useAIChat()
// 打开聊天并发送初始消息
open('如何安装这个模块?')
// 切换聊天可见性
toggle()
</script>
自定义
自定义模型提供商
import { modelProviderRegistry } from '#ai-chat/server/utils/modelProviders'
import { createAnthropic } from '@ai-sdk/anthropic'
export default defineNitroPlugin(() => {
// 覆盖默认提供商配置
modelProviderRegistry.register('anthropic', ({ config, modelId }) => {
const anthropic = createAnthropic({
apiKey: config.anthropicApiKey,
// 自定义配置...
})
return anthropic(modelId)
})
})
配置环境变量:
ANTHROPIC_API_KEY=your_api_key
内置提供商
配置对应环境变量后,匹配前缀的模型会直连官方 SDK;未命中任何前缀的模型回退至 AI Gateway。可选 <PROVIDER>_BASE_URL(如 ALIBABA_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 切到阿里云国内端点)覆盖端点/区域。在 server/plugins/ 中用 modelProviderRegistry.register(prefix, ...) 注册同名前缀可覆盖内置实现。
| 提供商 | 前缀 | 环境变量 |
|---|---|---|
| OpenAI | openai | OPENAI_API_KEY |
| Anthropic | anthropic | ANTHROPIC_API_KEY |
| DeepSeek | deepseek | DEEPSEEK_API_KEY |
| 阿里云通义千问 | alibaba | ALIBABA_API_KEY |
| 智谱 GLM | zai | ZHIPU_API_KEY |
| AI Gateway | 无(兜底) | AI_GATEWAY_API_KEY |
系统提示词
要自定义 AI 的行为,请创建编辑以下文件中的系统提示词:
server/api/ai-chat.ts
样式
组件使用 Nuxt UI 和 Tailwind CSS 设计令牌。你可以通过修改组件文件或覆盖 UI 属性来自定义外观。
API
AiChat
最简单的集成方式,展示助手按钮。
查看源代码AiChatFloatingInput
浮动输入框,位于视口下方。无需任何属性。
键盘快捷键:
⌘I/Ctrl+I- 聚焦输入框Escape- 失焦输入框Enter- 提交问题
Teleport 和 ClientOnly 包裹以确保正确渲染。AiChatModelSelect
模型选择下拉菜单,用于切换 AI 模型。无需任何属性。
nuxt.config.ts 中配置的 models 列表,并使用 useModels 组合式函数管理模型状态。AiChatPanel
完整的 AI 聊天面板界面。
特性:
- 可展开/折叠的侧边栏面板
- 自动推动主内容区域
- 内置消息历史和流式响应
- 支持代码高亮和 Markdown 渲染
AiChatDisabled
当 AI Chat 功能未启用时显示的禁用状态组件。
查看源代码Composables
useAIChat()
对话状态管理,提供聊天界面的状态控制和消息管理功能。
返回值
useModels()
模型配置管理,控制可用的 AI 模型列表和当前选中的模型。
返回值
nuxt.config.ts 的 aiChat.models 配置读取。anthropic/claude-sonnet-4.6。useHighlighter()
异步加载 Shiki 代码高亮器实例,用于代码块的语法高亮渲染。
返回值
返回一个 Promise,resolve 为配置好的 Shiki Highlighter 实例。
vue, js, ts, css, html, json, yaml, markdown, bash支持的主题:material-theme-palenight(深色模式)material-theme-lighter(浅色模式)
const highlighter = await useHighlighter()
// 使用示例
const html = highlighter.codeToHtml(code, {
lang: 'typescript',
theme: 'material-theme-palenight'
})
useToolCall(state, toolName, input)
AI 聊天工具调用的扩展点,允许自定义工具调用时显示的文本标签和图标。
当 AI 助手调用工具时,AiChatPanel 组件会调用此 composable 获取对应工具的显示信息。默认实现返回空对象,内置工具标签由组件自身处理。通过在应用层覆盖此 composable,可以为自定义工具添加显示支持。
参数
'output-available' 表示已完成,其他值表示进行中。name 字段对应。返回值
i-lucide-search。扩展自定义工具
在应用层创建同名 composable 覆盖默认实现:
import type { ToolState } from '#ai-chat/types'
export function useToolCall(state: ToolState, toolName: string, input: Record<string, string | undefined>) {
const searchVerb = state === 'output-available' ? '已搜索' : '搜索中'
const readVerb = state === 'output-available' ? '已读取' : '读取中'
const toolMessage: Record<string, string> = {
'search-api': `${searchVerb} API 文档`,
'get-schema': `${readVerb} ${input.name || ''} 类型定义`,
}
const toolIcon: Record<string, string> = {
'search-api': 'i-lucide-book-open',
'get-schema': 'i-lucide-braces',
}
return {
toolMessage,
toolIcon,
}
}
内置工具的默认处理
以下工具由 AiChatPanel 内置处理,无需在 useToolCall 中定义。默认处理已按当前项目内置的 MCP 工具裁剪,并由同一份配置同时生成显示文本与图标:
| 工具名 | 显示文本 | 图标 |
|---|---|---|
search-documentation | 搜索中 / 已搜索 文档页面,可附带 section、search 条件 | i-lucide-book-search |
search-composables | 搜索中 / 已搜索 组合函数,可附带 search 条件 | i-lucide-braces |
search-icons | 搜索中 / 已搜索 图标,可附带 query 条件 | i-lucide-search |
list-examples | 搜索中 / 已搜索 示例 | i-lucide-codesandbox |
get-documentation-page | 读取中 / 已读取 {path} 页面 | i-lucide-book-open |
get-example | 读取中 / 已读取 {exampleName} 示例 | i-lucide-codepen |
get-component | 读取中 / 已读取 {componentName} 组件文档 | i-lucide-box |
get-component-metadata | 读取中 / 已读取 {componentName} 组件元数据 | i-lucide-file-code |