Ask AI 智能问答
AI 驱动的文档问答组件,搜索文档并回答用户问题
Ask AI 智能问答
Why — 为什么需要
用户访问网站时经常有问题,但不想翻阅大量文档页面。Ask AI 组件提供即时的对话式问答体验 — 基于你现有的 Fumadocs 文档内容。
用户只需输入问题,即可获得基于实际文档的 AI 生成答案。
What — 是什么
一个紧凑的浮动组件(右下角),工作流程:
- 提取关键词 — 用快速模型(
gpt-5-nano)从用户问题中提取搜索关键词 - 搜索文档 — 通过 Fumadocs
/api/search端点搜索相关文档 - 流式回答 — 用
gpt-5-mini基于搜索结果生成答案
组件作为共享包(share-domains/ask-ai)提供:
components/— 客户端聊天组件,基于 KUI AI elements + AI SDK v6logic/— 服务端工具函数(关键词提取、文档搜索、提示词构建)
UI 行为
| 状态 | 外观 |
|---|---|
| 收起 | 迷你输入框 + 💬 图标 + "Ask AI" 占位符 |
| 聚焦 | 输入框展开至 320px,空聊天面板出现 |
| 对话中 | 聊天面板显示对话,输入框保持展开 |
| Escape / 关闭 | 收回迷你输入框 |
How — 怎么用
1. 环境变量
在 .env 中添加:
# 必需:启用组件
ENABLE_ASK_AI=true
# 必需:OpenAI API 访问
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.openai.com/v1 # 可选,用于代理
# 可选:覆盖默认模型
ASK_AI_MODEL=gpt-5-mini # 答案生成(默认:gpt-5-mini)
ASK_AI_FAST_MODEL=gpt-5-nano # 关键词提取(默认:gpt-5-nano)
# 必需:应用 URL,用于内部搜索 API 调用
NEXT_PUBLIC_APP_URL=http://localhost:30002. 添加 Tailwind Source
在应用的 global.css 中添加:
@source "../../../../packages/share-domains";3. 创建 API 路由
创建 src/app/api/search/ai/route.ts:
import { createOpenAI } from "@ai-sdk/openai";
import { streamText } from "ai";
import { buildSystemPrompt, extractKeywords, searchDocs } from "share-domains/ask-ai/logic";
export async function POST(req: Request) {
const { messages } = await req.json();
const lastUserMessage = [...messages].reverse().find((m) => m.role === "user");
const question = lastUserMessage?.content || "";
const openai = createOpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL || undefined,
});
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
const keywords = await extractKeywords(openai(process.env.ASK_AI_FAST_MODEL || "gpt-5-nano"), question);
const docsContext = await searchDocs(baseUrl, keywords);
const result = streamText({
model: openai(process.env.ASK_AI_MODEL || "gpt-5-mini"),
system: buildSystemPrompt(docsContext),
messages,
});
return result.toUIMessageStreamResponse();
}4. 在 Layout 中添加组件
在根 layout.tsx(Server Component)中:
import { AskAIWidget } from "share-domains/ask-ai/components";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
{process.env.ENABLE_ASK_AI === "true" && (
<AskAIWidget
endpoint="/api/search/ai"
title="Ask MyApp"
placeholder="Ask AI"
welcomeMessage="有什么可以帮你的?"
/>
)}
</body>
</html>
);
}配置属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
endpoint | string | /api/search/ai | API 路由路径 |
placeholder | string | Ask AI | 输入框占位文本 |
title | string | AI Assistant | 聊天面板标题 |
welcomeMessage | string | "" | 面板为空时显示的消息 |
maxHeight | string | 480px | 聊天面板最大高度 |
架构流程
用户输入问题
→ [客户端] AskAIWidget (useChat + DefaultChatTransport)
→ [服务端] POST /api/search/ai
→ extractKeywords(gpt-5-nano, 问题) → "i18n 配置 多语言"
→ searchDocs(baseUrl, 关键词) → fumadocs /api/search
→ streamText(gpt-5-mini, 文档上下文) → 流式答案
→ [客户端] MessageResponse 渲染 Markdown前置条件
- Fumadocs 已配置
/api/search路由 - 已安装
@ai-sdk/openai、ai包 share-domains作为 workspace 依赖kui作为 workspace 依赖(用于 AI elements)