AI聊天界面构建Skill building-ai-chat

此技能专注于构建AI聊天界面,支持流式文本响应、上下文管理、多模态交互,适用于开发ChatGPT风格接口、AI助手、代码副驾驶等。关键词:AI聊天界面、流式响应、上下文管理、多模态支持、前端开发、AI应用。

前端开发 0 次安装 0 次浏览 更新于 3/23/2026

name: building-ai-chat description: 构建AI聊天界面和对话式用户界面,支持流式响应、上下文管理和多模态支持。适用于创建ChatGPT风格接口、AI助手、代码副驾驶或对话代理。处理流式文本、令牌限制、再生、反馈循环、工具使用可视化和AI特定错误模式。提供来自领先AI产品的经过实战测试的组件,内置可访问性和性能。

AI聊天界面组件

目的

为2024-2025年AI集成热潮中的AI/人类对话界面定义新兴标准。此技能利用从构建与Claude交互获得的元知识,确立流式用户体验、上下文管理和多模态交互的权威模式。由于行业缺乏既定模式,此技能提供了他人将遵循的参考实现。

何时使用

在以下情况下激活此技能:

  • 构建ChatGPT风格对话界面
  • 创建AI助手、副驾驶或聊天机器人
  • 实现带Markdown的流式文本响应
  • 管理对话上下文和令牌限制
  • 处理多模态输入(文本、图像、文件、语音)
  • 处理AI特定错误(幻觉、拒绝、限制)
  • 添加反馈机制(点赞、再生、编辑)
  • 实现对话分支或线程
  • 可视化工具/函数调用

快速开始

在50行以内构建最小化AI聊天界面:

import { useChat } from 'ai/react';

export function MinimalAIChat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading, stop } = useChat();

  return (
    <div className="chat-container">
      <div className="messages">
        {messages.map(m => (
          <div key={m.id} className={`message ${m.role}`}>
            <div className="content">{m.content}</div>
          </div>
        ))}
        {isLoading && <div className="thinking">AI正在思考...</div>}
      </div>

      <form onSubmit={handleSubmit} className="input-form">
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="问任何问题..."
          disabled={isLoading}
        />
        {isLoading ? (
          <button type="button" onClick={stop}>停止</button>
        ) : (
          <button type="submit">发送</button>
        )}
      </form>
    </div>
  );
}

有关带流式Markdown的完整实现,请参见examples/basic-chat.tsx

核心组件

消息显示

构建用户、AI和系统消息气泡,支持流式:

// 用户消息
<div className="message user">
  <div className="content">{message.content}</div>
  <time className="timestamp">{formatTime(message.timestamp)}</time>
</div>

// AI消息带流式
<div className="message ai">
  <Streamdown className="content">{message.content}</Streamdown>
  {message.isStreaming && <span className="cursor">▊</span>}
</div>

// 系统消息
<div className="message system">
  <Icon type="info" />
  <span>{message.content}</span>
</div>

有关Markdown渲染、代码块和格式化详情,请参见references/message-components.md

输入组件

创建带附件和语音的丰富输入体验:

<div className="input-container">
  <button onClick={attachFile} aria-label="附加文件">
    <PaperclipIcon />
  </button>

  <textarea
    value={input}
    onChange={handleChange}
    onKeyDown={handleKeyDown}
    placeholder="输入消息..."
    rows={1}
    style={{ height: textareaHeight }}
  />

  <button onClick={toggleVoice} aria-label="语音输入">
    <MicIcon />
  </button>

  <button type="submit" disabled={!input.trim() || isLoading}>
    <SendIcon />
  </button>
</div>

响应控制

AI响应的基本控制:

<div className="response-controls">
  {isStreaming && (
    <button onClick={stop} className="stop-btn">
      停止生成
    </button>
  )}

  {!isStreaming && (
    <>
      <button onClick={regenerate} aria-label="重新生成响应">
        <RefreshIcon /> 重新生成
      </button>
      <button onClick={continueGeneration} aria-label="继续">
        继续
      </button>
      <button onClick={editMessage} aria-label="编辑消息">
        <EditIcon /> 编辑
      </button>
    </>
  )}
</div>

反馈机制

收集用户反馈以改进AI响应:

<div className="feedback-controls">
  <button
    onClick={() => sendFeedback('positive')}
    aria-label="好响应"
    className={feedback === 'positive' ? 'selected' : ''}
  >
    <ThumbsUpIcon />
  </button>

  <button
    onClick={() => sendFeedback('negative')}
    aria-label="差响应"
    className={feedback === 'negative' ? 'selected' : ''}
  >
    <ThumbsDownIcon />
  </button>

  <button onClick={copyToClipboard} aria-label="复制">
    <CopyIcon />
  </button>

  <button onClick={share} aria-label="分享">
    <ShareIcon />
  </button>
</div>

流式与实时用户体验

AI响应的渐进渲染需要特殊处理:

// 使用Streamdown进行AI流式(处理不完整Markdown)
import { Streamdown } from '@vercel/streamdown';

// 自动滚动管理
useEffect(() => {
  if (shouldAutoScroll()) {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }
}, [messages]);

// 智能自动滚动启发式
function shouldAutoScroll() {
  const threshold = 100; // 距离底部的像素
  const isNearBottom =
    container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
  const userNotReading = !hasUserScrolledUp && !isTextSelected;
  return isNearBottom && userNotReading;
}

有关完整流式模式、自动滚动行为和停止生成,请参见references/streaming-ux.md

上下文管理

清晰地向用户传达令牌限制:

// 用户友好的令牌显示
function TokenIndicator({ used, total }) {
  const percentage = (used / total) * 100;
  const remaining = total - used;

  return (
    <div className="token-indicator">
      <div className="progress-bar">
        <div className="progress-fill" style={{ width: `${percentage}%` }} />
      </div>
      <span className="token-text">
        {percentage > 80
          ? `⚠️ 大约剩余${Math.floor(remaining / 250)}条消息`
          : `${Math.floor(remaining / 250)}页对话剩余`}
      </span>
    </div>
  );
}

有关摘要策略、对话分支和组织,请参见references/context-management.md

多模态支持

处理图像、文件和语音输入:

// 带预览的图像上传
function ImageUpload({ onUpload }) {
  return (
    <div
      className="upload-zone"
      onDrop={handleDrop}
      onDragOver={preventDefault}
    >
      <input
        type="file"
        accept="image/*"
        onChange={handleFileSelect}
        multiple
        hidden
        ref={fileInputRef}
      />
      {previews.map(preview => (
        <img key={preview.id} src={preview.url} alt="上传预览" />
      ))}
    </div>
  );
}

有关完整多模态模式包括语音和屏幕共享,请参见references/multi-modal.md

错误处理

优雅地处理AI特定错误:

// 拒绝处理
if (response.type === 'refusal') {
  return (
    <div className="error refusal">
      <Icon type="info" />
      <p>我无法帮助处理该请求。</p>
      <details>
        <summary>原因?</summary>
        <p>{response.reason}</p>
      </details>
      <p>尝试询问:{response.suggestion}</p>
    </div>
  );
}

// 速率限制沟通
if (error.code === 'RATE_LIMIT') {
  return (
    <div className="error rate-limit">
      <p>请等待{error.retryAfter}秒</p>
      <CountdownTimer seconds={error.retryAfter} onComplete={retry} />
    </div>
  );
}

有关全面错误模式,请参见references/error-handling.md

工具使用可视化

显示AI何时使用工具或函数:

function ToolUsage({ tool }) {
  return (
    <div className="tool-usage">
      <div className="tool-header">
        <Icon type={tool.type} />
        <span>{tool.name}</span>
        {tool.status === 'running' && <Spinner />}
      </div>
      {tool.status === 'complete' && (
        <details>
          <summary>查看详情</summary>
          <pre>{JSON.stringify(tool.result, null, 2)}</pre>
        </details>
      )}
    </div>
  );
}

有关函数调用、代码执行和网络搜索模式,请参见references/tool-usage.md

实施指南

推荐技术栈

主要库(已验证至2025年11月):

# 核心AI聊天功能
npm install ai @ai-sdk/react @ai-sdk/openai

# 流式Markdown渲染
npm install @vercel/streamdown

# 语法高亮
npm install react-syntax-highlighter

# 用于LLM输出的安全
npm install dompurify

性能优化

对平滑流式至关重要:

// 消息渲染的记忆化
const MemoizedMessage = memo(Message, (prev, next) =>
  prev.content === next.content && prev.isStreaming === next.isStreaming
);

// 流式更新的防抖
const debouncedUpdate = useMemo(
  () => debounce(updateMessage, 50),
  []
);

// 长对话的虚拟滚动
import { VariableSizeList } from 'react-window';

有关详细性能模式,请参见references/streaming-ux.md

安全考虑

始终净化AI输出:

import DOMPurify from 'dompurify';

function SafeAIContent({ content }) {
  const sanitized = DOMPurify.sanitize(content, {
    ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'code', 'pre', 'blockquote', 'ul', 'ol', 'li'],
    ALLOWED_ATTR: ['class']
  });

  return <Streamdown>{sanitized}</Streamdown>;
}

可访问性

确保AI聊天对所有人可用:

// 屏幕阅读器的ARIA活动区域
<div role="log" aria-live="polite" aria-relevant="additions">
  {messages.map(msg => (
    <article key={msg.id} role="article" aria-label={`${msg.role}消息`}>
      {msg.content}
    </article>
  ))}
</div>

// 加载公告
<div role="status" aria-live="polite" className="sr-only">
  {isLoading ? 'AI正在响应' : ''}
</div>

有关完整可访问性模式,请参见references/accessibility.md

捆绑资源

脚本(无令牌执行)

  • 运行scripts/parse_stream.js以在流式期间解析不完整Markdown
  • 运行scripts/calculate_tokens.py以估计令牌使用和上下文限制
  • 运行scripts/format_messages.js以格式化消息历史以进行导出

参考(渐进披露)

  • references/streaming-patterns.md - 完整流式用户体验模式
  • references/context-management.md - 令牌限制和对话策略
  • references/multimodal-input.md - 图像、文件和语音处理
  • references/feedback-loops.md - 用户反馈和RLHF模式
  • references/error-handling.md - AI特定错误场景
  • references/tool-usage.md - 可视化函数调用和工具使用
  • references/accessibility-chat.md - 屏幕阅读器和键盘支持
  • references/library-guide.md - 详细库文档
  • references/performance-optimization.md - 流式性能模式

示例

  • examples/basic-chat.tsx - 最小化ChatGPT风格接口
  • examples/streaming-chat.tsx - 带记忆化的高级流式
  • examples/multimodal-chat.tsx - 图像和文件上传
  • examples/code-assistant.tsx - IDE风格代码副驾驶
  • examples/tool-calling-chat.tsx - 函数调用可视化

资产

  • assets/system-prompts.json - 针对不同使用场景的精选提示
  • assets/message-templates.json - 预建消息组件
  • assets/error-messages.json - 用户友好错误消息
  • assets/themes.json - 浅色、深色和高对比度主题

设计令牌集成

所有视觉样式使用设计令牌系统:

/* 消息气泡使用设计令牌 */
.message.user {
  background: var(--message-user-bg, var(--color-primary));
  color: var(--message-user-text, var(--color-white));
  padding: var(--message-padding, var(--spacing-md));
  border-radius: var(--message-border-radius, var(--radius-lg));
}

.message.ai {
  background: var(--message-ai-bg, var(--color-gray-100));
  color: var(--message-ai-text, var(--color-text-primary));
}

参见skills/design-tokens/以获取完整主题系统。

关键创新

此技能提供行业首创的解决方案,用于:

  • 记忆化流式渲染 - 10-50倍性能提升
  • 智能自动滚动 - 用户活动感知滚动
  • 令牌隐喻 - 用户友好上下文沟通
  • 不完整Markdown处理 - 优雅的部分渲染
  • RLHF模式 - 有效反馈收集
  • 对话分支 - 非线性对话树
  • 多模态集成 - 无缝文件/图像/语音处理
  • 可访问性优先 - 内置屏幕阅读器支持

战略重要性

这是最关键技能,因为:

  1. 完美时机 - 每个应用都在添加AI(2024-2025年热潮)
  2. 无标准存在 - 定义模式的机会
  3. 元优势 - 与Claude构建 = 亲密用户体验知识
  4. 独特挑战 - 流式、上下文、幻觉全是新的
  5. 参考实现 - 可以成为他人遵循的标准

掌握此技能以引领AI界面革命。