LY Corporation Tech Blog

LY Corporation과 LY Corporation Group(LINE Plus, LINE Taiwan and LINE Vietnam)의 기술과 개발 문화를 알립니다.

AI와 글쟁이의 동행: 코드 주면 API 레퍼런스 써드려요

기술 문서는 늘 부족합니다. 특히 좋은 기술 문서가 부족하죠.

테크니컬 라이터는 좋은 기술 문서를 쓸 수 있지만, 사내 프로젝트를 모두 담당하기에는 수가 턱없이 모자랍니다. '개발자 글쓰기 교육'으로 그 간극을 메워보려는 시도도 있지만, 과연 교육만 들으면 모든 개발자가 기술 문서를 잘 쓰게 될까요?

글쎄요, 저는 회의적입니다. '잘 쓰는 방법을 몰라서'는 개발자가 기술 문서를 쓰지 않는 원인 중 하나일 뿐, 전부가 아니니까요. '시간'이나 '관심' 같은 외부적 원인은 교육으로는 해결하지 못합니다.

문서 엔지니어로서, 저는 이 문제를 '개발자 교육'보다 '엔지니어링'으로 풀어보려고 노력해 왔습니다. 프로세스를 통한 강제화, 도구를 이용한 자동화로요. 생성형 AI가 글 쓰는 직무를 대체할 것이라는 예측도 있지만, 이런 관점에서 볼 때 도큐먼트 엔지니어에게 AI가 반드시 경쟁자인 것만은 아니더군요. 오히려 기존의 한계를 극복하게 해주는 기회에 가깝죠. 비유하자면, 테크니컬 라이터가 한 땀 한 땀 공들여 문서를 만들어 내던 가내수공업 방식을 공장형 자동 생산으로 바꿀 기회랄까요.

공장형 생산이 꼭 가내수공업보다 좋다는 말은 아닙니다. 짧은 시간에 대량으로 처리할 수 있다는 장점이 있지만, 품질을 담보할 수 없다는 단점도 있으니까요.

LINE Plus의 Document Engineering 팀은 이런 마음가짐으로 AI를 꾸준히 활용해 왔고, 덕분에 그 아이디어를 시험해 볼 기회를 얻었습니다.

생성형 AI로 API 레퍼런스 만들기

LY 그룹은 업무에 생성형 AI를 도입하는 데 적극적입니다. 그 일환으로 주요 개발 단계에서 생성형 AI를 활용하는 프로젝트를 진행 중인데요. 대상 작업 중 하나가 문서화입니다.

저희 팀은 프로젝트를 시작하면서 문서화 생산성을 높이겠다는 목적 아래 개발 단계에서 가장 필요한 문서가 무엇일지 한참 고민했습니다(프로젝트 자체 요구 사항을 참고해서요). 몇 가지 아이디어가 있었고, 그중 소스 코드를 이용하면서 개발자나 사용자에게 모두 영향을 미치는 API 레퍼런스 문서에 적용해 보기로 했습니다.

소스 코드를 설명하는 기능은 GitHub Copilot 같은 코딩 어시스턴트가 이미 잘하고 있는데 '뭘 더 하려는 것일까?'하는 의문이 생기실 수도 있겠네요. 아쉽게도 코딩 어시스턴트로는 해결하지 못하는 문제가 몇 개 있습니다.

  • 사내 기술 문서 스타일을 따르지 못함
  • 사내 기술과 컨텍스트를 반영하지 못함
  • 일관성을 유지하지 못함

더불어 프로젝트마다 API 문서 형식도 다르고 배포하는 곳도 달라서 참고하기 어렵다는 개발 팀 의견도 있었습니다. 코딩 어시스턴트는 이것도 해결하지 못하죠. 따라서 저희는 '사내 정보를 참고해서 사내 스타일에 맞는 API 주석을 작성하고, 이를 레퍼런스로 만들어 한곳에서 배포하기'를 목표로 삼아 프로젝트를 시작했습니다.

프롬프트와 워크플로

저희 팀은 기술 문서를 검토하고 다국어화한 경험이 많습니다. 이미 몇몇 프로젝트에서는 문법, 표현, 스타일 일관성을 확인하는 용도로 프롬프트를 만들어 AI를 활용하고 있고요.

사내 스타일 가이드에 맞춰 일관된 톤과 스타일을 유지하려면 꽤 긴 프롬프트가 필요합니다. 여기에 프로그래밍 언어별로 상세한 API 주석을 작성하는 방법과 용어 정보까지 더했더니 LLM이 몇몇 지시를 놓치기 시작했습니다(LLM도 지시가 많으면 기억력이 떨어지나 봅니다). 그러잖아도 사내 머신 러닝 팀 전문가의 도움을 받고 있었던 터라 개선 방안을 여쭸더니, 실행 단계를 나누고 단계별로 수행할 프롬프트를 분리하라고 하시더군요.

처음에는 아래와 같이 세세하게 단계를 나눴습니다.

  1. API 설명 작성
  2. 파라미터 설명 작성
  3. 응답 값 설명 작성
  4. 예제 코드 작성
  5. 추가 정보 작성

과연 단계를 나누니 한꺼번에 요청하는 것보다 정확하고 자세한 설명을 써줬지만, 단계가 길어질수록 시간이 오래 걸렸습니다. 그래서 정확하고 자세한 설명과 처리 시간 사이에서 적절한 타협점을 찾아야 했습니다.

저희는 결과물을 비교하면서 단계를 나누기 전과 크게 달라지지 않는 부분을 합친 다음, 프로그래밍 언어에 맞는 프롬프트를 선택하도록 언어를 판별하는 단계를 더해 총 3단계로 줄였습니다.

  1. 프로그래밍 언어 인식
  2. API 파악해서 추가 정보와 예제 코드 작성
  3. API 설명과 파라미터, 응답 값 설명 작성
주석 생성 워크플로
주석 생성 워크플로

비록 팀원 수는 적었지만, 프롬프트 엔지니어링 담당과 기능 구현 담당을 나누고 프롬프트 엔지니어링의 결과물을 기능 구현 담당이 워크플로에 반영하는 방식으로 진행했더니 계획한 일정에 맞춰 '테크니컬 라이터의 손길을 담은 API 주석 작성 및 문서 배포기' 프로토타입을 완성할 수 있었습니다.

프로토타입은 VS Code의 Chat 익스텐션으로 만들었습니다. 개발자에게 익숙할 GitHub Copilot과 유사한 UX를 제공하는 편이 좋을 테니까요. VS Code Chat 창에서 @doc으로 익스텐션을 부르고 /generate를 명령하면, 열린 파일 또는 선택한 코드 블록에 API 문서용 주석을 만들어 줍니다. Swagger로 작성한다면 주석 대신 Swagger 어노테이션으로 작성한 뒤 /publish를 명령하면, 주석을 참고해서 웹 문서를 배포해 줍니다. 개발자 입장에서는 소스 파일을 열고 명령어만 입력하면 누구나 볼 수 있는 API 문서를 만들 수 있으니 일일이 설명을 쓰고 CI/CD를 통해 배포하던 방식과 비교해 훨씬 편리할 것입니다(물론 두 명령어 사이에서 '주석이 정확한지 사람이 검토'하는 작업은 꼭 필요하지만요!).

이렇게 만든 프로토타입으로 사내 정보가 섞인 API 구현 코드에 주석을 생성해 보겠습니다. 아래는 이 글에서 예시로 사용할 용도로 만든 예시 함수입니다.

const findInfoByMid = (mid) => {
  const uid = getUidById(mid);
  if (uid) {
    return { name: getName(mid), detailedInfo: getDetailedInfo(mid, uid) };
  }
  return null;
};

MID는 LINE 앱에서 고유 ID로 사용하는 정보인데요. GitHub Copilot은 이런 정보를 잘 모릅니다. 따라서 코드를 파악해서 유추한 정보(Member ID)로 주석을 만들어 냅니다(어떨 때는 Machine ID라고 쓰기도 해요).

/**
 * Finds and returns information for a given MID.
 *
 * @param {string} mid - The MID (Member ID) to look up.
 * @returns {{ name: string, detailedInfo: any } | null} An object containing the name and detailed information if found, otherwise null.
 */

반면 저희 주석 생성기는 아래와 같이 씁니다. MID가 'Member ID'의 약자가 아니라 사용자 정보와 연결되는 고유 식별자라는 것을 알고 있죠.

/**
 * Retrieves detailed information using a given identifier.
 * This function obtains a UID and returns an object with properties or null if no uid exists.
 *
 * Ensure that getUidById, getName, and getDetailedInfo are defined and functional. Use a valid MID.
 *
 * @param {*} mid - The unique identifier (MID) to retrieve the corresponding user information.
 * @returns {Object|null} An object with properties `name` and `detailedInfo`, or null if no uid is found.
 *
 * @ai-doc
 */

이렇게 해서 '사내 컨텍스트를 반영한' 문서를 만든다는 목표를 이룰 수 있습니다. 이번에는 생성한 주석을 배포해 볼까요? @doc /publish만 입력하면 문서를 배포하고 링크를 알려줍니다. 아래는 예시 함수를 배포한 결과입니다.

배포한 웹 문서 화면
배포한 웹 문서 화면

VS Code 익스텐션에서 MCP로

앞서 언급했다시피 프로토타입은 VS Code 익스텐션입니다. IDE 구별 없이 사용할 수 있는 GitHub Copilot 익스텐션도 고려했지만, 아쉽게도 당시는 공개 프리뷰 버전이어서 프로토타입에 적용할 수가 없었거든요. 그런데 개발자 참여 테스트를 시작하면서 "VS Code 말고 IntelliJ를 쓸 순 없나요?"라는 질문을 많이 받았습니다. 문서화뿐 아니라 AI를 활용하는 다른 프로젝트에도 IntelliJ를 사용하는 개발자 수요가 많다고 하더군요.

마침 JetBrains사도 Junie라는 AI 코딩 어시스턴트를 내놓으며 MCP를 지원하겠다고 했고, GitHub Copilot 역시 공개 프리뷰 버전으로 MCP를 지원 중이니, 특정 IDE에 의존하는 솔루션보다는 MCP로 범용성을 확보하는 편이 좋다는 결론을 내렸습니다. 솔직히 말하자면 MCP로 변경하자는 이야기를 처음 들었을 때는 또 (고통스러운 변화의) 시작인가 했는데요. 기능 변경 사항을 정리하다 보니 오히려 MCP가 간편하다는 것을 깨달았습니다.

VS Code 익스텐션을 MCP로 바꿀 때 기능 전환 구조
VS Code 익스텐션을 MCP로 바꿀 때 기능 전환 구조

MCP 서버는 MCP 클라이언트하고만 통신하므로 사용자 인터페이스에 신경 쓰지 않고 오롯이 기능에 집중할 수 있습니다. 사용자가 어떤 코드 블록을 선택했는지, 지원하는 프로그래밍 언어인지 아닌지, 생성 언어는 무엇으로 할 것인지 같은 문제는 MCP 호스트가 사용자와 협의할 테니까요. 사실 VS Code 익스텐션을 만들 때는 UI를 고민하고 구현하는 데도 꽤 품이 들었습니다. 하지만 위 그림에서 보다시피 일부 UX 기능(연결선이 x 표시된 상자)은 아예 제거할 수 있게 되었습니다.

또한 VS Code에서 일일이 구현한 기능 일부를 MCP 호스트로 넘길 수 있는 데다 시간상 만들지 못한 기능(위 그림의 VS Code extension 쪽의 점선 상자)도 제공할 수 있을 것 같았습니다. 물론 MCP 호스트의 기능과 성능에 의존한다는 문제가 있지만 그렇다고 해도 저희가 직접 인터페이스를 구현하느니 널리 쓰이는 MCP 호스트의 발전에 맡기는 게 낫겠지요.

주석을 생성할 때 사용하는 정보인 코드와 주석 작성 언어, Swagger 사용 여부 같은 정보도 MCP 호스트가 잘 판단해 주고, 설사 잘못하더라도 다시 지시하면 순순히 바꿔줍니다. 사용자가 대화를 주고받으며 실행하는 방식이 다소 귀찮아 보일 수는 있지만 요즘 많은 사람이 채팅 방식의 AI를 사용하는 데 익숙해져서 충분히 받아들일 만한 UI라고 생각합니다.

MCP 서버에 필요한 파라미터를 대화로 입력하는 모습
MCP 서버에 필요한 파라미터를 대화로 입력하는 모습

AI는 완벽하지 않은 동반자

AI가 쓴 API 레퍼런스는 얼마나 잘 썼을까요? 평가하기 위해 평소 API 문서를 작성할 때 쓰던 기준을 바탕으로 평가표를 만들고 LLM이 평가하게 했습니다. 그랬더니 이런 결과가 나왔네요.

  • 전체 주석의 88%가 평가 기준 만족
    비교 평가 결과 그래프(평가 기준 만족 주석 비율)
  • API 개수 기준으로 78%가 GitHub Copilot으로 생성한 주석보다 우수
    비교 평가 결과 그래프(GitHub Copilot과 비교)

평가 기준과 비교 우위 모두를 고려할 때 써 볼 만한 결과입니다. 하지만 100%가 아닌 만큼 완벽하다고 할 수는 없습니다. 실제로 API 담당 개발자가 실제 내용을 찬찬히 뜯어보며 평가해 보니 틀린 정보도 조금 있었거든요.

처음 이 프로젝트를 시작할 때에는 'API 레퍼런스는 길이가 짧고 필요한 내용도 정해져 있으니 기술 문서 중에서는 AI가 쓰기에 가장 적절하지 않을까?'라고 생각했습니다. 그런데 하면 할수록 AI에게는 오히려 더 어려운 주제였다는 생각이 듭니다.

첫째, AI는 정확성에 포커스를 두지 않습니다.

대학생 때 알고리즘 교수님께 들은 이야기를 떠올려 보자면, 알고리즘은 정확도 100%는 기본이고 거기서 얼마나 시간과 공간을 줄이느냐를 다루는데요. AI는 얼마나 확률을 높이느냐를 다룹니다. 지금의 AI는 그 시절의 AI와는 비교할 수도 없이 좋아졌지만, 여전히 100%를 담보하지 못합니다.

물론 저도 100% 올바른 글을 쓰기를 기대하지는 않았습니다. 하지만 생각해 보세요. AI가 100줄짜리 블로그 글을 써서 한 줄쯤 틀린 내용을 썼다면 사람들은 충분히 잘 썼다고 생각할 겁니다. 반면, 한두 줄 정도인 API 레퍼런스에서 한 줄이 틀리면 해당 문서는 쓸모가 없어집니다. 총 100개 중 하나가 틀린 것이라고 해도 그 API 하나를 본 사용자에게는 100% 틀린 것이 되니까요.

둘째, AI는 지시를 따를 줄은 알지만, 지시를 따르지 않아도 되는 예외 상황을 알아서 판단하지는 못합니다. 예를 들어, '범위를 명시해'라는 지시에 따르기 위해 딱히 범위를 지정할 필요가 없는 경우라도 무작정 아무 범위나 갖다 붙입니다. 물론 잘 손보면 알아서 잘, 딱, 깔끔하고 센스 있게 써줄 수도 있겠지만, AI의 속내를 훤히 들여다볼 수 없는 우리로서는 언제 어느 때 말을 잘 듣는지 정확히 파악할 수 없습니다.

그러니 아직은 AI에게 완전히 일을 맡길 수 없습니다. 저희가 만든 주석 생성기로 AI에게 API 레퍼런스를 쓰도록 맡길 수는 있지만, 그렇더라도 '결과가 완벽하지 않으니 내가 한 번 검토해야 한다'는 사실을 꼭 기억해야만 합니다. AI의 역할은 '내가 할 일을 0으로 만들어 주는 것'이 아니라 '내가 1시간 들여서 할 일을 10분 만에 끝내게 해주는 것'이라고 생각합니다. 그 10분은 AI의 결과물을 검토하고 고치는 시간일 테고요.

이 프로젝트를 시작할 때 팀원끼리 "이거 만들어서 정말 잘 되면 우리 잘리는 거 아냐?"라는 농담을 했었습니다(AI가 그만한 결과를 내진 못해서 다행인 걸까요?!). ChatGPT가 등장했을 때, 많은 사람들이 AI가 내 직무를 대체할까 봐 불안해했습니다. 테크니컬 라이터는 잘 알려진 직업이 아니어서 크게 언급되진 않았지만 주 업무가 글쓰기이다 보니 '미래에 사라질 직업군' 중 하나로 생각하는 사람도 있었습니다. 

하지만 AI는 경쟁자가 아닙니다. 어쩌면 테크니컬 라이터는 (개발자가 아니라) AI가 글을 잘 쓰게끔 가르치면서 외연을 더 확장할 수 있을지도 모릅니다. 또한 도큐먼트 엔지니어는 (개발자 대신) AI가 만든 수많은 문서 품질을 자동 검토하고 반복되는 문제점을 찾아 해결해 나갈 수 있습니다. 혹은 그렇게 만든 문서를 읽은 AI가 또 다른 문서를 만들어 내도록 할 수도 있을 테고요. 

물론 AI가 글 쓰는 사람을 대체하다 못해 개발까지 다 해주는 바람에 숫제 개발 문서나 기술 문서를 읽는 사람이 사라질 수도 있습니다. 하지만 그럴 때는 또 그 세상에 맞는 적응 방법이 있겠죠!  제 개인 블로그에 올린 변화하는 글쓰기라는 글에 썼다시피, 저는 변화에 적응하면 살아남는다는 낙관주의자입니다. AI는 변화의 하나일 뿐이고, 제 직무를 빼앗을지 아닐지 결정하는 것은 AI가 아니라 그 변화에 적응하느냐 마느냐 하는 제 선택에 달려 있다고 생각합니다. 그렇기에 AI와 함께, 새로운 문서화 세상에 적응하는 법을 계속 찾아볼 예정입니다.