PR-Agent 오픈소스 기여 후기: “시퀀스 다이어그램 자동 생성” 기능

김가희·2025년 11월 26일

왜 이걸 했나

PR 요약은 보통 텍스트 기반이다.
그래서 함수 간 호출 흐름이나 비동기 이벤트가 어떻게 흘러가는지 한눈에 파악하기 어렵다.
리뷰어는 파일을 왔다 갔다 하며 맥락을 조립해야 하는데, 그 과정에서 중요한 상호작용을 놓치기 쉽다.

이 문제를 해결하기 위해 “/describe 했을 때 코드 흐름을 자동으로 시각화할 수 있으면 어떨까?”라는 아이디어에서 출발했다.
그 결과, PR-Agent에 Mermaid 시퀀스 다이어그램을 자동 삽입하는 기능을 구현하기로 했다.



1차: 동작 가능한 MVP 구현

기능 방향

  • 기존 워크플로를 깨지 않도록 옵트인(opt-in) 옵션으로 제공
  • 설정 파일·CLI·프롬프트 어느 방향에서도 다이어그램을 키고 끌 수 있게 확장

구현 포인트

  • configuration.toml에 다이어그램 플래그 추가
  • 프롬프트(pr_description_prompts.toml)를 조건부로 확장: 플래그가 켜져 있을 때만 Mermaid 지시문을 붙임
  • /describe CLI 옵션 추가

PR 기록

1차는 깔끔하게 마무리됐다.



2차: 확장하려다가

MVP는 무사히 돌아갔지만, 실제로 서비스에 적용할 수준이냐는 또 다른 문제였다.

팀은 기능의 완성도를 높여보기 위해 2차 작업을 다음 네 가지 축으로 확장했다.

  • 정확성
  • 확장성
  • 언어 호환성
  • 프롬프트 유연성

그리고 각자 관심사에 맞춰 역할을 나눴다.

  • 김지한: LLM 기반 시퀀스 다이어그램 기능의 정확성 검증 문제 제기, AST 기반 호출 흐름 검증 프레임 구상(Tree-sitter 중심)
  • 김가희: 시퀀스 다이어그램 정확성 검증 방안 실험(Tree-sitter vs LLM 방식)
  • 주동욱: 컨텍스트 윈도우/토큰 전략 실험(Adaptive Prompt Tuning)
  • 한유진: 프롬프트 기반 검증 체크리스트(삽입 위치·Mermaid 문법·요약 규칙) 정립
  • 김예지: Java·JavaScript 코드 기반 다이어그램 품질 검증
  • 윤선웅: Python·C++ 기반 다이어그램 생성 품질 검증

왜 이걸 맡게 되었나

1차 기능에서는 “다이어그램이 생성되기만 하면 성공”이 목표였기 때문에 출력 자체는 잘 되었다.

문제는 그 다음이었다. 이 다이어그램이 정말 코드를 기반으로 한 흐름인가? 혹은 LLM이 “그럴듯하게 지어낸” 흐름인가?

정확성 검증이 전혀 없기 때문에 그림이 맞는지 틀린지 판단할 기준조차 없다는 게 핵심 문제였다.
PR 리뷰어 입장에서 다이어그램은 진짜 코드 흐름이어야 의미가 있다.
그래서 나는 어떻게 하면 이 다이어그램이 정확한지 검증할 수 있을까를 맡아 깊게 파 보기로 했다.


어떻게 접근했는가 (Tree-sitter 방식 vs LLM 방식)

시퀀스 다이어그램의 신뢰성을 높이기 위해, 코드에서 실제 호출 흐름을 추출하는 방법을 두 가지로 나눠 실험했다.

1) Tree-sitter 기반 정적 분석 방식

가장 먼저 떠올린 건 Tree-sitter였다.
PR diff를 AST로 분석하면 실제 함수 호출 관계(call graph)를 정적으로 뽑아낼 수 있다.
이 흐름을 Mermaid 다이어그램과 비교하면 LLM이 어느 부분을 틀렸는지 정확히 판단할 수 있다고 보았다.

  • 장점

    • 코드 기반이라 정확하고 일관적
    • 언어만 인식되면 동일 파이프라인으로 확장 가능
    • “범용 검증 체계”로 만들기 좋음
  • 한계

    • 언어별 grammar/쿼리 구현 비용 매우 큼
    • 단순 검증이 아니라 “AST로 다이어그램을 직접 만드는 게 낫다”는 지점까지 감
    • 메인테이너와의 장기적인 합의가 필요

→ 결론: 기술적으로 최고지만, 지금 당장은 오버스펙.

2) LLM 기반 “정답 호출 흐름(call_flow)” 추출 방식

두 번째 접근은 현재 PR-Agent 구조와 잘 맞고, 실험 속도도 빠른 방식이다.
동일한 PR 코드를 LLM에게 입력해 “실제 호출 흐름만 JSON 형태로 추출”하게 하고,
이를 생성된 시퀀스 다이어그램과 비교하는 방식이다.

  • 장점

    • 언어 중립적 → JS, Python, Java 등 대부분의 케이스에 적용 가능
    • 기존 PR-Agent 구조를 거의 건드리지 않아도 됨
    • 프롬프트 수정만으로 빠르게 실험 가능
  • 한계

    • LLM의 일관성 부족
    • 코드 길어지면 누락·왜곡 발생
    • call_flow가 List[Dict]라 기존 PR description 빌더와 타입 충돌
    • 결국 전용 파이프라인이 필요

→ 결론: 당장 적용 가능한 건 LLM 기반 검증.


구현하면서 겪은 문제

실제로 LLM에게서 호출 흐름(call_flow)을 성공적으로 추출했고, 이걸 PR description 생성 단계에 넣어보려던 시점에서 문제가 발생했다.

pr_description.py 내부 로직이 “description은 문자열 또는 문자열 리스트”라는 전제에 맞춰 설계되어 있었고,

call_flow는 구조화된 리스트(List[Dict])였기 때문에 description 빌더에서 타입 충돌이 일어났다.

elif key.lower().strip() == 'description':
    if isinstance(value, list): ...

여기서 value가 “리스트이긴 하지만 문자열 리스트가 아닌 Dict 리스트”라 기존 로직이 바로 깨지는 문제가 있었다.

이걸 해결하려면

  • description 빌더의 구조 자체를 뜯어고치거나
  • call_flow만 위한 전용 섹션/어댑터를 만들어 분리하거나
  • description → diagram → call_flow의 파이프라인을 재정의해야 한다.

즉, 구조적 리팩토링이 불가피한 상황이었다.

이건 단순 기능 추가를 넘어서 PR-Agent 전체 구조에 영향이 있었기 때문에, 멘토링 프로그램 내에서 해결하기엔 범위가 너무 컸다. 그래서 “정확성 검증을 위한 핵심 문제 정의”까지만 이번에 마무리하게 됐다.



정리

내가 맡은 역할은 단순히 “다이어그램이 잘 나오는지 확인하는 것”이 아니라 “이 다이어그램이 실제 코드의 흐름을 얼마나 정확하게 반영하고 있는가?” 를 검증하는 방법을 설계하는 일이었다.

그 과정에서

  • Tree-sitter는 정확하지만 도입 장벽이 높고
  • LLM 기반 검증은 당장 적용 가능한 현실적 접근이며
  • call_flow를 안전하게 합류시키기 위한 구조적 과제가 필요하다는 것도 발견했다.

기능 완성까지는 못 갔지만 “정확성 검증을 위해 무엇이 필요한가”를 명확히 정의하고, 다음 스텝으로 넘길 수 있는 토대를 만든 점에서는 의미 있는 시도였다고 생각한다.

팀 전체가 하나의 기능을 단순히 “만들었다”를 넘어서
“어떻게 하면 제대로 만들 수 있을까?”를 고민한 프로젝트였고,
그 안에서 내가 기여할 수 있었던 부분이 있어 값진 경험이었다.

0개의 댓글