내용이 산만하고 복잡하여. 순서 정리. 부분 위주로 살펴볼 것
Fault Comprehension -> Code Navigation -> Fault Confirmation: 크게 세 단계로 구성
- 각 단계는 작은 두개의 단계를 각각 갖고 있음.
Abstract
- 문제점: LLM은 잘하나, 긴 컨텍스트를 처리하지 못해 (전체 시스템)을 보고 버그 진단하는것은 어려움. 따라서, 기존 LLM FL은 작은 코드(메소드, 클래스)로 제한됨.
- AGENTFL 소개:
- 위 한계를 해결하기 위해 ChatGPT 기반 다중 에이전트 시스템
- 개발자의 디버깅 행동을 분석하고 FL 작업을 3단계 프로세스로 나눔(Comprehension, Navigation, Confirmation)
- 위 단계를 해결하기 위해, 전략을 세움
- Test Behavior Tracking (테스트 동작 추적)
- Document-Guided Search (문서 기반 탐색)
- Multi-Round Dialogue (다중 라운드 대화)
- 추가 연구:
- Ablation study를 통해 AGENTFL 구성 요소들의 필수 불가결성을 확인
1. Introduction
배경: 개발자들이 디버깅 시간의 절반을 버그 이해 및 localization에 소비 -> 자동화된 FL이 필요함.
- LLM기반 FL:
- LLM의 잠재력: 방대한 코드/텍스트 데이터로 훈련되어 코드 이해 및 버그 감지에서 강력한 능력 보유
- 기존 LLM 기반 FL의 한계: 1) 간단한 지시문으로 주어진 메소드 내 버그 localization. 2) LLMAO: 128개 연속 코드라인으로 제한된 범위에서만 작동
- 문제: 작은 코드(메소드/클래스)에서만 작동, 전체 소프트웨어 시스템 레벨 진단 불가
- 주요 문제:
- 컨텍스트 길이 제한: 실제 프로젝트 코드베이스는 수백만 토큰. GPT-3.5 시리즈 모델 입력 길이는 16385 토큰으로 제한됨. 따라서, 전체 프로젝트를 query하는 것은 불가능. 또한 긴 컨텍스트에서의 성능 저하 현상이 있음.
AgentFL
- 아이디어:
- Localization 프로세스를 여러 단계로 분해. 각 단계에서 다양한 디버깅 정보로 LLM을 선택적으로 향상
- 인간 개발자의 풀이과정에서 영감을 얻음:
- 결함 분석 (오류 추적/core dump 이해)
- 코드베이스 브라우징
- 코드 검사
- 다중 에이전트:
- 필요한 만큼의 정보만 제공: 각 단계에서 필요한 정보만 제공하여, 넘치는 컨텍스트를 제공하지 않음.
- LLM 능력 극대화: 각 에이전트를 전문가로 만들어 특정 작업에 잘하도록 함.
- 3단계 구조:
- Fault Comprehension: LLM으로 잠재적 원인 분석
- Codebase Navigation: 점진적인 개선 방법으로 의심스러운 메소드 식별
- Fault Confirmation: 의심스러운 모든 메소드 검토 후 최종 결과 결정
2. BACKGROUND & RELATED WORK
- Spectrum-Based Fault Localization (SBFL): FL은 실패한 테스트에 의해 더 많이 커버되어야 함
- Learning-Based Fault Localization (LBFL): DeepLearning기반 기법들
LLM-Based Fault Localization
- ChatGPT-4로 프로그램 코드와 오류 로그를 제공하여 오류 localize 및 수정
- 한계: 긴 컨텍스트 처리 한계, 코드 스니펫 내 버그 라인 localization에만 집중
LLM-driven Agents & SOP: 인간 디버깅 행동 연구, FL을 복잡한 작업으로 간주
LLM-driven Agents :Memory management, Tool, Multi-agent communication사용3. APPROACH
A. Overview
Inputs & Outputs:
- Input:
- 전체 프로젝트 코드 - 분석할 소프트웨어 소스코드
- 실패한 테스트들 - 버그 때문에 실패한 테스트 케이스들
- 에러 메시지 - 테스트 실패 시 나타나는 오류 정보
- 특징:
- 문제상황: 보통 하나의 버그가 여러 개의 테스트를 동시에 실패시킴
- 예: Chart-26 버그 때문에 22개의 테스트가 모두 실패
- 비효율적인 방법: 실패한 테스트 22개를 각각 분석하는 것
- AGENTFL 방법: 같은 클래스에 속한 실패한 테스트들을 하나의 그룹으로 묶어서 함께 분석
- 즉, 테스트 클래스 단위로 분석함
- 실패한 테스트 클래스가 5개 있다면, AGENTFL을 5번 실행
- 문제상황: 보통 하나의 버그가 여러 개의 테스트를 동시에 실패시킴
- Output:
- Top-1 의심스러운 메소드 - 가장 버그일 가능성이 높은 메소드 + 왜 의심스러운지 이유
- 의심스러운 클래스 - 버그가 있을 것으로 추정되는 클래스
- 기타 의심스러운 메소드들 - 그 클래스 안의 다른 의심스러운 메소드들 + 각각의 이유
Steps & Tasks.
- 인간의 debugging strategy를 모방
- (i) fault의 원인 이해(Fault Comprehension)
- (ii) 관련 program element들 브라우징(Codebase Navigation)
- (iii) buggy location 검증(Fault Confirmation)을 포함
Agents
- Test Code Reviewer(1): test code를 검토, test behavior를 요약하도록 설계
- Source Code Reviewer(4): 좋은 품질의 주석을 작성하도록 설계
- Software Architect(3, 5): software archi에서 설계적으로 문제가 될 수 있는 영역을 찾음.
- Software Test Engineer(2,6,7): test failure 분석 및 검증 관련 작업을 함.
Component(Tool like)
- 필요성: LLM은 긴 컨텍스트를 처리하지 못하며, 할루시네이션 위험도 있음. 따라서 컴포넌트를 도입함.
- 컴포넌트:
- Program Analysis (프로그램 분석기): 코드에서 정보를 뽑아냄. 테스트 실행시 어떤 메소드들이 호출되는지 추적함. 코드 구조를 분석해서 정보를 제공함. <- Tool과 유사
- Fig1 기준: Task1,3에서 실행함.
- Prompt Generator: 각 단계마다 LLM에게 줄 질문을 자동으로 만듦 <- Agent와 Agent사이의 윤활유 역할
- Task1~7시작전 Trigger함.
- Result Parser: LLM의 답변을 컴퓨터가 이해할 수 있는 형태로 정리 <- Agent와 Agent사이의 윤활유 역할
- Agent가 답변 완료 직후 Trigger.
- State Storage: 각 단계의 결과를 저장해서 다음 단계에서 사용할 수 있게 함 <- Agent와 Agent사이의 윤활유 역할
- 지속적으로 동작함.
- Program Analysis (프로그램 분석기): 코드에서 정보를 뽑아냄. 테스트 실행시 어떤 메소드들이 호출되는지 추적함. 코드 구조를 분석해서 정보를 제공함. <- Tool과 유사
- 더보기
예)// 실패한 테스트@Testpublic void testDiscountCalculation() { cart.addItem("laptop", 1000); cart.addItem("mouse", 50); cart.applyCoupon("SAVE20"); // 20% 할인 assertEquals(840, cart.getTotalPrice()); // 예상: 840, 실제: 1050}Program Analysis: 테스트 실행 시 addItem → applyCoupon → validateCoupon → applyDiscount 호출 순서를 추적- Prompt Generator가 만든 질문:
"다음 실패한 테스트의 동작을 분석해주세요:- 테스트 코드: [위의 testDiscountCalculation 코드]- 실행 중 호출된 메소드들: [Program Analysis가 추적한 정보] * cart.addItem() 호출됨 * cart.applyCoupon() 호출됨 * couponManager.validateCoupon() 호출됨 * priceCalculator.applyDiscount() 호출됨"-- Agent가 생성한 답변"이 테스트는 장바구니에 상품을 추가하고 20% 할인 쿠폰을 적용하는 시나리오입니다. 예상 결과는 840원이지만 실제로는 1050원이 나왔습니다."-- Result Parser가 정리한 결과:{ "test_behavior": "장바구니 상품 추가 + 할인 쿠폰 적용", "expected": 840, "actual": 1050, "covered_methods": ["addItem", "applyCoupon", "validateCoupon", "applyDiscount"]}-- State Storage에 저장----------------------------------------------------------------------------------------2단계: Software Test Engineer Agent--Prompt Generator가 이전 결과를 활용해 새 질문 생성:"테스트 동작: 장바구니 상품 추가 + 할인 쿠폰 적용 실패 원인: 예상 840원, 실제 1050원 가능한 원인들을 분석해주세요."-- Agent의 답변:"가능한 원인들:1. 할인이 전혀 적용되지 않음 (1050 = 1000 + 50)2. 쿠폰 검증 로직 문제3. 할인 계산 로직 문제"--Result Parser → State Storage 저장
B. Fault Comprehension
Figure1의 Steps의 Task1,2에 해당
Aim
인간의 사과와 비슷하게 "이해-추론"방식을 사용함. 이를 Fault Comprehension이라 명명하고, 이는 test failure정보와 source code의 사이의 간극을 연결시키는 역할을 함.
- Test Behavior Analysis(Task1): LLM에게 실패한 Test case들의 동작이 왜 실패했는지 설명하도록 함.
- Test Failure Analysis(Task2): 1에서 생성한 Test behavior analysis 및 test failure(error stack trace, test code, test output)을 활용해 에러의 원인들을 나열하도록 함.(이 원인들은 navigation에서 사용됨)
Challenge
- 입증한 것: 각 unit test에서 수행되는 Test method 활용이 FL에 도움이 된다.
- 한계: test method의 한정적 정보로 여전히 어려움을 겪음.
- Fig 2에서 Fault는 isFunction에서 발생하나 Test Method부분만 보고, 어떠한 코드인지 명확하게 알 수 없음.
- 실제 테스트 로직은 Test Utility Methods부분에 숨겨져 있음.
- 따라서, LLM이 Test Method만 보고 실제로 무엇을 테스트 하고 있는지 파악하기 어려움.
Strategy
Challenge에서 언급한 한계를 극복하고 Test execution behavior을 추적하기 위한 방법을 채택함.
- task1: Test Code Reviewer agent는 Test Code Analysis tool을 사용해서 Test Utility Code로 채운다.
- 원래라면 Test code reviewer agent는 test method만 보고 test behavior를 요약해야하나, 수집된 주변 정보들로 더 좋은 요약을 만들 수 있게 함. (Fig3)
- 순서:
- Instrumentation: 실패한 Test Case별로 Instrumentation을 진행하여 Trace를 수집, 여기에 속한 covered classes 수집
- Intersection: 모든 Failed test case에 커버된 공통 클래스를 추출 -> Common classes
-> 여기서 Test Utility Method을 포함할 것이라 생각함. - Static analysis: 2단계서 추출된 common class에서 document, name, code추출
상속의 상속의 상속의 상속은,,,? 커버 못하는 것으로 보임. - 분석 -> Extracted Classes
Class: Doc, Name
Method1: Code, Doc, Name
문제: 테스트가 실패했을 때, LLM이 테스트 메소드만 보고서는 "왜 실패했는지"를 완전히 이해하기 어려움. 왜냐하면 실제 테스트 로직이 다른 보조 메소드들(test utility method)에 숨어있기 때문
- 해결 방안: Test Behavior Tracking
- 1단계: 테스트 실행 추적
- 테스트가 실행될 때 어떤 메소드들이 호출되는지 기록
- 예: testNoThisInference() → inFunction() → 다른메소드들()
- 2단계: 커버된 클래스들 찾기
- 실행 중에 거쳐간 모든 클래스들을 목록화
- 각 클래스마다 "클래스 이름 + 사용된 메소드들"을 정리
- 3단계: 공통 클래스들만 추리기
- 여러 테스트가 실패했다면, 모든 실패한 테스트에서 공통으로 사용된 클래스들만 남김
- 이것들이 진짜 문제가 있을 가능성이 높은 클래스
- 4단계: 상세 정보 수집
- 남은 클래스들의 코드, 주석, 메소드 설명 등을 모두 수집
- 최종 결과
- LLM에게 단순히 "테스트 메소드만" 주는 게 아니라, "테스트 실행 과정에서 실제로 사용된 모든 보조 코드들"까지 함께 제공한다.
- 1단계: 테스트 실행 추적
순서 정리
Fault Comprehension
- Test Behavior analysis
- Program analysis component실행
- Instrumentation: Failed Test실행하면서 Method Call Trace 기록 (JVM레벨에서 bytecode instrument를 통해 수집)
- Static analysis: 코드베이스 클래스/메소드 정보 추출
- 결과: Extracted Classes생성 (커버된 test class와 test utility method들의 정보들)
- Prompt Generator
- Input: Failed Test, Test Code, Test utility code
- Output: System prompt에 해당 데이터 넣어서 Prompt생성.
- Test Code Reviewer Agent실행
- 구성된 prompt를 받아 test behavior 분석 및 요약
- Output: Test Behavior (자연어로 된 테스트 동작 설명)
- Result Parser & State Storage
- Test Code Reviewer의 응답을 파싱하여 Test Behavior를 추출
- State Storage에 저장 (Task 2에서 사용하기 위해)
- 분석한 결과물: 예) OBJECT_TYPE의 nullable 버전으로 thisType을 생성
- Program analysis component실행
- Test Failure analysis
- Prompt Generator 작동
- Input: Failed Test, Test Behavior(State Storage 저장한 것), Test Infos(error stack trace, test output)
- Prompt 생성: Software Test Engineer agent용 prompt 구성
- Software Test Engineer Agent실행
- Task 1에서 생성된 Test Behavior와 test failure 정보를 종합 분석
- LLM에게 질문: "이 테스트 동작과 실패 정보를 바탕으로 가능한 원인들을 나열해주세요"
- Output: Possible Causes (가능한 결함 원인들의 목록)
- Result Parser & State Storage
- Software Test Engineer의 응답을 파싱하여 Possible Causes 추출
- State Storage에 저장 (Codebase Navigation 단계에서 사용하기 위해)
- Prompt Generator 작동
C. Codebase Navigation
Aim. ChatGPT는 점진적으로 codebase를 global에서 local로 브라우징 하고 test failure을 유발하는 program entity를 식별함.
Challenge: 너무 verbose하게 작성됨.
Strategy: 너무 verbose하게 작성됨.
순서정리
Code Navigation
- Search Suspicious Class:
- 목표: test execution process 동안 커버된 모든 클래스 중에서 가장 의심스러운 클래스 하나를 식별(한계점임)
선택된 클래스를 심도있게 분석하는 것임. - Input: Failed Test, Possible Causes, Test infos, Covered Classes(Program analysis에서 추출된 클래스)
- ClassName + Class Doc형태의 markdown table
- Agent: Software Architect
- 수행 작업
- Document-Guided Search 전략 적용
- 커버된 클래스(실제 호출된 클래스)들의 이름과 documenation을 markdown으로 구성
- ChatGPT로 possible causes를 통해 단일 클래스를 선택
- class단위로 검색할 부분 축소
- Failed Tests: [FAILED TESTS]
Possible Causes: [POSSIBLE CAUSES FROM TASK 2]
Test Information: [TEST INFOS]
Here are the covered classes:
| Class Name | Documentation |
|------------|---------------|
| com.example.ClassA | This class handles... |
| com.example.ClassB | This class manages... |
...
Please select the most suspicious class that may cause the test failure.
- 수행 작업
- Output:
- Suspicious class
- class name + 이유/설명
- 목표: test execution process 동안 커버된 모든 클래스 중에서 가장 의심스러운 클래스 하나를 식별(한계점임)
- Method Doc Enhancement:
- 목표: 다음 단계에서 더 정확한 method 식별을 위해 documentation 품질 향상
- Input:
- Suspcious class(Task3에서 선택된 클래스)
- Class name + method code + class doc
- 해당 클래스에서 실행된 method들의 documentation
'''
This method removes unused variables
'''
- Agent: Software Architect
- 수행 작업:
- Documentation 품질 문제 해결: 소스코드가 input으로 들어감.
- 누락된 method comment 보완
- "Function nested" 문제 해결
- Method call relationship 분석
- 각 method에 대해, 개선된 주석으로 바꿈
- Documentation 품질 문제 해결: 소스코드가 input으로 들어감.
- 수행 작업:
- Output:
- Enhanced Method Doc (개선된 method documentation)
- Method Name + Enhanced Method Documentation 쌍들의 목록
- Find Related Methods:
- 목표: suspicious class 내에서 bug와 관련될 수 있는 모든 method들을 필터링
- Input: Prompt에 녹아져 있을 것임.
- Failed Tests
- Possible Causes(From Task2)
- Test Info
- Class Info(Task 3에서 선택된 suspicious class)
- Method Info(Task 4에서 개선된 enhanced documentation)
- Class Name + Covered Methods(Doc Enhanced) + Class Doc
- Agent:
- Local level로 범위 축소: 관련된 method들만 필터링
- Enhanced documentation을 활용한 정확한method식별
- Bug와 관련될 수 있는 모든 method 선별. (Prompt에 주어진 정보 바탕으로)
- Output:
- Related Methods
- Methods Full Name + Reason
D. Fault Confirmation
Aim. 이전 단계들에서, AGENTFL은 codebase에서 관련 method를 검색하기 위해 (documentation과 coverage 정보만)을 활용했으며, 이는 정확한 fault location을 검증하기에 충분하지 않을 수 있다. 따라서 유용한 정보를 집계하고 어떤 method가 buggy인지에 대한 최종 결정을 내리기 위해 Fault Confirmation 단계를 만들었음. 구체적으로, Software Test Engineer agent가 관련 method들의 source code를 검사하고 유용한 정보를 통합하여 buggy method를 인식하는 Method Review 작업을 진행함.
순서정리
Fault Confirmation
- Method Review
- Input:
- Codebase Navigation에서 식별된 Related Methods 목록
- Failed Tests 정보
- Possible Causes (Fault Comprehension에서 생성됨)
- Test Infos
- Class Info & Method Info
- 수행 작업
- Multi-Round Dialogue 방식 적용
- 모든 관련 메소드를 한 번에 처리하지 않음
- 한 번에 하나씩 메소드를 순차적으로 분석
- 각 라운드마다 하나의 메소드에 대해 집중적으로 검토
예)
라운드 1: Method A 검토
라운드 2: Method B 검토
라운드 3: Method C 검토
... (관련 메소드 수만큼 반복)
- Multi-Round Dialogue 방식 적용
- 목적: 해당 메소드가 buggy location인지 판단
- Output:
- TRUE로 판단된 모든 메소드들이 Suspicious Methods 목록으로 수집됨
- 각 suspicious method에 대한 이유(rationale)도 함께 저장됨
- Input:
- Get Top-1 Method
- Input:
- Method Review에서 생성된 Suspicious Methods 목록
- 각 suspicious method의 buggy 이유
- Possible Causes
- Buggy Method Code
- Test Class 정보
- 수행 작업
- Suspicious Methods 분석
- Method Review 단계에서 TRUE로 판단된 모든 메소드들을 종합적으로 검토
- 각 메소드의 buggy 이유를 비교 분석
- 특별한 경우 처리
- Case 1: Suspicious method가 1개만 있는 경우 → 해당 메소드를 직접 Top-1 Method로 선택
- Case 2: Suspicious method가 여러 개 있는 경우 → 회고적 분석(retrospective analysis) 수행
- 회고적 분석 과정 (여러 suspicious methods가 있는 경우)
- Software Test Engineer가 모든 failed test class의 context에서 분석
- 각 suspicious method의:
- 버그 가능성 정도
- Test failure와의 연관성
- Possible causes와의 일치도
- 종합적으로 가장 가능성 높은 fault location 결정
- 최종 결정 과정
- 모든 정보를 종합하여 단일한 Top-1 Method 선택
- 선택된 메소드에 대한 상세한 이유 제공
- Suspicious Methods 분석
- Input:
- Output:
- Top-1 Method: 가장 의심스러운 단일 메소드
- 이유: 해당 메소드가 선택된 구체적인 근거
- Class: 해당 메소드가 속한 클래스
- Suspicious Methods: 다른 의심스러운 메소드들과 각각의 이유