모델 제공자(클라우드)

ADK-Rust은 adk-model 크레이트를 통해 여러 클라우드 LLM 제공자를 지원합니다. 모든 제공자는 Llm 트레이트를 구현하므로 에이전트에서 서로 교체하여 사용할 수 있습니다.

개요

┌─────────────────────────────────────────────────────────────────────┐
│                     Cloud Model Providers                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   • Gemini (Google)    ⭐ Default    - Multimodal, large context    │
│   • OpenAI (GPT-5)    🔥 Popular    - Best ecosystem               │
│   • Anthropic (Claude) 🧠 Smart      - Best reasoning               │
│   • DeepSeek           💭 Thinking   - Chain-of-thought, cheap      │
│   • Groq               ⚡ Ultra-Fast  - Fastest inference           │
│                                                                     │
│   For local/offline models, see:                                    │
│   • Ollama     → ollama.md                                          │
│   • mistral.rs → mistralrs.md                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

빠른 비교

제공업체최적 용도속도비용주요 기능
Gemini일반적인 사용⚡⚡⚡💰멀티모달, 대규모 컨텍스트, 사고
OpenAI신뢰성⚡⚡💰💰최고의 생태계
Anthropic복잡한 추론⚡⚡💰💰가장 안전하고 신중함
DeepSeek사고 연쇄⚡⚡💰사고 모드, 저렴함
Groq속도 중시⚡⚡⚡⚡💰가장 빠른 추론

1단계: 설치

필요한 공급자를 Cargo.toml에 추가합니다:

[dependencies]
# Pick one or more providers:
adk-model = { version = "2.1.0", features = ["gemini"] }        # Google Gemini (default)
adk-model = { version = "2.1.0", features = ["openai"] }        # OpenAI GPT-5
adk-model = { version = "2.1.0", features = ["anthropic"] }     # Anthropic Claude
adk-model = { version = "2.1.0", features = ["deepseek"] }      # DeepSeek
adk-model = { version = "2.1.0", features = ["groq"] }          # Groq (ultra-fast)

# Or all cloud providers at once:
adk-model = { version = "2.1.0", features = ["all-providers"] }

2단계: API 키 설정

export GOOGLE_API_KEY="your-key"      # Gemini
export OPENAI_API_KEY="your-key"      # OpenAI
export ANTHROPIC_API_KEY="your-key"   # Anthropic
export DEEPSEEK_API_KEY="your-key"    # DeepSeek
export GROQ_API_KEY="your-key"        # Groq

스키마 정규화

각 공급자는 요청 시 MCP 도구 스키마를 자동으로 정규화합니다. 별도로 수행할 작업은 없습니다 — 투명하게 작동합니다. 하지만 내부적으로는 다음과 같은 작업이 수행됩니다:

제공자스키마 어댑터동작
GeminiGeminiSchemaAdapter공격적: $ref을 해결하고, 결합자를 축약하며, 지원되지 않는 키워드를 제거함
OpenAI (엄격)OpenAiStrictSchemaAdapter구조를 유지하고 additionalProperties: false을 추가함
OpenAIOpenAiSchemaAdapter최소한의 안전한 수정
AnthropicAnthropicSchemaAdapter거의 그대로 통과
DeepSeekGenericSchemaAdapter보수적인 안전 변환
OllamaGenericSchemaAdapter보수적인 안전 변환

어댑터에 프로그래밍 방식으로 Llm 트레이트를 통해 액세스합니다:

use adk_core::{Llm, SchemaAdapter};

let adapter = model.schema_adapter();
let normalized = adapter.normalize_schema(raw_schema);

전체 문서는 스키마 정규화를 참조하세요.


Gemini (Google) ⭐ 기본값

적합한 용도: 범용 작업, 멀티모달 작업, 대규모 문서

주요 특징:

  • 🖼️ 기본 멀티모달 지원(이미지, 동영상, 오디오, PDF)
  • 📚 최대 2M 토큰 컨텍스트 창
  • 🧠 사고 모드: 사고 서명을 지원하는 수준 기반(Gemini 3) 및 예산 기반(Gemini 2.5)
  • 💰 경쟁력 있는 가격
  • ⚡ 빠른 추론

전체 작동 예제

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = GeminiModel::new(&api_key, "gemini-3.7-flash")?;

    let agent = LlmAgentBuilder::new("gemini_assistant")
        .description("Gemini-powered assistant")
        .instruction("You are a helpful assistant powered by Google Gemini. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

사용 가능한 모델

모델설명컨텍스트
gemini-3.7-flash기본 균형형 에이전트 모델1M 토큰
gemini-3.6-flash이전 균형형 세대1M 토큰
gemini-3.5-flash-lite비용 효율적인 라우팅 및 대규모 작업1M 토큰
gemini-3.1-pro-preview고급 미리보기 추론2M 토큰

사고 모드

Gemini 3 모델은 수준 기반 사고를 지원하는 반면, Gemini 2.5는 예산 기반 사고를 사용합니다. 함수 호출과 함께 사고 모드를 사용할 때 Gemini 2.5+ 및 3.x 모델은 이후 턴에서 추론 컨텍스트를 보존하기 위해 다시 반환해야 하는 thoughtSignature 값을 반환합니다. ADK-Rust가 이를 자동으로 처리합니다 — 서명이 존재하면 직렬화되고, None이면 생략됩니다.

use adk_gemini::{Gemini, ThinkingLevel};

// Gemini 3: level-based thinking
let response = client.generate_content()
    .with_user_message("Solve this step by step")
    .with_thinking_level(ThinkingLevel::High)
    .with_thoughts_included(true)
    .execute().await?;

// Gemini 2.5: budget-based thinking
let response = client.generate_content()
    .with_user_message("Solve this step by step")
    .with_thinking_budget(2048)
    .with_thoughts_included(true)
    .execute().await?;

출력 예시

👤 User: What's in this image? [uploads photo of a cat]

🤖 Gemini: I can see a fluffy orange tabby cat sitting on a windowsill. 
The cat appears to be looking outside, with sunlight illuminating its fur. 
It has green eyes and distinctive striped markings typical of tabby cats.

적합한 용도: 프로덕션 앱, 안정적인 성능, 폭넓은 기능

주요 특징:

  • 🏆 업계 표준
  • 🔧 뛰어난 도구/함수 호출
  • 📖 최고의 문서 및 생태계
  • 🎯 일관되고 예측 가능한 출력
  • 📋 JSON 스키마 적용을 통한 구조화된 출력
  • 🧠 GPT-5.6 추론 모델을 위한 추론 수준 제어
  • 🆕 Responses API — 추론 요약, 기본 제공 도구 및 서버 측 상태를 지원하는 /v1/responses 전용 클라이언트

완전한 작동 예시

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("OPENAI_API_KEY")?;
    let model = OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5.6-terra"))?;

    let agent = LlmAgentBuilder::new("openai_assistant")
        .description("OpenAI-powered assistant")
        .instruction("You are a helpful assistant powered by OpenAI GPT-5. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

구조화된 출력(JSON 스키마)

OpenAI는 output_schema를 통해 보장된 JSON 출력을 지원합니다. ADK-Rust는 이를 OpenAI의 response_format API에 자동으로 연결합니다.

use adk_rust::prelude::*;
use serde_json::json;
use std::sync::Arc;

let model = OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5.6-terra"))?;

let agent = LlmAgentBuilder::new("data_extractor")
    .model(Arc::new(model))
    .instruction("Extract person information from the text.")
    .output_schema(json!({
        "type": "object",
        "properties": {
            "name": { "type": "string" },
            "age": { "type": "number" },
            "email": { "type": "string" }
        },
        "required": ["name", "age"]
    }))
    .build()?;

// Response is guaranteed to be valid JSON matching the schema

중첩된 객체와 함께 엄격한 모드를 사용하려면 각 수준에 additionalProperties: false를 포함하세요.

.output_schema(json!({
    "type": "object",
    "properties": {
        "title": { "type": "string" },
        "metadata": {
            "type": "object",
            "properties": {
                "author": { "type": "string" },
                "tags": { "type": "array", "items": { "type": "string" } }
            },
            "required": ["author"],
            "additionalProperties": false  // Required for nested objects
        }
    },
    "required": ["title", "metadata"],
    "additionalProperties": false  // Auto-injected at root level
}))

추론 수준

OpenAI 추론 모델의 경우 모델이 적용하는 추론 수준을 제어할 수 있습니다.

use adk_model::openai::{OpenAIClient, OpenAIConfig, OpenAIReasoningEffort};

let config = OpenAIConfig::new(&api_key, "gpt-5.6-terra");
let model = OpenAIClient::new_with_reasoning_effort(
    config,
    OpenAIReasoningEffort::XHigh,
)?;

전체 어휘는 None, Minimal, Low, Medium, High, XHigh, 및 Max이며, 사용 가능 여부는 모델과 API에 따라 달라집니다. GPT-5.6 Chat Completions는 최대 XHigh까지 지원하며, Max에는 OpenAIResponsesClient을 사용하세요. 기존의 3값 ReasoningEffort API은 이전 버전과의 호환성을 위해 계속 사용할 수 있습니다.

OpenAI-호환 로컬 APIs

로컬 서버(Ollama, vLLM, LM Studio)에 연결하려면 OpenAIConfig::compatible()을 사용하세요.

// Ollama exposes OpenAI-compatible API at /v1
let config = OpenAIConfig::compatible(
    "not-needed",                      // API key (ignored by Ollama)
    "http://localhost:11434/v1",       // Base URL
    "llama3.2"                         // Model name
);
let model = OpenAIClient::new(config)?;

참고: 구조화된 출력(output_schema)을 사용하려면 백엔드 지원이 필요합니다. 네이티브 OpenAI는 이를 완전히 지원하지만, 로컬 서버는 지원이 제한적일 수 있습니다.

OpenAI-호환 엔드포인트를 통한 Gemini

Gemini 모델은 https://generativelanguage.googleapis.com/v1beta/openai의 OpenAI Chat Completions 와이어 형식을 통해 접근할 수 있습니다. openai 기능에 포함된 OpenAICompatibleConfig::gemini(...) 프리셋을 GEMINI_API_KEY와 함께 사용하면, 다른 모든 프로바이더에 사용하는 것과 동일한 OpenAI-호환 클라이언트를 통해 Gemini를 실행할 수 있습니다.

use adk_model::openai_compatible::{OpenAICompatible, OpenAICompatibleConfig};

let api_key = std::env::var("GEMINI_API_KEY")?;
let model = OpenAICompatible::new(
    OpenAICompatibleConfig::gemini(api_key, "gemini-3.5-flash"),
)?;

이 경로는 채팅, 스트리밍, 함수 호출, 구조화된 출력 및 추론 수준(OpenAI의 reasoning_effort는 Gemini의 사고 수준/예산에 매핑됨)을 지원합니다. include_thoughts을 사용하는 thinking_config이나 cached_content 같은 Gemini 전용 옵션은 요청의 extensions["openai"]["extra_body"]["google"] 맵을 통해 전달되며, 클라이언트는 이를 요청 본문에 변경 없이 병합합니다.

GeminiModel 대신 이를 사용해야 하는 경우: 네이티브 Gemini 기능 (서버 측 도구, Interactions API, 네이티브 ThinkingConfig, 멀티모달 중심의 사용 편의성)이 필요하다면 GeminiModel를 우선 사용하세요. 프로바이더 전반에서 단일하고 통일된 클라이언트를 사용하려는 경우에는 OpenAI-호환 프리셋을 사용하세요.

예시(GEMINI_API_KEY 또는 GOOGLE_API_KEY 필요):

# Direct client: chat, reasoning effort, extra_body thinking, streaming,
# function calling, structured output.
cargo run -p adk-model --features openai --example gemini_openai_compat

# The same compat client driving a normal LlmAgent in a Runner.
# (Lives in adk-agent: it exercises the agent layer, which sits above adk-model.)
cargo run -p adk-agent --example gemini_openai_compat_agent

레거시 추론 수준 API

기존의 3단계 ReasoningEffort API는 호환성을 위해 계속 사용할 수 있습니다.

use adk_model::openai::{OpenAIClient, OpenAIConfig, ReasoningEffort};

let config = OpenAIConfig::new(&api_key, "gpt-5")
    .with_reasoning_effort(ReasoningEffort::High);
let model = OpenAIClient::new(config)?;

사용 가능한 수준: Low(가장 빠름), Medium(균형 잡힘), High(가장 철저함).

사용 가능한 모델

모델설명컨텍스트
gpt-5.6-terra프로덕션 에이전트를 위한 균형 잡힌 기본 모델256K 토큰
gpt-5.6-sol최고급 추론 및 코딩256K 토큰
gpt-5.6-luna비용 효율적인 대규모 작업 부하128K 토큰
gpt-5.6플래그십 별칭256K 토큰

예시 출력

👤 User: Write a haiku about Rust programming

🤖 GPT-5: Memory so safe,
Ownership guards every byte—
Compiler, my friend.

Anthropic (Claude) 🧠 스마트

적합한 용도: 복잡한 추론, 안전이 중요한 앱, 긴 문서

주요 특징:

  • 🧠 탁월한 추론 능력
  • 🛡️ 안전성에 가장 중점을 둠
  • 📚 200K 토큰 컨텍스트
  • ✍️ 뛰어난 글쓰기 품질

완전한 작동 예제

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("ANTHROPIC_API_KEY")?;
    let model = AnthropicClient::new(AnthropicConfig::new(&api_key, "claude-sonnet-5"))?;

    let agent = LlmAgentBuilder::new("anthropic_assistant")
        .description("Anthropic-powered assistant")
        .instruction("You are a helpful assistant powered by Anthropic Claude. Be concise and thoughtful.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

사용 가능한 모델

모델설명컨텍스트
claude-sonnet-5균형 잡힌 지능과 비용 (기본값)1M 토큰
claude-opus-5플래그십 성능1M 토큰
claude-fable-5프리미엄 창작 및 장문 작업1M 토큰
claude-haiku-4-5비용 효율적인 이전 세대200K 토큰

예시 출력

👤 User: Explain quantum entanglement to a 10-year-old

🤖 Claude: Imagine you have two magic coins. When you flip them, they always 
land the same way - both heads or both tails - even if one coin is on Earth 
and the other is on the Moon! Scientists call this "entanglement." The coins 
are connected in a special way that we can't see, like invisible best friends 
who always make the same choice at the exact same time.

DeepSeek 💭 사고

적합한 용도: 복잡한 문제 해결, 수학, 코딩, 추론 작업

주요 특징:

  • 💭 사고 모드 - 사고 과정 표시
  • 💰 GPT-4보다 매우 비용 효율적(10배 저렴)
  • 🔄 반복되는 접두사를 위한 컨텍스트 캐싱
  • 🧮 수학 및 코딩에 강함

완전한 작동 예제

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("DEEPSEEK_API_KEY")?;
    
    // Standard chat model
    let model = DeepSeekClient::chat(&api_key)?;
    
    // OR: Reasoning model with thinking mode
    // let model = DeepSeekClient::reasoner(&api_key)?;

    let agent = LlmAgentBuilder::new("deepseek_assistant")
        .description("DeepSeek-powered assistant")
        .instruction("You are a helpful assistant powered by DeepSeek. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

사용 가능한 모델

모델설명특수 기능
deepseek-v4-flash현재 기본값빠른 범용 에이전트
deepseek-v4-pro고급 추론복잡한 에이전트 작업

추론기(사고 모드 포함) 예시 출력

👤 User: What's 17 × 23?

🤖 DeepSeek: <thinking>
Let me break this down:
17 × 23 = 17 × (20 + 3)
       = 17 × 20 + 17 × 3
       = 340 + 51
       = 391
</thinking>

The answer is 391.

Groq ⚡ 초고속

최적의 용도: 실시간 애플리케이션, 챗봇, 속도가 중요한 작업

주요 특징:

  • 가장 빠른 추론 - 경쟁 제품보다 10배 빠름
  • 🔧 LPU(Language Processing Unit) 기술
  • 💰 경쟁력 있는 가격
  • 🦙 LLaMA, Mixtral, Gemma 모델 실행

완전히 작동하는 예제

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("GROQ_API_KEY")?;
    let model = GroqClient::new(GroqConfig::gpt_oss_120b(&api_key))?;

    let agent = LlmAgentBuilder::new("groq_assistant")
        .description("Groq-powered assistant")
        .instruction("You are a helpful assistant powered by Groq. Be concise and fast.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

사용 가능한 모델

모델메서드설명
openai/gpt-oss-120bGroqClient::new(GroqConfig::gpt_oss_120b(key))현재 프로덕션 기본값
openai/gpt-oss-20bGroqClient::new(GroqConfig::new(key, "openai/gpt-oss-20b"))더 저렴한 GPT-OSS 모델
모든 모델GroqClient::new(GroqConfig::new(key, "model"))사용자 지정 모델

예시 출력

👤 User: Quick! Name 5 programming languages

🤖 Groq (in 0.2 seconds): 
1. Rust
2. Python
3. JavaScript
4. Go
5. TypeScript

제공자 전환

모든 제공자는 동일한 Llm 트레이트를 구현하므로 전환이 쉽습니다.

use adk_agent::LlmAgentBuilder;
use std::sync::Arc;

// Just change the model - everything else stays the same!
let model: Arc<dyn adk_core::Llm> = Arc::new(
    // Pick one:
    // GeminiModel::new(&api_key, "gemini-3.7-flash")?
    // OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5.6-terra"))?
    // AnthropicClient::new(AnthropicConfig::new(&api_key, "claude-sonnet-5"))?
    // DeepSeekClient::chat(&api_key)?
    // GroqClient::new(GroqConfig::gpt_oss_120b(&api_key))?
);

let agent = LlmAgentBuilder::new("assistant")
    .instruction("You are a helpful assistant.")
    .model(model)
    .build()?;

예시

cargo-adk를 사용하여 검증된 0.8 종속성으로 제공자별 프로젝트를 생성합니다.

cargo adk new gemini_agent --provider gemini
cargo adk new openai_agent --template openai
cargo adk new anthropic_agent --provider anthropic

생성된 프로젝트는 scripts/check-cargo-adk-templates.sh에 의해 CI에서 컴파일됩니다. 전체 예시 모음은 adk-playground 저장소에서 관리됩니다.



이전: ← 실시간 에이전트 | 다음: Ollama (로컬) →

제공자가 전달할 수 없는 콘텐츠는 어떻게 처리되는가

Content은 단일 제공자 전송 방식이 허용하는 것보다 더 많은 내용을 표현할 수 있으므로, 각 어댑터는 나머지 내용을 어떻게 처리할지 결정해야 합니다. 이제 이러한 결정은 보이지 않게 적용되는 대신 기록됩니다. 모든 부분은 다음과 같이 분류됩니다:

처리 방식의미
Converted동등한 네이티브 형식으로 제공자에게 전달됨
Downgraded정보 손실이 더 큰 형식으로 전달됨 — 모델이 읽을 수 있지만 가져올 수는 없는 설명 텍스트로 렌더링된 파일 참조
Omitted전혀 전달되지 않음

다운그레이드와 생략은 기록될 때 tracing 경고를 발생시키며, 어느 쪽도 조용히 처리되지 않도록 파트 종류, MIME 유형 및 이유를 명시합니다.

요청을 전송하기 전에 결과를 확인하려면:

use adk_core::{Content, Part};
use adk_model::bedrock::convert::report_for_contents;

let content = Content {
    role: "user".to_string(),
    parts: vec![Part::inline_data("audio/wav", vec![0u8; 16])],
};
let report = report_for_contents(std::slice::from_ref(&content));

for omission in report.omitted_parts() {
    println!("{} was dropped: {}", omission.kind, omission.detail);
}

모델이 전혀 보지 못한 자료에 대한 응답을 받는 대신, 불완전한 상태로 모델에 도달할 요청을 거부하려면:

use adk_core::{Content, Part};
use adk_model::bedrock::convert::report_for_contents;

let content = Content {
    role: "user".to_string(),
    parts: vec![Part::inline_data("video/mp4", vec![0u8; 16])],
};

if let Some(error) = report_for_contents(std::slice::from_ref(&content)).into_error() {
    return Err(error);
}

into_error은 생략만 다룹니다. 다운그레이드는 여전히 모델에 도달하며, 이를 거부하면 문서화된 텍스트 대체 처리를 거부하게 됩니다.

참고: 원장에는 설계상 모든 항목이 기록됩니다. 기록된 처리 결과 없이 어댑터를 벗어나는 모든 파트(향후 변경으로 추가된 파트 포함)는 명시적인 "기록된 이유 없음"과 함께 생략으로 기록되며, adk-model/tests/part_conversion_matrix_tests.rs 는 해당 항목에서 실패합니다.

Bedrock Converse 지원 범위

부분처리 방식
텍스트, FunctionCall, FunctionResponse, 사고Converted
JPEG의 InlineData, PNG, GIF, WebP이미지 블록으로서의 Converted
지원되는 문서 유형(PDF 등)의 InlineData문서 블록으로서의 Converted
오디오, 비디오 또는 임의의 바이너리가 포함된 InlineDataOmitted
이미지 또는 지원되는 문서용 FileData텍스트로 변환하는 Downgraded — Converse는 임의의 URLs가 아닌 S3 URIs을 사용합니다
그 밖의 모든 유형용 FileDataOmitted
ServerToolCall, ServerToolResponseOmitted — Gemini 전용
EmbeddedResource 텍스트 또는 지원되는 유형의 blobConverted
지원되지 않는 유형의 EmbeddedResource blobOmitted
모델 제공자(클라우드) - ADK-Rust 문서 | ADK-Rust