3. 고쳐도 안 깨지는 코드
혼자 고치면 안 되는 네 가지
이 차시를 마치면
절대 유지해야 하는 네 가지를 알아보고, 왜 함께 고쳐야 하는지 설명합니다.
코드에서 절대 유지해야 하는 것 네 가지입니다. 이것을 알면 나머지는 자유롭게 고쳐도 됩니다.
먼저, 오해를 풉니다
학습팩은 이 문장으로 시작합니다.
'절대 바꾸면 안 되는 것'은 코드 문자열 자체가 아니라, 시스템 계약과 안전 불변조건(invariant) 을 의미합니다.
즉 "이 줄을 건드리지 마라"가 아닙니다. 혼자 바꾸면 안 되고 관련된 곳을 함께 바꿔야 한다는 뜻입니다.
비유
건물로 보면 이렇습니다.
A 는 기둥과 내력벽, 그리고 소방 규정입니다. 없애면 건물이 무너지거나 사람이 다칩니다. 옮기려면 구조 설계를 다시 해야 합니다.
B 는 벽지 색, 가구 배치, 조명입니다. 바꿔도 건물은 서 있습니다.
C 는 벽지를 바꾸는 줄 알았는데 내력벽을 뚫는 것입니다. 본인은 B 를 한다고 생각하지만 실제로는 A 를 깬 상태입니다.
A-1. 주고받는 형식의 약속 (Interface Contract)
State key, Tool argument schema, Structured output schema, DB 와 API field contract 가 여기 해당합니다.
바꾸려면 caller, callee, migration, test 를 함께 바꿔야 합니다.
A-2. 언제나 참이어야 하는 조건 (Safety Invariant)
- 실제 이메일 발송은 승인 이후
- 삭제는 확인 이후
- 개인정보는 허용된 저장소에만 저장
학습팩은 이렇게 못 박습니다. 이런 규칙은 prompt 편의를 위해 제거하면 안 됩니다.
"프롬프트를 고치기 번거로우니 승인 단계를 빼자"는 요청이 왔을 때 이 항목을 근거로 거절할 수 있습니다.
A-3. 반복이 끝나는 조건 (Termination Condition)
Loop 가 있는 경우 max_retry, 종료 route, timeout 또는 budget 중 최소 하나 이상의 제어가 있어야 합니다.
MAX_RETRY = 2
def route_after_approval(state):
"""승인되면 실행하고, 반려되면 재시도하되 상한을 지킨다."""
if state["approved"]:
return "execute"
if state["retry_count"] >= MAX_RETRY:
return "__end__"
return "revise"
A-4. 저장에 관한 약속 (Persistence Contract)
HITL 에서 Checkpointer, thread_id, resume semantics 를 제거하면 중단과 재개 기능 자체가 깨질 수 있습니다.
네 가지의 관계
A-1 은 코드끼리의 약속이고, A-2 는 사람과의 약속입니다. A-3 과 A-4 는 그 약속이 지켜지도록 뒷받침하는 장치입니다. 분석
A-3 이 없으면 무한 반복으로 비용과 부하가 발생하고, A-4 가 없으면 A-2 의 "승인 이후"라는 조건이 실행 시점에 성립하지 않습니다.
| 항목 | 없으면 무슨 일이 생기는가 |
|---|---|
| A-1 계약 | 한쪽만 고친 순간 다른 쪽이 실행 시점에 깨집니다 |
| A-2 안전 규칙 | 되돌릴 수 없는 일이 승인 없이 일어납니다 |
| A-3 종료 조건 | 무한 반복으로 비용과 부하가 늘어납니다 |
| A-4 저장 계약 | 멈췄다가 이어서 실행하는 것 자체가 불가능해집니다 |
이 차시의 파이썬 코드는 개념을 보이려고 떼어 놓은 예시 조각입니다. 문법 검사는 통과하지만 그대로 돌려서 결과를 확인한 코드는 아닙니다. 실행까지 검증한 코드는 4번과 6번 트랙에 있으며, 그 차시에는 무엇을 어떻게 확인했는지 따로 적어 두었습니다.