building-ai-chat

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AI Chat Interface Components

AI聊天界面组件

Purpose

用途

Define the emerging standards for AI/human conversational interfaces in the 2024-2025 AI integration boom. This skill leverages meta-knowledge from building WITH Claude to establish definitive patterns for streaming UX, context management, and multi-modal interactions. As the industry lacks established patterns, this provides the reference implementation others will follow.
在2024-2025年AI集成热潮中,定义AI与人类对话界面的新兴标准。该技能利用与Claude协作开发积累的元知识,为流式用户体验、上下文管理和多模态交互建立权威模式。由于行业目前缺乏既定标准,本内容将成为其他开发者遵循的参考实现。

When to Use

适用场景

Activate this skill when:
  • Building ChatGPT-style conversational interfaces
  • Creating AI assistants, copilots, or chatbots
  • Implementing streaming text responses with markdown
  • Managing conversation context and token limits
  • Handling multi-modal inputs (text, images, files, voice)
  • Dealing with AI-specific errors (hallucinations, refusals, limits)
  • Adding feedback mechanisms (thumbs, regeneration, editing)
  • Implementing conversation branching or threading
  • Visualizing tool/function calling
在以下场景中使用本技能:
  • 构建ChatGPT风格的对话界面
  • 创建AI助手、Copilot或聊天机器人
  • 实现带Markdown格式的流式文本响应
  • 管理对话上下文与令牌限制
  • 处理多模态输入(文本、图片、文件、语音)
  • 处理AI特有的错误(幻觉、拒绝响应、限制触发)
  • 添加反馈机制(点赞/点踩、重生成、编辑)
  • 实现对话分支或线程管理
  • 可视化工具/函数调用

Quick Start

快速开始

Minimal AI chat interface in under 50 lines:
tsx
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>
  );
}
For complete implementation with streaming markdown, see
examples/basic-chat.tsx
.
不到50行代码实现极简AI聊天界面:
tsx
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

Core Components

核心组件

Message Display

消息展示

Build user, AI, and system message bubbles with streaming support:
tsx
// 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>
For markdown rendering, code blocks, and formatting details, see
references/message-components.md
.
构建支持流式渲染的用户、AI及系统消息气泡:
tsx
// 用户消息
<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

Input Components

输入组件

Create rich input experiences with attachments and voice:
tsx
<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>
创建支持附件与语音的富输入体验:
tsx
<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>

Response Controls

响应控制

Essential controls for AI responses:
tsx
<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响应的核心控制组件:
tsx
<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>

Feedback Mechanisms

反馈机制

Collect user feedback to improve AI responses:
tsx
<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>
收集用户反馈以优化AI响应:
tsx
<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>

Streaming & Real-Time UX

流式与实时用户体验

Progressive rendering of AI responses requires special handling:
tsx
// 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;
}
For complete streaming patterns, auto-scroll behavior, and stop generation, see
references/streaming-ux.md
.
AI响应的渐进式渲染需要特殊处理:
tsx
// 使用Streamdown处理AI流式渲染(支持不完整Markdown)
import { Streamdown } from '@vercel/streamdown';

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

// 智能自动滚动启发式逻辑
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

Context Management

上下文管理

Communicate token limits clearly to users:
tsx
// 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>
  );
}
For summarization strategies, conversation branching, and organization, see
references/context-management.md
.
向用户清晰展示令牌使用限制:
tsx
// 友好的令牌使用展示组件
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

Multi-Modal Support

多模态支持

Handle images, files, and voice inputs:
tsx
// 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>
  );
}
For complete multi-modal patterns including voice and screen sharing, see
references/multi-modal.md
.
处理图片、文件与语音输入:
tsx
// 带预览的图片上传组件
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

Error Handling

错误处理

Handle AI-specific errors gracefully:
tsx
// 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>
  );
}
For comprehensive error patterns, see
references/error-handling.md
.
优雅处理AI特有的错误场景:
tsx
// 拒绝响应处理
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

Tool Usage Visualization

工具调用可视化

Show when AI is using tools or functions:
tsx
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>
  );
}
For function calling, code execution, and web search patterns, see
references/tool-usage.md
.
展示AI调用工具或函数的过程:
tsx
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

Implementation Guide

实现指南

Recommended Stack

推荐技术栈

Primary libraries (validated November 2025):
bash
undefined
经过验证的核心库(更新至2025年11月):
bash
undefined

Core AI chat functionality

核心AI聊天功能

npm install ai @ai-sdk/react @ai-sdk/openai
npm install ai @ai-sdk/react @ai-sdk/openai

Streaming markdown rendering

流式Markdown渲染

npm install @vercel/streamdown
npm install @vercel/streamdown

Syntax highlighting

语法高亮

npm install react-syntax-highlighter
npm install react-syntax-highlighter

Security for LLM outputs

LLM输出安全处理

npm install dompurify
undefined
npm install dompurify
undefined

Performance Optimization

性能优化

Critical for smooth streaming:
tsx
// 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';
For detailed performance patterns, see
references/streaming-ux.md
.
流式渲染的关键优化策略:
tsx
// 消息渲染组件记忆化
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

Security Considerations

安全考量

Always sanitize AI outputs:
tsx
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输出进行净化处理:
tsx
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>;
}

Accessibility

可访问性

Ensure AI chat is usable by everyone:
tsx
// 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>
For complete accessibility patterns, see
references/accessibility.md
.
确保AI聊天界面面向所有用户可用:
tsx
// 屏幕阅读器ARIA实时区域
<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>

// 加载状态播报
<div role="status" aria-live="polite" className="sr-only">
  {isLoading ? 'AI正在响应' : ''}
</div>
完整的可访问性实现模式,请查看
references/accessibility.md

Bundled Resources

配套资源

Scripts (Token-Free Execution)

脚本(无需令牌即可运行)

  • Run
    scripts/parse_stream.js
    to parse incomplete markdown during streaming
  • Run
    scripts/calculate_tokens.py
    to estimate token usage and context limits
  • Run
    scripts/format_messages.js
    to format message history for export
  • 运行
    scripts/parse_stream.js
    解析流式渲染中的不完整Markdown
  • 运行
    scripts/calculate_tokens.py
    估算令牌使用量与上下文限制
  • 运行
    scripts/format_messages.js
    格式化消息历史以用于导出

References (Progressive Disclosure)

参考文档(渐进式披露)

  • references/streaming-patterns.md
    - Complete streaming UX patterns
  • references/context-management.md
    - Token limits and conversation strategies
  • references/multimodal-input.md
    - Image, file, and voice handling
  • references/feedback-loops.md
    - User feedback and RLHF patterns
  • references/error-handling.md
    - AI-specific error scenarios
  • references/tool-usage.md
    - Visualizing function calls and tool use
  • references/accessibility-chat.md
    - Screen reader and keyboard support
  • references/library-guide.md
    - Detailed library documentation
  • references/performance-optimization.md
    - Streaming performance patterns
  • 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

示例项目

  • examples/basic-chat.tsx
    - Minimal ChatGPT-style interface
  • examples/streaming-chat.tsx
    - Advanced streaming with memoization
  • examples/multimodal-chat.tsx
    - Images and file uploads
  • examples/code-assistant.tsx
    - IDE-style code copilot
  • examples/tool-calling-chat.tsx
    - Function calling visualization
  • examples/basic-chat.tsx
    - 极简ChatGPT风格界面
  • examples/streaming-chat.tsx
    - 带记忆化的高级流式界面
  • examples/multimodal-chat.tsx
    - 支持图片与文件上传的界面
  • examples/code-assistant.tsx
    - IDE风格代码Copilot
  • examples/tool-calling-chat.tsx
    - 函数调用可视化界面

Assets

资源文件

  • assets/system-prompts.json
    - Curated prompts for different use cases
  • assets/message-templates.json
    - Pre-built message components
  • assets/error-messages.json
    - User-friendly error messages
  • assets/themes.json
    - Light, dark, and high-contrast themes
  • assets/system-prompts.json
    - 针对不同场景的精选提示词
  • assets/message-templates.json
    - 预构建消息组件模板
  • assets/error-messages.json
    - 用户友好的错误提示文案
  • assets/themes.json
    - 亮色、暗色与高对比度主题

Design Token Integration

设计令牌集成

All visual styling uses the design-tokens system:
css
/* 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));
}
See
skills/design-tokens/
for complete theming system.
所有视觉样式均使用设计令牌系统:
css
/* 消息气泡使用设计令牌 */
.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/

Key Innovations

核心创新点

This skill provides industry-first solutions for:
  • Memoized streaming rendering - 10-50x performance improvement
  • Intelligent auto-scroll - User activity-aware scrolling
  • Token metaphors - User-friendly context communication
  • Incomplete markdown handling - Graceful partial rendering
  • RLHF patterns - Effective feedback collection
  • Conversation branching - Non-linear conversation trees
  • Multi-modal integration - Seamless file/image/voice handling
  • Accessibility-first - Built-in screen reader support
本技能提供行业首创的解决方案:
  • 记忆化流式渲染 - 10-50倍性能提升
  • 智能自动滚动 - 感知用户行为的滚动逻辑
  • 令牌隐喻展示 - 面向用户的友好上下文沟通方式
  • 不完整Markdown处理 - 优雅的部分渲染支持
  • RLHF模式 - 高效的用户反馈收集
  • 对话分支 - 非线性对话树管理
  • 多模态集成 - 无缝的文件/图片/语音处理
  • 可访问性优先 - 内置屏幕阅读器支持

Strategic Importance

战略重要性

This is THE most critical skill because:
  1. Perfect timing - Every app adding AI (2024-2025 boom)
  2. No standards exist - Opportunity to define patterns
  3. Meta-advantage - Building WITH Claude = intimate UX knowledge
  4. Unique challenges - Streaming, context, hallucinations all new
  5. Reference implementation - Can become the standard others follow
Master this skill to lead the AI interface revolution.
本技能是当前最关键的AI开发技能,原因如下:
  1. 时机完美 - 2024-2025年所有应用都在集成AI
  2. 无行业标准 - 有机会定义行业通用模式
  3. 元知识优势 - 与Claude协作开发积累的深度UX认知
  4. 独特挑战 - 流式渲染、上下文管理、幻觉处理均为全新问题
  5. 参考实现价值 - 可成为行业通用的标准实现
掌握本技能,引领AI界面革命。