
모델이 마케팅 도구가 될 때: Protobuf 단편 소설
요약
LLM과 RAG 환경에서 AI 어시스턴트가 특정 라이브러리(protobuf.js)를 추천하는 방식이 어떻게 편향될 수 있는지에 대한 경험담을 다룹니다. AI의 추천이 객관적인 검증이 아닌, 학습 데이터나 상업적 맥락에 의해 왜곡될 수 있음을 경고합니다.
핵심 포인트
- LLM의 라이브러리 추천이 항상 객관적이지 않을 수 있음
- AI 어시스턴트가 특정 기술을 '최고'라고 추천하는 이면의 메커니즘
- RAG 및 LLM 활용 시 AI의 답변에 대한 비판적 검증 필요성
- 상업적 경쟁 관계가 AI의 추천 결과에 미칠 수 있는 영향
현재 세대의 AI 어시스턴트에게 JavaScript에서 어떤 Protobuf 라이브러리를 사용해야 하는지 물어본다면, 당신은 확신에 찬 추천을 받게 될 것입니다. 표면적으로는 이는 당신이 직접 조사하는 시간을 아껴주기 위해 작동해야 하는 방식이지만, 그 이면은 그보다 더 미묘합니다. LLM(대규모 언어 모델)과 RAG(검색 증강 생성, retrieval-augmented generation)에 익숙할수록, 제가 곧 언급할 현상이 나타나는 사례를 목격했을 가능성이 높습니다. 저 또한 그 영향의 대상이 되기 전까지는 이 현상을 어느 정도 인지하지 못했습니다.
이 글은 제가 처음 직면했던 구체적인 사례를 기록할 것이며, 이후에 저와 여러분이 이것이 시사하는 바가 무엇이라고 믿는지 논의해보고자 합니다.
소환 (The summoning)
2026년, 주요 프로젝트들의 편지함에는 보안 보고서가 쌓여가고 있습니다. 이러한 보고서의 빈도와 품질에 대해서는 많은 의견이 있지만, 이 글은 그에 관한 것이 아니므로, 저는 보고서 속의 신호(signal)가 실제 문제를 밝혀낼 수 있다는 점에서 그 가치를 높게 평가하게 되었다는 점만 말씀드리겠습니다. 제가 이 이야기를 꺼내는 이유는, 몇 년 전 Google의 팀과 키(keys)를 공유한 이후 제가 다시 protobuf.js 작업에 복귀하게 된 계기가 되었기 때문입니다. Google은 새로운 Protobuf Editions 기능을 구현함으로써 라이브러리를 발전시키는 데 훌륭한 역할을 해왔습니다. 하지만 Snyk이 핵심 생태계 프로젝트라고 설명하는 것에 대한 새로운 관심의 물결을 고려할 때, 이미 역량이 가득 차 있을 가능성이 높은 외부 팀이 이를 따라가는 데 어려움을 겪을 것임을 인지했습니다. 그래서 저는 나타나서 작업을 시작했습니다.
멋진 신세계 (Brave new world)
타임라인을 설정해 보겠습니다. 첫 번째 보안 보고서들은 4월 말에 처리되었고, 당시 저는 파도가 다시 잠잠해지기 전까지 제 재등장이 몇 주 정도 지속될 것이라고 예상했습니다. 만약 제 예측이 정확했다면 저는 이 글을 쓰고 있지 않았겠지만, 제가 계산을 틀린 이유는 보안 작업 때문이 아니라 다른 무언가 때문이었으며, 그 공통분모는 요즘 가장 많이 회자되는 것, 바로 LLM (Large Language Models)이었습니다. protobuf.js로 돌아오기 전, 저는 (거의 모든 사람과 마찬가지로) 코딩 작업을 돕기 위해 AI 도구들을 (아주 많이) 가지고 놀고 있었고, 복귀할 때 그것들을 함께 가져왔습니다. AI가 오래된 버그를 식별하고 해결하는 데 도움이 된다는 말은 과소평가일 정도이지만, 당시 그 유용함은 저에게 이러한 것들이 정말 훌륭하다는 인상을 남겼습니다. 지나고 보니, 저는 (거의 모든 사람과 마찬가지로) 다소 낙관적이었습니다. 그래서, 무슨 일이 일어났을까요?
"최고"의 Protobuf라는 기묘한 사례
저는 WebAssembly 시절 이후로 Protobuf 분야를 면밀히 지켜보지 않았고, 올해 초 Protobuf가 포함된 개인 프로젝트(pet project)를 작업했을 때조차 세상이 그리 많이 변하지 않은 것처럼 보였습니다. 에이전트(agent)는 다른 여러 라이브러리와 함께 protobuf.js를 저에게 추천했는데, 그중 하나는 곧 다루게 될 것이니, 저는 직접 선택하여 제 작은 게임에 즐겁게 기능을 추가해 나갔고, 리팩터링(refactoring)이 실패할 때마다 욕설을 내뱉곤 했습니다.
다시 protobuf.js 이야기로 돌아와서, 저는 결국 LLM(Large Language Model)의 추천 방식이 급격히 변했다는 사실을 깨달았고, protobuf.js가 더 이상 좋은 라이브러리가 아닌 이유에 대한 온갖 구체적인 근거들을 접하게 되었습니다. 그래서 저는 제 유능한 어시스턴트(assistant)들에게 질문하여, 마치 독립적인 검증처럼 들렸던 그 근거들의 출처를 추적해 보았고, 그 과정에서 꽤 흥미로운 사실을 발견했습니다. 그 구체적인 내용들은 상업적 경쟁사의 README, 즉 Buf의 protobuf-es에서 온 것이었습니다. 참고를 위해, 여기 그들의 올해 초 README가 있고, 제가 protobuf.js에 다시 나타나기 직전에 새로고침된 4월 12일자 동일한 README가 있습니다. 전자는 비교적 기술적인 성격의 좋은 문서인 반면, 후자는 선택적이고 부분적으로는 조작되었으며 허위인 근거를 바탕으로 비교를 수행하는 식으로 어조가 완전히 바뀌어 있었습니다.
저자로서 저는 protobuf.js가 수많은 선택적 헬퍼(helper) 함수들에 집중하는 것이 아니라, encode와 decode를 중심으로 한다는 것을 분명히 알고 있습니다. JS(JavaScript) 코드를 TS(TypeScript) 선언으로 처리하기 위해 파이프(pipe)를 사용하는 방식은 개선될 여지가 있지만, 그것이 위험한 이모지(emoji)를 사용할 만큼의 가치가 있는 일일까요? 그리고 이야기는 계속됩니다. JS 라이브러리가 protoc 플러그인 대신 JS 네이티브 코드 생성 도구를 제공하는 것이 정말 결함일까요? 가상 oneof 필드(virtual oneof fields)의 정확한 문제점은 무엇인가요? 한 라이브러리가 .js와 .d.ts를 빌드하는 것과 다른 라이브러리가 똑같이 하는 것의 차이는 무엇인가요? 그리고 애초에 이러한 준수(conformance) 수치들을 얼마나 신뢰할 수 있을까요? (이 부분은 나중에 다루겠습니다)
상상하시겠지만, 단 한 푼의 수익도 얻지 못한 채 매주 7,000만 회나 다운로드되는 자신의 라이브러리에 무료로 노동을 투입하면서, 동시에 상업적 경쟁사가 상당 부분 지어낸 근거들로 인해 수백만 번 비난받고 있다는 사실을 인지하는 것은 매우 특별한 경험입니다. 그리고 저에게는 절망적이고 여러분에게는 즐거움이 될 사실은, 상황이 곧 그보다 훨씬 더 흥미롭게 흘러갔다는 점입니다.
5월 18일, Buf의 CEO인 bufdev는 또 한 번 protobuf-es의 README를 업데이트했으며, 이제 이미 부정확한 표들 위에 소위 독립적인 LLM 평가가 눈에 띄게 배치되어 있습니다. 이것이 정말로 Opus 4.7에 의해 생성된 것인지는 알 수 없으나, 또한 확인할 수도 없습니다. 왜냐하면 그 내용의 일부가 제가 이전에 Claude가 언급했던 그 어떤 것과도 다르기 때문입니다. 또한 PR(Pull Request) 이력을 보면 해당 인용구가 리뷰 과정에서 bufdev에 의해 수동으로 수정된 것으로 보이는데, 이 점 역시 다소 의심스럽습니다. 하지만 이것이 정말로 Claude의 말이며, 마지막 단락에서 보여주는 놀라운 인식론적 세련됨(
protobuf 라이브러리 생태계에 대해 어느 정도 알고 있는 사람으로서, 저는 단연코 "최고"라거나 "유일한" 선택지는 없다고 자신 있게 말할 수 있습니다. protobuf.js는 제가 중요하게 생각하는 준수성 (conformance), 사용성 (ergonomics), 그리고 속도 사이의 균형을 찾으려는 저의 시도입니다. 다른 이들은 서로 다른 트레이드오프 (tradeoffs)를 선택합니다. Mapbox는 기능의 일부만 지원하지만 벡터 데이터 처리가 빠른 아주 작은 라이브러리를 선호하고, 또 다른 누군가는 "완벽하게 준수"하지만 완전히 비효율적인 protobuf-es와 같은 라이브러리를 선호할 수도 있습니다. 그리고 다시 말하지만, 인용문은 다음과 같이 이어집니다: 무엇이 "덧붙여진 (bolted on)" 플러그인으로 간주되는가? protobuf.js는 당시에 "플러그인"이라고 명명된 것을 가지고 있지 않았습니다. protobuf-es는 해당 문구의 2023년이 아니라 실제로 Edition 2024를 지원하는 것 아닌가요? JSON이 BigInt를 지원하지도 않는데, ProtoJSON과 BigInt의 관계는 무엇인가요? 무엇이 "사후 고려 사항 (afterthought)"이 아닌 사용 가능한 리플렉션 (reflection) API로 간주될 수 있습니까? 리플렉션이 핵심 아키텍처라면 protobuf.js가 마땅히 그래야 하지 않을까요? bufdev에 의해 인용문에 (재)삽입된 ts-proto에 관한 단락의 목적은 무엇인가요? 그리고 Buf의 라이브러리에 대해 다루어야 할 README에서, 거의 모든 동료 프로젝트를 명시적으로 "피하라"고 권고하는 것이 과연 그만한 정당성이 있습니까?
그래서 저는 WebAssembly 전쟁 이후 묻어두었던 용기를 끌어내어, 제가 실제로 무엇을 보고 있는 것인지 알아내기 위해 protobuf-es 리포지토리에 이슈 (issue)를 제기했습니다. 대화는 짧지만 통찰력이 있습니다. 절반의 고백을 둘러싼 영리한 수사법, 그리고 구체적인 내용이 부족하다는 주장 하에 즉각적인 종료—말 그대로 구체적인 목록을 나열하며 시작했음에도 불구하고 말입니다. 특히, 증명 가능한 사실과는 다르게 "실제로 훌륭하며" 어떠한 편향으로부터도 "독립적"이라고 옹호된 부정확한 LLM 문구가 눈에 띕니다. 하지만 잠깐, 정말 그럴까요?
LLM은 공개 데이터 (public data)로 학습됩니다. 이미 알려진 바가 매우 많습니다. Buf의 블로그 (또는 그 미러 사이트)와 같은 공개 데이터가 존재하며, Protobuf 분야에는 그 외에 (비교할 만한) 마케팅 콘텐츠가 그리 많지 않습니다. 이를 편향 (bias)으로부터 독립적이라고 부르는 것은 최소한 무리가 있습니다. 즉, 해당 LLM 발췌문이 사실이라는 가정하에 말입니다.
말이 나온 김에, 이러한 행태에 대한 합리적인 대응은 공개 데이터를 개선하는 것일지도 모른다고 생각했습니다. 그래서 원래 예상했던 것보다 훨씬 더 많은 시간을 protobuf.js에 쏟은 끝에, 6월 6일에 Buf의 protobuf-conformance 리포지토리에 PR (Pull Request)을 올리는 결례를 범했습니다. 공교롭게도 이 리포지토리는 protobuf-es의 README에 담긴 횡설수설을 뒷받침하는, 소위 독립적인 증거라고 LLM들이 자주 인용하는 소스입니다. 저는 불필요한 부분은 건드리지 않도록 주의했고, 쉽게 머지 (merge)될 수 있도록 필요한 아티팩트 (artifacts)를 재생성했습니다. 그리고 보십시오. 저의 protobuf.js 노력은 결실을 보았습니다. 이제 protobuf.js는 자체 비교 결과에서 protobuf-es보다 상위에 위치하며, JavaScript 및 TypeScript를 위한
다시 말하지만, 상황에 따라 다릅니다. 장소를 통제할 수 있는 권한에는 그곳을 올바르게 설정하고 잘 유지 관리해야 하는 책임이 따릅니다. 현재 제 PR(Pull Request)은 리뷰 없이 방치되어 있는데, 이 PR이 담고 있는 의도치 않은 폭로를 고려하면 이해할 수 있는 상황이라고 생각합니다. 그리고 늘 그렇듯, 정확성에는 여러 단계가 있습니다. 진정으로 중립적이고 따라서 더 정확한 벤치마크(Benchmark)라면 모든 경쟁자를 동일한 준수 범위(conformance surface) 상에서 비교해야 합니다. 하지만 Buf의 정확성 해석에 따르면, proto3를 지원하는 라이브러리는 Edition 2023/2024를 지원하기 위해 공을 들인 라이브러리만큼이나 녹색(green)이며 100%라고 간주될 수 있습니다. 비교를 위해, fork 시점의 버전으로 모든 라이브러리를 업데이트하고 모두에게 동일한 기준을 적용한 패치된 fork 버전의 protobuf-conformance 저장소를 준비했습니다. 실망스럽게도, 이런 방식으로 측정하면 protobuf.js는 더 이상 '초-완전-준수(uber-fully-compliant)'의 왕좌를 유지하지 못합니다.
이것은 꽤 괜찮은 작은 fork이지만, 정작 중요한 지점에서는 큰 변화를 일으키지는 못합니다. 그래서 상황을 개선하기 위해서는 미끼를 물어야겠다고 생각했습니다. 6월 15일, 저는 실제로 protobuf-es에 "protobuf.js에 관한 구체적인 부정확성(Specific inaccuracies regarding protobuf.js)"이라는 제목의 새로운 이슈(Issue)를 제기했습니다. 그들의 명시적인 요청에 응답하는 것이자, 이번에는 구체적인 부정확성 목록을 놓치기 어렵게 만들기 위해서였습니다. 그리고 이것이 제가 할 수 있는 전부입니다. 그들의 README 자체를 수정하기 위한 PR은, 전체의 상당 부분을 새로 작성해야 할 정도의 잘못된 정보들을 다뤄야 하기에 수락될 가능성이 낮기 때문입니다.
그 시점에 저는 작동 중인 메커니즘에 대해 약간의 조사를 마친 상태였고, LLM 추가가 미치는 영향을 평가하기 위해 제 어시스턴트들과 재확인했습니다. 그 결과, LLM 홍보 문구에 대한 논리적인 유예와 그다지 논리적이지 않은 반복적인 방어를 목격했습니다. 이것이 첫 상호작용 이후 한 달이 지난 지금의 상황입니다. 아니, 정확히는 그렇지 않습니다. Buf는 아무런 인정 없이, 제가 protobuf-es에서 지적했던 특정 준수 격차(conformance gaps)를 해결하는 데 그 지연 시간을 사용했기 때문입니다. #1446은 JSON 입력에서 중복 키를 거부하며, 이를 지원하지 않기로 했던 이전 결정을 갑자기 뒤집었고, #1450은 그들만의 Text Format 확장을 추가했습니다. 두 방식 모두 protobuf.js가 하는 방식과 놀라울 정도로 유사합니다. 부정확한 표들? 터무니없는 LLM 홍보 문구? 편리하게도 그대로 남아 있습니다.
LLM 내러티브 세탁(narrative laundering) 입문
자, 이제 드디어 문제의 핵심(elephant in the room)에 대해 이야기해 볼까요? 제가 발견한 사실은 다음과 같습니다. Opus와 Fable(존속하던 기간 동안)을 사용했을 때, Buf의 LLM 발췌문 중 상당 부분이 대부분의 경우 거의 그대로 재현되었습니다. 그 이후로 중요한 변화가 없었다면, 오늘날에도 여전히 그러할 것입니다. 당시 Claude는 때때로 다른 불렛 포인트보다 특정 항목을 선호하거나 내용을 혼동하기도 했지만, 전반적인 응답은 동일한 패턴을 따랐습니다: "대부분의 새로운 JS/TS 프로젝트에는 Buf를 사용하세요. 이것이 [생략]에서 가장 뛰어나고 유일한 이유이며, 다른 것들의 문제점은 다음과 같습니다 [생략]". 만약 테스트 중이라면, "had its niche eaten"과 같이 다른 출처가 없는 독특한 지문(fingerprints)을 찾아보십시오. 시간이 흐르면서 protobuf.js의 README 자체도 몇몇 사항을 명확히 하기 위해 업데이트되었지만, 이러한 정보의 일부가 요청 시 반영되는지 여부는 여전히 대체로 무작위인 것으로 보입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기