Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

Lab 03: 자기 수정 피드백 루프 구축

Session 4 실습 | 소요 시간: 25분 에이전트의 비대화형 실행으로 버그를 자동 수정하고, 그 피드백 루프를 직접 구현한다.


학습 목표

  • 에이전트의 비대화형(non-interactive) 실행 모드를 이해한다
  • 테스트 실패 → 에이전트 수정 → 재검증 피드백 루프를 직접 구현한다
  • 자동화 루프(Ralph 원리)가 왜 강력한지 체험한다

준비

# Python 3.8 이상 필요 (표준 라이브러리만 사용)
python3 --version

# 실습 디렉토리로 이동
cd labs/03-feedback-loop

# 환경 확인
just setup

I DO — 실제 세션 로그: 에이전트가 버그를 자동 수정하다 (5분)

아래는 opencode run 명령으로 에이전트를 비대화형으로 실행했을 때의 실제 세션 출력이다. 에이전트가 사람의 개입 없이 버그를 찾고 수정하는 전 과정이 담겨 있다.

실행한 프롬프트

cd src
opencode run "test_vocab.py를 실행하면 test_case_insensitive_answer가 실패합니다. \
quiz.py의 check_answer() 함수를 분석하고 버그를 수정해주세요. \
test_vocab.py는 수정하지 마세요."

실제 세션 출력 (원문)

> build · gpt-5.4

✱ Glob "**/quiz.py" in . · 1 match
✱ Glob "**/test_vocab.py" in . · 1 match
→ Read quiz.py
→ Read test_vocab.py
⚙ apply_patch Success. Updated the following files:
M 03-feedback-loop/src/quiz.py

$ python3 test_vocab.py
test_case_insensitive_answer ... ok
test_whitespace_trimming ... ok
test_delete_cleans_stats ... FAIL
test_word_count_after_delete ... ok
test_score_calculation_with_string_values ... FAIL
...
Ran 10 tests in 0.008s
FAILED (failures=2)

`quiz.py`의 `check_answer()`를 수정해서 입력값과 정답을 공백 제거 후
소문자로 비교하도록 바꿨습니다. 이제 "Apple"과 "apple"을 같은 정답으로
처리합니다.

에이전트 행동 타임라인

[요청] "test_case_insensitive_answer가 실패합니다. quiz.py를 분석하고 수정해줘"
    │
[탐색] Glob "**/quiz.py" → 1개 파일 발견
    │  Glob "**/test_vocab.py" → 1개 파일 발견
    │
[분석] Read quiz.py → check_answer() 함수 확인
    │              → "대소문자 구분 비교" 주석과 버그 코드 발견
    │  Read test_vocab.py → 테스트가 기대하는 동작 파악
    │                    → "Apple"을 "apple"과 동일하게 처리해야 함
    │
[수정] apply_patch quiz.py → .lower() 추가
    │
[검증] python3 test_vocab.py 실행
    │  → test_case_insensitive_answer: FAIL → ok (수정 성공!)
    │  → 나머지 2개 FAIL은 다른 버그 (범위 밖)
    │
[완료] 변경 파일: quiz.py, 소요 시간: ~10초

에이전트가 실제로 적용한 diff

--- a/quiz.py
+++ b/quiz.py
@@ -13,6 +13,3 @@ def check_answer(user_answer: str, correct_answer: str) -> bool:
-    # 버그: 대소문자 구분 비교
-    return user_answer.strip() == correct_answer.strip()
-    # 올바른 코드:
-    # return user_answer.strip().lower() == correct_answer.strip().lower()
+    return user_answer.strip().lower() == correct_answer.strip().lower()

변경은 딱 한 줄이다. .lower()를 양쪽에 추가하는 것이 전부다.

수정 전후 테스트 결과 비교

테스트 수정 전 수정 후
test_case_insensitive_answer FAIL OK
test_whitespace_trimming ok ok
test_delete_cleans_stats FAIL FAIL (다른 버그)
test_score_calculation_with_string_values FAIL FAIL (다른 버그)
나머지 6개 ok ok
합계 7/10 통과 8/10 통과

관찰 포인트

1. 에이전트는 테스트 실패 메시지를 단서로 파일을 찾았다

에이전트는 test_case_insensitive_answer라는 테스트 이름에서 quiz.py를 추론하지 않았다. 대신 Glob "**/quiz.py"로 파일을 직접 찾고, 코드를 읽어서 버그 위치를 확인했다. 프롬프트에 파일 이름이 있어도 에이전트는 코드를 먼저 읽는다.

2. opencode run은 비대화형이다

# 대화형 (사람이 응답 확인 후 다음 단계 진행)
opencode

# 비대화형 (사람 개입 없이 작업 완료까지 자동 실행)
opencode run "프롬프트"

opencode run은 프롬프트를 주면 스스로 탐색 → 수정 → 검증까지 완료한다. 이 모드가 루프에서 쓸 수 있는 이유다.

3. 에이전트가 범위를 지켰다

프롬프트에 "test_vocab.py는 수정하지 마세요"를 명시했고, 에이전트는 정확히 quiz.py만 수정했다. 나머지 2개의 버그(stats.py, vocab.py)는 이번 프롬프트 범위 밖이므로 건드리지 않았다.


WE DO (10분) — 함께 자동화 스크립트 완성

src/auto_fix.sh 템플릿에 TODO 부분을 함께 채워봅니다.

단계 1: 테스트 실행 추가

# TODO 1 자리에 다음을 추가
TEST_OUTPUT_FILE="test_output.txt"
python3 -m unittest test_vocab -v 2>&1 | tee "$TEST_OUTPUT_FILE" | tee -a "$LOG_FILE"
TEST_EXIT_CODE=${PIPESTATUS[0]}

단계 2: 성공 조건 추가

# TODO 2, 3 자리에 다음을 추가
if [ $TEST_EXIT_CODE -eq 0 ]; then
    echo "모든 테스트 통과! 완료."
    exit 0
fi

단계 3: 에이전트 호출 추가

# TODO 4 자리에 다음을 추가
opencode run "다음 테스트 실패를 분석하고 코드를 수정해주세요:
$(cat $TEST_OUTPUT_FILE)
test_vocab.py는 수정하지 마세요."

함께 첫 번째 루프 돌리기

스크립트를 완성한 뒤 첫 번째 시도를 실행해봅니다:

cd src
bash auto_fix.sh

I DO에서 본 것처럼 에이전트가 quiz.py의 .lower() 버그를 먼저 수정할 것입니다.


YOU DO (10분) — 나머지 버그 자동화 루프로 수정

목표

완성된 auto_fix.sh를 사용하여 3개 버그를 모두 자동으로 수정합니다.

시작하기

cd src

# 현재 실패 상태 확인 (3개 실패)
python3 -m unittest test_vocab -v

# 자동 수정 루프 실행
bash auto_fix.sh

성공 기준

Ran 10 tests in 0.XXXs
OK

기록 양식

루프가 완료되면 다음을 기록하세요:

항목 내용
총 시도 횟수 ___ 회
버그 1 (quiz.py) 에이전트 분석: ___ / 수정 방법: ___
버그 2 (stats.py) 에이전트 분석: ___ / 수정 방법: ___
버그 3 (vocab.py) 에이전트 분석: ___ / 수정 방법: ___
가장 흥미로운 점 ___
한계나 문제점 ___

세션 로그로 피드백 루프 분석 (선택)

루프가 끝난 뒤 세션 데이터에서 에이전트의 행동 패턴을 정량적으로 분석할 수 있다.

# 세션 목록 확인
opencode session list

# 가장 최근 세션 ID로 세부 내용 추적
python3 ~/.claude/skills/oc-trace/oc_trace.py trace <session-id> -v

분석 포인트:

  • 도구 호출 패턴: Read → apply_patch → Bash 순서가 몇 번 반복되었는가?
  • 루프 반복 횟수: 에이전트가 테스트를 몇 번 실행했는가?
  • 버그당 소요 시간: 버그마다 수정 속도가 다른가?

토론 주제

  • 에이전트가 항상 올바른 버그를 찾았나요? 틀린 곳을 수정한 경우는?
  • 몇 번 시도 만에 성공했나요? 왜 그런 차이가 생겼을까요?
  • 이 루프를 실제 프로젝트에 적용한다면 어떤 조건이 필요할까요?

막혔을 때

힌트 보기

just hints

솔루션 확인

# 솔루션으로 테스트 전부 통과 확인
just test-solution

# 솔루션 코드 직접 확인
cat solution/vocab.py
cat solution/quiz.py
cat solution/stats.py
cat solution/auto_fix.sh

버그 요약

파일 버그 유형 위치 수정 방법
quiz.py 로직 버그 check_answer() .lower() 변환 추가
stats.py 타입 에러 calculate_score() int(correct) 변환 추가
vocab.py 데이터 무결성 delete_word() stats도 함께 삭제

정리

# 데이터 파일 정리
just clean