mcpField
B
building-ai-chat

building-ai-chat

github.com/ancoleman设计与 UI525144 次安装46 周前更新
代码仓库

关于 building-ai-chat

building-ai-chat 为构建对话式 AI 界面的开发者提供设计与实现指导,内容包括流式响应、上下文、多模态输入和错误处理。它还涵盖工具调用展示、无障碍设计及响应反馈。

主要功能

  1. 01流式消息与 Markdown 渲染模式
  2. 02上下文和令牌用量管理
  3. 03图像、文件与语音输入模式
  4. 04AI 错误和拒绝响应处理
  5. 05工具调用展示与用户反馈
  6. 06无障碍和性能优化建议

适用场景

  1. 01构建聊天机器人或 AI 助手界面
  2. 02实现流式 Markdown 回复
  3. 03支持图像、文件或语音输入
  4. 04在界面中呈现工具调用和响应反馈

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ancoleman/ai-design-components --skill building-ai-chat

安装后在 Claude Code 中输入/building-ai-chat确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

outputs.yaml
assets/
error-messages.json
message-templates.json
system-prompts.json
themes.json
examples/
basic-chat.tsx
code-assistant.tsx
multimodal-chat.tsx
streaming-chat.tsx
tool-calling-chat.tsx
references/
accessibility-chat.md
accessibility.md
context-management.md
error-handling.md
feedback-loops.md
library-guide.md
message-components.md
multi-modal.md
multimodal-input.md
performance-optimization.md
streaming-patterns.md
streaming-ux.md
tool-usage.md
scripts/
calculate_tokens.py
format_messages.js
parse_stream.js

详细介绍

AI 聊天界面组件

目的

为 2024-2025 年 AI 集成热潮中的 AI/人类对话界面定义新兴标准。此技能借助与 Claude 协作构建的元知识,确立流式 UX、上下文管理和多模态交互的权威模式。由于行业尚未形成成熟模式,本指南将提供其他项目可遵循的参考实现。

何时使用

在以下情况下启用此技能:

  • 构建 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 is thinking...</div>}
      </div>

      <form onSubmit={handleSubmit} className="input-form">
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="Ask anything..."
          disabled={isLoading}
        />
        {isLoading ? (
          <button type="button" onClick={stop}>Stop</button>
        ) : (
          <button type="submit">Send</button>
        )}
      </form>
    </div>
  );
}

如需包含流式 Markdown 的完整实现,请参见 examples/basic-chat.tsx。

核心组件

消息显示

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

// User message
<div className="message user">
  <div className="content">{message.content}</div>
  <time className="timestamp">{formatTime(message.timestamp)}</time>
</div>

// AI message with streaming
<div className="message ai">
  <Streamdown className="content">{message.content}</Streamdown>
  {message.isStreaming && <span className="cursor">▊</span>}
</div>

// System message
<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="Attach file">
    <PaperclipIcon />
  </button>

  <textarea
    value={input}
    onChange={handleChange}
    onKeyDown={handleKeyDown}
    placeholder="Type a message..."
    rows={1}
    style={{ height: textareaHeight }}
  />

  <button onClick={toggleVoice} aria-label="Voice input">
    <MicIcon />
  </button>

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

AI 响应的基本控制项:

<div className="response-controls">
  {isStreaming && (
    <button onClick={stop} className="stop-btn">
      Stop generating
    </button>
  )}

  {!isStreaming && (
    <>
      <button onClick={regenerate} aria-label="Regenerate response">
        <RefreshIcon /> Regenerate
      </button>
      <button onClick={continueGeneration} aria-label="Continue">
        Continue
      </button>
      <button onClick={editMessage} aria-label="Edit message">
        <EditIcon /> Edit
      </button>
    </>
  )}
</div>
反馈机制

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

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

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

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

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

流式传输与实时 UX

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

// Use Streamdown for AI streaming (handles incomplete markdown)
import { Streamdown } from '@vercel/streamdown';

// Auto-scroll management
useEffect(() => {
  if (shouldAutoScroll()) {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }
}, [messages]);

// Smart auto-scroll heuristic
function shouldAutoScroll() {
  const threshold = 100; // px from bottom
  const isNearBottom =
    container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
  const userNotReading = !hasUserScrolledUp && !isTextSelected;
  return isNearBottom && userNotReading;
}

如需了解完整的流式传输模式、自动滚动行为和停止生成功能,请参见 references/streaming-ux.md。

上下文管理

向用户清晰说明令牌限制:

// User-friendly token display
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
          ? `⚠️ About ${Math.floor(remaining / 250)} messages left`
          : `${Math.floor(remaining / 250)} pages of conversation remaining`}
      </span>
    </div>
  );
}

如需了解摘要策略、对话分支和组织方式,请参见 references/context-management.md。

多模态支持

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

// Image upload with preview
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="Upload preview" />
      ))}
    </div>
  );
}

如需了解包含语音和屏幕共享的完整多模态模式,请参见 references/multi-modal.md。

错误处理

妥善处理 AI 特有错误:

// Refusal handling
if (response.type === 'refusal') {
  return (
    <div className="error refusal">
      <Icon type="info" />
      <p>I cannot help with that request.</p>
      <details>
        <summary>Why?</summary>
        <p>{response.reason}</p>
      </details>
      <p>Try asking: {response.suggestion}</p>
    </div>
  );
}

// Rate limit communication
if (error.code === 'RATE_LIMIT') {
  return (
    <div className="error rate-limit">
      <p>Please wait {error.retryAfter} seconds</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>View details</summary>
          <pre>{JSON.stringify(tool.result, null, 2)}</pre>
        </details>
      )}
    </div>
  );
}

如需了解函数调用、代码执行和网络搜索模式,请参见 references/tool-usage.md。

实现指南

推荐技术栈

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

# Core AI chat functionality
npm install ai @ai-sdk/react @ai-sdk/openai

# Streaming markdown rendering
npm install @vercel/streamdown

# Syntax highlighting
npm install react-syntax-highlighter

# Security for LLM outputs
npm install dompurify
性能优化

确保流式传输流畅的关键:

// Memoize message rendering
const MemoizedMessage = memo(Message, (prev, next) =>
  prev.content === next.content && prev.isStreaming === next.isStreaming
);

// Debounce streaming updates
const debouncedUpdate = useMemo(
  () => debounce(updateMessage, 50),
  []
);

// Virtual scrolling for long conversations
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 live regions for screen readers
<div role="log" aria-live="polite" aria-relevant="additions">
  {messages.map(msg => (
    <article key={msg.id} role="article" aria-label={`${msg.role} message`}>
      {msg.content}
    </article>
  ))}
</div>

// Loading announcements
<div role="status" aria-live="polite" className="sr-only">
  {isLoading ? 'AI is responding' : ''}
</div>

如需了解完整的无障碍访问模式,请参见 references/accessibility.md。

随附资源

脚本(无令牌执行)
  • 运行 scripts/parse_stream.js,在流式传输期间解析未完成的 Markdown
  • 运行 scripts/calculate_tokens.py,估算令牌用量和上下文限制
  • 运行 scripts/format_messages.js,格式化消息历史以供导出
参考资料(渐进式披露)
  • references/streaming-patterns.md - 完整的流式 UX 模式
  • 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 - 浅色、深色和高对比度主题

设计令牌集成

所有视觉样式均使用 design-tokens 系统:

/* Message bubbles use design tokens */
.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 一起构建 = 深入了解 UX
  4. 独特挑战 - 流式处理、上下文和幻觉都是全新的问题
  5. 参考实现 - 有望成为其他人遵循的标准

掌握这项技能,引领 AI 界面革命。

评论

支持 Markdown