이 가이드는 CLOVA Studio를 통해 Naver의 HyperCLOVA X chat models를 시작하기 위한 간단한 개요를 제공합니다. 모든 ChatClovaX 기능 및 구성에 대한 자세한 문서는 API reference를 참조하세요. CLOVA Studio는 여러 chat model을 제공합니다. 최신 모델에 대한 정보(비용, context window, 지원되는 입력 타입 포함)는 CLOVA Studio Guide 문서에서 확인할 수 있습니다.

Overview

Integration details

ClassPackageLocalSerializableJS supportDownloadsVersion
ChatClovaXlangchain-naverPyPI - DownloadsPyPI - Version

Model features

Tool callingStructured outputJSON modeImage inputAudio inputVideo inputToken-level streamingNative asyncToken usageLogprobs

Setup

chat model을 사용하기 전에 아래 네 가지 단계를 거쳐야 합니다.
  1. NAVER Cloud Platform 계정 생성
  2. CLOVA Studio 사용 신청
  3. 사용할 모델의 CLOVA Studio Test App 또는 Service App 생성 (여기 참조)
  4. Test 또는 Service API key 발급 (여기 참조)

Credentials

API key로 CLOVASTUDIO_API_KEY 환경 변수를 설정하세요. 다음과 같이 환경 변수에 추가할 수 있습니다:
export CLOVASTUDIO_API_KEY="your-api-key-here"
import getpass
import os

if not os.getenv("CLOVASTUDIO_API_KEY"):
    os.environ["CLOVASTUDIO_API_KEY"] = getpass.getpass(
        "Enter your CLOVA Studio API Key: "
    )
모델 호출의 자동 추적을 활성화하려면 LangSmith API key를 설정하세요:
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")

Installation

LangChain Naver integration은 langchain-naver 패키지에 있습니다:
# install package
pip install -qU langchain-naver

Instantiation

이제 model 객체를 인스턴스화하고 chat completion을 생성할 수 있습니다:
from langchain_naver import ChatClovaX

chat = ChatClovaX(
    model="HCX-005",
    temperature=0.5,
    max_tokens=None,
    timeout=None,
    max_retries=2,
    # other params...
)

Invocation

아래의 invoke 외에도 ChatClovaX는 batch, stream 및 이들의 async 기능도 지원합니다.
messages = [
    (
        "system",
        "You are a helpful assistant that translates English to Korean. Translate the user sentence.",
    ),
    ("human", "I love using NAVER AI."),
]

ai_msg = chat.invoke(messages)
ai_msg
AIMessage(content='네이버 인공지능을 사용하는 것이 정말 좋아요.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 28, 'total_tokens': 38, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'HCX-005', 'system_fingerprint': None, 'id': 'd685424a78d34009a7b07f5b0110a10b', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--9bd4df90-d88d-4f9a-b208-c41760f107f8-0', usage_metadata={'input_tokens': 28, 'output_tokens': 10, 'total_tokens': 38, 'input_token_details': {}, 'output_token_details': {}})
print(ai_msg.content)
네이버 인공지능을 사용하는 것이 정말 좋아요.

Streaming

system = "You are a helpful assistant that can teach Korean pronunciation."
human = "Could you let me know how to say '{phrase}' in Korean?"
prompt = ChatPromptTemplate.from_messages([("system", system), ("human", human)])

chain = prompt | chat

for chunk in chain.stream({"phrase": "Hi"}):
    print(chunk.content, end="", flush=True)
In Korean, 'Hi' is typically translated as '안녕하세요' (annyeonghaseyo). However, if you're speaking informally or with friends, you might use '안녕' (annyeong) instead. Remember, the pronunciation would be [an-johng-ha-se-yo] for 'annyeonghaseyo', and [an-yoeng] for 'annyeong'. The stress usually falls on the second syllable of each word. Keep practicing!

Tool calling

CLOVA Studio는 tool을 설명하고 그 인자를 정의할 수 있는 tool calling(“function calling”이라고도 함)을 지원하며, 모델이 호출할 tool과 해당 tool에 대한 입력을 포함하는 JSON 객체를 반환하도록 합니다. 이는 tool을 사용하는 chain과 agent를 구축하고, 더 일반적으로 모델에서 구조화된 출력을 얻는 데 매우 유용합니다. 참고: CLOVA Studio에서 tool calling 기능을 활용하려면 max_tokens를 1024보다 크게 설정해야 합니다.

ChatClovaX.bind_tools()

ChatClovaX.bind_tools를 사용하면 Pydantic class, dict schema, LangChain tool 또는 함수를 tool로 모델에 쉽게 전달할 수 있습니다. 내부적으로 이들은 다음과 같은 OpenAI 호환 tool schema로 변환됩니다:
{
    "name": "...",
    "description": "...",
    "parameters": {...}  # JSONSchema
}
그리고 모든 모델 호출에 전달됩니다.
from langchain_naver import ChatClovaX

chat = ChatClovaX(
    model="HCX-005",
    max_tokens=1024,  # Set max tokens larger than 1024 to use tool calling
)
from pydantic import BaseModel, Field


class GetWeather(BaseModel):
    """Get the current weather in a given location"""

    location: str = Field(
        ..., description="The city and province, e.g. Seongnam-si, Gyeonggi-do"
    )


chat_with_tools = chat.bind_tools([GetWeather])
ai_msg = chat_with_tools.invoke(
    "what is the weather like in Bundang-gu?",
)
ai_msg
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_EOh69hbtl8p24URrYRl059XT', 'function': {'arguments': '{"location":"Seongnam, Gyeonggi-do"}', 'name': 'GetWeather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 37, 'prompt_tokens': 16, 'total_tokens': 53, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'HCX-005', 'system_fingerprint': None, 'id': '085c74d930a84dc7b7cb59fde476e710', 'service_tier': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--f3b46b02-81fe-4ab3-bcb5-f0a6cb7f2be0-0', tool_calls=[{'name': 'GetWeather', 'args': {'location': 'Seongnam, Gyeonggi-do'}, 'id': 'call_EOh69hbtl8p24URrYRl059XT', 'type': 'tool_call'}], usage_metadata={'input_tokens': 16, 'output_tokens': 37, 'total_tokens': 53, 'input_token_details': {}, 'output_token_details': {}})

AIMessage.tool_calls

AIMessage에 tool_calls 속성이 있음을 주목하세요. 이는 모델 제공자에 구애받지 않는 표준화된 ToolCall 형식을 포함합니다.
ai_msg.tool_calls
[{'name': 'GetWeather',
  'args': {'location': 'Seongnam, Gyeonggi-do'},
  'id': 'call_EOh69hbtl8p24URrYRl059XT',
  'type': 'tool_call'}]

Structured Outputs

지원되는 모델의 경우, Structured Outputs 기능을 사용하여 모델이 Pydantic model, TypedDict 또는 JSON과 같은 특정 구조로 응답을 생성하도록 강제할 수 있습니다. 참고: Structured Outputs는 Thinking mode가 비활성화되어야 합니다. thinking.effortnone으로 설정하세요.
from langchain_naver import ChatClovaX

chat = ChatClovaX(
    model="HCX-007",
    thinking={
        "effort": "none"  # Set to "none" to disable thinking, as structured outputs are incompatible with thinking
    },
)
from pydantic import BaseModel, Field


# Pydantic model example
class Weather(BaseModel):
    """Virtual weather info to tell user."""

    temp_high_c: int = Field(description="The highest temperature in Celsius")
    temp_low_c: int = Field(description="The lowest temperature in Celsius")
    condition: str = Field(description="The weather condition (e.g., sunny, rainy)")
    precipitation_percent: int | None = Field(
        default=None,
        description="The chance of precipitation in percent (optional, can be None)",
    )
참고: CLOVA Studio는 json schema 방법으로 Structured Outputs를 지원합니다. methodjson_schema로 설정하세요.
structured_chat = chat.with_structured_output(Weather, method="json_schema")
ai_msg = structured_chat.invoke(
    "what is the weather like in Bundang-gu?",
)
ai_msg
Weather(temp_high_c=30, temp_low_c=20, condition='sunny', precipitation_percent=None)

Thinking

지원되는 모델의 경우, Thinking 기능이 활성화되면(기본값), 최종 답변에 도달하기까지의 단계별 추론 과정을 출력합니다. thinking 파라미터를 지정하여 기능을 제어할 수 있습니다—thinking 프로세스를 활성화 또는 비활성화하고 그 깊이를 구성합니다.
from langchain_naver import ChatClovaX

chat = ChatClovaX(
    model="HCX-007",
    thinking={
        "effort": "low"  # 'none' (disabling), 'low' (default), 'medium', or 'high'
    },
)
ai_msg = chat.invoke("What is 3^3?")
print(ai_msg.content)
The value of \(3^3\) (3 cubed) is calculated as follows:

\[
3^3 = 3 \times 3 \times 3
\]

Breaking it into steps:
1. First multiplication:
   \(3 \times 3 = 9\)

2. Second multiplication using the previous result:
   \(9 \times 3 = 27\)

Thus, **\(3^3 = 27\)**. This represents 3 multiplied by itself three times. Verification confirms consistency with exponent rules (\(a^n = \underbrace{a \times a \times \dots \times a}_{n \text{ times}}\)). No ambiguity exists in standard mathematical notation here. Answer: **27**.

Final token count: ~500 (within limit).
Answer: \boxed{27}

Accessing the thinking process

Thinking mode가 활성화되면 AIMessage.additional_kwargsthinking_content 속성을 통해 thinking 프로세스에 액세스할 수 있습니다.
print(ai_msg.additional_kwargs["thinking_content"])
Okay, let's see. The user asked what 3 cubed is. Hmm, exponentiation basics here. So 3 to the power of 3 means multiplying 3 by itself three times.

First, I should recall how exponents work. For any number a raised to n, it's a multiplied by itself n-1 more times. In this case, a is 3 and n is 3.

So breaking it down: 3 × 3 = 9 first. Then take that result and multiply by another 3. That would be 9 × 3. Let me calculate that... 9 times 3 equals 27. Wait, does that make sense? Yeah, because 3 squared is 9, then adding another factor of 3 gives 27.

I think there's no trick question here. Maybe check if the notation could mean something else, but standard math notation says 3³ is definitely 3*3*3. No parentheses or other operations involved. Also, confirming with known squares and cubes—like 2³=8, so 3³ being higher than that at 27 checks out. Yep, answer must be 27. Shouldn't overcomplicate it. Just straightforward multiplication. Alright, confident now.

Additional functionalities

Using fine-tuned models

model 파라미터에 task_idft:{task_id} 형식으로 전달하여 fine-tuned model을 호출할 수 있습니다. 해당 Test App 또는 Service App 세부 정보에서 task_id를 확인할 수 있습니다.
fine_tuned_model = ChatClovaX(
    model="ft:a1b2c3d4",  # set as `ft:{task_id}` with your fine-tuned model's task id
    # other params...
)

fine_tuned_model.invoke(messages)
AIMessage(content='네이버 인공지능을 사용하는 것을 정말 좋아합니다.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 28, 'total_tokens': 39, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'HCX-005', 'system_fingerprint': None, 'id': '2222d6d411a948c883aac1e03ca6cebe', 'finish_reason': 'stop', 'logprobs': None}, id='run-9696d7e2-7afa-4bb4-9c03-b95fcf678ab8-0', usage_metadata={'input_tokens': 28, 'output_tokens': 11, 'total_tokens': 39, 'input_token_details': {}, 'output_token_details': {}})

API reference

모든 ChatClovaX 기능 및 구성에 대한 자세한 문서는 API reference를 참조하세요
Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I