AIHero
    12 / 16Vercel AI SDK 教程

    使用 Vercel AI SDK 构建替代文本生成器

    通过简明指南,学习如何使用 Vercel AI SDK 为本地文件和 URL 图片生成替代文本。

    Matt Pocock
    Matt Pocock
    源代码下一课
    本页目录

    AI SDK 另一项开箱即用的能力,是把图像和文件传给 LLM。

    LLM 随后可以查看文件或图像,并据此执行任务。这是一项非常强大的功能。

    并非所有 LLM 都支持这种能力,但对于支持的模型,AI SDK 可以直接使用。

    在这个例子中,我们希望 LLM 为传入的图像生成替代文本。

    这些替代文本可以用于网站,帮助无法看到图像的人理解其中内容。

    滚动式代码讲解

    1

    我们使用一个非常简单的系统提示词:

    2

    然后创建一个名为 describeImage 的函数,它接收本地文件系统中的图像路径。

    const systemPrompt =
    `You will receive an image. ` +
    `Please create an alt text for the image. ` +
    `Be concise. ` +
    `Use adjectives only when necessary. ` +
    `Do not pass 160 characters. ` +
    `Use simple language. `;

    看起来没问题,但函数内部还没有使用 imagePath

    不能直接把图像路径当作提示词传入。首先需要把图像加载到内存,再传给 generateText 函数。

    滚动式代码讲解

    1

    为了把图像加载到内存,使用 readFileSync ,它来自 Node.js。

    它会把图像以 Uint8Array形式存入内存,本质上就是构成图像的原始字节表示。

    2

    当然,也可以使用 readFile from fs.promises 实现非阻塞 I/O,但 readFileSync 已经足以满足当前需求。

    3

    现在可以把这个 Uint8Array 传给 generateText 函数。但不能直接把它作为提示词传入,而需要放进一个 messages 数组:

    它采用与前面聊天历史相同的格式,但这次包含 content ,也就是由不同消息部分组成的数组。

    传入的消息部分类型是 image,随后传入 Uint8Array 传给 image 属性。

    import { readFileSync } from "fs";
    import { generateText } from "ai";
    export const describeImage = async (
    imagePath: string,
    ) => {
    const imageAsUint8Array = readFileSync(imagePath);
    const { text } = await generateText({
    model,
    system: systemPrompt,
    });
    return text;
    };

    运行看看。我准备了一张烟花图片,把它传入后观察结果。

    const description = await describeImage(
    "./fireworks.jpg",
    );
    console.log(description);

    会得到一段漂亮的描述:

    Colorful fireworks display over a city skyline at night, with bursts of red, white, and blue reflections on the water. Spectators watch from the shoreline.

    总结一下,我们把图像读入内存,再通过 generateText 中的 messages 数组直接传入,并获得图像描述。效果很不错。

    从 URL 读取

    当前方式适用于文件已经在内存中的情况。如果只有文件 URL 呢?

    这里有个很方便的捷径:可以把 URL 直接传给 AI SDK。

    import { generateText } from "ai";
    export const describeImage = async (
    imageUrl: string,
    ) => {
    const { text } = await generateText({
    model,
    system:
    `You will receive an image. ` +
    `Please create an alt text for the image. ` +
    `Be concise. ` +
    `Use adjectives only when necessary. ` +
    `Do not pass 160 characters. ` +
    `Use simple language. `,
    messages: [
    {
    role: "user",
    content: [
    {
    type: "image",
    image: new URL(imageUrl),
    },
    ],
    },
    ],
    });
    return text;
    };

    使用 new URL 包装 URL,告诉 AI SDK 这是一个需要发送给 LLM 的网络 URL。

    测试一下。我在 GitHub 上托管了一张教堂图片,希望让模型描述它:

    const description = await describeImage(
    "https://github.com/ai-hero-dev/ai-hero/blob/main/internal/assets/image.jpg?raw=true",
    );
    console.log(description);

    运行后,URL 会被传给 LLM。LLM 下载并查看图像,然后返回描述。

    Lake Bled in Slovenia with church on small peninsula and castle on cliff, surrounded by mountains. Calm water reflects buildings and autumn trees.

    处理托管在网络上的图像时,这是一种非常方便的快捷方式。

    登录以保存进度。