Vercel AI SDK
Vercel AI SDK
TypeScript 기반 Vercel AI SDK 앱에 Confident AI의 LLM 옵저버빌리티와 평가를 사용해볼게요. Vercel의 AI SDK는 어떤 LLM 프로바이더든 대상으로 AI 앱을 만드는 TypeScript 프레임워크예요. Confident AI는 OpenTelemetry 네이티브 트레이싱 SDK인 confident-trace로 AI SDK 앱을 몇 줄만으로 트레이싱하고 평가하게 해줘요.
출처: 문서
본문
개요
Vercel의 AI SDK는 모든 LLM 프로바이더를 대상으로 AI 앱을 만드는 TypeScript 프레임워크예요. Confident AI는 Confident AI의 OpenTelemetry 네이티브 트레이싱 SDK인 confident-trace를 사용해 AI SDK 앱을 몇 줄의 코드만으로 트레이싱하고 평가하게 해줘요.
여러분의 generateText와 streamText 호출은 전혀 바뀌지 않아요 — 모든 호출이 Observatory에서 에이전트, 스텝, 모델, 툴 스팬을 가진 트레이스로 나타나서, 앱이 무엇을 했는지, 토큰이 얼마나 들었는지 보고 평가를 실행할 수 있어요.
Node.js 22+와 AI SDK
>=7.0.93 <8이 필요해요. AI SDK 5/6의experimental_telemetryAPI는 현재 어댑터의 지원 범위 밖이에요; 이 통합을 쓰려면 AI SDK 7로 업그레이드하세요.
이 통합은 AI SDK 프로바이더를 통해 이뤄진 모델 호출을 트레이싱해요. AI SDK 밖에서 OpenAI 클라이언트를 직접 호출한다면 OpenAI 통합을 참고하세요 — 둘 다 같은
init()호출로 활성화돼요.
자동 계측 (Auto-Instrument)
EU 지역 사용자는 아래처럼 OTEL 엔드포인트를 EU 버전으로 설정해주세요:
export CONFIDENT_OTEL_ENDPOINT="https://eu.otel.confident-ai.com/v1/traces"
의존성 설치
필요한 패키지를 설치하려면 다음 명령을 실행해요. tsx는 TypeScript 소스를 직접 실행할 때만 필요해요:
npm install confident-trace 'ai@>=7.0.93 <8' @ai-sdk/openai@4
npm install -D tsx
API 키 설정
Confident AI에서 프로젝트 API 키를 받은 뒤, 이 예시가 사용하는 프로바이더 키와 함께 설정해요:
export CONFIDENT_API_KEY="<your-confident-project-key>"
export OPENAI_API_KEY="<your-openai-key>"
트레이싱 초기화
앱이 시작될 때, AI SDK 호출 전에 init()을 한 번 호출해요. 그게 전부예요 — generateText에 telemetry 옵션이나 트레이서를 전달할 필요 없어요. 지원되는 AI SDK 호출은 자동으로 계측돼요.
텍스트 생성 (Generate Text)
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { init } from "confident-trace";
const runtime = init();
try {
const result = await generateText({
model: openai("gpt-4.1-mini"),
prompt: "How to make the best coffee?",
});
console.log(result.text);
} finally {
await runtime.shutdown();
}
텍스트 스트리밍 (Stream Text)
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { init } from "confident-trace";
const runtime = init();
try {
const result = streamText({
model: openai("gpt-4.1-mini"),
prompt: "Invent a new holiday and describe its traditions.",
});
for await (const textPart of result.textStream) {
process.stdout.write(textPart);
}
} finally {
await runtime.shutdown();
}
flush나 shutdown 전에 스트림을 소비(또는 중단)하세요 — 스트리밍 호출의 스팬은 스트림이 끝나야 완료돼요. 스트리밍 응답을 반환하는 요청 핸들러에서는 공유 런타임을 종료하지 마세요; flush와 shutdown을 참고하세요.
툴 콜링 (Tool Calling)
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { init } from "confident-trace";
import { z } from "zod";
const runtime = init();
try {
const result = await generateText({
model: openai("gpt-4.1-mini"),
tools: {
weather: tool({
description: "Get the weather in a location",
inputSchema: z.object({
location: z.string().describe("The location to get the weather for"),
}),
execute: async ({ location }) => ({
location,
temperature: 72 + Math.floor(Math.random() * 21) - 10,
}),
}),
},
prompt: "What is the weather in San Francisco?",
});
console.log(result.text);
} finally {
await runtime.shutdown();
}
AI SDK 5/6에서 오셨나요? 더 이상 매 호출에
experimental_telemetry: { isEnabled: true, tracer }가 필요하지 않아요. AI SDK 7에서confident-trace는 Node가 로드할 때 SDK를 훅해요(바로 다음 단계의 preload가 하는 일이죠), 그래서 코드를 건드리지 않아도 지원되는 모든 호출에 텔레메트리가 켜져요. 번들된 애플리케이션은 아래 보이는 preload 훅을 보존해야 해요.
장기 실행 서버에서는 시작 시
init()을 한 번 호출하고, 요청 간 런타임을 재사용하며, 활성 요청이 끝난 뒤 한 번만 종료하세요 — 요청마다 하지 마세요. 한 번 초기화를 참고하세요.
애플리케이션 실행
confident-trace/register preload로 진입점 파일을 시작해 SDK가 Node가 로드할 때 ai 패키지를 훅할 수 있게 해요. init()은 내보내기를, preload는 계측을 처리해요 — 둘 다 필요해요:
# Running TypeScript source directly
node --import tsx --import confident-trace/register src/index.ts
# Running compiled JavaScript
node --import confident-trace/register dist/index.js
이것을 평소 시작 명령으로 만들려면 package.json 스크립트에 추가하세요:
{
"scripts": {
"start": "node --import confident-trace/register dist/index.js",
"dev": "node --import tsx --import confident-trace/register src/index.ts"
}
}
완료 ✅. Confident AI Observatory 안의 traces 페이지에서 트레이스를 확인할 수 있어요.
트레이스가 보이지 않는다면 거의 항상 두 가지 중 하나예요: 진입점을
--import confident-trace/register로 시작하지 않았거나(설정 경고가 표시되고 스팬이 없어요), 프로세스가runtime.shutdown()이 큐를 비우기 전에 종료된 거예요.runtime.getInstrumentationStatus()를 호출해 AI SDK가 실제로 훅됐는지 확인할 수 있어요. 자세한 내용은 troubleshooting을 참고하세요.
캡처되는 것
모든 스팬은 Vercel AI SDK 통합 라벨을 가지며, 호출 시점에 활성인 스팬 아래에 중첩돼요:
- 에이전트와 스텝 스팬 — 전체
generateText/streamText호출용 스팬 하나, 그리고 멀티스텝 실행에서는 스텝마다 하나 - 모델 호출 — 모델 이름과 토큰 사용량을 가진 LLM 스팬. 그래서 비용이 자동으로 표시돼요
- 툴 호출 — 툴 이름, 인풋, 아웃풋을 가진 툴 스팬
- 콘텐츠 — 프롬프트와 응답 텍스트. 크기 제한을 구성하지 않으면 크기 제한 없이 기본으로 켜져요. 마스킹과 콘텐츠 컨트롤 참고
추론(reasoning)과 바이너리 콘텐츠 파트는 표시되지만 내보내지지 않으며, 원시 요청 헤더, 임의의 SDK 메타데이터, 예외 메시지는 제외돼요. 임베딩, 리랭킹, 이미지/오디오 API는 이 통합 범위에 포함되지 않아요.
트레이스 스팬 속성 설정 (Set Trace Span Properties)
트레이스 컨텍스트를 사용해 호출이 시작되기 전에 아는 속성을 추가해요. 추가 스팬은 만들지 않아요; generateText()가 시작한 트레이스가 태그, 메타데이터, 유저 ID, 고객 ID를 상속해요.
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { init, traceContext } from "confident-trace";
init();
const result = await traceContext(
{
tags: ["support"],
metadata: { release: "2026-09" },
userId: "user-42",
customerId: "customer-7",
},
() => generateText({
model: openai("gpt-4.1-mini"),
prompt: "Explain OpenTelemetry in one sentence.",
}),
);
각 ID 옆에 선택적 표시 이름을 설정하려면 users와 customers를, 모든 지원 트레이스 속성과 업데이트 동작은 trace context를 참고하세요.
멀티턴 계측 (Instrumenting Multi-Turn)
하나의 Vercel AI SDK 진입점 호출이 이미 하나의 대화 턴일 때는 turn()이 필요하지 않아요 — 통합이 그 턴의 트레이스를 자동으로 만들어요. 경계를 직접 정의하고 싶을 때, 예를 들어 연속된 두 Vercel AI SDK 호출을 하나의 턴으로 묶고 싶을 때 turn()을 사용해요. 이후 턴에 같은 thread ID를 재사용해 하나의 대화로 묶어요.
import { init, turn } from "confident-trace";
init();
const answer = await turn({ name: "support-turn", threadId: "chat-42" }, async () => {
const context = await generateText({ model: openai("gpt-4.1-mini"), prompt: "Find the relevant account details." });
return generateText({ model: openai("gpt-4.1-mini"), prompt: `Summarize these details: ${context.text}` });
});
스레드 I/O, 턴 ID, 유저 ID는 threads를 참고하세요.
Vercel AI SDK 계측 비활성화
init()에 통합 식별자 목록을 전달해 해당 통합만 옵트인해요. Vercel AI SDK의 식별자는 TypeScript에서 "vercel-ai"이며, 생략하면 이 통합이 비활성화돼요. 빈 목록은 모든 자동 계측을 비활성화해요:
import { init } from "confident-trace";
init({ instrumentations: [] });
// Use ["vercel-ai"] to opt in; omit "vercel-ai" to disable it.
이것은 Confident AI의 자동 계측을 끄며, 초기화 후에 이뤄진 호출은 이 통합이 계측하지 않아요.
다음 단계
이제 AI SDK 앱이 트레이싱되니 더 깊이 파볼게요:
멀티턴 앱 계측
공유 threadId로 트레이스를 스레드로 묶어 전체 대화를 보고 평가할 수 있어요.
온라인 평가 (Online Evals)
트레이스, 스팬, 스레드가 Confident AI로 수집될 때 실시간으로 평가를 실행해 AI 품질을 모니터링해요.