C.W.K.
Stream
Lesson 03 of 04 · published

Chat, 에러, Multimodal

~14 min · typescript, chat, errors, multimodal

Level 0Spark
0 XP0/35 lessons0/10 achievements
0/140 XP to next level140 XP to go0% complete

TypeScript 의 chat session

Python 과 같은 모양. ai.chats.create({...}) 가 chat 객체 반환, sendMessage 로 호출. History 는 in-memory 유지.

에러는 ApiError 로 옴

TS SDK 가 API 에러를 ApiError 로 wrap, name: 'ApiError'. instanceof 가 module 경계에서 fragile 할 수 있으니 name 으로 체크하고 e.statuse.message 읽어.

Multimodal 은 createUserContent + createPartFromUri 사용

한 user turn 에 image/file 을 text 와 함께 보내려면 헬퍼 함수 사용. 옳은 parts 구조 만들어줌.

Code

Multi-turn chat·typescript
const chat = ai.chats.create({
  model: 'gemini-2.5-flash',
  config: {
    systemInstruction: 'You are a precise but warm tutor.',
  },
});

const r1 = await chat.sendMessage({ message: 'Tell me a fact about octopuses.' });
console.log(r1.text);

const r2 = await chat.sendMessage({ message: 'Now relate that to neural networks.' });
console.log(r2.text);

// Streaming chat
const stream = await chat.sendMessageStream({ message: 'And a haiku?' });
for await (const chunk of stream) {
  if (chunk.text) process.stdout.write(chunk.text);
}
내성 있는 에러 핸들링·typescript
import { ApiError } from '@google/genai';

async function robustGenerate(prompt: string, maxRetries = 4) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await ai.models.generateContent({
        model: 'gemini-2.5-flash',
        contents: prompt,
      });
    } catch (e: any) {
      if (e?.name === 'ApiError') {
        if (e.status === 429 || (e.status >= 500 && e.status < 600)) {
          // Rate limit or server error — back off and retry
          await new Promise(r => setTimeout(r, Math.min(2 ** attempt, 30) * 1000));
          continue;
        }
        // 4xx other than 429 — your fault, don't retry
        throw e;
      }
      throw e;
    }
  }
  throw new Error(`Gave up after ${maxRetries} retries`);
}
Multimodal — image + text·typescript
import { createUserContent, createPartFromUri } from '@google/genai';

// 1. Upload via File API
const uploaded = await ai.files.upload({
  file: 'photo.jpg',
  config: { mimeType: 'image/jpeg' },
});

// 2. Wait for processing if needed
// (large videos go through PROCESSING state)

// 3. Reference in a generateContent call
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    createUserContent([
      'Describe this image in two sentences:',
      createPartFromUri(uploaded.uri!, uploaded.mimeType!),
    ]),
  ],
});
console.log(response.text);

External links

Exercise

작은 TypeScript chat CLI 만들어: 라인 읽고 streaming chat 으로 보냄, stdout 에 render, history 를 JSONL 파일에 persist. API 호출은 robustGenerate 로 wrap 해서 429 가 loop 죽이지 않게. JSONL 에서 reload 해서 chat 이 restart 가로질러 유지되는지 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.