Cline AI 어시스턴트는 매혹적이다
원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기
어제 Cline AI 어시스턴트를 써 봤는데, 이후 5시간 동안 넋을 놓고 Cline이 버그를 고치는 모습만 멍하니 바라봤다.
전문 개발자로서 그 경험은 매혹적이면서도 두려웠다. AI가 이 정도 수준에 도달했다는 사실이 매혹적이다. 그리고 같은 이유로 두렵기도 하다. AI가 나보다 더 잘, 더 빠르게 코드를 작성하는 세상에서 나는 어떤 역할을 해야 할지 모르겠기 때문이다.
이 흐름에 남들보다 늦게 합류한 셈이다. 이미 대부분의 개발자는 AI 도구를 워크플로에 훨씬 깊숙이 통합했다는 걸 알고 있다. 하지만 아직 이런 경험을 해보지 못한 사람들을 위해 내가 본 것을 공유하고 싶었다.
예전에도 AI 도구를 써봤다
Cline이 AI를 처음 써 본 것은 아니다.
지난 2년간 LLM 어시스턴트를 실험해 왔다. 특히 최근 6개월 동안은 모델이 신뢰할 만한 올바른 코드를 만들어내는 수준에 도달하면서 훨씬 더 많이 활용하기 시작했다.
나는 검색 엔진으로 Kagi를 사용하고 있는데, Ultimate 요금제를 쓰면 주요 LLM을 무제한으로 이용할 수 있다. 주로 Kagi Assistant 기능을 통해 LLM과 대화하는데, 그냥 LLM과 채팅하는 웹 UI다.

내가 쓰는 검색 엔진 Kagi는 주요 LLM을 모두 쓸 수 있는 깔끔한 웹 채팅 인터페이스를 제공한다.
밝혀두자면, 나는 Kagi 크라우드펀딩에 참여해서 Kagi에 약간의 금전적 투자를 하고 있다. 정확히 어떤 구조인지는 나도 잘 모르겠다.
AI 도구를 쓰면 내가 봇이 된 기분이다
최근 느낀 문제는 AI 도구를 쓰면 내가 기계가 된 것 같은 기분이 든다는 것이었다. 에디터와 채팅창 사이에서 멍하니 코드를 복사해 붙여넣고, “안 되는데요”라고 말하며 에러 메시지를 붙여넣는 일을 네다섯 번씩 반복할 뿐이었다.


챗봇 LLM이 버그에 대해 계속 잘못된 수정 방법을 알려주고, 전체 해결책을 보여주기까지는 한참을 재촉해야 했다.
이걸 위한 도구가 있어야 할 텐데
내가 하던 방식보다 AI를 더 잘 통합할 방법이 있을 거라고 생각했다.
‘코드와 에러 메시지를 이리저리 복사해 나르는 사람’ 역할을 대신해 줄 도구가 필요했다.
Sourcegraph Cody를 1년 간격을 두고 두 번 써 봤는데, 두 번 다 실망스러웠다. 코드를 제자리에서 바로 수정해 주는 건 브라우저와 에디터 사이에서 복사해 붙여넣는 것보다 나았지만, Cody는 느리고 버그도 많아서 결국 다시 웹 브라우저로 코드를 복사해 붙여넣는 방식으로 돌아갔다.
최근 Cline에 대한 블로그 글 몇 개를 봤는데, 몇 가지 이유로 끌렸다:
- 코드가 오픈소스다.
- 내 주력 에디터인 VS Code와 연동된다.
- 로컬 파일을 편집하고, 명령어를 실행하며, 그 실행 결과를 바탕으로 반복 작업을 수행할 수 있다.
- 원한다면 로컬에 호스팅한 LLM을 사용할 수 있다.
- 다른 많은 AI 어시스턴트처럼 AI API 구매를 중개하려 들지 않는다.
단점은 Cline이 투자금을 태우는 것 외에는 뚜렷한 수익원이 없어 보인다는 점이다. 그래서 지속 가능하지 않을 수도 있지만, 지금 당장은 괜찮다.
어휘 착시: AI 어시스턴트를 시험하기에 완벽한 프로그램
최근 내 블로그에서 “어휘 착시(lexical illusions)”를 찾아주는 도구가 있으면 좋겠다고 생각했다. 텍스트에서 중복된 단어를 인지하지 못하는 현상을 Matt Might는 이렇게 부른다, 예를 들면 다음과 같다:
많은 독자들은
the라는 단어가
새 줄에서 시작될 때
뇌가 두 번째 단어를 자동으로 무시한다는 사실을 모른다.
나는 블로그에서 이런 실수를 자주 하고, 교정 후반부나 발행 후에야 발견하곤 한다.
Matt Might는 어휘 착시를 찾는 Perl 스크립트를 공유한 적이 있지만, 기초적인 수준이라 내 블로그에서는 Markdown 서식 문자 때문에 오탐이 많이 나왔다.
Kagi Assistant에 Markdown을 인식하는 Python 버전을 만들어 달라고 했지만, 계속 버그 있는 코드만 만들어냈다.
이 문제가 Cline을 시험하기에 완벽한 테스트 케이스라는 생각이 들었다. 문제를 정의하기 쉽기 때문이다. 원하는 동작을 담은 테스트 케이스를 AI 어시스턴트에게 계속 보여주면, 테스트를 통과할 때까지 알아서 코드를 고쳐 나가면 된다.
또한 Zig로 코드를 작성할 좋은 핑계이기도 했다. 이 도구가 많은 파일을 최대한 빠르게 스캔해야 하는데다, 나는 Zig로 작업하는 걸 좋아하기 때문이다.
문제 정의하기
내 도구의 메인 인터페이스는 단순했다. 파일 내용을 문자열(Zig에서는 [] const u8)로 받아서, 중복 단어와 해당 줄 번호 목록을 반환하면 됐다.
기본 인터페이스는 이렇게 생겼다:
pub const DupeWord = struct {
line_number: u32,
word: []const u8,
};
pub fn FindAdjacentDupes(allocator: std.mem.Allocator,
input: []const u8) !ArrayList(DupeWord) {
// TODO: Implement this.
}그리고 처음 작성한 유닛 테스트는 다음과 같았다:
test "FindAdjacentDupes" {
// Don't consider distinct words to be duplicates.
try testFindDupes("cat dog", &[_]DupeWord{});
// Find simple dupes.
try testFindDupes("cat cat", &[_]DupeWord{
.{ .line_number = 1, .word = "cat" },
});
}
fn testFindDupes(input: []const u8, expected: []const DupeWord) !void {
const allocator = testing.allocator;
var result = try FindAdjacentDupes(allocator, input);
defer {
for (result.items) |item| {
allocator.free(item.word);
}
result.deinit();
}
try testing.expectEqual(expected.len, result.items.len);
for (expected, 0..) |expected_dupe, i| {
try testing.expectEqual(expected_dupe.line_number, result.items[i].line_number);
try testing.expect(std.mem.eql(u8, expected_dupe.word, result.items[i].word));
}
}Cline의 초기 결과
약 30초, LLM 크레딧 0.09달러 만에 Cline이 테스트를 통과시켰다:

Cline은 FindAdjacentDupes를 이렇게 구현했다:
pub fn FindAdjacentDupes(allocator: std.mem.Allocator, input: []const u8) !ArrayList(DupeWord) {
var result = ArrayList(DupeWord).init(allocator);
var it = std.mem.splitScalar(u8, input, ' ');
var prev_word: ?[]const u8 = null;
while (it.next()) |word| {
if (prev_word) |prev| {
if (std.mem.eql(u8, prev, word)) {
const dupe_word = try allocator.dupe(u8, word);
try result.append(DupeWord{
.line_number = 1,
.word = dupe_word,
});
}
}
prev_word = word;
}
return result;
}Cline은 var 대신 const를 써야 하는 곳에 var를 쓰거나 더 이상 쓰지 않는 API를 사용하는 등 몇 번 잘못된 방향으로 가기도 했지만, 사람처럼 에러 메시지를 보고 스스로 수정했다.
구현은 당연히 아직 불완전했다. Markdown 서식이나 대소문자, 문장 부호 같은 걸 처리하지 못했기 때문이다. 줄 번호가 1이 아닌 테스트 케이스를 Cline에게 보여준 적이 없어서, 현재 구현은 줄 번호를 항상 1로 하드코딩해서 반환했다.
그때 빠져들었다
Cline이 초기 구현을 끝낸 뒤, 나는 새로운 테스트 케이스를 계속 작성했고 Cline이 내 테스트를 통과하도록 코드를 업데이트하는 모습을 지켜봤다.
그리고 그때 완전히 빠져들었다. 이런 식으로 소프트웨어를 개발할 수 있다는 사실에 정말 놀랐다. 내가 원하는 것을 말하기만 하면, 도구가 시키는 대로 정확히 해냈기 때문이다.
실제로 어떤 모습인지, 글 맨 위에 올린 영상을 다시 소개한다:
결과
그날 남은 시간을 Cline과 함께 도구를 구현하며 보냈고, 이제 중복 단어를 찾는 도구의 동작하는 버전을 갖게 됐다. 이름은 wordword다:
wordword를 이용해 내 블로그에서 어휘 착시 오류 7건을 찾아냈다.
총비용은 OpenRouter에서 크레딧으로 6달러였는데, Cline과 5시간 동안 쉬지 않고 작업한 결과다.
지금까지 배운 점
방치하면 비효율적이지만, 신경 쓸 정도의 비용은 아니다
Cline에는 각 단계 전에 계획을 승인하라고 묻는 옵션이 있다. 5초마다 “승인”을 누르는 게 금방 지겨워져서, 파일 읽기, 파일 쓰기, 명령어 실행은 자동 승인되도록 설정했다.
신경을 끄고 있으면 Cline이 가끔 막다른 골목에 빠져 실패할 게 뻔한 전략을 반복하는 경우가 있었다.
그럼에도 나는 대부분 Cline이 해결책에 도달하거나 20회 시도 제한에 걸릴 때까지 그냥 방치했다. 이런 막다른 시도가 API 크레딧을 소모하긴 했지만 몇 센트 수준이라, 어시스턴트를 일일이 관리하는 것보다 몇 센트 낭비하는 쪽을 택했다.
Cline은 당신을 무조건 신뢰하므로, 말을 신중하게 골라야 한다
Cline이 가장 엉뚱하게 동작했던 때는 내가 실수로 잘못된 동작을 담은 테스트 케이스를 작성했을 때였다.
내가 너무 성급하게 작성한 테스트 케이스다:
// Detect duplicates after a heading
try testFindDupes(
\\## Foods
\\
\\These potatoes potatoes are the best!
, &[_]DupeWord{
.{ .line_number = 1, .word = "potatoes" },
}줄 번호를 3이라고 써야 하는데 실수로 1이라고 썼다.
Cline에게 이 테스트를 통과시켜 달라고 하자, 명백히 3이어야 할 줄 번호를 어떻게든 1로 정당화해보려다 약간 혼란에 빠졌다.
Cline에게 디버그 출력문을 추가하도록 시켜라
LLM은 코드가 왜 그렇게 동작하는지에 대한 정보를 더 모으기 위해 멈추기보다는, 해결책을 추측하려는 경향이 있음을 알게 됐다.
Cline이 버그를 고치려 맹목적인 시도를 반복하며 루프에 빠졌을 때, 작업을 멈추고 코드에 대한 가정을 검증하기 위해 디버그 출력문을 삽입하라고 지시하는 것이 도움이 됐다. Cline은 유용한 디버깅 출력을 추가했고, 해결책이 완성됐다고 선언하기 전에 그 출력문들을 모두 제거하는 것도 잊지 않았다.
Kagi는 나 때문에 손해를 보고 있을 것이다
종량제 LLM API를 써 본 건 이번이 처음이다. 사람들이 토큰 비용에 대해 이야기하는 걸 본 적은 있지만, Kagi는 기본적으로 “비용은 신경 쓰지 마세요”라는 식이라 감이 잘 오지 않았다.
Cline은 각 코딩 작업이 진행되면서 크레딧이 얼마나 쌓였는지 친절하게 보여준다.

그래서 나는 Kagi의 월 25달러 무제한 요금제에서 확실히 이득을 보고 있다. Cline으로 5시간 동안 6달러를 썼는데, Cline은 토큰 소모를 최소화하기 위해 여러 조치를 취한다. 나는 Kagi Assistant를 매일 쓰고, 대화 중에 거대한 파일을 10번 이상 붙여넣는 경우도 자주 있다. 비용을 직접 보니, 하루에 Kagi에 5~10달러의 API 비용을 지출하게 하고 있는 셈이다.
참고할 만한 다른 자료
대부분의 AI 관련 글은 내용이 빈약하거나 실질적인 교훈이 부족하다. 무엇을 할 수 있는지 보여주는 측면에서 내가 가장 유용하다고 느낀 글들은 다음과 같다:
- “Everything I built with Claude Artifacts this week” by Simon Willison
- “How I Use ‘AI’” by Nicholas Carlini
- “How I program with LLMs” by David Crawshaw
글을 무작위로 읽기
댓글
로그인하고 댓글 남기기