关于 building-ai-chat
building-ai-chat 为构建对话式 AI 界面的开发者提供设计与实现指导,内容包括流式响应、上下文、多模态输入和错误处理。它还涵盖工具调用展示、无障碍设计及响应反馈。
主要功能
- 01流式消息与 Markdown 渲染模式
- 02上下文和令牌用量管理
- 03图像、文件与语音输入模式
- 04AI 错误和拒绝响应处理
- 05工具调用展示与用户反馈
- 06无障碍和性能优化建议
适用场景
- 01构建聊天机器人或 AI 助手界面
- 02实现流式 Markdown 回复
- 03支持图像、文件或语音输入
- 04在界面中呈现工具调用和响应反馈
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ancoleman/ ai-design-components --skill building-ai-chat安装后在 Claude Code 中输入/building-ai-chat确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
outputs.yamlassets/error-messages.jsonmessage-templates.jsonsystem-prompts.jsonthemes.jsonexamples/basic-chat.tsxcode-assistant.tsxmultimodal-chat.tsxstreaming-chat.tsxtool-calling-chat.tsxreferences/accessibility-chat.mdaccessibility.mdcontext-management.mderror-handling.mdfeedback-loops.mdlibrary-guide.mdmessage-components.mdmulti-modal.mdmultimodal-input.mdperformance-optimization.mdstreaming-patterns.mdstreaming-ux.mdtool-usage.mdscripts/calculate_tokens.pyformat_messages.jsparse_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 模式 - 高效收集反馈
- 对话分支 - 非线性对话树
- 多模态集成 - 无缝处理文件、图片和语音
- 无障碍优先 - 内置屏幕阅读器支持
战略重要性
这是最关键的技能,因为:
- 时机绝佳 - 每款应用都在添加 AI(2024-2025 年热潮)
- 尚无标准 - 有机会定义模式
- 元优势 - 与 Claude 一起构建 = 深入了解 UX
- 独特挑战 - 流式处理、上下文和幻觉都是全新的问题
- 参考实现 - 有望成为其他人遵循的标准
掌握这项技能,引领 AI 界面革命。