>  기사  >  웹 프론트엔드  >  Vercel AI SDK

Vercel AI SDK

WBOY
WBOY원래의
2024-08-16 06:12:02444검색

추적, 다중 모달 첨부, 클라이언트로의 JSON 스트리밍 등을 소개합니다.

Vercel AI SDK는 JavaScript 및 TypeScript를 사용하여 AI 애플리케이션을 구축하기 위한 툴킷입니다. 통합 API를 통해 모든 언어 모델을 사용할 수 있으며 Next.js 및 Svelte와 같은 주요 웹 프레임워크에 대한 강력한 UI 통합을 제공합니다.

Vercel AI SDK 3.3에는 다음과 같은 네 가지 주요 기능이 도입되었습니다.

  • 추적(실험용): 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' });
}

추적 기능은 실험적이므로 Experiment_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 후크의 handlerSubmit() 핸들러에 Experiment_attachments를 추가했습니다.

Vercel AI SDK

useChat으로 이미지 및 텍스트 첨부 파일 보내기

이 실제 사례를 확인하고 템플릿을 배포하세요.

메시지와 함께 첨부 파일을 보내는 방법에는 두 가지가 있습니다. 하나는 FileList 개체를 제공하거나 URL 목록을 HandleSubmit 함수에 제공하는 것입니다.

파일 목록

FileList를 사용하면 파일 입력 요소를 사용하여 여러 파일을 메시지와 함께 첨부 파일로 보낼 수 있습니다. 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.