byteforce

CPN 한국어 자습서 · 러닝패스 2 / 4 — Building with the Claude API

도구 사용

웹 검색 도구

The web search tool

Claude에 내장된 또 하나의 도구, 웹 검색(web search)입니다. 이름 그대로 Claude가 최신·전문 정보를 웹에서 찾아 답에 반영합니다. 텍스트 편집 도구와 달리 우리가 실행을 구현할 필요가 없습니다 — 검색은 Claude가 전부 처리합니다. 우리는 작은 스키마 하나만 tools에 넣으면 됩니다.

전체 내레이션영상 나레이션 한국어 번역 (전체)

Stephen Grider · Anthropic 기술 스태프

Claude에는 또 하나의 도구가 곧바로 내장되어 있습니다. 이름은 웹 검색 도구입니다. 이름이 말해 주듯, 이 도구는 사용자의 질문에 답하기 위해 최신이거나 전문적인 정보를 웹에서 찾게 해 줍니다. 예를 들어 양자 컴퓨팅의 최신 동향을 물으면, Claude는 이 도구로 관련 최신 기사를 찾아 그 내용을 바탕으로 답을 구성할 수 있습니다.

텍스트 편집 도구와 달리, 실제 검색을 돌리는 구현을 우리가 제공할 필요가 없습니다. 검색은 전적으로 Claude가 처리합니다 — 그래서 이 도구는 쓰기가 정말 쉽습니다. 코드로 동작 방식을 살펴봅시다. 노트북 맨 아래에 Claude로 요청을 보내는 평소의 코드가 있고, 바로 위 셀에 web_search_schema라는 새 변수를 만듭니다. 이 스키마를 요청에 도구로 포함시켜 웹 검색 기능을 켭니다.

텍스트 편집 도구처럼, 우리는 아주 작은 스키마만 주면 됩니다 — 뒤에서 훨씬 큰 스키마로 확장됩니다. 필드를 몇 개 넣습니다. type은 web_search_20250305, name은 web_search, max_uses는 5. 지금은 그게 전부입니다. max_uses는 Claude가 검색을 돌릴 수 있는 횟수입니다. 한 번의 검색이 여러 결과를 돌려줄 수 있고, 그 결과의 내용에 따라 Claude가 후속 검색을 더 할 수도 있습니다. 이 과정은 여러 번 반복될 수 있어, 검색 횟수의 총합을 5로 제한해 둡니다.

그 셀을 실행한 뒤, 아래에서 "다리 근육을 키우는 데 가장 좋은 운동은?"이라고 묻고, 방금 만든 스키마를 tools로 넣습니다. 실행하면 응답이 오기까지 시간이 좀 걸립니다. 돌아오는 응답은 꽤 큽니다 — 정보가 엄청나게 많습니다. 이해를 돕기 위해, 이 messages content 리스트에서 많은 내용을 덜어 낸 축약본을 보겠습니다.

content 리스트에는 전에 못 본 블록이 여럿 들어 있습니다. 먼저 응답 전체를 여는 텍스트 블록이 옵니다 — Claude가 질문에 더 잘 답하려고 웹 검색을 하겠다고 말합니다. 다음으로 server tool use 블록이 보이는데, 그 안 input에 Claude가 웹을 검색할 때 쓴 바로 그 쿼리가 들어 있습니다. 그다음 web search tool result 블록이 오고, 그 안에 여러 개의 web search result 블록이 들어 있습니다 — 그 쿼리로 받은 검색 결과들입니다.

실제 응답에는 결과가 많지만, 여기선 하나만 남겼습니다. 이것이 실제 검색 결과 하나입니다 — Claude가 가져온 페이지의 제목과 실제 URL이 보입니다. 아직 본문 내용은 없습니다. 이건 Claude가 검색으로 무엇을 찾았는지만 알려 줍니다. 그다음 Claude가 사용자 질문에 답하기 시작하는데, 여러 텍스트 블록으로 답하며 그 안에 citations 리스트가 들어 있을 수 있습니다. citations는 Claude가 펼치는 주장을 어떤 식으로든 뒷받침하는 텍스트입니다 — 여기선 특정 웹 페이지를 인용하고, 그 구체적 텍스트로 자기 논점을 받쳐 줍니다.

웹 검색 스키마를 정의할 때 넣을 수 있는 필드가 여럿입니다. 사용자가 무엇을 물을지 잘 안다면 꼭 고려해 볼 필드가 하나 있습니다. 우리 경우 다리 근육을 키우는 운동을 물었죠. 온라인에는 AI로 자동 생성됐을 법한 블로그가 무수히 많고, 거기서 얻는 조언이 가장 정확하거나 최선이 아닐 수 있습니다. 반면 PubMed처럼 학술 논문을 모아 둔 사이트가 있습니다 — 미국 정부가 운영하며 의학 관련 학술 문헌이 가득합니다. 근거가 탄탄한 운동 조언을 거기서 찾을 수 있습니다.

그래서 Claude가 이 페이지만 검색하게 하면 좋겠죠. 그 도메인은 nih.gov입니다. 노트북으로 돌아가 web_search_schema에 allowed_domains 필드를 추가하고 ["nih.gov"] 리스트를 넣습니다. 이러면 Claude의 검색이 그 도메인으로만 제한되고 다른 곳은 찾지 않습니다. 셀을 다시 실행하고 요청을 보내면, 응답을 스크롤해 봤을 때 URL이 전부 nih.gov 도메인에 속하고 다른 건 없어야 합니다. 적어도 과학적으로 뒷받침된 조언만 사용자에게 주도록 보장할 수 있습니다.

마지막으로, 이 도구를 쓰면 돌아오는 이 거대한 블록 리스트를 실제로 어떻게 쓰도록 의도됐는지 보여 드리겠습니다. 발상은 이렇습니다 — 모든 텍스트 블록은 일반 텍스트로 렌더링하고, web search result 블록이나 citation web search result location을 만나면 그것들을 UI에 따로 그려서, 사용자가 "이 정보가 어떤 근거로 뒷받침되는지"를 한눈에 알 수 있게 합니다. 작은 페이지를 하나 만들어, 응답 메시지의 블록들을 받아 렌더링해 봤습니다.

맨 위에는 web search tool result 블록들을 모아 목록으로 둡니다 — Claude가 검색으로 찾은 페이지들입니다. 그다음 전체 블록 리스트를 순회하며 모든 텍스트 블록의 텍스트를 보여 줍니다. citation web search result location이 달린 텍스트 블록을 만나면, 작은 인용 카드로 렌더링합니다 — 도메인, 찾은 페이지의 제목, 정확한 주소, 그리고 인용된 텍스트까지요. 이렇게 하면 Claude가 실제로 어디서 정보를 얻었는지 사용자가 더 잘 이해할 수 있습니다.

이 장에서 배우는 것What you'll learn

약 7분
1

웹 검색 = Claude 내장 도구 — 최신·전문 정보를 웹에서 찾아 답에 반영

2

텍스트 편집 도구와 달리 구현 불필요 — 검색은 Claude가 전부 처리

3

작은 스키마: type web_search_20250305 · name · max_uses

4

max_uses = 총 검색 횟수 상한 — 후속 검색까지 합쳐 제한

5

응답 블록: text → server_tool_use(query) → web_search_tool_result → 인용 text

6

allowed_domains로 신뢰 사이트(nih.gov)만 검색 → 근거 있는 답

먼저 짚고 갈 용어
web search tool (웹 검색 도구)
Claude에 내장된 도구. 우리가 실행을 구현하지 않아도 Claude가 직접 웹을 검색해 결과를 답에 쓴다.
max_uses
한 요청에서 Claude가 검색을 돌릴 수 있는 총 횟수 상한. 후속 검색까지 합산된다.
server_tool_use 블록
Claude가 실행한 검색을 나타내는 블록. input에 실제 검색 쿼리가 담긴다.
web_search_tool_result 블록
검색 결과 묶음. 안에 여러 web_search_result(제목·URL)가 들어 있다.
citations (인용)
Claude가 답의 주장을 뒷받침하려고 단 근거. 도메인·제목·URL·인용문을 담는다.
allowed_domains
검색을 특정 도메인으로 제한하는 필드. 신뢰할 수 있는 출처만 쓰게 한다.

웹 검색 도구란

A built-in tool

웹 검색은 Claude에 내장된 도구입니다. 최신이거나 전문적인 정보를 웹에서 찾아 답에 반영합니다. 텍스트 편집 도구와 달리 우리가 실행을 구현할 필요가 없습니다 — 검색은 Claude가 전부 처리합니다.

왜 쉬운가

커스텀 도구는 우리가 함수를 만들고 tool_result를 돌려줘야 했습니다. 웹 검색은 그 과정이 없습니다 — 스키마만 주면 검색·결과 회수까지 Claude가 알아서 합니다.

웹 검색 도구 흐름 · 질문 → 검색 → 인용 답
1
2
3
4
USER

우리가 보내는 건 질문 하나뿐입니다. 검색·결과 수집·인용은 모두 Claude가 처리해 한 응답의 여러 블록으로 돌아옵니다.

스키마 정의 + 요청

Schema & request

텍스트 편집 도구처럼, 아주 작은 스키마만 주면 뒤에서 훨씬 큰 스키마로 확장됩니다. type·name·max_uses 세 필드로 시작합니다.

006_web_search.ipynb · web_search_schema
web_search_schema = {
    "type": "web_search_20250305",
    "name": "web_search",
    "max_uses": 5,
}

max_uses는 Claude가 검색을 돌릴 수 있는 총 횟수입니다. 한 번의 검색이 여러 결과를 돌려줄 수 있고, 그 내용에 따라 Claude가 후속 검색을 더 할 수도 있습니다. 그 반복까지 합쳐 5회로 제한해 둡니다.

이제 질문을 보내며 이 스키마를 tools에 넣습니다. 커스텀 도구와 똑같이 tools=[...]로 전달하면 됩니다.

질문 + tools=[web_search_schema]
messages = []
add_user_message(
    messages,
    """
    What's the best exercise for gaining leg muscle?
    """,
)
response = chat(messages, tools=[web_search_schema])
response
참고

응답은 시간이 조금 걸리고, 돌아오는 내용은 꽤 큽니다. 다음 단계에서 축약본으로 구조를 살펴봅니다.

응답 블록 읽기

Reading the blocks

응답 content 리스트에는 전에 못 본 블록이 여럿입니다. 이해를 돕기 위해 결과를 대폭 축약한 형태로 흐름을 봅니다.

응답 content (축약) · 4종 블록
# response content 리스트 (이해를 위해 대폭 축약)
[
    # (1) 답변을 여는 일반 텍스트 블록
    TextBlock(
        text="I'll help you find information about the best exercises ...",
    ),
    # (2) Claude가 실행한 검색 — 입력에 정확한 쿼리
    ServerToolUseBlock(
        input={
            "query": "best exercises building leg muscle strength scientific research"
        },
    ),
    # (3) Claude가 받은 검색 결과들
    WebSearchToolResultBlock(
        content=[
            WebSearchResultBlock(
                title="Gluteus Maximus Activation during Common Strength ...",
                type="web_search_result",
                url="https://pmc.ncbi.nlm.nih.gov/articles/PMC7######/",
            ),
            # ... 실제로는 결과가 여럿. 여기선 하나만 남김
        ],
    ),
    # (4) 인용을 단 텍스트 블록으로 최종 답을 이어 감
    TextBlock(
        text="Lower body exercises like squats and deadlifts ...",
        citations=[
            CitationsWebSearchResultLocation(
                url="https://pmc.ncbi.nlm.nih.gov/articles/PMC7######/",
                title="Gluteus Maximus Activation ...",
                cited_text="...the gluteus maximus must has dis...",
            ),
        ],
    ),
]
블록 4종 한눈에
  • TextBlock — 응답을 여는 일반 텍스트. 검색해서 답하겠다는 도입.
  • ServerToolUseBlock — Claude가 실행한 검색. input.query에 실제 쿼리.
  • WebSearchToolResultBlock — 검색 결과 묶음. 안에 WebSearchResultBlock(제목·URL).
  • TextBlock + citations — 인용을 달아 최종 답을 이어 감(도메인·제목·URL·인용문).

도메인 제한 + 렌더링

allowed_domains & rendering

사용자가 무엇을 물을지 안다면 allowed_domains가 강력합니다. 운동 조언이라면 AI 생성 블로그 대신 PubMed(미국 정부 운영, 도메인 nih.gov)처럼 근거 있는 출처만 검색하게 막을 수 있습니다.

allowed_domains 추가 · nih.gov만 검색
web_search_schema = {
    "type": "web_search_20250305",
    "name": "web_search",
    "max_uses": 5,
    "allowed_domains": ["nih.gov"],   # 이 도메인만 검색
}

다시 실행해 요청을 보내면, 응답의 URL이 전부 nih.gov 도메인에 속해야 합니다 — 과학적으로 뒷받침된 답만 사용자에게 주도록 보장합니다.

마지막으로, 돌아온 블록 리스트를 실제로 어떻게 쓰는지 봅니다. 텍스트 블록은 일반 텍스트로, 검색 결과인용은 UI에 따로 그려 이 정보가 어떤 근거로 뒷받침되는지를 사용자에게 보여 줍니다.

블록 → UI 렌더링 (발상)
# 응답의 블록들을 UI로 렌더링하는 발상
for block in response.content:
    if block.type == "web_search_tool_result":
        # 상단에 Claude가 찾은 페이지 목록을 보여 줌
        for result in block.content:
            show_source(result.title, result.url)

    elif block.type == "text":
        render_text(block.text)   # 본문은 일반 텍스트로
        if block.citations:
            for c in block.citations:
                # 도메인, 제목, 주소, 인용문을 작은 카드로
                render_citation(c.url, c.title, c.cited_text)
핵심

텍스트는 본문으로, 출처 목록인용 카드(도메인·제목·주소·인용문)는 따로 — 답의 신뢰를 눈에 보이게 만드는 것이 목적입니다.

MEMBER SESSION REQUIRED · REGISTRATION IS FREE

여기부터는 등록한 분에게 열립니다.

전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 76개 레슨을 끝까지 읽을 수 있습니다.

등록하고 이어서 읽기

이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.