Raindrop Observability
Raindrop Observability
Raindrop는 AI 애플리케이션을 위한 옵저버빌리티를 제공해요. Raindrop의 AI SDK 통합은 generateText, streamText, generateObject, streamObject, 모델 호출, 도구 호출, 오류, 지연 시간, 토큰 사용량에 대한 이벤트와 trace를 기록해요.
Raindrop은 AI SDK v7 텔레메트리 인터페이스를 직접 지원하므로, OpenTelemetry 설정을 추가하지 않고도 registerTelemetry와 telemetry 옵션을 사용할 수 있어요.
출처: 문서
본문
설정
Raindrop AI SDK 통합을 설치해요:
npm install @raindrop-ai/ai-sdk
Raindrop write key를 설정해요 (Raindrop 대시보드에서 만들 수 있어요):
RAINDROP_WRITE_KEY="..."
그런 다음 애플리케이션 시작 시 한 번 Raindrop을 등록해요. raindrop()은 RAINDROP_WRITE_KEY를 자동으로 읽으며 @ai-sdk/otel이나 OpenTelemetry 설정이 필요 없어요:
import { registerTelemetry } from 'ai';
import { raindrop } from '@raindrop-ai/ai-sdk';
registerTelemetry(raindrop());
사용법
등록되면 AI SDK 호출이 자동으로 텔레메트리를 내보내요. functionId 같은 함수 수준 설정에는 telemetry 옵션을 사용해요:
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const { text } = await generateText({
model: openai('gpt-6-luna'),
prompt: 'Write a short welcome message for a new user.',
telemetry: {
functionId: 'welcome-message',
},
});
Raindrop은 userId가 준비되면 이벤트를 기록해요. 따라서 호출을 사용자에게 귀속시키려면 Raindrop context를 설정해요. 전역적으로 등록할 때(raindrop({ context: { userId } })) 또는 telemetry.integrations를 통해 요청별로 제공할 수 있어요 (아래 참고). userId가 없으면 Raindrop은 호출에 대한 trace를 여전히 기록하지만 이벤트는 내보내지 않아요.
요청별 Raindrop 컨텍스트
userId, convoId, eventName 같은 Raindrop 이벤트 필드가 요청마다 달라지면, 해당 호출에 대해 telemetry.integrations를 통해 Raindrop 통합을 전달해요:
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { raindrop } from '@raindrop-ai/ai-sdk';
const userId = 'user_123';
const convoId = 'chat_456';
const raindropTelemetry = raindrop({
context: { userId, convoId, eventName: 'support-chat' },
});
const { text } = await generateText({
model: openai('gpt-6-luna'),
prompt: 'Summarize the latest support ticket.',
telemetry: {
functionId: 'support-summary',
integrations: [raindropTelemetry],
},
});
await raindropTelemetry.flush();
호출별
telemetry.integrations는 해당 호출에 대해 전역 등록된 통합을 대체해요. 다른 텔레메트리 통합도 사용한다면 같은integrations배열에 포함해요.
스트리밍
스트리밍 호출도 동일하게 작동해요. AI SDK UI 라우트의 경우 v7 스트림 헬퍼를 반환하고 스트림이 끝나면 Raindrop을 flush해요:
import {
convertToModelMessages,
createUIMessageStreamResponse,
streamText,
toUIMessageStream,
type UIMessage,
} from 'ai';
import { openai } from '@ai-sdk/openai';
import { raindrop } from '@raindrop-ai/ai-sdk';
export async function POST(req: Request) {
const { id, messages, userId } = (await req.json()) as {
id: string;
messages: UIMessage[];
userId: string;
};
const raindropTelemetry = raindrop({
context: { userId, convoId: id, eventName: 'chat' },
});
const result = streamText({
model: openai('gpt-6-luna'),
messages: await convertToModelMessages(messages),
telemetry: {
functionId: 'chat-route',
integrations: [raindropTelemetry],
},
onEnd: async () => {
await raindropTelemetry.flush();
},
});
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
});
}
개인정보 보호 제어
recordInputs와 recordOutputs는 프롬프트와 응답이 추적 스팬(trace spans) 에 첨부될지 제어해요:
const result = await generateText({
model: openai('gpt-6-luna'),
prompt: 'Summarize this private document.',
telemetry: {
recordInputs: false,
recordOutputs: false,
},
});
이 플래그들은 스팬 속성에만 영향을 미쳐요. Raindrop의 이벤트 페이로드는 여전히 입력(마지막 사용자 메시지)과 출력(최종 텍스트)을 기록해요. 민감한 콘텐츠를 Raindrop에서 완전히 제외하려면 이벤트 캡처를 비활성화해 trace만 기록되게 해요:
registerTelemetry(raindrop({ events: { enabled: false } }));
프로바이더 옵션의 자격 증명 형태 값은 기본적으로 trace에서 제거돼요. traces.transformSpan 또는 traces.disableDefaultRedaction으로 커스텀할 수 있어요.
리소스
더 알아보기 (Learn more)
- 출처 문서: Raindrop Observability