building-ai-chat
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAI 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.tsxCore 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.mdInput 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.mdAI响应的渐进式渲染需要特殊处理:
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.mdContext 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.mdMulti-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.mdError 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.mdTool 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.mdImplementation Guide
实现指南
Recommended Stack
推荐技术栈
Primary libraries (validated November 2025):
bash
undefined经过验证的核心库(更新至2025年11月):
bash
undefinedCore 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
undefinednpm install dompurify
undefinedPerformance 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.mdSecurity 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.mdBundled Resources
配套资源
Scripts (Token-Free Execution)
脚本(无需令牌即可运行)
- Run to parse incomplete markdown during streaming
scripts/parse_stream.js - Run to estimate token usage and context limits
scripts/calculate_tokens.py - Run to format message history for export
scripts/format_messages.js
- 运行解析流式渲染中的不完整Markdown
scripts/parse_stream.js - 运行估算令牌使用量与上下文限制
scripts/calculate_tokens.py - 运行格式化消息历史以用于导出
scripts/format_messages.js
References (Progressive Disclosure)
参考文档(渐进式披露)
- - Complete streaming UX patterns
references/streaming-patterns.md - - Token limits and conversation strategies
references/context-management.md - - Image, file, and voice handling
references/multimodal-input.md - - User feedback and RLHF patterns
references/feedback-loops.md - - AI-specific error scenarios
references/error-handling.md - - Visualizing function calls and tool use
references/tool-usage.md - - Screen reader and keyboard support
references/accessibility-chat.md - - Detailed library documentation
references/library-guide.md - - Streaming performance patterns
references/performance-optimization.md
- - 完整流式用户体验模式
references/streaming-patterns.md - - 令牌限制与对话策略
references/context-management.md - - 图片、文件与语音处理
references/multimodal-input.md - - 用户反馈与RLHF模式
references/feedback-loops.md - - AI特有的错误场景
references/error-handling.md - - 函数调用与工具使用可视化
references/tool-usage.md - - 屏幕阅读器与键盘支持
references/accessibility-chat.md - - 详细库文档
references/library-guide.md - - 流式性能优化模式
references/performance-optimization.md
Examples
示例项目
- - Minimal ChatGPT-style interface
examples/basic-chat.tsx - - Advanced streaming with memoization
examples/streaming-chat.tsx - - Images and file uploads
examples/multimodal-chat.tsx - - IDE-style code copilot
examples/code-assistant.tsx - - Function calling visualization
examples/tool-calling-chat.tsx
- - 极简ChatGPT风格界面
examples/basic-chat.tsx - - 带记忆化的高级流式界面
examples/streaming-chat.tsx - - 支持图片与文件上传的界面
examples/multimodal-chat.tsx - - IDE风格代码Copilot
examples/code-assistant.tsx - - 函数调用可视化界面
examples/tool-calling-chat.tsx
Assets
资源文件
- - Curated prompts for different use cases
assets/system-prompts.json - - Pre-built message components
assets/message-templates.json - - User-friendly error messages
assets/error-messages.json - - Light, dark, and high-contrast themes
assets/themes.json
- - 针对不同场景的精选提示词
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 for complete theming system.
skills/design-tokens/所有视觉样式均使用设计令牌系统:
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:
- Perfect timing - Every app adding AI (2024-2025 boom)
- No standards exist - Opportunity to define patterns
- Meta-advantage - Building WITH Claude = intimate UX knowledge
- Unique challenges - Streaming, context, hallucinations all new
- Reference implementation - Can become the standard others follow
Master this skill to lead the AI interface revolution.
本技能是当前最关键的AI开发技能,原因如下:
- 时机完美 - 2024-2025年所有应用都在集成AI
- 无行业标准 - 有机会定义行业通用模式
- 元知识优势 - 与Claude协作开发积累的深度UX认知
- 独特挑战 - 流式渲染、上下文管理、幻觉处理均为全新问题
- 参考实现价值 - 可成为行业通用的标准实现
掌握本技能,引领AI界面革命。