웹 검색 통합

웹 검색 통합 (Web Search Integration)

어떤 LLM 프로바이더에서든 투명한 서버 사이드 웹 검색 실행을 활성화하는 방법을 알려드릴게요. LiteLLM이 웹 검색 도구 호출을 자동으로 가로채서, 설정해 둔 검색 프로바이더(Parallel, Perplexity, Tavily 등)로 실행해요.

출처: 문서

본문

퀵 스타트 (Quick Start)

1. 웹 검색 가로채기 설정

config.yaml에 추가하세요:

model_list:
  - model_name: gpt-5.6-terra
    litellm_params:
      model: openai/gpt-5.6-terra
      api_key: os.environ/OPENAI_API_KEY

litellm_settings:
  callbacks: ["websearch_interception"]
  websearch_interception_params:
    enabled_providers:
      - openai
      - minimax
      - anthropic
    search_tool_name: perplexity-search  # Optional

search_tools:
  - search_tool_name: perplexity-search
    litellm_params:
      search_provider: perplexity
      api_key: os.environ/PERPLEXITY_API_KEY

2. 어떤 프로바이더와도 사용

import litellm

response = await litellm.acompletion(
    model="gpt-5.6-terra",
    messages=[
        {"role": "user", "content": "What's the weather in San Francisco today?"}
    ],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "litellm_web_search",
                "description": "Search the web for information",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "query": {"type": "string", "description": "Search query"}
                    },
                    "required": ["query"]
                }
            }
        }
    ]
)
# Response includes search results automatically!
print(response.choices[0].message.content)

작동 방식 (How It Works)

모델이 웹 검색 도구 호출을 할 때 LiteLLM은:

  • 응답에서 litellm_web_search 도구 호출을 감지
  • 설정된 검색 프로바이더로 검색 실행
  • 검색 결과를 포함한 후속 요청 수행
  • 최종 답변을 사용자에게 반환

결과: 사용자 API 호출 1회 → 검색 결과가 포함된 완전한 답변

모델이 보는 검색 도구 (The Search Tool the Model Sees)

요청에 실린 웹 검색 도구가 무엇이든, LiteLLM은 모델이 보기 전에 이를 자체 litellm_web_search 정의로 교체해요. Anthropic의 web_search_20250305, Responses API의 web_search_preview, Claude Code의 web_search, 그리고 query 파라미터만 있는 직접 만든 litellm_web_search 함수 도구 모두, 호출한 API의 도구 형식(Anthropic input_schema, Chat Completions function.parameters, 또는 평면 Responses function tool)의 아래 스키마로 모델에 도달해요.

litellm_web_search 입력 스키마

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "The search query to execute"
    },
    "objective": {
      "type": "string",
      "description": "Natural-language description of the goal behind the search, including any source or freshness requirements."
    },
    "search_queries": {
      "type": "array",
      "items": {"type": "string"},
      "description": "Two to five short keyword queries (3-6 words each) covering different angles of the objective, e.g. varying names, synonyms, or phrasings. Provide together with objective for the best results."
    }
  },
  "required": ["query"]
}

query는 필수이며 대부분의 검색 프로바이더가 받는 값이에요. objectivesearch_queries는 선택사항으로, 모델이 무엇을 원하는지 말하고 한 도구 호출에서 여러 키워드 검색을 펴내도록 해줘요. LiteLLM은 이들을 네이티브로 그 모양을 받는 검색 프로바이더에만 전달하는데, 지금은 Parallel AI가 그 대상이에요. 거기서 search_queries 목록은 프로바이더의 queries가 되고 objective가 그 옆에 붙어요(검색 도구의 litellm_params가 이미 objective를 설정했다면 그것이 유지돼요). 다른 모든 검색 프로바이더(Perplexity, Tavily, Exa 등)는 계속 단일 query 문자열을 받고, query만 채운 모델은 모든 프로바이더에서 이전과 똑같이 동작해요.

선택 필드는 전달 전에 검증돼요: 빈 objective는 무시되고, search_queries는 배열이어야 하며(빈 문자열은 문자로 분리되지 않고 무시), 비어 있지 않은 문자열이 아닌 항목은 버려지고, 처음 다섯 개 쿼리만 유지되어 Parallel의 상한과 일치해요.

Parallel AI 검색 도구를 설정하면, 모델의 도구 호출과 LiteLLM이 그로부터 만드는 요청은 다음과 같아요. 아웃바운드 body는 --detailed_debughttps://api.parallel.ai/v1/search로 보낸 요청으로 출력하는 내용이에요.

모델이 내보낸 도구 호출

{
  "name": "litellm_web_search",
  "input": {
    "query": "latest stable Node.js release",
    "objective": "Find the most current stable Node.js release version and what changes were included in that release",
    "search_queries": ["latest stable Node.js release", "Node.js newest version changelog", "current Node.js LTS release"]
  }
}

LiteLLM이 Parallel AI에 보내는 요청

{
  "objective": "Find the most current stable Node.js release version and what changes were included in that release",
  "search_queries": ["latest stable Node.js release", "Node.js newest version changelog", "current Node.js LTS release"],
  "mode": "basic",
  "advanced_settings": {"max_results": 5}
}

같은 도구 호출을 Tavily 검색 도구로 보내면 Tavily는 "query": "latest stable Node.js release"만 받고 나머지 두 필드는 받지 않아요. Anthropic 네이티브 web_search_* 도구를 보낸 클라이언트의 경우, 최종 응답의 server_tool_use 블록에도 여전히 query만 표시돼요.

지원 프로바이더 (Supported Providers)

웹 검색 통합은 다음을 사용하는 모든 프로바이더에서 작동해요:

  • ✅ Base HTTP Handler (BaseLLMHTTPHandler)
  • ✅ OpenAI Completion Handler (OpenAIChatCompletion)

Base HTTP Handler 사용 프로바이더: | 프로바이더 | 상태 | 비고 | | --- | --- | --- | | OpenAI | ✅ | GPT-4, GPT-3.5 등 | | Anthropic | ✅ | HTTP 핸들러를 통한 Claude 모델 | | MiniMax | ✅ | 모든 MiniMax 모델 | | Mistral | ✅ | Mistral AI 모델 | | Cohere | ✅ | Command 모델 | | Fireworks AI | ✅ | 모든 Fireworks 모델 | | Together AI | ✅ | 모든 Together AI 모델 | | Groq | ✅ | 모든 Groq 모델 | | Perplexity | ✅ | Perplexity 모델 | | DeepSeek | ✅ | DeepSeek 모델 | | xAI | ✅ | Grok 모델 | | Hugging Face | ✅ | Inference API 모델 | | OCI | ✅ | Oracle Cloud 모델 | | Vertex AI | ✅ | Google Vertex AI 모델 | | Bedrock | ✅ | AWS Bedrock 모델 (converse_like route) | | Azure OpenAI | ✅ | Azure 호스팅 OpenAI 모델 | | Sagemaker | ✅ | AWS Sagemaker 모델 | | Databricks | ✅ | Databricks 모델 | | DataRobot | ✅ | DataRobot 모델 | | Hosted VLLM | ✅ | 셀프호스팅 VLLM | | Heroku | ✅ | Heroku 호스팅 모델 | | RAGFlow | ✅ | RAGFlow 모델 | | Compactif | ✅ | Compactif 모델 | | Cometapi | ✅ | Comet API 모델 | | A2A | ✅ | Agent-to-Agent 모델 | | Bytez | ✅ | Bytez 모델 |

OpenAI Handler 사용 프로바이더: | 프로바이더 | 상태 | 비고 | | --- | --- | --- | | OpenAI | ✅ | 네이티브 OpenAI API | | Azure OpenAI | ✅ | Azure 호스팅 OpenAI | | OpenAI-Compatible | ✅ | 모든 OpenAI 호환 API |

설정 (Configuration)

WebSearch Interception 파라미터

파라미터 타입 필수 설명 예시
enabled_providers List[String] 웹 검색을 활성화할 프로바이더 목록 [openai, minimax, anthropic]
search_tool_name String 아니요 search_tools 설정에서 특정 검색 도구. 설정 안 하면 첫 번째 사용 perplexity-search

프로바이더 값

enabled_providers에 사용하는 값: | 프로바이더 | 값 | 프로바이더 | 값 | | --- | --- | --- | --- | | OpenAI | openai | Anthropic | anthropic | | MiniMax | minimax | Mistral | mistral | | Cohere | cohere | Fireworks AI | fireworks_ai | | Together AI | together_ai | Groq | groq | | Perplexity | perplexity | DeepSeek | deepseek | | xAI | xai | Hugging Face | huggingface | | OCI | oci | Vertex AI | vertex_ai | | Bedrock | bedrock | Azure | azure | | Sagemaker | sagemaker_chat | Databricks | databricks | | DataRobot | datarobot | VLLM | hosted_vllm | | Heroku | heroku | RAGFlow | ragflow | | Compactif | compactif | Cometapi | cometapi | | A2A | a2a | Bytez | bytez |

검색 프로바이더 (Search Providers)

프로바이더 search_provider 환경 변수
Perplexity AI perplexity PERPLEXITYAI_API_KEY
Tavily tavily TAVILY_API_KEY
Exa AI exa_ai EXA_API_KEY
Brave Search brave BRAVE_API_KEY
Parallel AI parallel_ai PARALLEL_AI_API_KEY
Google PSE google_pse GOOGLE_PSE_API_KEY, GOOGLE_PSE_ENGINE_ID
DataForSEO dataforseo DATAFORSEO_LOGIN, DATAFORSEO_PASSWORD
Firecrawl firecrawl FIRECRAWL_API_KEY
SearXNG searxng SEARXNG_API_BASE (필수)
Linkup linkup LINKUP_API_KEY
Serper serper SERPER_API_KEY
SearchAPI.io searchapi SEARCHAPI_API_KEY

자세한 설정은 Search Providers 문서를 참고하세요.

완전한 설정 예시

model_list:
  # OpenAI
  - model_name: gpt-5.6-terra
    litellm_params:
      model: openai/gpt-5.6-terra
      api_key: os.environ/OPENAI_API_KEY
  # MiniMax
  - model_name: minimax
    litellm_params:
      model: minimax/MiniMax-M2.1
      api_key: os.environ/MINIMAX_API_KEY
  # Anthropic
  - model_name: claude
    litellm_params:
      model: anthropic/claude-sonnet-5
      api_key: os.environ/ANTHROPIC_API_KEY
  # Azure OpenAI
  - model_name: azure-gpt
    litellm_params:
      model: azure/gpt-5.6-terra
      api_base: https://my-azure.openai.azure.com
      api_key: os.environ/AZURE_API_KEY

litellm_settings:
  callbacks: ["websearch_interception"]
  websearch_interception_params:
    enabled_providers:
      - openai
      - minimax
      - anthropic
      - azure
    search_tool_name: perplexity-search

search_tools:
  - search_tool_name: perplexity-search
    litellm_params:
      search_provider: perplexity
      api_key: os.environ/PERPLEXITY_API_KEY
  - search_tool_name: tavily-search
    litellm_params:
      search_provider: tavily
      api_key: os.environ/TAVILY_API_KEY
  - search_tool_name: parallel-search
    litellm_params:
      search_provider: parallel_ai
      api_key: os.environ/PARALLEL_API_KEY

Parallel Search를 쓰려면 websearch_interception_params에서 search_tool_name: parallel-search을 지정하세요.

사용 예시 (Usage Examples)

Python SDK

import litellm

# Configure callbacks
litellm.callbacks = ["websearch_interception"]

# Make completion with web search tool
response = await litellm.acompletion(
    model="gpt-5.6-terra",
    messages=[
        {"role": "user", "content": "What are the latest AI news?"}
    ],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "litellm_web_search",
                "description": "Search the web for current information",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "query": {
                            "type": "string",
                            "description": "Search query"
                        }
                    },
                    "required": ["query"]
                }
            }
        }
    ]
)
print(response.choices[0].message.content)

Proxy 서버

# Start proxy with config
litellm --config config.yaml

# Make request
curl http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ***" \
  -d '{
    "model": "gpt-5.6-terra",
    "messages": [
      {"role": "user", "content": "What is the weather in San Francisco?"}
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "litellm_web_search",
          "description": "Search the web",
          "parameters": {
            "type": "object",
            "properties": {
              "query": {"type": "string"}
            },
            "required": ["query"]
          }
        }
      }
    ]
  }'

검색 도구 선택 방식 (How Search Tool Selection Works)

  • search_tool_name이 지정되면 → 해당 검색 도구 사용
  • search_tool_name이 없으면 → search_tools 목록의 첫 번째 검색 도구 사용
search_tools:
  - search_tool_name: perplexity-search  # ← This will be used if no search_tool_name specified
    litellm_params:
      search_provider: perplexity
      api_key: os.environ/PERPLEXITY_API_KEY
  - search_tool_name: tavily-search
    litellm_params:
      search_provider: tavily
      api_key: os.environ/TAVILY_API_KEY

문제 해결 (Troubleshooting)

웹 검색이 동작하지 않을 때

  • 프로바이더 활성화 확인: enabled_providers에 프로바이더가 있는지
  • 검색 도구 설정 확인: search_tools 구성 확인
  • API 키 설정 확인: export PERPLEXITY_API_KEY=your-key
  • 디버그 로깅 활성화: litellm.set_verbose = True

일반적인 문제

  • 문제: 모델이 최종 답변 대신 tool_calls를 반환 → 원인: 프로바이더가 enabled_providers 목록에 없음 → 해결: 프로바이더를 목록에 추가
  • 문제: "No search tool configured" 오류 → 원인: search_tools 설정에 검색 도구 없음 → 해결: 검색 도구 설정 1개 이상 추가
  • 문제: "Invalid function arguments json string" 오류(MiniMax) → 원인: 최신 버전에서 수정됨 — arguments가 제대로 JSON 직렬화되지 않았음 → 해결: 최신 LiteLLM 버전으로 업데이트

기술 세부사항 (Technical Details)

아키텍처

웹 검색 통합은 커스텀 콜백(WebSearchInterceptionLogger)으로 구현되며:

  • Pre-request Hook: 네이티브 웹 검색 도구를 LiteLLM 표준 형식으로 변환
  • Post-response Hook: 응답에서 웹 검색 도구 호출 감지
  • Agentic Loop: 검색을 실행하고 후속 요청을 자동 수행

지원 API

  • ✅ Chat Completions API (OpenAI 형식)
  • ✅ Anthropic Messages API (Anthropic 형식)
  • ✅ 스트리밍 (자동 변환)
  • ✅ 비스트리밍

응답 형식 감지

핸들러가 응답 형식을 자동 감지해요:

  • OpenAI 형식: assistant 메시지의 tool_calls
  • Anthropic 형식: content의 tool_use 블록

성능

  • 지연 시간: LLM 호출 1회 추가(검색 결과를 포함한 후속 요청)
  • 캐싱: 검색 결과 캐시 가능 (검색 프로바이더에 따라 다름)
  • 병렬 검색: 여러 검색 쿼리를 병렬 실행

기여 (Contributing)

버그를 찾았거나 새 프로바이더 지원을 추가하고 싶다면 Contributing Guide를 참고하세요.

더 알아보기 (Learn more)