OpenAI / Claude 에이전트에 실시간 웹 검색을 4단계로 추가하기

에이전트 답변을 최신 정보로 뒷받침하고 싶다면 두 가지가 필요하다: LLM 친화 스니펫을 반환하는 검색 API와 모델이 호출할 도구 정의. 이 가이드는 둘 다 4단계로 끝낸다.
한눈에
- •Step 1: API 키 발급(무료) 후 curl로 엔드포인트 동작 확인.
- •Step 2: API에서 OpenAI / Claude tool schema 직접 가져오기 — JSON 손으로 쓰지 않기.
- •Step 3: 에이전트(OpenAI Assistants, Anthropic Messages, LangChain, n8n)에 도구 등록.
- •Step 4: tool 핸들러로 /api/search/web 호출, 결과를 모델에 반환.
왜 이 글이 짧은가
'LLM에 웹 검색 추가' 튜토리얼이 길어지는 이유는 사실 검색 API SDK나 무거운 에이전트 프레임워크 가이드라서 그렇다. 이 글은 다르다. 일은 단순하다: 엔드포인트 고르기 → 도구 등록 → 5줄짜리 핸들러 작성.
1무료 API 키 받고 엔드포인트 호출하기
apipick.com/dashboard/api-keys에서 가입. 신규 계정 100 크레딧 무료, 카드 불필요. 키를 만들고:
curl -X POST https://www.apipick.com/api/search/web \
-H "x-api-key: pk_yourkey" \
-H "Content-Type: application/json" \
-d '{"query": "what is retrieval augmented generation"}'정리된 ranked 리스트(title, URL, snippet)가 돌아온다. curl에서 동작 확인하면 이후 디버깅 시간이 크게 준다.
2tool schema 가져오기(직접 쓰지 말 것)
API Pick은 GET /api/search/web/tool-schema에서 붙여 쓸 수 있는 tool schema를 제공. OpenAI 함수 정의와 Claude tool use 정의 모두 포함.
curl https://www.apipick.com/api/search/web/tool-schema결과는 캐시해도 된다 — 자주 변하지 않는다. 함수 schema 직접 작성은 에이전트 코드에서 가장 흔한 버그 출처(타입 오류, required 누락, description 부재).
3에이전트에 도구 등록
OpenAI Assistants
from openai import OpenAI
import requests
client = OpenAI()
schema = requests.get("https://www.apipick.com/api/search/web/tool-schema").json()
assistant = client.beta.assistants.create(
name="Research Agent",
model="gpt-4o",
instructions="Use web_search whenever the user asks about current events or anything that changes after your training cutoff.",
tools=[{"type": "function", "function": schema["openai"]}],
)Anthropic Claude
import anthropic
import requests
schema = requests.get("https://www.apipick.com/api/search/web/tool-schema").json()
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=[schema["claude"]],
messages=[{"role": "user", "content": "Summarise this week's RAG research."}],
)LangChain
from langchain.tools import tool
import requests
@tool
def web_search(query: str) -> dict:
"""Real-time web search. Use for any question that needs current information."""
return requests.post(
"https://www.apipick.com/api/search/web",
headers={"x-api-key": "pk_yourkey"},
json={"query": query},
).json()n8n
HTTP Request 노드 추가: 메서드 POST, URL https://www.apipick.com/api/search/web, 헤더 x-api-key: pk_yourkey, JSON 본문 {"query": "{{ $json.query }}"}. 에이전트 노드나 LLM Chain 노드에 연결. SDK 불필요.
4도구 호출 처리
OpenAI Assistants의 run이 requires_action으로 멈추면 검색 실행 후 결과 제출:
import json, time, requests
from openai import OpenAI
client = OpenAI()
KEY = "pk_yourkey"
def run_with_tool(thread_id: str, assistant_id: str):
run = client.beta.threads.runs.create(thread_id=thread_id, assistant_id=assistant_id)
while True:
run = client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run.id)
if run.status == "requires_action":
outputs = []
for call in run.required_action.submit_tool_outputs.tool_calls:
if call.function.name == "web_search":
args = json.loads(call.function.arguments)
result = requests.post(
"https://www.apipick.com/api/search/web",
headers={"x-api-key": KEY},
json=args,
).json()
outputs.append({"tool_call_id": call.id, "output": json.dumps(result)})
client.beta.threads.runs.submit_tool_outputs(
thread_id=thread_id, run_id=run.id, tool_outputs=outputs,
)
elif run.status in ("completed", "failed", "cancelled", "expired"):
return run
time.sleep(0.5)Anthropic Messages 루프도 비슷 — 응답에 tool_use 블록이 나오면 API 호출 후 다음 턴에서 tool_result 블록으로 회신.
루프 안정화 팁
- tool description은 모델 시점으로 작성: 'Use this when the user asks about current events, breaking news, or anything that may have changed after your training cutoff.' '이것은 웹 검색 API'라고만 쓰지 말 것.
- 같은 세션에서 반복되는 동일 query는 핸들러에서 캐시. 검색 결과는 분 단위로 안정적이라 같은 대화에서 15 크레딧 두 번 낼 필요 없음.
- 신선도가 중요하면
start_date추가. '이번 주 뉴스'를 날짜 필터 없이 보내면 작년 헤드라인이 자주 돌아온다.
다음 단계
에이전트가 검색할 수 있게 됐다면 자연스러운 다음은 링크를 읽기. URL 콘텐츠 추출 API를 두 번째 도구로 등록 — 같은 인증, 같은 JSON 형식, 호출당 최대 25 URL. '검색 + 추출'이 가장 작고 유용한 리서치 에이전트.
자주 묻는 질문
Assistants 대신 OpenAI Responses API에서도 사용 가능?
가능. 같은 tool schema를 client.responses.create()의 tools=[{...}]로 그대로 전달. 핸들러 형태도 동일: tool_calls 파싱, POST /api/search/web 호출, JSON 반환.
결과를 모델에 돌려주기 전에 포맷팅이 필요한가?
불필요. POST /api/search/web가 ranked title + URL + LLM 친화 snippet을 반환한다. 원본 JSON을 그대로 도구 결과로 넘기면 모델이 snippet을 인용하고 URL을 링크한다.
에이전트 1턴당 비용은?
웹 검색 1회 15 크레딧($5/5,000 환산 약 $0.015). 도구를 한 번 쓰는 일반 1턴의 검색 비용은 1센트 미만. 비용의 대부분은 LLM 토큰.
모델이 도구를 호출하지 않으면?
tool description을 구체적으로. 'Use this for any question that requires current or post-training information'이 'web search'보다 훨씬 잘 동작한다. 모델은 '이 도구가 무엇을 하는지' 이해하면 알아서 사용한다.
국가나 날짜로 제한 가능?
가능. country_code(ISO 3166-1 alpha-2), start_date / end_date(YYYY-MM-DD)를 전달. 모델이 직접 선택하게 하려면 tool schema에 파라미터로 포함, 에이전트가 고정 locale이나 신선도 요건이 있다면 핸들러에 직접 박아 넣어도 된다.
이 글에서 사용한 API
Sarah Choy는 API Pick의 CEO입니다. AI 에이전트와 LLM 워크플로를 위한 프로덕션 등급 API에 대해 씁니다.