azosi · 2026.7.28 01:24 · 조회 1

Kimi Web Search

상위 문서: ← Kimi Tooling workflows 출처: Kimi API Platform 공식 문서 — Use Kimi API's Internet Search Functionality 한글화 (2026-07-22) 공급사: Moonshot AI (月之暗面)

⚠️ 업데이트 안내: 웹 검색(web_search)은 현재 업데이트 중이라 가까운 시일 내 사용을 권장하지 않습니다. 본 문서는 일부 구버전이며, 후속 업데이트를 따라가 주세요.

$web_search(builtin_function 타입)는 Kimi의 내장 웹 검색 도구 함수로, tool_calls 사용 위에 구현됩니다 — 모델은 검색 인자만 생성하고, 검색 자체는 Kimi LLM이 정의하고 실행합니다. 검색 엔진 호출, 페이지 가져오기, 콘텐츠 정리를 직접 구현하고 싶지 않을 때 이 내장 도구를 선언하면 즉시 웹 검색을 사용할 수 있습니다.

기본 사용법과 흐름은 일반 tool_calls 호출과 동일 — 도구 정의 → tools로 제출 → 모델이 인자 생성 → 실행 결과 반환 → 모델의 답변. 전체 흐름은 Use Kimi API to Complete Tool Calls 참고. 이 페이지는 $web_search가 일반 function과 다른 점만 강조.

1. $web_search 선언

일반 tool과 달리, $web_search 함수는 별도 파라미터 설명이 필요 없음typefunction.name만 선언하면 등록됩니다:

tools = [
    {
        "type": "builtin_function",  # <-- Kimi 내장 도구를 builtin_function으로 표시 (일반 function과 구분)
        "function": {
            "name": "$web_search",
        },
    },
]

$web_search 함수는 달러 사인 $로 시작하며, 이는 Kimi 내장 함수를 나타내는 약속된 방식입니다 (일반 function 정의에서 $는 허용되지 않음). 앞으로 추가될 Kimi 내장 함수도 $ 접두사를 사용할 예정.

$web_search는 각 모델의 사고 동작과 직접 연동kimi-k3는 항상 사고, kimi-k2.6도 사고 활성화 시 웹 검색 가능.

$web_search는 일반 function 도구와 공존 가능 — 같은 tools 선언에서 type=builtin_functiontype=function을 자유롭게 혼합 가능.

2. 웹 검색 실행

$web_search를 사용할 때 기본 흐름은 일반 function과 다르지 않습니다. 개발자는 기존 tool_calls 실행 코드를 수정할 필요조차 없음. 다음 예시는 전체 흐름을 보여줍니다: $web_search를 선언하고, 질문을 던지고, tool_calls를 순회해 모델의 최종 답변을 받을 때까지 반복. search_impl은 모델이 생성한 인자를 그대로 반환:

import os
import json
from typing import Any, Dict
from openai import OpenAI
from openai.types.chat.chat_completion import Choice

client = OpenAI(
    base_url="https://api.moonshot.ai/v1",
    api_key=os.environ.get("MOONSHOT_API_KEY"),
)

def search_impl(arguments: Dict[str, Any]) -> Any:
    """
    Moonshot AI가 제공하는 검색 도구를 사용할 때, 인자를 그대로 반환만 하면 됨.
    추가 처리 로직 불필요.
    
    다른 모델을 사용하면서 웹 검색 기능을 유지하고 싶다면, 여기 구현만 수정하면 됨
    (예: 검색 엔진 호출, 웹 콘텐츠 가져오기 등). 함수 시그니처는 변경 불필요.
    """
    return arguments

def chat(messages) -> Choice:
    return client.chat.completions.create(
        model="kimi-k3",
        messages=messages,
        max_tokens=32768,
        tools=[{
            "type": "builtin_function",
            "function": {"name": "$web_search"},
        }],
    ).choices[0]

def main():
    messages = [{"role": "system", "content": "You are Kimi."}]
    messages.append({
        "role": "user",
        "content": "Moonshot AI의 Context Caching 기술을 검색해서 알려줘.",
    })

    finish_reason = None
    while finish_reason is None or finish_reason == "tool_calls":
        choice = chat(messages)
        finish_reason = choice.finish_reason
        if finish_reason == "tool_calls":
            messages.append(choice.message)  # <-- assistant 메시지를 컨텍스트에 추가
            for tool_call in choice.message.tool_calls:
                name = tool_call.function.name
                args = json.loads(tool_call.function.arguments)
                if name == "$web_search":
                    result = search_impl(args)
                else:
                    result = f"Error: 도구를 찾을 수 없음 '{name}'"

                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "name": name,
                    "content": json.dumps(result),  # <-- 문자열 포맷으로 전달
                })

    print(choice.message.content)

if __name__ == "__main__":
    main()

search_impl에 검색·파싱·콘텐츠 가져오기 로직이 필요 없는 이유: 이름 그대로 builtin_function은 Kimi LLM의 내장 함수로, Kimi LLM이 정의하고 실행합니다.

  1. finish_reason=tool_calls를 반환하면 Kimi LLM이 $web_search 실행이 필요함을 인지하고 모든 준비를 마침
  2. Kimi LLM이 tool_call.function.arguments에 필요한 인자를 반환. 호출자는 이 인자를 그대로 Kimi LLM에 제출
  3. role=tool 메시지로 인자를 제출하면, Kimi LLM이 즉시 온라인 검색을 시작하고 그 결과를 사용해 사용자가 읽을 수 있는 메시지(finish_reason=stop)를 생성

3. 자체 검색 구현으로 전환

Kimi API의 $web_search원래 API/SDK 호환성을 깨지 않고도 신뢰할 수 있는 LLM 웹 검색을 제공하는 것이 목표이며, 원래 tool_calls 기능과 완전히 호환됩니다. Kimi의 웹 검색에서 자체 구현으로 전환하려면 두 단계만 거치면 전체 코드 구조를 훼손하지 않고 전환 가능:

  1. $web_searchtool 정의를 자체 구현으로 수정 (name, description 등). 모델이 생성해야 할 파라미터를 알 수 있도록 tool.function에 추가 정보를 더할 수 있음. parameters 필드에 필요한 파라미터를 자유롭게 추가
  2. search_impl 함수 구현을 변경. Kimi의 $web_search는 인자를 그대로 반환만 하면 되지만, 자체 검색 서비스를 사용한다면 searchcrawl 함수를 완전히 구현해야 함 — 검색 엔진 API 호출(또는 자체 콘텐츠 검색), URL 기반 웹 페이지 가져오기(사이트별 다른 읽기 규칙 필요 가능), 가져온 콘텐츠를 모델이 인식하기 쉬운 포맷(Markdown 등)으로 정제, 다양한 에러/예외 처리

4. 웹 검색 토큰 사용량 추적

Kimi가 제공하는 $web_search를 사용할 때, 검색 결과는 prompt의 토큰(prompt_tokens)에 포함됩니다. 보통 검색 결과에 많은 콘텐츠가 포함되므로 토큰 소비가 상당히 큽니다. 의도치 않은 대량 토큰 소비를 피하기 위해 usage 객체 안에 total_tokens 필드가 추가되어, 호출자에게 검색 콘텐츠가 차지한 총 토큰 수를 알립니다(arguments.usage.total_tokens). 이 토큰은 전체 웹 검색 과정이 끝나면 prompt_tokens에 합산됩니다.

# chat 함수 내부에서 finish_reason == "stop"일 때 출력
if choice.finish_reason == "stop":
    print(f"chat_prompt_tokens:          {usage.prompt_tokens}")
    print(f"chat_completion_tokens:      {usage.completion_tokens}")
    print(f"chat_total_tokens:           {usage.total_tokens}")

# tool_calls 처리 중, 웹 검색 결과의 토큰 수 출력
search_content_total_tokens = tool_call_arguments.get("usage", {}).get("total_tokens")
print(f"search_content_total_tokens: {search_content_total_tokens}")

5. 모델 선택

웹 검색을 활성화하면 검색 결과가 대화에 추가되어 컨텍스트 길이가 크게 늘어납니다. Input token length too long 트리거를 피하려면 1M 토큰 컨텍스트 윈도우를 가진 kimi-k3 사용을 권장:

def chat(messages) -> Choice:
    return client.chat.completions.create(
        model="kimi-k3",
        messages=messages,
        tools=[{
            "type": "builtin_function",
            "function": {"name": "$web_search"},
        }],
    ).choices[0]

6. 웹 검색 과금

토큰 소비 외에 웹 검색 1회당 호출 수수료도 부과됩니다. 자세한 내용은 Pricing 참고.


변경 이력

날짜변경
2026-07-22초판 작성 (공식 Web Search 가이드 한글화)
2026-07-22제목에 "Kimi" 접두사 추가, 본문 H1 중복 제거

댓글

아직 댓글이 없습니다.

댓글을 작성하려면 로그인이 필요합니다.