[AI 활용법 13] Tool 사용 전략 — 검색 · MCP · 코드 실행, 언제 어느 것
환각이 의심되면 검색. 외부 시스템이면 MCP. 컴퓨테이션이면 실행. 셋의 경계 그리기
시리즈 13편. LLM은 혼자 다 알지 않는다. 그게 단점이 아니라 도구를 쓸 줄 안다 는 강점. 단, 어느 도구를 언제 부를지가 핵심.
도구 3종
| 도구 | 무엇을 해결 | 언제 쓰나 |
|---|---|---|
| 웹 검색 | 환각, 최신 정보 | 버전·CVE·”요즘”·생소한 에러 |
| MCP | 외부 시스템 / 영속 상태 | DB, git, Jira, Obsidian, 회사 도구 |
| 코드 실행 | 정확한 컴퓨테이션, 파일 검증 | 계산, 파싱, 검증 스크립트 |
세 도구의 범위가 겹치지 않는다. 그래서 어느 것을 고를지 결정하는 게 가장 큰 가치.
웹 검색 — 환각 의심에 가장 먼저
다음 신호에서는 검색 먼저:
- “최신 / 요즘 / 현재” 같은 단어
- 라이브러리·프레임워크 버전 이 의문일 때
- 최근 CVE / 보안 권고
- 처음 보는 에러 메시지
- 모델의 학습 컷오프 이후 의 것
검색의 함정:
- 첫 결과만 보고 결론 내지 않기
- 1차 출처 (공식 문서) 우선 — Stack Overflow는 많이 틀린다
- 생성된 요약 이 원문 과 일치하는지 확인
LLM에게 “이거 검색해서 출처와 함께 알려 줘”가 좋은 디폴트.
MCP — 외부 시스템에 영속적 으로 붙기
MCP(Model Context Protocol)는 LLM 클라이언트 가 외부 도구/리소스 에 표준화된 방식으로 접근하는 프로토콜이다. stdio 기반 서버 하나를 띄우면 모든 MCP 호환 클라이언트(Claude Code, Claude Desktop)가 그 도구를 자동 인식.
쓰는 자리:
| 시스템 | MCP 가치 |
|---|---|
| Obsidian | 메모/ADR 검색 + 작성 |
| GitHub | PR 만들기, 이슈 조회 |
| Jira / Linear | 티켓 워크플로우 |
| Database | 읽기 전용 조회 (안전) |
| 사내 도구 | 권한 모델 그대로 |
MCP의 핵심 디자인 결정:
- read-only / mutating 분리 — 어느 호출이 쓰기 인지 명확
- 권한 — Claude Code의 권한 매처와 자연스럽게 결합
- stdio — 네트워크 노출 없이 로컬 만으로
LazyClaude의 Memex, PathSentinel 모두 MCP 서버를 주요 진입점 으로 둔 사례.
코드 실행 — 환각 안 나는 단 하나의 영역
LLM은 계산 을 의외로 못한다. 작은 산수에서도 틀린다. 이걸 막는 가장 단순한 방법: 계산은 코드에게.
# Don't: ask the model to compute average
# Do: ask the model to write code, then run it.
import statistics
print(statistics.mean([12.4, 7.8, 15.1, 9.0]))
# 11.075
코드 실행이 적합한 자리:
- 통계, 변환, 파싱
- 파일 형식 검증 (JSON 스키마, YAML)
- 정규식 매칭
- 작은 그래프/플롯 생성
- 다른 세 도구의 결과 를 합치기
숫자가 들어가는 답변은 코드 실행으로 검증 — 가장 단순한 환각 방어.
도구 사용의 순서
복잡한 작업의 디폴트 순서:
1. 검색 — 모르는 사실 채우기
2. MCP 조회 — 외부 시스템 상태 확인
3. 코드 실행 — 결과 검증/계산
4. 결과 보고 — 출처와 함께
이 순서를 명시적으로 시키면 LLM이 혼자 추측 하는 빈도가 줄어든다.
도구 호출의 비용
각 도구는 비용이 다르다:
| 도구 | 비용 | 지연 |
|---|---|---|
| 검색 | 쿼리당 (저렴) | 1~3s |
| MCP | 호출당 (거의 0) | 100ms ~ |
| 코드 실행 | 컴퓨트 | 1~10s |
불필요한 호출을 만들지 않게 하는 것도 가드레일. 캐시·메모이제이션·이미 안다 의 빠른 분기.
MCP를 직접 만들기
내 도구를 MCP로 노출하는 건 의외로 단순하다 — Anthropic의 SDK는 stdio를 내장.
# minimal MCP server (Python)
from mcp.server import Server
from mcp.types import Tool, TextContent
srv = Server("my-tool")
@srv.list_tools()
async def list_tools():
return [Tool(
name="echo",
description="Echo back the input",
inputSchema={"type":"object",
"properties":{"text":{"type":"string"}}},
)]
@srv.call_tool()
async def call_tool(name, args):
if name == "echo":
return [TextContent(type="text", text=args["text"])]
if __name__ == "__main__":
srv.run_stdio()
이 짧은 코드가 모든 MCP 클라이언트에 자동 으로 노출된다.
도구 사용 안티패턴 — 도구가 답이 아닐 때
LLM에게 이걸 도구 없이 답할 수 있는지 도 묻자. 다음 경우엔 도구를 안 쓰는 게 맞다:
- 작은 사실 회상 (모델이 안다)
- 단순한 코드 변환 (정규식 잘못 쓰면 더 나쁨)
- 이미 컨텍스트에 있는 정보
- 1+1 같은 간단한 산수 (이건 LLM도 한다…보통)
도구는 쓸 때 가치 가 있고, 남용하면 비용 이 된다.
한 줄 요약
도구 사용의 첫 결정은 “어느 도구를 쓰지 말지” 다. 다음이 “어느 순서로”.
다음 편: AI 활용법 14 — 응답 프로토콜과 작업 보고 형식 이전 편: AI 활용법 12 — 문서화 3계층