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

# Claude 프로토콜: Anthropic Messages API 연동

> /v1/messages 헤더, cURL·Python SDK 예제, 콘텐츠 블록, 스트리밍, 도구 호출, 오류 해결로 LaoZhang API를 Anthropic Messages 형식으로 호출합니다.

Claude 프로토콜은 Anthropic의 Messages API 형식입니다. base URL을 바꾸고 LaoZhang API 키를 쓰면 Anthropic SDK와 Claude Code를 그대로 연결할 수 있습니다.

| 항목 | 내용 |
| - | - |
| 엔드포인트 | `POST https://api.laozhang.ai/v1/messages` |
| 헤더 | `Authorization: Bearer`에 API 키, 그리고 `anthropic-version: 2023-06-01` |
| 필수 본문 필드 | `model`, `messages`, `max_tokens` |
| 응답 | `content[]`의 타입별 블록 |
| SDK base URL | Anthropic Python SDK의 `base_url`을 `https://api.laozhang.ai`로 설정 |
| 예제 모델 | `glm-5.2` |

```text theme={null}
POST https://api.laozhang.ai/v1/messages
```

애플리케이션이 OpenAI SDK를 쓴다면 [OpenAI 프로토콜](https://docs.laozhang.ai/ko/api-reference/chat-completions.md)을 이용하세요. 아래 모델들은 두 형식을 모두 받습니다. 두 형식은 요청과 응답 구조가 다르므로 클라이언트마다 하나만 고르세요.

## 모델 고르기

[모델 및 가격](https://docs.laozhang.ai/ko/models.md)에서 **Endpoints** 열에 Anthropic Messages가 포함된 모델을 쓰세요. 2026년 10월 18일 기준 공개 가격표에서는 다음 모델이 해당됩니다.

* Claude 모델: `claude-sonnet-5-5`, `claude-opus-5-5` 등 11개이며 `default` 토큰 그룹에 올라 있습니다. 전체 목록과 가격은 [모델 및 가격](https://docs.laozhang.ai/ko/models.md)의 Anthropic 항목을 참고하세요.
* `glm-5.2`: 이 페이지의 예제에서 사용합니다. `default` 토큰 그룹에 올라 있으며, 이 프로토콜에서는 공식 Messages API와 매우 비슷하게 동작합니다.
* `deepseek-v4-pro`
* `deepseek-v4-flash`

> [!NOTE]
>
> **Claude 모델은 2026년 10월 18일부터 다시 제공됩니다.** 전환하기 전에 아래 Claude 모델 제한을 읽고, 자세한 내용은 [공지](https://docs.laozhang.ai/en/announcements/claude-models-2026-10.md)를 확인하세요.

모델 ID는 제품 이름이나 Bedrock·Vertex AI ID로 조합하지 말고 카탈로그 또는 [콘솔 가격 페이지](https://api.laozhang.ai/account/pricing)에서 정확히 복사하세요.

### Claude 모델 제한

Claude 모델은 스트리밍, 도구 사용, 적응형 사고(adaptive thinking), 5분·1시간 수명의 프롬프트 캐싱, 이미지 입력을 지원합니다. Anthropic 자체 API와 다르게 동작하는 부분이 몇 가지 있습니다.

* **출력 길이:** 응답 하나는 32,768토큰으로 제한됩니다. 더 큰 `max_tokens`는 이 한도로 줄어듭니다.
* **PDF와 문서:** `document` 콘텐츠 블록은 지원하지 않습니다. 텍스트를 먼저 추출해 `text` 블록으로 보내세요.
* **서버 도구:** `web_search`, `web_fetch`, `code_execution` 같은 Anthropic 서버 도구는 지원하지 않으며, 이를 선언한 요청은 400을 반환합니다.
* **그 밖의 엔드포인트:** `/v1/messages/count_tokens`, Message Batches, Files API는 사용할 수 없습니다.
* **중단 시퀀스:** 중단 시퀀스가 일치하면 `stop_reason`은 `end_turn`, `stop_sequence`는 `null`입니다.
* **긴 Haiku 프롬프트:** `claude-haiku-5-5` 프롬프트가 캐시 읽기와 쓰기를 포함해 100,000토큰을 넘으면, 요청 전체가 카탈로그의 구간별 가격에 표시된 긴 컨텍스트 요금으로 과금됩니다.

## 메시지 보내기

[토큰 관리](https://api.laozhang.ai/token)에서 과금 방식을 사용량 우선(콘솔 표시: 按量优先, 권장) 또는 사용량 과금(按量计费)으로 설정해 API 키(콘솔에서는 '토큰'이라고 부릅니다)를 만들고, 터미널에서 환경 변수로 설정하세요.

```bash theme={null}
export LAOZHANG_API_KEY="YOUR_LAOZHANG_API_KEY"
```

> [tab] cURL
>
> ```bash theme={null}
> curl --fail-with-body --max-time 120 \
>   "https://api.laozhang.ai/v1/messages" \
>   -H "Authorization: Bearer $LAOZHANG_API_KEY" \
>   -H "anthropic-version: 2023-06-01" \
>   -H "content-type: application/json" \
>   -d '{
>     "model": "glm-5.2",
>     "max_tokens": 1024,
>     "system": "당신은 간결하게 답하는 어시스턴트입니다.",
>     "messages": [
>       {"role": "user", "content": "connected라고만 답하세요"}
>     ]
>   }'
> ```

> [tab] Python
>
> `python -m pip install anthropic`으로 SDK를 설치하세요.
>
> ```python theme={null}
> import os
> from anthropic import Anthropic
>
> client = Anthropic(
>     api_key=os.environ["LAOZHANG_API_KEY"],
>     base_url="https://api.laozhang.ai",
>     timeout=120.0,
>     max_retries=0,
> )
> message = client.messages.create(
>     model="glm-5.2",
>     max_tokens=1024,
>     system="당신은 간결하게 답하는 어시스턴트입니다.",
>     messages=[{"role": "user", "content": "connected라고만 답하세요"}],
> )
> for block in message.content:
>     if block.type == "text":
>         print(block.text)
> ```

답변은 `connected`여야 합니다.

SDK가 API 키와 `anthropic-version` 헤더를 대신 보내고 base URL 뒤에 `/v1/messages`를 붙이므로, `base_url`에는 `/v1`을 넣지 마세요.

시스템 지시문은 `system` 역할의 메시지가 아니라 최상위 `system` 필드에 넣습니다.

`messages`는 `user`와 `assistant` 턴이 번갈아 나옵니다. 대화를 이어 가려면 이전 턴들을 보낸 다음 새 `user` 메시지를 추가하세요.

## 응답 읽기

읽어야 할 필드만 줄인 응답 예시입니다.

```json theme={null}
{
  "type": "message",
  "role": "assistant",
  "model": "glm-5.2",
  "content": [
    {"type": "text", "text": "connected"}
  ],
  "stop_reason": "end_turn",
  "usage": {"input_tokens": 21, "output_tokens": 4}
}
```

`content`는 블록 목록이며 하나의 답변에 여러 블록이 들어 있을 수 있습니다. `content[0]`이 텍스트라고 가정하지 말고 `type`별로 읽으세요.

| 블록 타입 | 내용 | 할 일 |
| - | - | - |
| `text` | `text`에 담긴 답변 | 표시하거나 저장합니다. |
| `thinking` | `thinking`에 담긴 모델의 추론 | 사용자에게 보여 주는 답변에서는 제외합니다. |
| `tool_use` | `id`, `name`, `input`이 있는 도구 호출 | 도구를 실행하고 `tool_result`를 돌려줍니다. |

`stop_reason`은 답변이 끝난 이유를 알려 줍니다.

* `end_turn`: 답변이 완결되었습니다.
* `max_tokens`: 출력 제한 때문에 잘렸습니다.
* `tool_use`: 모델이 도구 결과를 기다리고 있습니다.

토큰 수는 `usage`에 있고, 요청별 청구 금액은 [호출 로그](https://docs.laozhang.ai/en/faq/call-logs.md)에서 확인합니다.

## 응답 스트리밍

`"stream": true`를 추가하면 답변을 서버 전송 이벤트(SSE)로 받습니다.

텍스트는 `delta.type`이 `text_delta`인 `content_block_delta` 이벤트로 도착하며, 스트림은 `message_stop` 이벤트로 끝납니다.

> [tab] cURL
>
> `-N`은 cURL의 출력 버퍼링을 꺼서 각 이벤트가 도착하는 즉시 출력되게 합니다.
>
> ```bash theme={null}
> curl --fail-with-body -N --max-time 300 \
>   "https://api.laozhang.ai/v1/messages" \
>   -H "Authorization: Bearer $LAOZHANG_API_KEY" \
>   -H "anthropic-version: 2023-06-01" \
>   -H "content-type: application/json" \
>   -d '{
>     "model": "glm-5.2",
>     "max_tokens": 1024,
>     "stream": true,
>     "messages": [
>       {"role": "user", "content": "변수 이름을 짓는 요령 세 가지를 짧게 알려 주세요."}
>     ]
>   }'
> ```

> [tab] Python
>
> ```python theme={null}
> import os
> from anthropic import Anthropic
>
> client = Anthropic(
>     api_key=os.environ["LAOZHANG_API_KEY"],
>     base_url="https://api.laozhang.ai",
>     timeout=300.0,
>     max_retries=0,
> )
> with client.messages.stream(
>     model="glm-5.2",
>     max_tokens=1024,
>     messages=[{"role": "user", "content": "변수 이름을 짓는 요령 세 가지를 짧게 알려 주세요."}],
> ) as stream:
>     for text in stream.text_stream:
>         print(text, end="", flush=True)
> print()
> ```

스트리밍 응답은 다음 순서로 진행됩니다. 필요한 필드만 줄였습니다.

```text theme={null}
event: message_start
data: {"type":"message_start","message":{"type":"message","role":"assistant","content":[]}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"1. 변수 이름은"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"}}

event: message_stop
data: {"type":"message_stop"}
```

스트림을 읽을 때는 다음을 지키세요.

* 블록 `index`별로 `text_delta` 조각을 이어 붙이면 답변이 됩니다.
* 추론과 도구 입력은 다른 delta 타입을 쓰고 스트림에 `ping` 이벤트가 들어갈 수도 있으므로, 처리하지 않는 이벤트 타입은 건너뛰세요.
* Python의 `text_stream`은 텍스트만 반환하고 `message_stop` 뒤에 끝납니다.
* `message_stop` 전에 연결이 닫히면 답변이 불완전한 것으로 처리하세요.

## 도구 사용

`tools` 배열에 정의한 도구는 LaoZhang API가 아니라 내 애플리케이션에서 실행됩니다. 답변이 `stop_reason: "tool_use"`로 끝나면 다음 순서로 처리합니다.

1. 각 `tool_use` 블록의 `id`, `name`, `input`을 읽습니다.
2. 코드에서 해당하는 함수를 실행합니다.
3. 어시스턴트 턴을 그대로 둔 채, 호출마다 `tool_result` 블록 하나씩을 담은 `user` 턴을 이어 붙여 다음 요청을 보냅니다. 각 `tool_use_id`는 응답하는 호출의 `id`와 일치해야 합니다.

이어지는 요청의 `messages` 배열은 다음과 같습니다.

```json theme={null}
[
  {"role": "user", "content": "파리의 날씨는 어때요?"},
  {"role": "assistant", "content": [
    {"type": "tool_use", "id": "toolu_01", "name": "get_weather", "input": {"city": "Paris"}}
  ]},
  {"role": "user", "content": [
    {"type": "tool_result", "tool_use_id": "toolu_01", "content": "18°C, 흐림"}
  ]}
]
```

아래 루프는 Python SDK로 전체 과정을 실행합니다. 날씨 함수를 선언하고, 모델이 요청하면 로컬에서 실행해 결과를 돌려보내며, 모델이 텍스트로 답할 때까지 반복합니다.

```python theme={null}
import os
from anthropic import Anthropic

client = Anthropic(
    api_key=os.environ["LAOZHANG_API_KEY"],
    base_url="https://api.laozhang.ai",
    timeout=120.0,
    max_retries=0,
)
tools = [{
    "name": "get_weather",
    "description": "도시의 현재 날씨를 조회합니다",
    "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string", "description": "도시 이름"}},
        "required": ["city"],
    },
}]


def get_weather(city):
    # 날씨 서비스 호출 같은 실제 로직으로 바꾸세요
    return f"{city}: 흐림, 18°C"


messages = [{"role": "user", "content": "파리의 날씨는 어때요?"}]
for _ in range(5):
    message = client.messages.create(
        model="glm-5.2",
        max_tokens=1024,
        tools=tools,
        messages=messages,
    )
    tool_uses = [block for block in message.content if block.type == "tool_use"]
    if not tool_uses:
        break
    messages.append({"role": "assistant", "content": message.content})
    results = []
    for block in tool_uses:
        if block.name == "get_weather":
            output = get_weather(**block.input)
        else:
            output = f"알 수 없는 도구: {block.name}"
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": output,
        })
    messages.append({"role": "user", "content": results})

print("".join(block.text for block in message.content if block.type == "text"))
```

이어지는 요청마다 같은 `tools`를 보내고, 어시스턴트 턴은 반환된 그대로 유지하세요.

`web_search_*`, `code_execution_*` 같은 Anthropic 서버 도구 타입은 게이트웨이가 실행하지 않습니다. Claude 모델은 이를 선언한 요청을 400 오류로 거부합니다. 다른 모델은 검색이나 코드 실행 없이 호출을 일반 `tool_use` 블록으로 반환합니다. 이런 호출은 클라이언트 도구처럼 애플리케이션에서 처리하거나, 요청에서 해당 도구를 빼세요.

## Claude Code에서 사용하기

Claude Code는 Anthropic Messages 형식을 사용합니다.

* `ANTHROPIC_BASE_URL`을 `https://api.laozhang.ai`(`/v1`이 없는 호스트 루트)로 설정합니다.
* **Endpoints**에 Anthropic Messages가 포함된 모델을 고르세요. `claude-sonnet-5-5`, `glm-5.2`가 있으며 둘 다 `default` 토큰 그룹에서 쓸 수 있습니다.
* 과금 방식이 사용량 우선인 `default` 그룹의 키를 쓰세요. 이전에 `Claude Code` 그룹(구 claude\_code)에서 만든 키는 계속 작동하며, 새 키는 그 그룹이 필요하지 않습니다.

전체 `~/.claude/settings.json` 예시는 [LaoZhang API로 Claude Code 설정하기](https://docs.laozhang.ai/en/scenarios/programming/claude-code.md)를 참고하세요. Claude Code가 400 ValidationException을 반환한다면 [Claude Code 400 ValidationException 해결](https://docs.laozhang.ai/en/faq/claude-code-aws-400-validation-error.md)을 보세요.

## 오류 해결

* **401:** `Authorization: Bearer` 헤더를 확인하고, 계정 AccessToken이 아니라 [토큰 관리](https://api.laozhang.ai/token)의 모델 API 키를 사용하세요.
* **`max_tokens`가 언급된 400:** `max_tokens`를 추가하세요. Chat Completions와 달리 Messages 요청에는 필수입니다.
* **요청 URL에 `/v1/v1/messages`가 있음:** SDK base URL이 `/v1`로 끝납니다. `https://api.laozhang.ai`로 설정하세요.
* **404 또는 모델을 찾을 수 없음:** 정확한 모델 ID를 확인하고, [모델 및 가격](https://docs.laozhang.ai/ko/models.md)에서 내 토큰 그룹에 Anthropic Messages가 표시되어 있는지 확인하세요.
* **Claude Code가 `400 ValidationException` 또는 `Extra inputs are not permitted`를 반환:** [Claude Code 400 ValidationException 해결](https://docs.laozhang.ai/en/faq/claude-code-aws-400-validation-error.md)을 따르세요.
* **Claude 모델에서 `web_search` 등 서버 도구를 선언한 뒤 400:** `tools`에서 서버 도구를 빼세요. 검색은 애플리케이션에서 실행하고 결과를 `tool_result` 블록으로 돌려주세요.
* **업스트림 혼잡 메시지가 있는 529:** 피크 시간에 용량이 부족한 경우입니다. 잠시 기다렸다가 다시 시도하세요. Anthropic SDK는 기본적으로 529를 자동 재시도합니다.

타임아웃이나 5xx 오류가 났다면 요청을 다시 보내기 전에 [호출 로그](https://api.laozhang.ai/log)를 확인하세요. Python 예제는 자동 재시도를 꺼 두었으므로 재시도 시점은 애플리케이션에서 정합니다.

## 관련 문서

* [Anthropic Messages API 레퍼런스](https://platform.claude.com/docs/en/api/messages/create)
* [Anthropic 스트리밍 레퍼런스](https://platform.claude.com/docs/en/build-with-claude/streaming)
* [Anthropic 도구 사용 개요](https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview)
* [Anthropic 모델 개요](https://platform.claude.com/docs/en/models/overview)
* [OpenAI 프로토콜: Chat Completions](https://docs.laozhang.ai/ko/api-reference/chat-completions.md)
* [모델 사용 가능 여부와 권한](https://docs.laozhang.ai/en/faq/model-availability.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.