- 后端
- 前端
- CRM
- 人工智能
- AI Agent
【免费下载链接】crm
Comp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.
本文基于 Comp AI CRM 仓库中 .agents/skills/ai-elements/references/image.md 整理而成。该文档属于 AI Elements 组件库(本仓库通过 skills-lock.json 锁定了来自 vercel/ai-elements 的技能源)中Image组件的参考指南,面向要在 AI 原生界面里展示文生图结果的开发者。读完本文,你将掌握如何安装该组件、用 AI SDK 的experimental_generateImage在服务端生成图像、将 base64 数据流式传输到前端并交由Image组件渲染,以及如何理解其 Props、默认样式与 TypeScript 类型约定。
组件概览:为 AI SDK 生成的图像而生的展示组件
Image组件解决的是一个非常具体的问题:AI SDK 的generateImage系列函数返回的并非一个可直接交给<img>使用的 URL,而是一个Experimental_GeneratedImage对象,其中携带base64、uint8Array、mediaType等原始数据字段。Image组件直接接受该对象,并自动将这些数据转换为合法的 data URL 完成渲染,省去了手写「base64 → data URL」转换逻辑的样板代码。
核心特性(见原文档 Features 一节):
- 直接接受 AI SDK 返回的
Experimental_GeneratedImage对象; - 自动从 base64 编码的图像数据构造正确的 data URL;
- 支持所有标准 HTML 图像属性(
alt、className等); - 默认响应式:内置
max-w-full h-auto样式; - 可通过额外 CSS 类继续定制外观;
- 为 AI SDK 兼容性提供完整的 TypeScript 类型支持。
一句话概括其定位:它是 AI SDK「生成图像」工作流在前端展示环节的最后一公里组件。
安装:通过 AI Elements CLI 引入组件
在 Next.js + AI SDK + shadcn/ui 的项目中,运行以下命令即可把Image组件安装进项目:
npx ai-elements@latest add image关于安装有几点重要说明(来自 .agents/skills/ai-elements/SKILL.md):
- 包管理器选择:CLI 命令应使用项目
packageManager字段对应的 runner,即npx ai-elements@latest、pnpm dlx ai-elements@latest或bunx --bun ai-elements@latest,示例中统一使用npx,实际请按项目替换。 - 前置条件:Node.js 18 及以上、已安装 AI SDK 的 Next.js 项目、已初始化 shadcn/ui(若未安装,执行安装命令时会自动带上)。
- 落盘位置:组件代码会下载到项目的
@/components/ai-elements/目录(或你在 components.json 中配置的组件目录),与普通 shadcn/ui 组件一样直接成为你代码库的一部分——这意味着你可以直接打开组件源文件查看实现、按需修改,而不是被隐藏在某个库里。 - 官方建议配合 Vercel AI Gateway 使用,在
env.local中配置AI_GATEWAY_API_KEY以统一各模型供应商的密钥管理。
端到端实战:从提示词到生成图像的完整链路
原文档提供了一个完整的示例:前端一个输入框收集用户的提示词,POST 给后端路由,后端调用 AI SDK 生成图像并把图像数据返回,前端用Image组件展示。下面完整还原这个流程。
第一步:安装 OpenAI 图像模型包
npm i @ai-sdk/openai该包提供openai客户端实例,后续通过openai.image("dall-e-3")指定图像生成模型。
第二步:前端组件(app/page.tsx)
前端使用Image组件负责展示,用PromptInput系列组件(同一组件库的输入组件,详见 prompt-input.md)负责收集提示词:
"use client"; import { Image } from "@/components/ai-elements/image"; import { PromptInput, type PromptInputMessage, PromptInputTextarea, PromptInputSubmit, } from "@/components/ai-elements/prompt-input"; import { useState } from "react"; import { Spinner } from "@/components/ui/spinner"; const ImageDemo = () => { const [prompt, setPrompt] = useState("A futuristic cityscape at sunset"); const [imageData, setImageData] = useState<any>(null); const [isLoading, setIsLoading] = useState(false); const handleSubmit = async (message: PromptInputMessage) => { if (!message.text.trim()) return; setPrompt(""); setIsLoading(true); try { const response = await fetch("/api/image", { method: "POST", body: JSON.stringify({ prompt: message.text.trim() }), }); const data = await response.json(); setImageData(data); } catch (error) { console.error("Error generating image:", error); } finally { setIsLoading(false); } }; return ( <div className="max-w-4xl mx-auto p-6 relative size-full rounded-lg border h-[600px]"> <div className="flex flex-col h-full"> <div className="flex-1 overflow-y-auto p-4"> {imageData && ( <div className="flex justify-center"> <Image {...imageData} alt="Generated image" className="h-[300px] aspect-square border rounded-lg" /> </div> )} {isLoading && <Spinner />} </div> <PromptInput onSubmit={handleSubmit} className="mt-4 w-full max-w-2xl mx-auto relative" > <PromptInputTextarea value={prompt} placeholder="Describe the image you want to generate..." onChange={(e) => setPrompt(e.currentTarget.value)} className="pr-12" /> <PromptInputSubmit status={isLoading ? "submitted" : "ready"} disabled={!prompt.trim()} className="absolute bottom-1 right-1" /> </PromptInput> </div> </div> ); }; export default ImageDemo;注意第 73 行{...imageData}的展开方式:后端返回的base64、uint8Array、mediaType三个字段被整体透传给Image组件——这正是「组件直接接受Experimental_GeneratedImage对象」这一设计带来的便利。className传入h-[300px] aspect-square border rounded-lg控制尺寸与圆角,展示区用条件渲染{imageData && ...}配合Spinner处理加载态。
第三步:后端路由(app/api/image/route.ts)
import { openai } from "@ai-sdk/openai"; import { experimental_generateImage } from "ai"; export async function POST(req: Request) { const { prompt }: { prompt: string } = await req.json(); const { image } = await experimental_generateImage({ model: openai.image("dall-e-3"), prompt: prompt, size: "1024x1024", }); return Response.json({ base64: image.base64, uint8Array: image.uint8Array, mediaType: image.mediaType, }); }这里的关键点:
experimental_generateImage返回的对象中,image携带base64、uint8Array、mediaType三个字段,路由把它们原样序列化为 JSON 响应;model: openai.image("dall-e-3")指定 OpenAI 的 DALL·E 3 图像模型,size: "1024x1024"指定输出尺寸,prompt直接透传用户输入;- 由于
uint8Array(Uint8Array)经Response.json()序列化后会被编码为普通数组,Image组件必须能够兼容「以数组形式到达的字节数据」——这正是其内部「自动构造 data URL」逻辑要处理的边界情况之一。
组件源码佐证:仓库中的示例脚本
本仓库在 .agents/skills/ai-elements/scripts/image.tsx 提供了该组件的独立运行示例。该脚本展示了两个值得注意的用法:
- 对象展开 + 自定义样式组合:
const Example = () => ( <Image {...exampleImage} alt="Example generated image" className="aspect-square h-[150px] border" /> );与文档中的前端示例一致,exampleImage对象直接展开传入,className负责控制尺寸与边框样式,印证了「...props接收图像数据 +className叠加样式」的 Props 设计。
- 数据形状的真实形态:示例中的
exampleImage包含一长串/9j/4AAQSkZJRg...的 JPEG base64 字符串、mediaType: "image/jpeg"以及空的uint8Array: new Uint8Array([])。这从数据层面说明:base64与mediaType是渲染的主数据来源,uint8Array可能是空数组——因此组件内部必须以base64 + mediaType为主路径构造 data URL,而不能假定字节数组总是可用的。
Props API 一览
原文档给出的 Props 表格如下:
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
alt | string | - | 图像的替代文本(无障碍与 SEO 必需) |
className | string | - | 应用到图像上的额外 CSS 类 |
...props | Experimental_GeneratedImage | - | 要显示的图像数据,即 AI SDK 的返回结果 |
结合源码与特性可以进一步理解:
alt没有默认值:示例代码中都显式传入了alt(如"Generated image"、"Example generated image"),实际项目中建议根据提示词动态生成描述性 alt,例如Generated image of: ${prompt};...props的类型是Experimental_GeneratedImage:这是 AI SDK 导出的对象类型,包含base64、uint8Array、mediaType等字段,组件据此获得完整的 TypeScript 类型检查;className支持任意 Tailwind 类:示例中出现了aspect-square、h-[150px]、h-[300px]、border、rounded-lg等,均可自由组合;由于组件默认带max-w-full h-auto,传入aspect-square等尺寸类时可覆盖默认比例。
定制与故障排查
AI Elements 的所有组件都「尽量接受尽可能多的原生属性」,Image组件扩展了 HTML 图像的标准属性集,因此你可以像使用普通<img>一样传入width、height、loading、fetchPriority等属性。组件安装后无需额外配置即可使用——样式(Tailwind 类)与脚本已随组件一并集成进你的代码库,需要去圆角就去掉rounded-lg,需要改响应式就去改max-w-full,因为代码就躺在你的components/ai-elements/image.tsx里。
若遇到问题,.agents/skills/ai-elements/SKILL.md 的 Troubleshooting 一节提供了排查清单:
- 组件没有样式:确认项目正确配置了 shadcn/ui 与 Tailwind 4,
globals.css导入了 Tailwind 及 shadcn 基础样式; - 运行 CLI 后什么都没添加:检查当前目录是否为
package.json所在的项目根目录、components.json是否正确,并确保使用最新版 CLI(npx ai-elements@latest); - 主题切换失效:确保应用使用 shadcn/ui 期望的
data-theme体系,默认实现是在<html>元素上切换data-theme属性; - 「module not found」导入失败:确认
tsconfig.json配置了@/路径别名,即"paths": { "@/*": ["./*"] },因为所有示例都从@/components/ai-elements/...导入。
小结
Image组件是 AI Elements 组件库中面向「文生图」场景的标准化展示方案:安装一条命令,前后端两端示例代码即可跑通从提示词到图像的完整链路。它的核心价值在于把 AI SDK 的Experimental_GeneratedImage数据对象直接当作组件的props使用,让 base64 到 data URL 的转换、响应式布局、类型安全这些重复工作从业务代码中消失。在 Comp AI CRM 这类以 AI Agent 为核心体验的应用中,它既可以单独用于对话中的文生图结果展示,也可以与PromptInput、Message、Conversation等组件组合,构建完整的 AI 原生交互界面。
- 后端
- 前端
- CRM
- 人工智能
- AI Agent
【免费下载链接】crm
Comp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.
相关推荐
在 ZCode 中用 AI Elements 的 Image 组件渲染 AI SDK 生成的图片
在 ZCode 中用 AI Elements 的 Image 组件渲染 AI SDK 生成的图片 导读 本文介绍 ZCode 仓库内置的 AI Elements
Comp AI CRM 中的 AI 推理展示:ai-elements Reasoning 组件集成实战指南
Comp AI CRM 中的 AI 推理展示:ai elements Reasoning 组件集成实战指南 本文是一份以 ai elements 技能文档 ht
后端前端CRM人工智能AI AgentLifeOS Synapse 输入路由器详解:一份捕获契约、琥珀账本与五阶段信号路由循环
LifeOS Synapse 输入路由器详解:一份捕获契约、琥珀账本与五阶段信号路由循环 Synapse 是 LifeOS 的输入路由器(Input Route
后端前端CRM人工智能AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考