跳转到主要内容

你将构建的内容

一个可复用的小部件,可将AI 助手直接嵌入到你的应用中。该小部件提供:
  • 浮动按钮,点击即可打开聊天面板
  • 基于你的文档信息的实时流式回复
  • 支持 Markdown 的消息渲染
用户无需离开你的应用即可通过该小部件获取产品帮助。
演示打开助手小部件,用户输入“如何开始?”,随后助手作出回应。

先决条件

  • Mintlify Pro 或 Enterprise 计划
  • 你的 domain 名称,它位于控制台 URL 的末尾。例如,如果你的控制台 URL 是 https://dashboard.mintlify.com/org-name/domain-name,你的 domain 名称就是 domain-name
  • 一个 AI 助手 API key
  • 已安装 Node.js v18 或更高版本及 npm
  • 基础的 React 知识

获取你的 AI 助手 API key

  1. 在控制台中前往 API keys 页面。
  2. 点击 Create Assistant API Key
  3. 复制 AI 助手 API key(以 mint_dsc_ 开头)并妥善保存。
AI 助手 API key 是一个可在前端代码中使用的公共令牌。使用该令牌的调用将计入你套餐的消息配额,并可能产生超额费用。

设置示例

克隆示例存储库,并按需进行自定义。
1

克隆存储库

git clone https://github.com/mintlify/assistant-embed-example.git
cd assistant-embed-example
2

选择你的开发工具

该存储库包含 Next.js 和 Vite 示例。选择你更习惯使用的工具。
cd nextjs
npm install
3

配置你的项目

打开 src/config.js,并填入你的 Mintlify 项目信息。
src/config.js
export const ASSISTANT_CONFIG = {
  domain: 'your-domain',
  docsURL: 'https://yourdocs.mintlify.app',
};
将以下内容替换为你的实际信息:
  • your-domain 替换为你在控制台 URL 末尾看到的 Mintlify 项目 domain。
  • https://yourdocs.mintlify.app 替换为你的文档实际 URL。
4

添加你的 API 令牌

在项目根目录创建一个 .env 文件。
.env
VITE_MINTLIFY_TOKEN=mint_dsc_your_token_here
mint_dsc_your_token_here 替换为你的 AI 助手 API key。
5

启动开发服务器

npm run dev
在浏览器中打开你的应用,点击 Ask 按钮以打开 AI 助手挂件。

自定义思路与示例

来源引注

从 AI 助手的回复中提取并显示出处:
const extractSources = (parts) => {
  return parts
    ?.filter(p => p.type === 'tool-invocation' && p.toolInvocation?.toolName === 'search')
    .flatMap(p => p.toolInvocation?.result || [])
    .map(source => ({
      url: source.url || source.path,
      title: source.metadata?.title || source.path,
    })) || [];
};

// In your message rendering:
{messages.map((message) => {
  const sources = message.role === 'assistant' ? extractSources(message.parts) : [];
  return (
    <div key={message.id}>
      {/* 消息内容 */}
      {sources.length > 0 && (
        <div className="mt-2 text-xs">
          <p className="font-semibold">来源:</p>
          {sources.map((s, i) => (
            <a key={i} href={s.url} target="_blank" rel="noopener noreferrer" className="text-blue-600">
              {s.title}
            </a>
          ))}
        </div>
      )}
    </div>
  );
})}

跟踪会话线程 ID

存储线程 ID,以在不同会话中保留对话历史:
import { useState, useEffect } from 'react';

export function AssistantWidget({ domain, docsURL }) {
  const [threadId, setThreadId] = useState(null);

  useEffect(() => {
    // 从 localStorage 中获取已保存的线程 ID
    const saved = localStorage.getItem('assistant-thread-id');
    if (saved) {
      setThreadId(saved);
    }
  }, []);

  const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
    api: `https://api.mintlify.com/discovery/v1/assistant/${domain}/message`,
    headers: {
      'Authorization': `Bearer ${import.meta.env.VITE_MINTLIFY_TOKEN}`,
    },
    body: {
      fp: 'anonymous',
      retrievalPageSize: 5,
      ...(threadId && { threadId }), // 如果可用则包含线程 ID
    },
    streamProtocol: 'data',
    sendExtraMessageFields: true,
    fetch: async (url, options) => {
      const response = await fetch(url, options);
      const newThreadId = response.headers.get('x-thread-id');
      if (newThreadId) {
        setThreadId(newThreadId);
        localStorage.setItem('assistant-thread-id', newThreadId);
      }
      return response;
    },
  });

  // ... 组件其余部分
}

添加键盘快捷键

允许用户通过键盘快捷键打开组件并提交消息:
useEffect(() => {
  const handleKeyDown = (e) => {
    // Cmd/Ctrl + Shift + I 切换 AI 助手
    if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === 'I') {
      e.preventDefault();
      setIsOpen((prev) => !prev);
    }

    // Enter(当 AI 助手获得焦点时)提交
    if (e.key === 'Enter' && !e.shiftKey && document.activeElement.id === 'assistant-input') {
      e.preventDefault();
      handleSubmit();
    }
  };

  window.addEventListener('keydown', handleKeyDown);
  return () => window.removeEventListener('keydown', handleKeyDown);
}, [handleSubmit]);