Zed + LM Studio + Gemma4 E4B — 로컬 AI 코딩 환경

VS Code를 꽤 오래 썼다. 익숙하고, 확장 생태계도 방대하고, 모르는 사람이 없다는 것 자체가 일종의 안전망이었다. 그런데 어느 순간부터 에디터를 켤 때마다 느끼는 묵직함이 쌓이기 시작했다. 탭이 많아질수록 버벅거리고, 설치된 익스텐션들이 서로 충돌하고, 설정 파일은 어느새 수백 줄이 넘어 있었다. 코드를 쓰는 도구인데, 도구를 관리하는 데 시간을 쓰고 있다는 느낌이었다.

VS Code에서 Zed로 갈아탄 이유

Zed는 2024년 초 오픈소스로 전환된 Rust 기반 코드 에디터다. 전환을 결심하게 된 이유는 크게 세 가지였다.

첫째는 속도다. Zed는 Electron 없이 GPU 렌더링으로 직접 UI를 그린다. 파일 열기, 전체 검색, 탭 전환이 체감상 즉각적이다. VS Code에서 대형 프로젝트를 열 때 기다리는 그 1~2초가 없다. 처음엔 사소하게 느껴졌는데, 하루 종일 쓰다 보면 그 차이가 꽤 크게 다가온다.

둘째는 단순함이다. Zed는 기본 설치 상태에서 이미 쓸 만하다. LSP(언어 서버 프로토콜), Git 통합, AI 어시스턴트, 멀티 커서, 분할 편집 — 별도 익스텐션 없이 기본 탑재다. VS Code가 “원하는 기능은 직접 찾아서 설치하라”는 철학이라면, Zed는 “이 정도면 충분하지 않냐”는 태도로 설계되어 있다. 설정 파일도 settings.json 하나로 관리된다.

셋째는 AI 기능이 에디터에 처음부터 내장되어 있다는 점이다. VS Code에서는 Copilot이나 Codeium 같은 익스텐션을 따로 설치하고, AI 패널은 또 별도 뷰로 관리해야 한다. Zed는 어시스턴트 패널과 인라인 편집이 에디터 기본 기능이다. 설치 직후부터 Cmd + ?로 AI와 대화하고, 코드를 선택해 인라인으로 수정을 요청할 수 있다.

개인적으로 덧붙이자면, 개발 도구가 가벼울수록 집중력이 올라간다고 생각한다. 에디터가 복잡해질수록 “이 기능이 어디 있었더라”, “이 단축키가 어떤 익스텐션에서 왔더라” 같은 메타 인지 비용이 늘어난다. Zed는 그 비용이 낮다. 물론 VS Code의 방대한 확장 생태계와 비교하면 아직 부족한 부분이 있고, JetBrains 계열의 깊은 언어별 지원에는 미치지 못한다. 하지만 빠르고 군더더기 없는 에디터를 원한다면 지금 시점에서 가장 현실적인 대안이다.

그런데 Zed로 옮긴 뒤 AI 기능을 쓰려다 보니 자연스럽게 다음 질문이 생겼다. 에디터는 가볍고 코드는 로컬에 있는데, AI 요청만 외부 서버로 보내는 게 맞는가. 코드 컨텍스트가 통째로 OpenAI나 Anthropic 서버를 거쳐간다는 게 어딘가 어색했다. 처음엔 Ollama로 시작했다. 설치가 간단하고 터미널 명령 몇 줄로 모델을 바로 받아 쓸 수 있어서 진입 장벽이 낮다. 그런데 쓰다 보니 불편한 점이 생겼다. 현재 어떤 모델이 메모리에 올라가 있는지, 얼마나 쓰고 있는지 확인하려면 터미널을 따로 열어야 했고, 파라미터를 바꿔가며 실험하는 것도 번거로웠다. 결국 LM Studio로 갈아탔다. 체감 속도도 달랐다. 동일한 모델, 동일한 하드웨어에서 LM Studio가 Ollama보다 약 11% 빠른 토큰 생성 속도를 보였다. 미세한 차이 같지만 짧은 질문에 반복적으로 답받는 상황에서는 꽤 느껴진다. GUI에서 모델 다운로드, 서버 시작, 메모리 사용량 모니터링, 파라미터 조정을 한 화면에서 처리할 수 있고, Ollama와 달리 현재 로드된 모델 상태가 실시간으로 보인다. CLI보다 시각적으로 확인하면서 쓰는 쪽이 편하다는 걸 느꼈다. 에디터도 로컬, 모델도 로컬 — 처음부터 끝까지 내 기기 안에서 끝나는 구조다.

Gemma 4 E4B는 어떤 모델인가

Gemma 4 E4B는 Google이 2025년에 공개한 Gemma 4 시리즈의 경량 변형이다. E4B는 “Effective 4B”의 약자로, 임베딩을 포함하면 8B 파라미터지만 실제 추론에 관여하는 유효 파라미터는 4.5B 수준이다. Q4_K_M 양자화(quantization) 기준으로 디스크 용량은 9.6GB, 컨텍스트 윈도우는 131,072 토큰이다.

무엇보다 눈길을 끄는 건 기능의 범위다. 텍스트 완성, 이미지 입력(비전), 오디오 처리, 도구 호출(function calling), 그리고 사고(thinking) 모드까지 지원한다. 소형 모델에서 이 정도 기능을 갖춘 경우는 드물다. 코딩 벤치마크인 LiveCodeBench에서 52.0%, MMLU Pro에서 69.4%를 기록했다.

설치 방법

1. LM Studio 설치

lmstudio.ai에서 macOS 또는 Windows 버전을 내려받아 설치한다. macOS는 Apple Silicon과 Intel 빌드가 별도로 제공되니 맞는 버전을 선택한다.

설치 후 LM Studio를 실행하면 로컬 서버가 `http://localhost:1234`에서 뜬다. 메뉴바의 서버 아이콘으로 실행 상태를 확인할 수 있다.

2. Gemma 4 E4B 모델 다운로드

LM Studio 좌측 사이드바에서 검색(돋보기) 아이콘을 클릭한 뒤 gemma-4-e4b로 검색한다. Google의 gemma-4-e4b 항목을 찾아 원하는 양자화 버전을 내려받는다. Q4_K_M 기준 약 9.6GB다.

다운로드가 끝나면 좌측 사이드바의 개발자(Developer) 탭에서 모델을 선택하고 서버를 시작한다. 서버가 실행되면 `http://localhost:1234/v1`로 OpenAI 호환 API가 활성화된다.

3. Zed 설치

zed.dev에서 macOS 또는 Linux 버전을 내려받거나, macOS는 Homebrew로:

brew install --cask zed

4. Zed settings.json에 LM Studio 연결

Zed를 열고 Cmd + ,로 설정을 연다. 또는 커맨드 팔레트(Cmd + Shift + P)에서 zed: open settings를 실행하면 settings.json 파일이 열린다.

Zed의 설정 파일은 JSONC(JSON with Comments) 형식이라 마지막 항목에 쉼표가 붙어도 파싱 오류 없이 동작한다.

다음 내용을 추가한다:

{
  "language_models": {
    "openai": {
      "api_url": "http://localhost:1234/v1",
      "available_models": [
        {
          "name": "google/gemma-4-e4b",
          "max_tokens": 131072,
          "supports_tools": true,
          "supports_images": true
        }
      ]
    }
  },
  "agent": {
    "default_model": {
      "provider": "lmstudio",
      "model": "google/gemma-4-e4b"
    },
    "dock": "right",
    "favorite_models": [],
    "model_parameters": []
  }
}

LM Studio는 OpenAI 호환 API를 제공하기 때문에 Zed에서 language_models.openai 섹션을 재사용한다. api_url을 LM Studio의 로컬 주소(http://localhost:1234/v1`)로 지정하면 된다.agent.default_modelprovider“lmstudio”로 명시한다. 모델명은 LM Studio에서 실제로 불러온 모델 식별자(google/gemma-4-e4b)와 일치시켜야 한다.max_tokens`를 131072로 명시하지 않으면 기본값 4,096으로 잡혀 실제 컨텍스트 윈도우를 제대로 활용하지 못한다.

5. 어시스턴트 패널 열기

설정을 저장한 후 Cmd + ?로 에이전트 패널을 연다. dock: "right" 설정 덕분에 패널이 오른쪽에 고정된다. 이후 모든 AI 요청은 로컬 LM Studio를 통해 처리되며 외부 서버로 나가는 트래픽은 없다.

터미널과 코드 화면이 함께 보이는 개발 환경

이미지 출처: Unsplash

한 단계 더: MCP로 웹검색 연결하기

여기까지만 해도 충분히 쓸 만한 로컬 AI 환경이지만, 한 가지 아쉬운 점이 남는다. 로컬 모델은 학습 시점 이후의 정보를 모른다. 최신 라이브러리 버전, 어제 올라온 GitHub 이슈, 방금 릴리스된 패키지 변경 내역 — 이런 것들을 물어보면 자신 있게 틀린 답을 내놓는다.

이 문제를 해결하는 방법이 MCP(Model Context Protocol)다. MCP는 Anthropic이 제안한 개방형 프로토콜로, AI 모델이 외부 도구(웹 검색, 파일 시스템, 데이터베이스 등)를 표준화된 방식으로 호출할 수 있게 해준다. Zed는 MCP를 기본 지원하며, context_servers 설정으로 로컬에서 실행 중인 MCP 서버를 연결할 수 있다.

구조는 단순하다.

Zed AI 어시스턴트 (Gemma 4)
    ↓ tool call
gemma-mcp (stdio MCP 서버)
    ↓ DuckDuckGo
웹 검색 결과 반환

Gemma 4가 답하기 어려운 질문을 받으면 MCP 서버에 웹 검색 도구 호출을 보내고, 서버가 DuckDuckGo로 검색해 결과를 돌려주는 식이다. 모든 과정이 로컬에서 처리된다. 외부 AI API를 거치지 않고, 검색 결과만 DuckDuckGo를 통해 가져온다.

MCP 서버 준비

MCP 서버는 ddgs 라이브러리를 이용해 DuckDuckGo 검색을 수행하는 Python 스크립트다. 먼저 의존성을 설치한다.

pip3 install ddgs

설치 확인:

python3 -c "from ddgs import DDGS; print('ok')"

MCP 서버 스크립트(gemma_mcp.py)는 ~/.local/bin/에 저장한다. 이 서버는 별도의 RPC 프레임워크 없이 순수 Python으로 구현한 stdio JSON-RPC 서버로, Gemma 4가 호출할 수 있는 도구들을 노출한다.

노출하는 도구:

  • web_search — DuckDuckGo 검색
  • duckduckgo_web_search — 동일 기능 (alias)
  • search — 동일 기능 (alias)
  • read_file — 로컬 파일 읽기
  • list_files — 디렉토리 목록
  • search_in_files — grep 검색

alias가 여럿인 이유가 있다. Gemma 4가 도구 이름을 hallucinate(환각)하는 경우가 있다. web_search를 써야 하는 상황에서 duckduckgo_web_searchsearch를 호출하는 식이다. 이를 No tool named X exists 오류로 처리하는 대신, 어떤 이름으로 불러도 같은 기능이 실행되도록 alias를 여러 개 등록해둔 것이다. 소형 모델의 현실적 한계를 우회하는 실용적인 해결책이다.

Zed settings.json에 MCP 서버 추가

context_servers 섹션을 추가한다:

{
  "language_models": {
    "openai": {
      "api_url": "http://localhost:1234/v1",
      "available_models": [
        {
          "name": "google/gemma-4-e4b",
          "max_tokens": 131072,
          "supports_tools": true,
          "supports_images": true
        }
      ]
    }
  },
  "context_servers": {
    "gemma-mcp": {
      "command": {
        "path": "/opt/homebrew/opt/python@3.12/libexec/bin/python3",
        "args": ["/Users/{사용자명}/.local/bin/gemma_mcp.py"]
      },
      "settings": {}
    }
  },
  "agent": {
    "default_model": {
      "provider": "lmstudio",
      "model": "google/gemma-4-e4b"
    },
    "dock": "right",
    "favorite_models": [],
    "model_parameters": []
  }
}

path는 Python 실행 파일의 절대 경로다. which python3으로 실제 경로를 확인한다. Homebrew로 설치한 Python 3.12라면 /opt/homebrew/opt/python@3.12/libexec/bin/python3 형태가 된다.

설정을 저장하면 Zed가 MCP 서버를 자동으로 시작한다. 에이전트 패널에서 도구 목록에 web_search 등이 나타나면 연결 성공이다. 도구가 보이지 않으면 Zed를 완전히 재시작(Cmd + Q)한다.

트러블슈팅

웹검색이 동작하지 않을 때 확인할 것들:

LM Studio 서버가 실행 중인지 먼저 확인한다. http://localhost:1234`가 열려 있어야 Gemma 4가 응답한다.ddgs` 라이브러리가 설치됐는지도 점검한다.

MCP 서버 연결 자체가 끊기거나 timeout이 발생한다면 Zed 로그를 확인한다:

cat ~/Library/Logs/Zed/Zed.log | grep context_server

여기서 오류 메시지를 보면 Python 경로가 잘못됐는지, MCP 스크립트 파일을 찾지 못하는지 파악할 수 있다.

실제로 써보니

짧은 함수 작성이나 코드 설명, 간단한 리팩터링 제안에서는 속도와 품질 모두 쓸만하다. 컨텍스트 창이 12만 토큰이 넘기 때문에 파일 전체를 넣고 “이 코드에서 문제 될 부분 찾아줘” 식의 요청도 가능하다. 실제로 Zed의 인라인 어시스턴트(Ctrl + Enter) 기능도 자주 쓴다. 수정하고 싶은 코드를 선택한 뒤 Ctrl + Enter를 누르면 선택 영역 바로 위에 프롬프트 창이 뜬다. “이 함수 async로 바꿔줘”처럼 입력하면 AI가 수정된 코드를 기존 코드와 초록/빨간 diff 형태로 인라인 표시해준다. Accept하면 바로 반영, Reject하면 원래대로 — VS Code의 Copilot 인라인 채팅과 같은 개념이다.

MCP 웹검색이 붙으면 사용 범위가 꽤 넓어진다. “이 라이브러리 최신 버전이 뭐야”, “이 오류 메시지 검색해줘” 같은 요청도 처리된다. 모델이 모르는 최신 정보를 검색으로 보완하는 구조라 단순 질답보다 훨씬 실용적이다.

반면 복잡한 멀티파일 아키텍처 설계나 긴 추론이 필요한 작업에서는 한계가 분명히 드러난다. GPT-4o나 Claude Sonnet과 비교하면 지시를 따르는 일관성이 떨어지고, 길어진 대화에서 앞서 정의한 맥락을 놓치는 경우도 있었다. 도구 호출 성공률이 들쭉날쭉한 점도 아직 아쉬운 부분이다.

LM Studio의 장점은 GUI다. 모델 다운로드, 서버 시작, 파라미터 조정을 모두 화면에서 할 수 있어 CLI가 익숙하지 않은 사람도 쉽게 접근할 수 있다. 현재 로드된 모델 상태나 메모리 사용량도 실시간으로 확인 가능하다.

전반적인 느낌은 “만능 AI 페어 프로그래머”보다는 “항상 곁에 있는 빠른 검색 도구”에 가깝다. 인터넷이 없는 환경에서도 쓸 수 있고, 코드가 외부로 나가지 않으며, 응답 비용이 전기료 이외엔 없다. 클라우드 AI를 완전히 대체하기보다는 “일상적인 질문은 로컬로, 무거운 작업은 클라우드로” 분리하는 방식이 지금으로선 가장 현실적인 운영 방법이다.

M 시리즈 맥이나 메모리가 넉넉한 Windows PC라면 한 번 시도해볼 만하다. LM Studio와 Zed 양쪽 모두 업데이트 속도가 빠르고, MCP 생태계도 빠르게 확장되고 있다. Gemma 5나 다음 세대 소형 모델들이 나올수록 이 조합의 실용성은 자연히 올라간다. 로컬 AI의 한계가 어디까지 좁혀지는지 직접 확인해보는 것, 그것 자체도 꽤 흥미로운 실험이다.


출처

댓글 남기기