[3편] 코드 전용 LLM의 필요성

Fill-in-the-middle이 안 되는 모델은 쓸 수 없다

by 오유나
이 글은 Pragmatic Engineer 뉴스레터 내 Building Windsurf with Varun Mohan을 바탕으로 작성되었습니다.
Windsurf의 CEO 바룬 모한(Varun Mohan)과의 인터뷰를 통해, 단순히 LLM으로 코드를 생성하는 기술을 넘어서, AI 에이전트 시대에 우리가 재정의해야 할 문제 해결력, 개발자의 역할, 그리고 신뢰할 수 있는 도구와 조직이란 무엇인지 실무자의 시선으로 되짚어봅니다.


많은 AI 모델들이 텍스트 생성에는 강하지만, 코드 생성에는 그다지 적합하지 않다는 이야기를 들어본 적 있을 것입니다. Windsurf 팀은 이 문제를 누구보다 먼저 체감한 팀이기도 합니다. 그들은 코드를 잘 작성하는 모델을 원했지만, 당시의 오픈소스 모델들로는 만족할 수 없었습니다.

그래서 내린 결론은 단 하나였습니다.

"우리가 직접 학습시켜야 한다."


오픈소스 모델의 한계 – 왜 직접 만들어야 했나

Varun은 Salesforce의 CodeGen 모델을 예로 들며 이렇게 말합니다.

"CodeGen은 훌륭한 시도였지만, 우리가 필요한 기능 중 가장 중요한 것이 빠져 있었습니다.
바로 fill-in-the-middle입니다."


Fill-in-the-middle은 코딩 도중 함수의 중간이나 줄 중간, 혹은 이미 있는 코드 사이에 새로운 내용을 삽입해야 할 때 필요한 기능입니다. 이는 텍스트 생성 모델이 주로 사용하는 next-token prediction 방식과는 전혀 다른 요구를 합니다.


일반적인 LLM은 입력의 끝에 무언가를 붙이는 데 최적화되어 있습니다. 하지만 코드 작성은 '중간에 들어가는 것'이 더 일반적인 작업입니다. 예를 들어 아래와 같은 상황을 생각해 봅시다.


return RETU

이 상황에서 모델은 RN, 공백, 다음 토큰 등을 예측해야 합니다.

하지만 RETU라는 토큰은 학습 데이터에 거의 존재하지 않았을 것이고,

모델은 이를 out-of-distribution으로 간주하게 됩니다.

Varun은 이 문제를 이렇게 정리합니다.

"이건 단순히 사후 학습(post-training)으로 해결할 수 있는 문제가 아닙니다.
아예 프리트레인 시점에서 설계가 달라야 합니다."


코드 전용 모델은 AST와 커밋 히스토리까지 학습한다

Windsurf는 단순히 코드 파일을 학습시키는 것이 아니라,

실제 개발자들이 어떻게 코드를 바꾸는지를 모델이 학습하도록 합니다. 그 방법은 독창적입니다.

오픈소스 저장소의 커밋 히스토리를 활용

코드 변경 전과 후, 그리고 PR 설명을 추출

설명(의도) → 수정 파일 선택 → 구체적 코드 수정 순서로 재구성


이를 통해 모델은 단순히 문장을 완성하는 것이 아니라, "이 기능을 추가하려면 어디에 어떤 코드를 수정해야 하는가"라는 고차원적인 reasoning을 학습하게 됩니다.

게다가 Windsurf는 단일 파일이 아니라 코드베이스 전체를 구조적으로 이해하는 데 집중합니다. 이를 위해 AST(Abstract Syntax Tree), 코드 간의 연결성, 디렉터리 구조, 클래스 계층 등을 파악하고, 이를 기반으로 knowledge graph를 구성합니다.

"개발자들이 수정한 커밋 기록은 최고의 학습 데이터입니다.
이 안에 진짜 소프트웨어 공학의 흐름이 담겨 있습니다."


Retrieval + 코드 변경 히스토리 = 확장 가능한 LLM

단순히 모델이 똑똑해지는 것만으로는 충분하지 않습니다. 실제 소프트웨어 개발 환경에서는, 다음과 같은 질문에 답할 수 있어야 합니다:

이 함수가 수정되었을 때, 어떤 테스트 코드를 함께 고쳐야 하나?

이 디렉터리에 새로운 API를 만들면, 어디에 등록해야 하나?

이 커밋 메시지의 목적을 달성하려면 어떤 순서로 수정해야 하나?


이런 질문에 답하기 위해 Windsurf는 LLM만으로는 부족하다는 걸 알고 있었습니다.

그래서 retrieval 시스템, knowledge graph, 파일 간 연관성 계산기 등을 LLM의 보조 시스템으로 결합합니다.


코드라는 세계의 고유한 제약과 기회

Varun은 코드 생성과 텍스트 생성의 결정적인 차이를 이렇게 정리합니다.

"텍스트는 흐름이 중요하지만, 코드는 정확성과 연관성이 중요합니다. 그리고 무엇보다 '돌아가야' 합니다."


이 말은 코드가 '실행 가능한 언어'라는 점에서, 모델의 출력이 단순히 자연스러워 보이는 것만으로는 부족하다는 뜻입니다. 정확한 구문, 타입 일관성, 라이브러리 호출의 정확도가 모두 맞아떨어져 야만 좋은 코드가 됩니다.


Windsurf는 이를 위해 LLM이 단순한 제안자가 아니라, 구조와 맥락을 이해하고 유지보수 가능한 코드를 생성하는 협업자가 되어야 한다고 봅니다. 그래서 자체 모델을 학습시키고, 그 모델을 IDE와 깊게 통합하며, 코드베이스 전체를 운영체제처럼 탐색할 수 있게 만들었습니다.


4편에서는 Windsurf의 Cascade(에이전트 기능)가 어떻게 개발되었는지, 초창기 실패와 전환점, 그리고 IDE를 넘는 개발자의 새로운 작업 흐름에 대해 다룹니다.

keyword
화, 목, 토 연재
이전 21화[2편] 우리는 추론 중에도 파인튜닝을 한다