4. 함부로 실행하지 않는 Agent
실제로 쓰기 전에 바꿀 것
이 차시를 마치면
학습용 코드를 운영으로 옮길 때 반드시 바꿀 곳을 찾아냅니다.
학습용 코드를 그대로 운영에 올리면 안전 성질이 깨집니다. 반드시 바꿔야 할 세 곳과 유지해야 할 테스트를 정리합니다.
반드시 바꿔야 할 세 곳
| 위치 | 학습용 | 운영에서 필요한 것 |
|---|---|---|
InMemorySaver() | 프로세스 메모리 | durable Checkpointer (PostgreSQL, Redis 등) |
_EXECUTED_ACTION_IDS (모듈 변수) | 재시작 시 소실 → 중복 실행 방어가 사라짐 | DB 의 unique 제약 등 durable 저장 분석 |
execute_side_effect 내부 주석 위치 | 실제 발송이나 삭제 코드 없음 | 실제 호출 + 실패 시 재시도와 fallback 정책. 반드시 pending_action 을 대상으로 |
| 시간 상한 | 없음. 반복 상한(MAX_RETRY)만 있음 | 모델 호출과 외부 요청에 timeout. 트랙 3의 A-3 은 "max_retry, 종료 route, timeout/budget 중 최소 하나" 를 요구합니다 분석 |
비유
두 번째 항목이 특히 위험합니다. 중복 실행을 막는 기록이 메모리에만 있다면, 서버를 다시 켠 순간 "이 작업은 이미 했다"는 기억이 사라집니다. 그러면 재시도가 들어왔을 때 한 번 더 실행됩니다.
영수증을 책상 위에만 올려 두고 퇴근한 것과 같습니다. 다음 날 아무도 기억하지 못합니다.
오류 처리 정책
학습팩이 든 오류 유형 여덟 가지입니다.
API timeout · rate limit · Tool error · parsing error · retrieval empty · malformed Structured Output · DB error · permission error
Node 마다 네 가지를 정합니다.
- 재시도 가능한가?
- fallback 이 있는가?
- 사람이 처리해야 하는가?
- State 에 error 를 남길 것인가?
Search
→ success → Verify
→ timeout → retry
→ retry exceeded → Human review
운영 원칙 — LLM 오류와 외부 시스템 오류를 같은 방식으로 처리하지 않습니다.
반드시 유지할 회귀 테스트 네 가지
1번 차시의 네 기준을 테스트 층에 대응시킨 것입니다. 분석
| 기준 | 테스트 층 | 무엇을 고정하는가 |
|---|---|---|
| ① 권한 최소화 | unit test | ../, 절대경로, 심볼릭 링크가 차단되는가 |
| ② 승인 게이트 | graph test | 고위험 입력이 approval Node 를 반드시 지나는가 |
| ③ 멱등성 | graph test | 같은 action_id 로 두 번 재개해도 한 번만 실행되는가 |
| ④ 추적 가능성 | graph test | 종료 State 의 audit_log 에 결정과 실행 기록이 남는가 |
네 가지 모두 작성해 통과시켰습니다. 여기에 2026-08-15 감사에서 찾은 결함 세 건의 회귀 테스트를 더해 총 38개가 통과합니다(Python 3.12.14 · langgraph 1.2.11). 상세는 6차시, 재현 방법은 8차시에 있습니다.
학습팩의 규칙을 다시 확인합니다. 핵심 business rule 을 검증하는 regression test 는 반드시 유지하고, 실패하는 테스트를 원인 수정 없이 삭제해서 'PASS' 로 만드는 것은 금지입니다.
남아 있는 확인 항목
초판에서 남겨 두었던 두 항목은 실행 검증으로 해소되었습니다.
| 초판의 미확인 항목 | 현재 |
|---|---|
sec_graph.py 동작 검증 | 해소 — 실행 검증 통과 (6차시) |
| 재개 시 Node 재실행 범위 | 해소 — Interrupt 를 부른 Node 는 다시 실행되고, 이미 끝난 앞 Node 는 실행되지 않음을 계측으로 확인 (6차시) |
아직 남은 항목입니다.
- 확인 필요 durable Checkpointer — 검증은
InMemorySaver로만 했습니다 - 확인 필요 동시 실행 — 같은
thread_id에 재개 요청 2개를 동시에 보내는 시험을 5회 했고 중복 실행이 없었습니다. 다만_EXECUTED_ACTION_IDS의 확인과 추가가 원자적이지 않으므로 이 관찰은 이 환경과 시도 횟수에서만 성립합니다. 운영에서는 저장소의 유일성 제약이 필요합니다 - 확인 필요 실제 LLM 연결 —
make_draft는 모델을 부르지 않습니다 - 확인 필요 승인자 인증 — 누가 승인했는지 확인하는 방법은 학습팩에 서술이 없습니다. 그래서 승인 게이트가 보장하는 것은 "사람이 한 번 개입했다" 이지 "권한 있는 사람이 승인했다" 가 아닙니다 분석
- 확인 필요 감사 로그의 정확성 — Reducer 덕분에 기존 기록의 삭제는 막히지만, 각 Node 가 내용을 자유롭게 씁니다. 로그는 노드를 신뢰하는 만큼만 신뢰할 수 있습니다 분석
- 확인 필요 감사 로그 보관 —
audit_log를 Checkpoint 밖으로 내보내는 방법은 학습팩에 없습니다 - 확인 필요 모델 ID — 학습팩 예제의
openai:gpt-5.4계열은 검증 기록이 없습니다 - 확인 필요 langgraph 버전 의존 — 1.2.11 기준입니다. 상위 버전에서 재개 동작이 달라질 수 있습니다
교재를 마치며
네 트랙을 모두 마쳤습니다. 정리하면 이렇습니다.
| 트랙 | 남길 것 |
|---|---|
| 1. 설치 가이드 | 자료가 나가는 지점은 네 곳이고, 그중 LLM Provider 선택이 보안 수준을 결정합니다 |
| 2. 입문 과정 | State 가 흐르고 Node 가 갱신합니다. 저장이 있어야 멈췄다 이어갈 수 있습니다 |
| 3. 코드 구조화 | 계약과 안전 불변조건은 함께 고칩니다. 한쪽만 고치는 것이 사고의 원인입니다 |
| 4. 보안 특화 | 지시가 아니라 구조로 막습니다. 승인 전에는 되돌릴 수 없는 일을 하지 않습니다 |