> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aihubmix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gemini 네이티브 SDK 통합

> @google/genai SDK를 통해 AIHubMix에 연결하고, Interactions, Embeddings, Context Caching 등 Gemini API의 모든 네이티브 기능을 호출합니다

## 개요

Google은 `@google/genai`(JavaScript / TypeScript)와 `google-genai`(Python) 두 가지 공식 SDK를 제공하며, Gemini API의 모든 엔드포인트를 지원합니다. `baseUrl`을 AIHubMix 게이트웨이로 지정하고 플랫폼 API Key로 교체하면, 네이티브 SDK를 통해 Interactions, Embeddings, Context Caching 등 OpenAI 호환 레이어에서 지원하지 않는 기능을 비즈니스 코드 변경 없이 호출할 수 있습니다.

## 빠른 시작

### 설치

<CodeGroup>
  ```bash JavaScript / TypeScript theme={null}
  npm install @google/genai
  # >= 2.0.0 필요; latest 설치 권장
  ```

  ```bash Python theme={null}
  pip install -U google-genai
  # >= 2.0.0 필요
  ```
</CodeGroup>

<Warning>
  Interactions API는 `@google/genai` **>= 2.0.0** 또는 `google-genai` **>= 2.0.0**이 필요합니다. 낮은 버전의 SDK 요청은 Google 백엔드에서 거부됩니다(`legacy Interactions schema no longer supported`).
</Warning>

### 클라이언트 초기화

<CodeGroup>
  ```js JavaScript theme={null}
  import { GoogleGenAI } from "@google/genai";

  const ai = new GoogleGenAI({
    apiKey: "sk-***", // AIHubMix에서 생성한 API Key로 교체
    httpOptions: {
      baseUrl: "https://aihubmix.com/gemini",
    },
  });
  ```

  ```python Python theme={null}
  from google import genai

  client = genai.Client(
      api_key="sk-***",  # AIHubMix에서 생성한 API Key로 교체
      http_options={"base_url": "https://aihubmix.com/gemini"},
  )
  ```
</CodeGroup>

<Tip>
  `baseUrl`은 `https://aihubmix.com/gemini`으로 고정되며, OpenAI 호환 엔드포인트 `https://aihubmix.com/v1`과 다릅니다.
</Tip>

***

## Interactions API

Interactions는 Gemini의 차세대 추론 인터페이스로, 구조화된 `Interaction` 객체를 반환하며 텍스트 생성, 네이티브 이미지 생성(Nano Banana) 및 다단계 추론을 지원합니다. 현재 **동기 모드**(`interactions.create()`)가 지원되며, 비동기 모드(Background Interactions: `get` / `cancel` / `delete`)는 곧 제공될 예정입니다.

### 텍스트 생성

`interactions.create()`를 호출하여 추론을 시작하면, 반환된 `Interaction` 객체의 `output_text` 편의 속성을 통해 모델의 마지막 텍스트 출력을 직접 가져올 수 있습니다.

<CodeGroup>
  ```js JavaScript theme={null}
  const interaction = await ai.interactions.create({
    model: "gemini-3.5-flash",
    input: "용一句话解释量子计算",
  });

  console.log(interaction.output_text);
  console.log(interaction.usage);
  // { total_tokens, total_input_tokens, total_output_tokens, ... }
  ```

  ```python Python theme={null}
  interaction = client.interactions.create(
      model="gemini-3.5-flash",
      input="용一句话解释量子计算",
  )

  print(interaction.output_text)
  ```
</CodeGroup>

### 네이티브 이미지 생성

`response_format`을 통해 출력 모달리티를 이미지로 설정합니다. 반환된 `Interaction` 객체의 `output_image` 편의 속성의 `data` 필드에 Base64 인코딩된 이미지 데이터가 포함됩니다.

<Tip>
  * 추천 모델: `gemini-3.1-flash-image`(Nano Banana 2, 범용 이미지 생성 모델).
  * `response_modalities` 값은 반드시 **소문자** `['text', 'image']`여야 합니다. 대문자는 `generateContent` API의 형식이며, Interactions API에서는 `400`을 반환합니다.
  * `delivery: 'inline'`을 전달하지 마세요(`400 Image delivery mode is not supported`). Interactions API는 기본적으로 inline 방식으로 이미지 데이터를 반환합니다.
</Tip>

**`response_format` 매개변수:**

| 필드             | 설명     | 가능한 값                                     |
| -------------- | ------ | ----------------------------------------- |
| `type`         | 출력 유형  | `"image"`                                 |
| `aspect_ratio` | 종횡비    | `"1:1"` `"3:4"` `"4:3"` `"9:16"` `"16:9"` |
| `image_size`   | 출력 해상도 | `"1K"` `"2K"` `"4K"`                      |
| `mime_type`    | 이미지 형식 | `"image/png"` `"image/jpeg"`              |

<CodeGroup>
  ```js JavaScript theme={null}
  import fs from "node:fs";

  const interaction = await ai.interactions.create({
    model: "gemini-3.1-flash-image",
    input: "A translucent banana-shaped glass lamp on a white desk, soft studio lighting.",
    response_modalities: ["text", "image"],
    response_format: { type: "image", aspect_ratio: "1:1", image_size: "1K" },
  });

  // 방법 1: output_image 편의 속성(마지막 생성 이미지 가져오기)
  if (interaction.output_image?.data) {
    fs.writeFileSync("output.png", Buffer.from(interaction.output_image.data, "base64"));
  }

  // 방법 2: steps 순회, 다단계 혼합 출력에 적합
  for (const step of interaction.steps ?? []) {
    for (const block of step.content ?? []) {
      if (block.type === "image" && block.data) {
        fs.writeFileSync("output.png", Buffer.from(block.data, "base64"));
      }
    }
  }
  ```

  ```python Python theme={null}
  import base64

  interaction = client.interactions.create(
      model="gemini-3.1-flash-image",
      input="A translucent banana-shaped glass lamp on a white desk, soft studio lighting.",
      response_format={
          "type": "image",
          "aspect_ratio": "1:1",
          "image_size": "1K",
      },
  )

  # output_image 편의 속성
  if interaction.output_image:
      with open("output.png", "wb") as f:
          f.write(base64.b64decode(interaction.output_image.data))
  ```
</CodeGroup>

### 스트리밍 출력

`stream: true`를 전달하여 Server-Sent Events(SSE) 스트리밍을 활성화합니다. 이벤트는 다음 순서로 도착합니다:

```
interaction.created → status_update → step.start → step.delta → step.stop → interaction.completed
```

증분 텍스트는 `event.delta.text`를 통해 가져오며, 이벤트 유형 필드는 `event_type`입니다.

```js JavaScript theme={null}
const stream = await ai.interactions.create({
  model: "gemini-3.5-flash",
  input: "写一首关于月亮的俳句",
  stream: true,
});

for await (const event of stream) {
  if (event.event_type === "step.delta" && event.delta?.type === "text") {
    process.stdout.write(event.delta.text);
  }
  if (event.event_type === "interaction.completed") {
    console.log("\nUsage:", JSON.stringify(event.interaction?.usage));
  }
}
```

***

## Embeddings

`embedContent` 엔드포인트를 통해 텍스트 또는 멀티모달 콘텐츠의 벡터 표현(embedding)을 가져옵니다.

<Tip>
  OpenAI 호환 `/v1/embeddings` 엔드포인트가 필요한 경우, [벡터 임베딩](/ko/api/EBD)을 참조하세요.
</Tip>

### embedContent

<CodeGroup>
  ```js JavaScript theme={null}
  const response = await ai.models.embedContent({
    model: "gemini-embedding-2-preview",
    contents: "What is the meaning of life?",
    config: {
      outputDimensionality: 768, // 선택 사항: 출력 차원 지정(128-3072), 기본값 3072
    },
  });

  console.log("dimensions:", response.embeddings[0].values.length); // 768
  ```

  ```python Python theme={null}
  from google.genai import types

  result = client.models.embed_content(
      model="gemini-embedding-2-preview",
      contents="What is the meaning of life?",
      config=types.EmbedContentConfig(
          output_dimensionality=768,  # 선택 사항: 출력 차원 지정(128-3072), 기본값 3072
      ),
  )

  print(f"dimensions: {len(result.embeddings[0].values)}")  # 768
  ```
</CodeGroup>

### 배치 Embeddings 가져오기

`embedContent`의 `contents` 매개변수에 `Content` 배열을 전달하면, 한 번의 호출로 여러 텍스트의 embedding을 가져올 수 있습니다:

```js JavaScript theme={null}
const response = await ai.models.embedContent({
  model: "gemini-embedding-2-preview",
  contents: [
    { parts: [{ text: "첫 번째 텍스트" }] },
    { parts: [{ text: "두 번째 텍스트" }] },
  ],
});

console.log("count:", response.embeddings.length); // 2
for (const emb of response.embeddings) {
  console.log("dimensions:", emb.values.length);
}
```

### 사용 가능한 모델 및 매개변수

| 모델                           | 입력 토큰 상한 | 기본 출력 차원      | 입력 모달리티                 | 설명                                        |
| ---------------------------- | -------- | ------------- | ----------------------- | ----------------------------------------- |
| `gemini-embedding-2-preview` | 8,192    | 3,072(권장 768) | 텍스트, 이미지, 비디오, 오디오, PDF | 최신 멀티모달 임베딩 모델, `outputDimensionality` 지원 |
| `gemini-embedding-001`       | 2,048    | 3,072         | 텍스트만                    | 이전 세대 텍스트 임베딩 모델, `taskType` 지원           |

`gemini-embedding-001`은 `config.taskType`을 통해 임베딩 용도를 지정하여 특정 다운스트림 작업의 벡터 품질을 최적화할 수 있습니다:

| `taskType`            | 용도              |
| --------------------- | --------------- |
| `SEMANTIC_SIMILARITY` | 의미 유사도 계산       |
| `RETRIEVAL_DOCUMENT`  | 문서 인덱싱(검색 대상 측) |
| `RETRIEVAL_QUERY`     | 검색 쿼리(검색 측)     |
| `CLASSIFICATION`      | 텍스트 분류          |
| `CLUSTERING`          | 텍스트 클러스터링       |

<Note>
  `gemini-embedding-2-preview`는 `taskType` 매개변수를 지원하지 않으며, 대신 프롬프트에서 접두사를 통해 작업 유형을 지정합니다(예: `search_query: ...` 또는 `search_document: ...`).
</Note>

***

## Context Caching(명시적 캐싱)

명시적 캐싱(Explicit Caching)을 통해 개발자는 `CachedContent` 객체를 수동으로 생성, 조회, 참조 및 삭제할 수 있으며, 여러 요청 간에 동일한 긴 컨텍스트를 재사용해야 하는 시나리오에 적합합니다. [암시적 캐싱](/ko/api/Gemini-Guides#컨텍스트-캐싱)과 달리, 명시적 캐싱은 애플리케이션 측에서 수명 주기를 주도적으로 관리합니다.

<Note>
  명시적 캐싱은 `generateContent` API에만 적용됩니다. Interactions API는 암시적 캐싱만 지원합니다.
</Note>

<Tip>
  스토리지 가격이 설정되지 않은 모델은 게이트웨이에서 캐시 생성 요청을 차단합니다(`context caching is not available for model`). 이는 스토리지 비용 누락을 방지하기 위함입니다. 주요 모델(gemini-2.5-flash, gemini-2.5-pro 등)은 모두 설정되어 있습니다.
</Tip>

### CachedContent 생성

`caches.create()`를 통해 캐시를 생성합니다. `ttl`(Time-To-Live)로 캐시 유효 기간을 제어하며, 만료 후 자동으로 삭제됩니다.

<CodeGroup>
  ```js JavaScript theme={null}
  const longDocument = "반복적으로 참조해야 하는 긴 텍스트 내용...".repeat(500);

  const cache = await ai.caches.create({
    model: "gemini-3.5-flash",
    config: {
      contents: longDocument,
      ttl: "300s",
    },
  });

  console.log("CachedContent name:", cache.name);
  // 형식: cachedContents/xxx
  ```

  ```python Python theme={null}
  long_document = "반복적으로 참조해야 하는 긴 텍스트 내용..." * 500

  cache = client.caches.create(
      model="gemini-3.5-flash",
      config={
          "contents": long_document,
          "ttl": "300s",
      },
  )

  print(f"CachedContent name: {cache.name}")
  ```
</CodeGroup>

### generateContent에서 캐시 참조

`cache.name`을 `cachedContent`(JS) 또는 `cached_content`(Python) 매개변수에 전달하면 추론 시 캐시를 히트할 수 있습니다. 히트된 토큰 수는 `usageMetadata.cachedContentTokenCount`에 반영됩니다.

<CodeGroup>
  ```js JavaScript theme={null}
  const response = await ai.models.generateContent({
    model: "gemini-3.5-flash",
    contents: "위 문서의 핵심 관점을 요약해 주세요",
    config: { cachedContent: cache.name },
  });

  console.log(response.text);
  console.log("cached tokens:", response.usageMetadata?.cachedContentTokenCount);
  ```

  ```python Python theme={null}
  response = client.models.generate_content(
      model="gemini-3.5-flash",
      contents="위 문서의 핵심 관점을 요약해 주세요",
      config={"cached_content": cache.name},
  )

  print(response.text)
  print(f"cached tokens: {response.usage_metadata.cached_content_token_count}")
  ```
</CodeGroup>

### 조회 및 삭제

<CodeGroup>
  ```js JavaScript theme={null}
  // CachedContent 메타데이터 조회
  const info = await ai.caches.get({ name: cache.name });
  console.log("model:", info.model, "expireTime:", info.expireTime);

  // 캐시 삭제
  await ai.caches.delete({ name: cache.name });
  ```

  ```python Python theme={null}
  # CachedContent 메타데이터 조회
  info = client.caches.get(name=cache.name)
  print(f"model: {info.model}  expire_time: {info.expire_time}")

  # 캐시 삭제
  client.caches.delete(name=cache.name)
  ```
</CodeGroup>

***

## 지원 기능 매트릭스

| 기능                                       | 상태 | 설명                                                 |
| ---------------------------------------- | -- | -------------------------------------------------- |
| `generateContent`                        | ✅  | 비스트리밍 + 스트리밍                                       |
| `systemInstruction` / `generationConfig` | ✅  | temperature, maxOutputTokens 등                     |
| Structured Output(`responseSchema`)      | ✅  | JSON mode                                          |
| Function Calling                         | ✅  | `functionDeclarations` 도구 선언                       |
| `thinkingConfig`                         | ✅  | 사고 과정 출력                                           |
| 멀티모달 입력                                  | ✅  | 이미지 / 오디오 / 비디오 / PDF via `inlineData` + Files API |
| Google Search Grounding                  | ✅  | 검색 증강                                              |
| `countTokens`                            | ✅  | 토큰 카운팅                                             |
| Imagen(`generateImages`)                 | ✅  | Imagen 3 이미지 생성                                    |
| Veo(`generateVideos`)                    | ✅  | 비디오 생성                                             |
| TTS                                      | ✅  | 음성 합성 출력                                           |
| Files API                                | ✅  | 대용량 파일 업로드 및 참조                                    |
| Interactions API                         | ✅  | 차세대 추론 인터페이스(텍스트 + Nano Banana 이미지 생성)             |
| Embeddings(`embedContent`)               | ✅  | 네이티브 벡터 임베딩                                        |
| Context Caching CRUD                     | ✅  | 명시적 캐시 관리                                          |
| Live API(WebSocket)                      | ❌  | 아직 지원되지 않음                                         |

***

## 자주 묻는 질문

<AccordionGroup>
  <Accordion title="interactions.create() 호출 시 legacy schema 오류 발생">
    SDK 버전이 너무 낮습니다. `@google/genai`는 >= 2.0.0, `google-genai`는 >= 2.0.0이어야 합니다. `npm install @google/genai@latest` 또는 `pip install -U google-genai`를 실행하여 최신 버전으로 업그레이드하세요.
  </Accordion>

  <Accordion title="모델이 404 Not Found를 반환">
    일부 초기 모델 이름(예: `gemini-2.5-flash-image-preview`)은 Interactions API에서 폐기되었습니다. `gemini-3.1-flash-image`(Nano Banana 2)와 같은 현재 사용 가능한 모델 식별자를 사용하세요. `generateContent` API는 영향을 받지 않습니다.
  </Accordion>

  <Accordion title="response_modalities가 400 Bad Request 반환">
    Interactions API의 `response_modalities` 값은 소문자(`"text"`, `"image"`)여야 합니다. 대문자 `"TEXT"` / `"IMAGE"`는 `generateContent` API의 형식이며, Interactions API에서는 허용되지 않습니다.
  </Accordion>

  <Accordion title="vertexai: true를 사용할 수 있나요?">
    사용할 수 없습니다. SDK의 `vertexai: true` 모드는 GCP OAuth + project / location 매개변수가 필요하며, `apiKey`와 상호 배타적입니다(SDK가 `Project/location and API key are mutually exclusive`를 throw합니다). AIHubMix를 통해 연결할 때는 Gemini Developer API 형태를 사용하면 되며, 백엔드가 자동으로 라우팅합니다.
  </Accordion>

  <Accordion title="캐시 생성 시 context caching is not available for model 오류">
    게이트웨이는 스토리지 가격이 설정되지 않은 모델에 대해 `caches.create()` 요청을 차단하여 스토리지 비용 누락을 방지합니다. 주요 모델(gemini-2.5-flash, gemini-2.5-pro 등)은 모두 설정되어 있습니다. 이 오류가 발생하면 해당 모델이 명시적 캐싱을 지원하는지 확인하세요.
  </Accordion>
</AccordionGroup>

***

마지막 업데이트: 2026-07-07
