Vercel AI SDK

WBOY
WBOYオリジナル
2024-08-16 06:12:02489ブラウズ

トレース、マルチモーダル添付ファイル、クライアントへの JSON ストリーミングなどを導入します。

Vercel AI SDK は、JavaScript と TypeScript を使用して AI アプリケーションを構築するためのツールキットです。統合された API により、あらゆる言語モデルを使用でき、Next.js や Svelte などの主要な Web フレームワークへの強力な UI 統合が可能になります。

Vercel AI SDK 3.3 には、次の 4 つの主要な機能が導入されています。

  • トレース (実験的): OpenTelemetry
  • を使用して AI SDK 関数を計測します
  • マルチモーダル ファイル添付ファイル (実験的): useChat を使用して添付ファイルを送信します
  • useObject フック (実験的): 構造化オブジェクトの生成をクライアントにストリームします
  • 追加の LLM 設定: ツールと構造化オブジェクトの生成、停止シーケンス、およびカスタム ヘッダーの送信用の生の JSON

また、AWS Bedrock および Chrome AI (コミュニティ) モデルプロバイダーに加え、多くの小規模な機能や追加機能も追加しました。マイナーな機能を含むすべての変更は、変更履歴で確認できます。

実験的な機能により、最新の AI SDK 機能をできるだけ早く使用できるようになります。ただし、パッチ バージョンでは変更される可能性があります。実験的な機能を使用する場合は、パッチ バージョンを固定してください。

トレース

言語モデルの非決定的な性質を考慮すると、AI アプリケーションを理解して開発するには可観測性が重要です。個々のモデル呼び出しのタイミング、トークンの使用法、プロンプト、および応答の内容を追跡して理解できる必要があります。

Vercel AI SDK は、実験的な機能として、テレメトリ情報を記録するためのオープンソース標準である OpenTelemetry によるトレースをサポートするようになりました。以下は、Vercel Datadog 統合によるトレースの視覚化の例です。

Vercel AI SDK

Datadog と Vercel AI SDK を使用したトレース視覚化

Datadog、Sentry、Axiom などの Vercel 可観測性統合を使用して AI SDK トレース データを分析できます。あるいは、LangFuse、Braintrust、LangSmith などの LLM 可観測性プロバイダーを使用することもできます。

Vercel AI SDK でテレメトリを使用するには、アプリケーションに合わせて構成する必要があります。 @vercel/otel を使用することをお勧めします。 Next.js を使用し、Vercel にデプロイする場合は、次のコードを含むinstrumentation.ts をプロジェクトに追加できます。

import { registerOTel } from '@vercel/otel';

export function register() {
  registerOTel({ serviceName: 'your-project-nameapp' });
}

トレース機能は実験的なものであるため、experimental_telemetry オプションを使用して情報を記録するにはオプトインする必要があります。また、関数 ID を指定して呼び出しの場所を特定したり、記録する追加のメタデータを指定したりすることもできます。

const result = await generateText({
  model: anthropic('claude-3-5-sonnet-20240620'),
  prompt: 'Write a short story about a cat.',
  experimental_telemetry: { 
    isEnabled: true,
    functionId: 'my-awesome-function',
    metadata: {
      something: 'custom',
      someOtherThing: 'other-value',
    },
  },
});

この機能を有効にすると、関数呼び出しのトレース データが記録されます。詳細については、AI SDK テレメトリのドキュメントを参照してください。始めたい場合は、デプロイ可能な AI SDK Next.js トレース テンプレートをチェックしてください。

マルチモーダル添付ファイル

多くの AI チャット アプリケーションでは、ユーザーはメッセージと一緒に画像、PDF、さまざまなメディア ファイルなどの添付ファイルを送信する必要があります。これらの添付ファイルは、ユーザーが表示するメッセージと一緒にプレビューできる必要もあります。

その結果、useChat() React フックの handleSubmit() ハンドラーに Experimental_attachments を追加しました。

Vercel AI SDK

useChat を使用して画像とテキストの添付ファイルを送信する

この例の動作を確認し、テンプレートをデプロイしてください。

メッセージに添付ファイルを送信するには、FileList オブジェクトまたは URL のリストを handleSubmit 関数に提供する 2 つの方法があります。

ファイルリスト

FileList を使用すると、file input 要素を使用して複数のファイルをメッセージとともに添付ファイルとして送信できます。 useChat フックはそれらを自動的にデータ URL に変換し、AI プロバイダーに送信します。

const { input, handleSubmit, handleInputChange } = useChat();
const [files, setFiles] = useState<FileList | undefined>(undefined);
return (
  <form
    onSubmit={(event) => {
      handleSubmit(event, {
        experimental_attachments: files,
      });
    }}
  >
    <input
      type="file"
      onChange={(event) => {
        if (event.target.files) {
          setFiles(event.target.files);
        }
      }}
      multiple
    />
    <input type="text" value={input} onChange={handleInputChange} />
  </form>
);

URL

URL をメッセージに添付して送信することもできます。これは、外部リソースまたはメディア コンテンツへのリンクを送信する場合に役立ちます。

const { input, handleSubmit, handleInputChange } = useChat();
const [attachments] = useState<Attachment[]>([
  {
    name: 'earth.png',
    contentType: 'image/png',
    url: 'https://example.com/earth.png',
  }
]);
return (
  <form
    onSubmit={event => {
      handleSubmit(event, {
        experimental_attachments: attachments,
      });
    }}
  >
    <input type="text" value={input} onChange={handleInputChange} />
  </form>
)

マルチモーダル チャットボット ガイドで詳細をご覧いただけます。

useObject フック

構造化データの生成は、AI アプリケーションにおける一般的な要件です。自然言語入力から情報を抽出します。新しい useObject フックを使用すると、構造化オブジェクトの生成をクライアントに直接ストリーミングできます。 React で現在利用できるこの実験的な機能を使用すると、ストリーミングされている JSON オブジェクトを表示する動的インターフェイスを作成できます。

たとえば、経費を償還用のテキストとして入力できるアプリケーションを想像してください。 AI を使用してテキスト入力を構造化オブジェクトに変換し、処理中に構造化された経費をユーザーにストリーミングできます。

Vercel AI SDK

Extracting and streaming an expense from plain text with useObject

Here's how you could implement this in a Next.js application. First, define a schema for the expenses. The schema is shared between client and server:

import { z } from 'zod';

export const expenseSchema = z.object({
  expense: z.object({
    category: z
      .string()
      .describe(
        'Category of the expense. Allowed categories: ' +
        'TRAVEL, MEALS, ENTERTAINMENT, OFFICE SUPPLIES, OTHER.',
      ),
    amount: z.number().describe('Amount of the expense in USD.'),
    date: z
      .string()
      .describe('Date of the expense. Format yyyy-mmm-dd, e.g. 1952-Feb-19.'),
    details: z.string().describe('Details of the expense.'),
  }),
});

export type PartialExpense = DeepPartial<typeof expenseSchema>['expense'];
export type Expense = z.infer<typeof expenseSchema>['expense'];

Then, you use streamObject on the server to call the language model and stream an object:

import { anthropic } from '@ai-sdk/anthropic';
import { streamObject } from 'ai';
import { expenseSchema } from './schema';

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

export async function POST(req: Request) {
  const { expense }: { expense: string } = await req.json();
  const result = await streamObject({
    model: anthropic('claude-3-5-sonnet-20240620'),
    system:
      'You categorize expenses into one of the following categories: ' +
      'TRAVEL, MEALS, ENTERTAINMENT, OFFICE SUPPLIES, OTHER.' +
      // provide date (including day of week) for reference:
      'The current date is: ' +
      new Date()
        .toLocaleDateString('en-US', {
          year: 'numeric',
          month: 'short',
          day: '2-digit',
          weekday: 'short',
        })
        .replace(/(\w+), (\w+) (\d+), (\d+)/, '$4-$2-$3 ($1)') +
      '. When no date is supplied, use the current date.',
    prompt: `Please categorize the following expense: "${expense}"`,
    schema: expenseSchema,
    onFinish({ object }) {
      // you could save the expense to a database here
    },
  });
  return result.toTextStreamResponse();
}

Finally, you consume the expense stream on a client page. While the expense is streaming, we preview the partial expense, and once the generation is finished, we append it to the list of expenses:

'use client';

import { experimental_useObject as useObject } from 'ai/react';
import {
  Expense,
  expenseSchema,
  PartialExpense,
} from '../api/expense/schema';
import { useState } from 'react';

export default function Page() {
  const [expenses, setExpenses] = useState<Expense[]>([]);
  const { submit, isLoading, object } = useObject({
    api: '/api/expense',
    schema: expenseSchema,
    onFinish({ object }) {
      if (object != null) {
        setExpenses(prev => [object.expense, ...prev]);
      }
    },
  });
  return (
    <div>
      <form onSubmit={e => {
        e.preventDefault();
        const input = e.currentTarget.expense as HTMLInputElement;
        if (input.value.trim()) {
          submit({ expense: input.value });
          e.currentTarget.reset();
        }
      }}
      >
        <input type="text" name="expense" placeholder="Enter expense details"/>
        <button type="submit" disabled={isLoading}>Log expense</button>
      </form>
      {isLoading && object?.expense && (
        <ExpenseView expense={object.expense} />
      )}
      {expenses.map((expense, index) => (
        <ExpenseView key={index} expense={expense} />
      ))}
    </div>
  );
}

The expenses are rendered using an ExpenseView that can handle partial objects with undefined properties with .? and ?? (styling is omitted for illustration purposes):

const ExpenseView = ({ expense }: { expense: PartialExpense | Expense }) => (
  <div>
    <div>{expense?.date ?? ''}</div>
    <div>${expense?.amount?.toFixed(2) ?? ''}</div>
    <div>{expense?.category ?? ''}</p></div>
    <div>{expense?.details ?? ''}</div>
  </div>
);

Check out this example in action and deploy the template.

You can use this approach to create generative user interfaces client-side for many different use cases. You can find more details on how to use it in our object generation documentation.

Additional LLM Settings

Calling language models is at the heart of the Vercel AI SDK. We have listened to your feedback and extended our functions to support the following features:

  • JSON schema support for tools and structured object generation: As an alternative to Zod schemas, you can now use JSON schemas directly with the jsonSchema function. You can supply the type annotations and an optional validation function, giving you more flexibility especially when building applications with dynamic tools and structure generation.
  • Stop sequences: Text sequences that stop generations have been an important feature when working with earlier language models that used raw text prompts. They are still relevant for many use cases, allowing you more control over the end of a text generation. You can now use the stopSequences option to define stop sequences in streamText and generateText.
  • Sending custom headers: Custom headers are important for many use cases, like sending tracing information, enabling beta provider features, and more. You can now send custom headers using the headers option in most AI SDK functions.

With these additional settings, you have more control and flexibility when working with language models in the Vercel AI SDK.

Conclusion

With new features like OpenTelemetry support, useObject, and support for attachments with useChat, it’s never been a better time to start building AI applications.

  • Start a new AI project: Ready to build something new? Check out our multi-modal chatbot guide.
  • Explore our templates: Visit our Template Gallery to see the AI SDK in action and get inspired for your next project.
  • Join the community: Let us know what you’re building with the AI SDK in our GitHub Discussions.

We can't wait to see what you'll build next with Vercel AI SDK 3.3!

Contributors

Vercel AI SDK 3.3 is the result of the combined work of our core team at Vercel and many community contributors.

Special thanks for contributing merged pull requests:

gclark-eightfold, dynamicwebpaige, Und3rf10w, elitan, jon-spaeth, jeasonstudio, InfiniteCodeMonkeys, ruflair, MrMaina100, AntzyMo, samuelint, ian-pascoe, PawelKonie99, BrianHung, Ouvill, gmickel, developaul, elguarir, Kunoacc, florianheysen, rajuAhmed1705, suemor233, eden-chan, DraganAleksic99, karl-richter, rishabhbizzle, vladkampov, AaronFriel, theitaliandev, miguelvictor, jferrettiboke, dhruvvbhavsar, lmcgartland, PikiLee

Your feedback and contributions are invaluable as we continue to evolve the SDK.

以上がVercel AI SDKの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。