머신러닝AI2026. 9. 20. 23:45

Claude Code는 꼭 Anthropic 서버에 붙어야만 동작하는 것은 아니다. Anthropic Messages API 형식으로 응답하는 서버만 있으면 어디든 붙는다. 이 점을 이용해 맥스튜디오(Mac Studio, 64GB이상 권장)에서 로컬 모델로 Claude Code를 구동했다. 구동 과정은 API 비용도 외부 전송도 없다(웹 검색만 예외).

ㅇ원리

claude CLI ──(Anthropic /v1/messages)──▶ oMLX :8000 ──▶ SuperQwen3.8-27B (MLX)
     └──(MCP over HTTP)──▶ SerpApi (웹 검색 / 소량 무료)

- API 호환: MLX 서빙 서버인 oMLX가 OpenAI 형식과 함께 Anthropic 형식 엔드포인트도 제공한다. ANTHROPIC_BASE_URL만 로컬로 바꾸면 해당 LLM서버를 호출해서 작동한다. OpenAI 호환방식과는 약간 차이가 있으니, vllm같은 다른 서버 환경을 사용한다면 AI와 추가로 상의해보자.

- Tool Call 호환: Claude Code의 파일 읽기, 편집, 셸 실행은 전부 tool call이다. 서버가 모델의 Tool Call 출력(Qwen은 XML 변형 포맷)을 Anthropic의 tool_use 블록으로 변환해 주면 해당 처리가 문제없이 가능하다. 따라서 이것은 oMLX의 변환지원 여부를 확인하면 되고, oMLX는 이를 잘 지원한다.
- 검색 보강: 내장 WebSearch는 Anthropic 서버에서 실행되는 도구라 로컬에서는 동작하지 않는다. 이를 막고, SerpApi의 MCP 서버를 대신 붙였다. 다른 MCP서비스를 이용해도 상관없다.

 


1. 모델 서버 띄우기

별도 venv에 oMLX를 설치하고, 모델을 ~/.omlx/models/ 아래에 둔다. 디렉터리 이름이 곧 모델 ID다.

$ python3.13 -m venv ~/dev/omlx-venv && ~/dev/omlx-venv/bin/pip install omlx
$ omlx serve --model-dir ~/.omlx/models --host 0.0.0.0 --port 8000 --no-hf-cache

상시 구동은 LaunchAgent로 등록한다. SuperQwen3.8-27B 8bit은 약 28GB가 상주하고, MTP(추측 디코딩) 드래프터를 붙이면 코드 생성이 약 30 tok/s 나온다. --no-hf-cache를 빼면 HF 캐시의 모든 모델이 목록에 노출된다.

 


2. ~/.zshrc에 설정 등록

 

claude로 기존 실행은 그냥 두고 claude-local 명령을 셋팅해서 필요할때 local로 붙도록 한다. mcp를 통한 웹검색도 따라서 claude-local일때말 활성화 한다. 궣난은 bypassPermissions를 이용한다. auto mode는 제대로 작동하지 않기 때문이다.

 

--------------------------------------------------------------------------------------
_claude_omlx() {
  local m="$1"; shift
  ANTHROPIC_BASE_URL=http://localhost:8000 \
  ANTHROPIC_API_KEY=dummy \
  ANTHROPIC_MODEL="$m" \
  ANTHROPIC_DEFAULT_OPUS_MODEL="$m" \
  ANTHROPIC_DEFAULT_SONNET_MODEL="$m" \
  ANTHROPIC_DEFAULT_HAIKU_MODEL="$m" \
  CLAUDE_CODE_SUBAGENT_MODEL="$m" \
  ANTHROPIC_SMALL_FAST_MODEL="$m" \
  CLAUDE_CODE_MAX_CONTEXT_TOKENS=262144 \
  CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
  command claude --permission-mode bypassPermissions --disallowedTools WebSearch \
    --mcp-config ~/.claude/mcp-local-search.json "$@"
}
claude-local() { _claude_omlx SuperQwen3.8-27b-abliterated-8bit "$@"; }

--------------------------------------------------------------------------------------

 

설정을 자세히 보자


- 모든 모델 호출을 같은 모델로 매핑: Claude Code는 내부적으로 opus, sonnet, haiku와 서브에이전트용 모델을 따로 호출한다. 하나라도 빠지면 존재하지 않는 모델 ID로 요청이 나가 에러가 난다.
- 환경변수를 함수 안에만 설정: export하지 않았으므로 평소의 claude는 그대로 Anthropic에 붙는다. claude-local로 실행한 세션에만 적용된다.
- API 키는 더미: 로컬 서버는 키를 검증하지 않는다. 다만 값이 비어 있으면 로그인 절차로 빠진다.
- DISABLE_NONESSENTIAL_TRAFFIC: 텔레메트리와 업데이트 확인 같은 외부 호출을 끈다.
- bypassPermissions: 매 도구 호출의 승인 프롬프트를 없앤다. 로컬 모델은 느려서 프롬프트마다 흐름이 끊기는 것이 특히 불편하다. 다만 모델이 셸 명령을 확인 없이 실행하므로 신뢰하는 작업 디렉터리에서만 써야 한다.

 


3. 검색 도구: SerpApi MCP

~/.claude/mcp-local-search.json:

{
  "mcpServers": {
    "serpapi": {
      "type": "http",
      "url": "https://mcp.serpapi.com/mcp",
      "headers": { "Authorization": "Bearer ${SERP_API_KEY}" }
    }
  }
}

serpapi 키는 ~/.zshrc에 export SERP_API_KEY=...로 두면 ${}로 확장된다. --mcp-config로 넘기므로 로컬 세션에서만 활성화된다. 모델 입장에서는 MCP 도구도 일반 tool call과 같아서, "검색해 줘"라고 하면 알아서 호출한다. 검색 쿼리만은 SerpApi로 나간다.

 


4. 사용

 

아래와 같이 claude code 실행시 "claude-local"이라고 입력해서 실행한다.

 

$ claude-local              # 대화형
$ claude-local -p "이 레포 구조 요약해줘"

써 보니

- 파일 탐색, 수정, 테스트 실행 같은 일상 에이전트 작업은 충분히 된다. Tool Call 벤치에서도 Qwen 계열이 안정적이었다.
- Claude Code는 시스템 프롬프트와 도구 정의만 수만 토큰이라 첫 턴이 길다. 27B 밀집 모델은 프리필이 약 100 tok/s라 체감 대기가 있다. 이후 턴은 프롬프트 캐시 덕에 빠르다.
- thinking이 길어지는 모델은 서버 쪽에서 thinking_budget을 걸어야 턴이 끝난다.
- 복잡한 설계나 장기 추론은 여전히 본가 Claude가 낫다. 민감한 코드, 오프라인, 반복 작업은 로컬로, 나머지는 claude로 나눠 쓰는 방법도 있다.

 

 

5. 기타

 

 claude code를 로컬로 실행하기 위해서는 tool call 호환, web fetch등의 기본 툴 이용, auto mode의 대안 탐색 필요가 중요하다. 그리고 claude code 버전별로 형태가 달라질 수 있으니 실행시 오류는 claude code와 상의할 수 있다. 또한 여러 agent가 구동되면 토큰처리도 병렬이 필요하므로, 충분한 용량의 메모리가 필요한 부분은 고려가 필요하다.

---

반응형
Posted by 작동미학