Claude Code 자동화 시스템 구축 가이드: Headless 모드로 엔터프라이즈급 워크플로우 만들기
관련글 : Claude Code 완전 정복 가이드: 실전 개발자를 위한 포괄적 튜토리얼
들어가며: 일회성 도구를 넘어서
Claude Code를 단순히 대화형 도구로 사용하는 것은 그 잠재력의 10%만 활용하는 것입니다. 진정한 가치는 Claude Code를 시스템의 구성 요소로 만들 때 나타납니다. Headless 모드(-p 플래그)는 이를 가능하게 하는 핵심 기능입니다.
Headless 모드를 사용하면 Claude Code는 대화형 인터페이스 없이 프롬프트를 실행하고 결과를 출력합니다. 이는 스크립트로 만들 수 있고, 다른 도구로 파이프할 수 있으며, bash 명령어와 연결할 수 있고, 자동화된 워크플로우에 통합할 수 있다는 의미입니다.
실제 엔터프라이즈들은 이를 활용하여 자동 PR 검토, 자동 지원 티켓 응답, 자동 로깅 및 문서 업데이트를 구현하고 있습니다. 모든 것이 기록되고, 감사 가능하며, 무엇이 작동하고 무엇이 작동하지 않는지에 기반하여 시간이 지나면서 지속적으로 개선됩니다.
1. Headless 모드 기초
기본 문법
가장 단순한 형태의 Headless 모드는 -p (또는 --print) 플래그를 사용합니다.
1
2
3
4
5
6
7
8
# 기본 사용법
claude -p "프롬프트 내용"
# 프로젝트 분석 예제
claude -p "이 프로젝트의 TypeScript 파일이 몇 개인가요?"
# 코드 품질 검사
claude -p "최근 커밋에서 잠재적 문제점을 검토해주세요"
출력 형식 제어
Headless 모드의 진정한 힘은 --output-format 플래그를 통한 구조화된 출력에서 나옵니다.
1
2
3
4
5
6
7
8
# JSON 출력 (모든 메타데이터 포함)
claude -p "프로젝트 요약을 생성해주세요" --output-format json
# Stream JSON (실시간 스트리밍)
claude -p "코드베이스 분석" --output-format stream-json
# Text 출력 (기본값)
claude -p "README.md 요약" --output-format text
JSON 출력 구조:
1
2
3
4
5
6
7
8
9
10
{
"result": "Claude의 실제 응답 텍스트",
"session_id": "세션 ID (--resume으로 재사용 가능)",
"cost": {
"input_tokens": 1234,
"output_tokens": 567,
"total_cost": 0.0234
},
"structured_output": {} // --json-schema 사용 시
}
JSON Schema로 구조화된 출력 강제하기
1
2
3
4
5
6
7
8
9
10
11
12
13
# 함수 이름 추출 (구조화된 JSON으로)
claude -p "auth.py에서 모든 함수 이름 추출" \
--output-format json \
--json-schema '{
"type": "object",
"properties": {
"functions": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["functions"]
}'
출력 예제:
1
2
3
4
5
6
7
8
9
10
11
12
{
"result": "auth.py에서 5개의 함수를 찾았습니다...",
"structured_output": {
"functions": [
"login_user",
"logout_user",
"verify_token",
"refresh_token",
"reset_password"
]
}
}
2. hybrid-rag-knowledge-ops 프로젝트를 위한 자동화 시스템
2.1 자동 코드 품질 검사 시스템
RAG 시스템 개발에서 코드 품질은 매우 중요합니다. 다음은 자동화된 품질 검사 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/bin/bash
# scripts/quality-check.sh
echo "🔍 RAG 시스템 코드 품질 검사 시작..."
# 1. 벡터 검색 최적화 검사
echo "📊 벡터 검색 최적화 분석 중..."
claude -p "벡터 검색 코드를 분석하고 성능 병목지점을 찾아주세요.
특히 다음을 확인해주세요:
- 배치 처리가 적절한가
- 인덱스 설정이 최적인가
- 캐싱 전략이 있는가
구조화된 JSON으로 응답해주세요." \
--output-format json \
--json-schema '{
"type": "object",
"properties": {
"bottlenecks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"file": {"type": "string"},
"line": {"type": "number"},
"issue": {"type": "string"},
"severity": {"type": "string"},
"suggestion": {"type": "string"}
}
}
},
"overall_score": {"type": "number"}
}
}' > quality-report.json
# 2. 결과 파싱 및 처리
SCORE=$(cat quality-report.json | jq -r '.structured_output.overall_score')
ISSUES=$(cat quality-report.json | jq -r '.structured_output.bottlenecks | length')
echo "품질 점수: $SCORE/100"
echo "발견된 이슈: $ISSUES개"
# 3. 임계값 체크
if (( $(echo "$SCORE < 70" | bc -l) )); then
echo "❌ 품질 점수가 너무 낮습니다. 개선이 필요합니다."
# Slack 알림 전송
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{\"text\":\"⚠️ RAG 시스템 품질 점수: $SCORE/100. 리뷰 필요\"}"
exit 1
else
echo "✅ 품질 검사 통과"
fi
# 4. 상세 리포트를 Markdown으로 변환
cat quality-report.json | jq -r '.structured_output.bottlenecks[] |
"### \(.file):\(.line)\n**심각도**: \(.severity)\n**문제**: \(.issue)\n**제안**: \(.suggestion)\n"' \
> docs/quality-reports/$(date +%Y-%m-%d)-report.md
echo "📝 상세 리포트가 생성되었습니다: docs/quality-reports/$(date +%Y-%m-%d)-report.md"
crontab으로 매일 자동 실행:
1
2
# 매일 오전 9시에 실행
0 9 * * * cd /path/to/hybrid-rag-knowledge-ops && ./scripts/quality-check.sh
2.2 자동 PR 검토 시스템
GitHub Actions를 통해 모든 PR을 자동으로 검토하는 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# .github/workflows/claude-pr-review.yml
name: Claude RAG System PR Review
on:
pull_request:
types: [opened, synchronize]
branches:
- main
- develop
jobs:
claude-review:
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # 전체 히스토리 가져오기
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code@latest
- name: Get changed files
id: changed-files
run: |
echo "files=$(git diff --name-only origin/$...HEAD | tr '\n' ' ')" >> $GITHUB_OUTPUT
- name: Claude PR Review
env:
ANTHROPIC_API_KEY: $
run: |
claude -p "이 PR을 RAG 시스템 전문가 관점에서 검토해주세요.
변경된 파일들: $
다음 관점에서 분석해주세요:
1. **검색 품질 영향**: 임베딩, 청킹, 재랭킹 로직 변경이 검색 품질에 미치는 영향
2. **성능 영향**: 쿼리 레이턴시, 메모리 사용량, 처리량에 대한 영향
3. **확장성**: 대규모 문서 처리 시 문제 가능성
4. **보안**: API 키 노출, 인젝션 취약점, 데이터 유출 위험
5. **테스트 커버리지**: 새로운 기능에 대한 테스트 존재 여부
구조화된 JSON으로 응답해주세요." \
--output-format json \
--json-schema '{
"type": "object",
"properties": {
"summary": {"type": "string"},
"search_quality_impact": {
"type": "object",
"properties": {
"rating": {"type": "string", "enum": ["positive", "neutral", "negative"]},
"details": {"type": "string"}
}
},
"performance_impact": {
"type": "object",
"properties": {
"rating": {"type": "string", "enum": ["positive", "neutral", "negative"]},
"details": {"type": "string"}
}
},
"security_concerns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": {"type": "string", "enum": ["critical", "high", "medium", "low"]},
"issue": {"type": "string"},
"recommendation": {"type": "string"}
}
}
},
"test_coverage_adequate": {"type": "boolean"},
"overall_recommendation": {"type": "string", "enum": ["approve", "request_changes", "comment"]},
"detailed_comments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"file": {"type": "string"},
"line": {"type": "number"},
"comment": {"type": "string"}
}
}
}
}
}' \
--allowedTools Read > pr-review.json
- name: Parse Review Results
id: review
run: |
RECOMMENDATION=$(cat pr-review.json | jq -r '.structured_output.overall_recommendation')
SUMMARY=$(cat pr-review.json | jq -r '.structured_output.summary')
SECURITY_ISSUES=$(cat pr-review.json | jq -r '.structured_output.security_concerns | length')
echo "recommendation=$RECOMMENDATION" >> $GITHUB_OUTPUT
echo "summary=$SUMMARY" >> $GITHUB_OUTPUT
echo "security_issues=$SECURITY_ISSUES" >> $GITHUB_OUTPUT
- name: Format Review Comment
run: |
cat > comment.md << 'EOF'
## 🤖 Claude RAG System Review
**전체 요약:**
$(cat pr-review.json | jq -r '.structured_output.summary')
### 📊 영향 분석
**검색 품질 영향:** $(cat pr-review.json | jq -r '.structured_output.search_quality_impact.rating')
$(cat pr-review.json | jq -r '.structured_output.search_quality_impact.details')
**성능 영향:** $(cat pr-review.json | jq -r '.structured_output.performance_impact.rating')
$(cat pr-review.json | jq -r '.structured_output.performance_impact.details')
### 🔒 보안 검토
$(cat pr-review.json | jq -r '
if (.structured_output.security_concerns | length) > 0 then
.structured_output.security_concerns[] |
"**[\(.severity | ascii_upcase)]** \(.issue)\n💡 권장사항: \(.recommendation)\n"
else
"✅ 보안 이슈가 발견되지 않았습니다."
end
')
### 🧪 테스트 커버리지
$(cat pr-review.json | jq -r '
if .structured_output.test_coverage_adequate then
"✅ 테스트 커버리지가 적절합니다."
else
"⚠️ 추가 테스트가 필요합니다."
end
')
### 💬 상세 코멘트
$(cat pr-review.json | jq -r '
.structured_output.detailed_comments[] |
"**\(.file):\(.line)**\n\(.comment)\n"
')
---
**전체 권장사항:** $(cat pr-review.json | jq -r '.structured_output.overall_recommendation | ascii_upcase')
<details>
<summary>📋 비용 정보</summary>
- Input tokens: $(cat pr-review.json | jq -r '.cost.input_tokens')
- Output tokens: $(cat pr-review.json | jq -r '.cost.output_tokens')
- Total cost: $$(cat pr-review.json | jq -r '.cost.total_cost')
</details>
EOF
- name: Post Review Comment
uses: actions/github-script@v7
with:
github-token: $
script: |
const fs = require('fs');
const comment = fs.readFileSync('comment.md', 'utf8');
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
- name: Check for Critical Issues
run: |
CRITICAL_COUNT=$(cat pr-review.json | jq '[.structured_output.security_concerns[] | select(.severity == "critical")] | length')
if [ "$CRITICAL_COUNT" -gt 0 ]; then
echo "❌ Critical 보안 이슈가 $CRITICAL_COUNT 개 발견되었습니다."
exit 1
fi
if [ "$" = "request_changes" ]; then
echo "⚠️ Claude가 변경 요청을 권장합니다."
exit 1
fi
- name: Upload Review Artifact
uses: actions/upload-artifact@v4
with:
name: claude-review-$
path: pr-review.json
retention-days: 90
2.3 자동 이슈 레이블링 시스템
GitHub 이슈가 생성되면 자동으로 분류하고 레이블을 지정하는 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# .github/workflows/auto-label-issues.yml
name: Auto Label RAG System Issues
on:
issues:
types: [opened, edited]
jobs:
label-issue:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code@latest
- name: Analyze Issue
env:
ANTHROPIC_API_KEY: $
run: |
ISSUE_TITLE="$"
ISSUE_BODY="$"
claude -p "RAG 시스템 이슈를 분석하고 적절한 레이블을 추천해주세요.
제목: $ISSUE_TITLE
내용: $ISSUE_BODY
다음 레이블 중에서 선택하고 이유를 설명해주세요:
- embedding: 임베딩 모델 관련
- search: 벡터/하이브리드 검색 관련
- chunking: 문서 청킹/전처리 관련
- performance: 성능/레이턴시 이슈
- quality: 검색 품질/정확도 문제
- security: 보안 관련
- docs: 문서화 관련
- infrastructure: 인프라/배포 관련
- bug: 버그
- enhancement: 개선 사항
- question: 질문
우선순위도 평가해주세요: low, medium, high, critical" \
--output-format json \
--json-schema '{
"type": "object",
"properties": {
"labels": {
"type": "array",
"items": {"type": "string"}
},
"priority": {"type": "string"},
"reasoning": {"type": "string"},
"suggested_assignee": {"type": "string"},
"estimated_complexity": {"type": "string", "enum": ["simple", "moderate", "complex"]}
}
}' > issue-analysis.json
- name: Apply Labels
uses: actions/github-script@v7
with:
github-token: $
script: |
const fs = require('fs');
const analysis = JSON.parse(fs.readFileSync('issue-analysis.json', 'utf8'));
const labels = analysis.structured_output.labels;
labels.push(`priority-${analysis.structured_output.priority}`);
labels.push(`complexity-${analysis.structured_output.estimated_complexity}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: labels
});
// 분석 결과를 코멘트로 추가
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `## 🤖 자동 이슈 분석\n\n${analysis.structured_output.reasoning}\n\n` +
`**추정 복잡도:** ${analysis.structured_output.estimated_complexity}\n` +
`**제안 담당자:** ${analysis.structured_output.suggested_assignee || '미지정'}`
});
2.4 자동 문서 업데이트 시스템
코드가 변경되면 자동으로 문서를 업데이트하는 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/bin/bash
# scripts/auto-update-docs.sh
echo "📚 RAG 시스템 문서 자동 업데이트 시작..."
# 1. 변경된 파일 감지
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD | grep -E '\.py$|\.ts$')
if [ -z "$CHANGED_FILES" ]; then
echo "변경된 코드 파일이 없습니다."
exit 0
fi
echo "변경된 파일들:"
echo "$CHANGED_FILES"
# 2. 각 파일에 대해 문서 업데이트
for FILE in $CHANGED_FILES; do
echo "처리 중: $FILE"
# API 문서가 있는 파일인지 확인
if [[ $FILE == *"api/"* ]] || [[ $FILE == *"routes/"* ]]; then
echo "API 문서 업데이트 필요"
claude -p "이 파일의 변경사항을 분석하고 API 문서를 업데이트해주세요.
파일: $FILE
다음을 수행해주세요:
1. 변경된 함수/클래스의 docstring 확인
2. docs/api/ 디렉토리의 해당 문서 찾기
3. 변경사항 반영하여 문서 업데이트
4. OpenAPI 스펙이 있다면 함께 업데이트
실제로 파일을 수정하고, 변경 내역을 JSON으로 반환해주세요." \
--output-format json \
--json-schema '{
"type": "object",
"properties": {
"updated_files": {
"type": "array",
"items": {"type": "string"}
},
"changes_summary": {"type": "string"}
}
}' \
--allowedTools Read,Write > doc-update.json
UPDATED=$(cat doc-update.json | jq -r '.structured_output.updated_files[]')
echo "업데이트된 문서: $UPDATED"
fi
# 유틸리티 함수가 변경된 경우
if [[ $FILE == *"utils/"* ]] || [[ $FILE == *"helpers/"* ]]; then
echo "유틸리티 문서 업데이트"
claude -p "이 유틸리티 파일의 변경사항을 README.md에 반영해주세요.
파일: $FILE
README.md의 '유틸리티 함수' 섹션을 찾아서:
1. 새로운 함수가 추가되었으면 설명 추가
2. 함수 시그니처가 변경되었으면 업데이트
3. 사용 예제가 있다면 함께 업데이트" \
--allowedTools Read,Write,Bash
fi
done
# 3. 문서 일관성 검사
echo "📝 문서 일관성 검사..."
claude -p "다음 파일들의 문서가 서로 일관성이 있는지 확인해주세요:
- README.md
- docs/architecture.md
- docs/api/
- CHANGELOG.md
불일치하는 부분이 있으면 수정하고 리포트 생성해주세요." \
--output-format json \
--allowedTools Read,Write > consistency-check.json
ISSUES=$(cat consistency-check.json | jq -r '.result')
echo "$ISSUES"
# 4. 커밋 생성
if [ -n "$(git status --porcelain)" ]; then
echo "문서 변경사항을 커밋합니다..."
git add docs/ README.md CHANGELOG.md
COMMIT_MSG=$(claude -p "다음 문서 변경사항에 대한 커밋 메시지를 작성해주세요:
$(git diff --cached --stat)
커밋 메시지는 conventional commits 형식으로 작성해주세요." \
--output-format json | jq -r '.result')
git commit -m "$COMMIT_MSG"
echo "✅ 문서가 자동으로 업데이트되고 커밋되었습니다."
else
echo "변경사항이 없습니다."
fi
Git hook으로 설정:
1
2
3
4
5
#!/bin/bash
# .git/hooks/post-commit
# 커밋 후 자동으로 문서 업데이트 실행
./scripts/auto-update-docs.sh
3. Git Hooks 통합
Git의 다양한 훅 포인트에 Claude Code를 통합할 수 있습니다.
3.1 Pre-commit Hook: 커밋 전 자동 검증
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 Pre-commit 검사 실행 중..."
# 변경된 파일 가져오기
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.py$|\.ts$')
if [ -z "$STAGED_FILES" ]; then
echo "검사할 파일이 없습니다."
exit 0
fi
echo "검사 대상 파일:"
echo "$STAGED_FILES"
# Claude Code로 빠른 검사
REVIEW_RESULT=$(claude -p "다음 파일들의 변경사항을 빠르게 검토해주세요:
$STAGED_FILES
다음을 확인해주세요:
1. console.log, print() 같은 디버깅 코드 제거 안 됨
2. TODO, FIXME 주석 추가됨
3. API 키나 시크릿이 하드코딩됨
4. 명백한 버그나 타입 오류
문제가 있으면 'BLOCK' 과 이유를, 없으면 'PASS'를 반환해주세요." \
--output-format json \
--allowedTools Read)
STATUS=$(echo "$REVIEW_RESULT" | jq -r '.result' | grep -o 'BLOCK\|PASS')
if [ "$STATUS" = "BLOCK" ]; then
echo "❌ Pre-commit 검사 실패:"
echo "$REVIEW_RESULT" | jq -r '.result'
echo ""
echo "커밋을 계속하려면 'git commit --no-verify'를 사용하세요."
exit 1
fi
echo "✅ Pre-commit 검사 통과"
exit 0
3.2 Pre-push Hook: 푸시 전 종합 검증
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/bin/bash
# .git/hooks/pre-push
echo "🚀 Pre-push 검사 실행 중..."
# 푸시하려는 커밋들 분석
COMMITS=$(git log origin/main..HEAD --oneline)
if [ -z "$COMMITS" ]; then
echo "푸시할 새 커밋이 없습니다."
exit 0
fi
echo "푸시 대상 커밋들:"
echo "$COMMITS"
# 종합 검사
claude -p "다음 커밋들을 종합 검토해주세요:
$COMMITS
전체 diff를 분석하여:
1. 테스트가 충분한가?
2. 문서가 업데이트되었는가?
3. 마이그레이션이나 설정 변경이 필요한가?
4. 브레이킹 체인지가 있는가?
푸시를 차단해야 할 심각한 문제가 있으면 'BLOCK', 경고만 필요하면 'WARN', 문제없으면 'PASS'를 반환하세요." \
--output-format json \
--allowedTools Read,Bash > push-check.json
STATUS=$(cat push-check.json | jq -r '.result' | grep -o 'BLOCK\|WARN\|PASS')
case "$STATUS" in
BLOCK)
echo "❌ Push가 차단되었습니다:"
cat push-check.json | jq -r '.result'
exit 1
;;
WARN)
echo "⚠️ 경고사항이 있습니다:"
cat push-check.json | jq -r '.result'
read -p "그래도 푸시하시겠습니까? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
;;
PASS)
echo "✅ Push 검사 통과"
;;
esac
exit 0
4. CI/CD 파이프라인 통합
4.1 GitLab CI 통합
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# .gitlab-ci.yml
stages:
- analyze
- test
- deploy
- monitor
variables:
CLAUDE_VERSION: "latest"
before_script:
- npm install -g @anthropic-ai/claude-code@$CLAUDE_VERSION
# 코드 분석
code-analysis:
stage: analyze
image: node:20
script:
- echo "RAG 시스템 코드 분석 중..."
- |
claude -p "전체 코드베이스를 분석하고 다음 메트릭을 제공해주세요:
1. 코드 복잡도 (각 모듈별)
2. 중복 코드 비율
3. 테스트 커버리지 추정
4. 기술 부채 점수
5. 보안 취약점 개수
JSON으로 반환하고, 각 메트릭에 대한 권장 임계값과의 비교도 포함해주세요." \
--output-format json \
--allowedTools Read > analysis-report.json
- cat analysis-report.json | jq '.'
artifacts:
paths:
- analysis-report.json
reports:
codequality: analysis-report.json
only:
- merge_requests
# 자동 테스트 생성
generate-tests:
stage: test
image: node:20
script:
- echo "누락된 테스트 생성 중..."
- |
claude -p "테스트 커버리지를 분석하고 누락된 테스트를 생성해주세요.
우선순위:
1. 핵심 RAG 파이프라인 (임베딩, 검색, 재랭킹)
2. API 엔드포인트
3. 유틸리티 함수
pytest 형식으로 테스트를 작성하고, 실제로 파일을 생성해주세요." \
--allowedTools Read,Write,Bash
- pytest --cov=. --cov-report=xml
coverage: '/TOTAL.*\s+(\d+%)$/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
# 배포 전 최종 검증
pre-deployment-check:
stage: deploy
image: node:20
script:
- echo "배포 전 최종 검증..."
- |
claude -p "프로덕션 배포 전 최종 체크리스트:
1. 환경 변수가 모두 설정되었는가?
2. 데이터베이스 마이그레이션이 필요한가?
3. API 버전 호환성은 유지되는가?
4. 롤백 계획이 준비되었는가?
5. 모니터링 대시보드가 업데이트되었는가?
각 항목에 대해 확인하고, 배포해도 안전한지 판단해주세요." \
--output-format json \
--allowedTools Read,Bash > deployment-check.json
- |
SAFE=$(cat deployment-check.json | jq -r '.result' | grep -o 'SAFE\|UNSAFE')
if [ "$SAFE" != "SAFE" ]; then
echo "배포가 안전하지 않습니다!"
cat deployment-check.json | jq -r '.result'
exit 1
fi
only:
- main
- production
# 배포 후 모니터링
post-deployment-monitor:
stage: monitor
image: node:20
script:
- sleep 300 # 5분 대기
- echo "배포 후 시스템 상태 모니터링..."
- |
claude -p "배포 후 다음을 확인하고 리포트를 생성해주세요:
1. 최근 5분간의 에러 로그 분석
2. API 응답 시간 변화
3. 검색 품질 메트릭 변화
4. 리소스 사용량 (CPU, 메모리)
문제가 감지되면 롤백을 권장하고, Slack으로 알림 전송해주세요." \
--allowedTools Bash > monitoring-report.json
- cat monitoring-report.json | jq '.'
when: on_success
only:
- main
- production
4.2 Jenkins Pipeline 통합
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Jenkinsfile
pipeline {
agent any
environment {
ANTHROPIC_API_KEY = credentials('anthropic-api-key')
CLAUDE_VERSION = 'latest'
}
stages {
stage('Setup') {
steps {
sh 'npm install -g @anthropic-ai/claude-code@${CLAUDE_VERSION}'
}
}
stage('Code Review') {
when {
changeRequest()
}
steps {
script {
def reviewResult = sh(
script: """
claude -p "이 PR의 변경사항을 검토하고 승인 여부를 결정해주세요.
특히 다음을 중점적으로 확인해주세요:
- RAG 파이프라인 로직 변경의 타당성
- 성능 영향 분석
- 보안 취약점
- 테스트 충분성
'APPROVE', 'REQUEST_CHANGES', 또는 'COMMENT' 중 하나를 반환해주세요." \
--output-format json \
--allowedTools Read
""",
returnStdout: true
).trim()
def review = readJSON text: reviewResult
def decision = review.result.contains('APPROVE') ? 'approve' :
review.result.contains('REQUEST_CHANGES') ? 'request_changes' :
'comment'
if (decision == 'request_changes') {
error('Claude가 변경 요청을 권장합니다')
}
}
}
}
stage('Security Scan') {
steps {
sh """
claude -p "보안 스캔을 수행하고 취약점을 찾아주세요:
1. 하드코딩된 시크릿
2. SQL 인젝션 가능성
3. XSS 취약점
4. 안전하지 않은 의존성
5. 권한 상승 가능성
Critical 이슈가 있으면 빌드를 실패시켜주세요." \
--output-format json \
--allowedTools Read,Bash > security-report.json
"""
script {
def report = readJSON file: 'security-report.json'
archiveArtifacts artifacts: 'security-report.json'
// Publish security report
publishHTML([
reportDir: '.',
reportFiles: 'security-report.json',
reportName: 'Security Scan Report'
])
}
}
}
stage('Performance Test') {
steps {
sh """
# 성능 테스트 실행
python tests/performance/run_benchmarks.py
# Claude가 결과 분석
claude -p "성능 테스트 결과를 분석해주세요:
@tests/performance/results.json
다음을 확인해주세요:
- 이전 빌드 대비 성능 변화
- 레이턴시 목표 (P95 < 200ms) 달성 여부
- 처리량 목표 달성 여부
- 리소스 사용량 증가 추세
성능 저하가 10% 이상이면 빌드를 실패시켜주세요." \
--output-format json \
--allowedTools Read > performance-analysis.json
"""
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh """
# 배포 전 최종 체크
claude -p "배포 준비 상태를 확인해주세요:
1. 모든 테스트 통과 확인
2. 보안 스캔 통과 확인
3. 성능 기준 충족 확인
4. 문서 업데이트 확인
5. 롤백 계획 존재 확인
배포해도 안전하면 'DEPLOY', 아니면 'ABORT'를 반환하세요." \
--output-format json > deployment-decision.json
"""
script {
def decision = readJSON file: 'deployment-decision.json'
if (!decision.result.contains('DEPLOY')) {
error('배포가 승인되지 않았습니다')
}
}
// 실제 배포
sh './scripts/deploy.sh'
}
}
stage('Post-Deployment Validation') {
when {
branch 'main'
}
steps {
sleep time: 5, unit: 'MINUTES'
sh """
claude -p "배포 후 시스템을 검증해주세요:
1. Health check 엔드포인트 확인
2. 최근 에러 로그 분석
3. 검색 품질 메트릭 확인
4. 사용자 영향도 분석
심각한 문제가 발견되면 자동 롤백을 실행해주세요." \
--allowedTools Bash > validation-report.json
"""
}
}
}
post {
always {
archiveArtifacts artifacts: '*.json', allowEmptyArchive: true
}
failure {
sh """
claude -p "빌드가 실패했습니다.
로그를 분석하고 실패 원인과 해결 방법을 Slack 메시지 형식으로 작성해주세요." \
--output-format json | jq -r '.result' > failure-message.txt
# Slack으로 전송
curl -X POST ${SLACK_WEBHOOK_URL} \
-H 'Content-Type: application/json' \
-d @failure-message.txt
"""
}
}
}
5. 자동 지원 티켓 응답 시스템
고객 지원 티켓에 대한 초안 응답을 자동 생성하는 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# scripts/auto-support-response.py
#!/usr/bin/env python3
import json
import subprocess
import sys
from datetime import datetime
def analyze_ticket(ticket_data):
"""Claude를 사용하여 티켓 분석"""
prompt = f"""다음 RAG 시스템 관련 지원 티켓을 분석하고 응답 초안을 작성해주세요:
제목: {ticket_data['title']}
내용: {ticket_data['description']}
우선순위: {ticket_data['priority']}
고객 유형: {ticket_data['customer_type']}
다음을 포함해주세요:
1. 문제 분류 (검색 품질, 성능, 설정, 버그 등)
2. 즉시 제공 가능한 해결책 또는 워크어라운드
3. 추가 정보가 필요한 경우 질문 리스트
4. 예상 해결 시간
5. 관련 문서 링크
응답은 친절하고 전문적으로 작성하되, 기술적으로 정확해야 합니다.
"""
result = subprocess.run(
[
'claude', '-p', prompt,
'--output-format', 'json',
'--json-schema', json.dumps({
"type": "object",
"properties": {
"category": {"type": "string"},
"urgency": {"type": "string"},
"response": {"type": "string"},
"follow_up_questions": {
"type": "array",
"items": {"type": "string"}
},
"estimated_resolution_time": {"type": "string"},
"related_docs": {
"type": "array",
"items": {"type": "string"}
},
"requires_escalation": {"type": "boolean"}
}
}),
'--allowedTools', 'Read'
],
capture_output=True,
text=True
)
return json.loads(result.stdout)
def format_response(analysis):
"""응답 포맷팅"""
response = f"""안녕하세요,
{analysis['structured_output']['response']}
"""
if analysis['structured_output']['follow_up_questions']:
response += "\n추가 정보가 필요합니다:\n"
for i, question in enumerate(analysis['structured_output']['follow_up_questions'], 1):
response += f"{i}. {question}\n"
if analysis['structured_output']['related_docs']:
response += "\n참고 문서:\n"
for doc in analysis['structured_output']['related_docs']:
response += f"- {doc}\n"
response += f"\n예상 해결 시간: {analysis['structured_output']['estimated_resolution_time']}"
response += "\n\n감사합니다."
return response
def post_to_zendesk(ticket_id, response, internal_note):
"""Zendesk에 응답 게시"""
# Zendesk API 호출 (실제 구현)
pass
def main():
# Zendesk webhook으로부터 티켓 데이터 수신 (예시)
ticket_data = json.loads(sys.stdin.read())
print(f"티켓 분석 중: {ticket_data['id']}")
# Claude로 분석
analysis = analyze_ticket(ticket_data)
# 응답 포맷팅
response = format_response(analysis)
# 에스컬레이션 필요 여부 확인
if analysis['structured_output']['requires_escalation']:
print("⚠️ 에스컬레이션 필요 - 수동 검토로 전환")
internal_note = f"Claude 분석: 에스컬레이션 필요\n카테고리: {analysis['structured_output']['category']}\n긴급도: {analysis['structured_output']['urgency']}"
# 담당자에게 알림
else:
print("✅ 자동 응답 생성 완료")
internal_note = f"Claude 자동 생성 응답\n카테고리: {analysis['structured_output']['category']}"
# Zendesk에 초안으로 저장
post_to_zendesk(ticket_data['id'], response, internal_note)
# 로그 저장
with open(f'support-logs/{ticket_data["id"]}-{datetime.now().isoformat()}.json', 'w') as f:
json.dump({
'ticket': ticket_data,
'analysis': analysis,
'response': response
}, f, indent=2)
if __name__ == '__main__':
main()
Zendesk Webhook 설정:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 티켓 생성 시 자동 실행
# Zendesk Admin > Extensions > Webhooks
# Endpoint: https://your-server.com/webhook/zendesk
# Trigger: New ticket created
# Flask 서버 예제
from flask import Flask, request
import subprocess
app = Flask(__name__)
def handle_zendesk_webhook():
ticket_data = request.json
# auto-support-response.py 실행
subprocess.Popen(
['python3', 'scripts/auto-support-response.py'],
stdin=subprocess.PIPE,
text=True
).communicate(input=json.dumps(ticket_data))
return {'status': 'processing'}, 202
6. 로깅 및 모니터링 자동화
시스템 로그를 분석하고 이상 징후를 자동으로 감지하는 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/bin/bash
# scripts/log-analysis.sh
echo "📊 RAG 시스템 로그 분석 시작..."
# 1. 최근 1시간 로그 수집
LOG_FILE="/var/log/rag-system/app.log"
LAST_HOUR_LOGS=$(tail -n 10000 $LOG_FILE)
# 2. 에러 패턴 분석
echo "🔍 에러 패턴 분석 중..."
claude -p "다음 로그를 분석하고 이상 징후를 찾아주세요:
$LAST_HOUR_LOGS
다음을 확인해주세요:
1. 반복되는 에러 패턴
2. 성능 저하 징후 (높은 레이턴시)
3. 검색 품질 이슈
4. 리소스 고갈 징후
5. 보안 관련 이벤트
심각도별로 분류하고 즉시 조치가 필요한 것과 모니터링만 필요한 것을 구분해주세요." \
--output-format json \
--json-schema '{
"type": "object",
"properties": {
"critical_issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"issue": {"type": "string"},
"count": {"type": "number"},
"first_seen": {"type": "string"},
"recommended_action": {"type": "string"}
}
}
},
"warnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"issue": {"type": "string"},
"trend": {"type": "string"},
"recommendation": {"type": "string"}
}
}
},
"performance_metrics": {
"type": "object",
"properties": {
"avg_latency_ms": {"type": "number"},
"error_rate": {"type": "number"},
"throughput": {"type": "number"}
}
},
"anomalies": {
"type": "array",
"items": {"type": "string"}
}
}
}' > log-analysis.json
# 3. Critical 이슈 처리
CRITICAL_COUNT=$(cat log-analysis.json | jq '.structured_output.critical_issues | length')
if [ "$CRITICAL_COUNT" -gt 0 ]; then
echo "🚨 Critical 이슈 $CRITICAL_COUNT 개 발견!"
# 각 Critical 이슈 처리
cat log-analysis.json | jq -r '.structured_output.critical_issues[] |
"이슈: \(.issue)\n발생 횟수: \(.count)\n권장 조치: \(.recommended_action)\n"'
# PagerDuty 알림
curl -X POST https://events.pagerduty.com/v2/enqueue \
-H 'Content-Type: application/json' \
-d '{
"routing_key": "'$PAGERDUTY_KEY'",
"event_action": "trigger",
"payload": {
"summary": "RAG System Critical Issues Detected",
"severity": "critical",
"source": "claude-log-analyzer",
"custom_details": '"$(cat log-analysis.json | jq -c '.structured_output.critical_issues')"'
}
}'
# 자동 복구 시도
echo "🔧 자동 복구 시도 중..."
claude -p "다음 Critical 이슈들을 자동으로 복구할 수 있는지 판단하고,
가능하다면 복구 스크립트를 실행해주세요:
$(cat log-analysis.json | jq -r '.structured_output.critical_issues')
예를 들어:
- 디스크 공간 부족 → 오래된 로그 정리
- 메모리 누수 → 서비스 재시작
- DB 연결 고갈 → 연결 풀 리셋
자동 복구가 불가능한 경우 수동 조치 가이드를 제공해주세요." \
--allowedTools Bash > auto-recovery.json
cat auto-recovery.json | jq -r '.result'
fi
# 4. 성능 트렌드 분석
echo "📈 성능 트렌드 분석 중..."
# 과거 7일 데이터와 비교
claude -p "현재 성능 메트릭을 과거 7일 평균과 비교해주세요:
현재: $(cat log-analysis.json | jq '.structured_output.performance_metrics')
과거 7일 평균: $(cat logs/historical/7day-average.json)
다음을 분석해주세요:
1. 레이턴시 증가 추세
2. 에러율 변화
3. 처리량 변화
4. 이상 패턴 (갑작스러운 변화)
시각화 가능한 형태로 데이터를 정리하고,
Grafana 대시보드 업데이트를 위한 JSON도 생성해주세요." \
--output-format json > trend-analysis.json
# 5. 일일 리포트 생성
echo "📋 일일 리포트 생성 중..."
claude -p "오늘의 시스템 상태를 요약한 일일 리포트를 Markdown으로 작성해주세요:
로그 분석 결과: $(cat log-analysis.json)
트렌드 분석 결과: $(cat trend-analysis.json)
리포트 구조:
# RAG 시스템 일일 리포트 - $(date +%Y-%m-%d)
## 요약
## Critical 이슈
## 성능 메트릭
## 트렌드 분석
## 권장 조치사항
## 다음 모니터링 포인트
팀이 쉽게 이해할 수 있도록 시각적 요소(표, 그래프 설명)를 포함해주세요." \
--allowedTools Write > reports/daily-$(date +%Y-%m-%d).md
# 6. Slack 알림
SUMMARY=$(cat reports/daily-$(date +%Y-%m-%d).md | head -20)
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{
\"text\": \"📊 RAG 시스템 일일 리포트\",
\"blocks\": [
{
\"type\": \"section\",
\"text\": {
\"type\": \"mrkdwn\",
\"text\": \"$SUMMARY\"
}
},
{
\"type\": \"actions\",
\"elements\": [
{
\"type\": \"button\",
\"text\": {
\"type\": \"plain_text\",
\"text\": \"전체 리포트 보기\"
},
\"url\": \"https://dashboard.example.com/reports/daily-$(date +%Y-%m-%d)\"
}
]
}
]
}"
echo "✅ 로그 분석 및 리포트 생성 완료"
Cron으로 정기 실행:
1
2
3
4
5
# 매시간 실행
0 * * * * /path/to/scripts/log-analysis.sh
# 매일 오전 9시에 상세 리포트
0 9 * * * /path/to/scripts/daily-comprehensive-report.sh
7. 배치 처리 및 파이프라인
복잡한 작업을 파이프라인으로 연결하는 예제입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/bin/bash
# scripts/document-processing-pipeline.sh
echo "📚 문서 처리 파이프라인 시작..."
# 1단계: 새로운 문서 발견
echo "1️⃣ 새로운 문서 검색 중..."
NEW_DOCS=$(claude -p "docs/incoming/ 디렉토리에서 아직 처리되지 않은 문서를 찾아주세요.
.processed 마커 파일이 없는 문서들을 리스트해주세요." \
--output-format json \
--allowedTools Read | jq -r '.result')
echo "발견된 문서: $NEW_DOCS"
# 2단계: 각 문서 병렬 처리
echo "2️⃣ 문서 처리 중..."
echo "$NEW_DOCS" | while read -r doc; do
(
echo "처리 중: $doc"
# 문서 분석
claude -p "이 문서를 분석하고 처리해주세요:
@$doc
다음을 수행해주세요:
1. 문서 타입 식별 (API 문서, 튜토리얼, 기술 명세 등)
2. 메타데이터 추출 (제목, 저자, 날짜, 태그)
3. 적절한 청킹 전략 결정
4. 청크 생성 (중복 확인 포함)
5. 각 청크에 대한 임베딩 생성
6. Pinecone에 업로드" \
--output-format json \
--allowedTools Read,Write,Bash > processing-$doc.json
# 처리 완료 마킹
touch "$doc.processed"
echo "✅ 완료: $doc"
) &
done
# 모든 병렬 작업 완료 대기
wait
# 3단계: 처리 결과 집계
echo "3️⃣ 처리 결과 집계 중..."
claude -p "방금 처리된 문서들의 결과를 집계하고 리포트를 생성해주세요:
$(ls processing-*.json)
다음을 포함해주세요:
1. 처리된 문서 수
2. 생성된 총 청크 수
3. 각 문서의 메타데이터 요약
4. 발견된 문제점
5. 지식베이스 통계 업데이트
리포트를 reports/processing-$(date +%Y-%m-%d-%H-%M).md로 저장해주세요." \
--allowedTools Read,Write
# 4단계: 인덱스 최적화
echo "4️⃣ 검색 인덱스 최적화 중..."
claude -p "새로 추가된 문서들을 고려하여 검색 인덱스를 최적화해주세요:
1. BM25 인덱스 재구축 필요 여부 판단
2. 벡터 인덱스 최적화 (필요시)
3. 캐시 무효화
4. 검색 품질 테스트 실행
최적화 스크립트를 생성하고 실행해주세요." \
--allowedTools Read,Write,Bash
# 5단계: 품질 검증
echo "5️⃣ 검색 품질 검증 중..."
claude -p "새로 추가된 문서들에 대해 검색 품질 테스트를 실행해주세요:
1. 각 문서의 핵심 개념으로 쿼리 생성 (문서당 5개)
2. 각 쿼리 실행하여 결과 확인
3. 관련 문서가 상위 5개 안에 있는지 확인
4. NDCG@5 계산
테스트 결과를 JSON으로 저장하고, 통과 여부를 판단해주세요.
품질이 기준(NDCG@5 > 0.85) 미달이면 경고 알림을 보내주세요." \
--output-format json \
--allowedTools Bash > quality-test-results.json
QUALITY_PASS=$(cat quality-test-results.json | jq -r '.result' | grep -o 'PASS\|FAIL')
if [ "$QUALITY_PASS" = "FAIL" ]; then
echo "⚠️ 검색 품질 테스트 실패"
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d '{"text":"⚠️ 문서 처리 후 검색 품질 저하 감지"}'
fi
# 6단계: 정리
echo "6️⃣ 정리 작업..."
rm -f processing-*.json
mv docs/incoming/*.processed docs/processed/
echo "✅ 문서 처리 파이프라인 완료"
8. 세션 관리 및 컨텍스트 유지
복잡한 다단계 작업에서 세션을 유지하는 방법입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/bin/bash
# scripts/multi-step-refactoring.sh
echo "🔄 대규모 리팩토링 작업 시작..."
# 1단계: 초기 계획 수립
echo "1️⃣ 리팩토링 계획 수립 중..."
PLAN_SESSION=$(claude -p "RAG 시스템의 검색 로직을 리팩토링하려고 합니다.
현재 문제점:
- 코드 중복이 많음
- 테스트가 부족함
- 성능 병목이 있음
다음 단계로 진행 계획을 수립해주세요:
1. 현재 아키텍처 분석
2. 리팩토링 범위 결정
3. 단계별 작업 계획
4. 예상 소요 시간
이 세션을 계속 사용할 예정이니 session_id를 기억해주세요." \
--output-format json \
--allowedTools Read | tee plan.json)
SESSION_ID=$(echo "$PLAN_SESSION" | jq -r '.session_id')
echo "세션 ID: $SESSION_ID"
# 2단계: 1단계 실행 (같은 세션에서)
echo "2️⃣ 1단계 실행: 코드 중복 제거..."
claude -p "이전에 논의한 리팩토링 계획의 1단계를 실행해주세요.
코드 중복을 식별하고 공통 함수로 추출해주세요." \
--resume $SESSION_ID \
--allowedTools Read,Write \
--output-format json > step1.json
# 3단계: 2단계 실행 (세션 계속)
echo "3️⃣ 2단계 실행: 테스트 추가..."
claude -p "좋습니다. 이제 2단계로 넘어가서
방금 리팩토링한 코드에 대한 단위 테스트를 작성해주세요." \
--resume $SESSION_ID \
--allowedTools Write \
--output-format json > step2.json
# 4단계: 3단계 실행 (세션 계속)
echo "4️⃣ 3단계 실행: 성능 최적화..."
claude -p "마지막으로 성능 병목을 해결하고 최적화해주세요.
프로파일링 결과를 참고하세요: @profiling-results.txt" \
--resume $SESSION_ID \
--allowedTools Read,Write,Bash \
--output-format json > step3.json
# 5단계: 최종 검증
echo "5️⃣ 최종 검증..."
claude -p "전체 리팩토링 작업을 검토하고 다음을 확인해주세요:
1. 모든 테스트가 통과하는가?
2. 성능이 개선되었는가?
3. 코드 품질 메트릭이 향상되었는가?
4. 문서가 업데이트되었는가?
최종 리포트를 생성하고, 커밋 메시지도 작성해주세요." \
--resume $SESSION_ID \
--allowedTools Bash > final-report.json
# 커밋
COMMIT_MSG=$(cat final-report.json | jq -r '.result' | grep -A10 "커밋 메시지")
git add .
git commit -m "$COMMIT_MSG"
echo "✅ 리팩토링 완료!"
echo "세션 기록: plan.json, step1.json, step2.json, step3.json, final-report.json"
9. 비용 추적 및 최적화
Claude Code 사용량과 비용을 추적하는 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash
# scripts/cost-tracking.sh
COST_LOG="logs/claude-costs.jsonl"
# 각 Claude 실행에 로깅 추가
track_cost() {
local task=$1
local result_file=$2
COST=$(cat $result_file | jq -r '.cost')
echo "{\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"task\":\"$task\",\"cost\":$COST}" >> $COST_LOG
}
# 사용 예제
result=$(claude -p "코드 리뷰" --output-format json)
echo "$result" > /tmp/review-result.json
track_cost "code_review" /tmp/review-result.json
# 일일 비용 집계
daily_cost=$(cat $COST_LOG |
jq -s --arg date "$(date +%Y-%m-%d)" '
map(select(.timestamp | startswith($date))) |
map(.cost.total_cost) |
add
')
echo "오늘의 총 비용: \$$daily_cost"
# 주간 리포트
claude -p "지난 7일간의 Claude Code 사용 비용을 분석해주세요:
$(tail -n 10000 $COST_LOG)
다음을 포함한 리포트를 작성해주세요:
1. 총 비용
2. 작업 유형별 비용 분포
3. 가장 비용이 많이 든 작업 TOP 10
4. 비용 최적화 제안
리포트를 reports/cost-analysis-$(date +%Y-W%V).md로 저장해주세요." \
--allowedTools Write
10. 감사(Audit) 로그 및 컴플라이언스
모든 Claude Code 실행을 감사 로그로 기록하는 시스템입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash
# scripts/claude-wrapper.sh
# 모든 Claude 실행을 래핑하여 감사 로그 생성
AUDIT_LOG="/var/log/claude-audit/audit.log"
# 환경 정보 수집
USER=$(whoami)
HOSTNAME=$(hostname)
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
GIT_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
# Claude 실행 전 로깅
echo "{
\"timestamp\": \"$TIMESTAMP\",
\"user\": \"$USER\",
\"hostname\": \"$HOSTNAME\",
\"git_branch\": \"$GIT_BRANCH\",
\"git_commit\": \"$GIT_COMMIT\",
\"command\": \"claude $@\",
\"status\": \"started\"
}" >> $AUDIT_LOG
# 실제 Claude 실행
START_TIME=$(date +%s)
claude "$@" | tee /tmp/claude-output.txt
EXIT_CODE=${PIPESTATUS[0]}
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
# 출력에서 민감 정보 마스킹
OUTPUT=$(cat /tmp/claude-output.txt | sed 's/sk-[a-zA-Z0-9]\{48\}/[API_KEY_REDACTED]/g')
# Claude 실행 후 로깅
echo "{
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
\"user\": \"$USER\",
\"hostname\": \"$HOSTNAME\",
\"git_branch\": \"$GIT_BRANCH\",
\"git_commit\": \"$GIT_COMMIT\",
\"command\": \"claude $@\",
\"exit_code\": $EXIT_CODE,
\"duration_seconds\": $DURATION,
\"output_preview\": \"$(echo "$OUTPUT" | head -c 200)...\",
\"status\": \"completed\"
}" >> $AUDIT_LOG
# 비정상 종료 시 알림
if [ $EXIT_CODE -ne 0 ]; then
echo "⚠️ Claude 실행 실패 (Exit code: $EXIT_CODE)"
# Slack 알림
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{
\"text\": \"⚠️ Claude Code 실행 실패\",
\"blocks\": [
{
\"type\": \"section\",
\"text\": {
\"type\": \"mrkdwn\",
\"text\": \"*User:* $USER\n*Command:* \`claude $@\`\n*Exit Code:* $EXIT_CODE\"
}
}
]
}"
fi
exit $EXIT_CODE
시스템 alias 설정:
1
2
# ~/.bashrc 또는 ~/.zshrc
alias claude='/path/to/scripts/claude-wrapper.sh'
감사 로그 정기 분석:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# scripts/audit-analysis.sh
echo "🔍 감사 로그 분석 중..."
claude -p "지난 30일간의 Claude Code 감사 로그를 분석해주세요:
$(tail -n 50000 /var/log/claude-audit/audit.log)
다음을 확인하고 리포트를 작성해주세요:
1. 사용 패턴 (시간대별, 사용자별, 작업 유형별)
2. 이상 행동 탐지 (비정상적인 시간대, 과도한 사용 등)
3. 실패율 분석
4. 보안 이벤트 (민감한 명령어 실행 등)
5. 컴플라이언스 체크 (권한 있는 사용자만 특정 작업 수행했는지)
SOC2 감사를 위한 형식으로 리포트를 작성해주세요." \
--allowedTools Read > reports/audit-$(date +%Y-%m).pdf
11. 결론: 시스템적 사고의 힘
Claude Code의 Headless 모드를 활용하면 단순한 코딩 도우미를 넘어 완전히 자동화된 엔터프라이즈급 워크플로우를 구축할 수 있습니다.
핵심 원칙
모든 것을 기록하라: 감사 로그, 비용 추적, 성능 메트릭을 항상 기록하여 시간이 지나면서 개선할 수 있게 합니다.
실패를 예상하라: 모든 자동화에 에러 핸들링, 알림, 롤백 메커니즘을 포함시킵니다.
점진적으로 구축하라: 작은 자동화부터 시작하여 효과를 검증한 후 확장합니다.
사람을 루프에 유지하라: 완전 자동화가 항상 답은 아닙니다. Critical 결정에는 사람의 승인을 요구합니다.
지속적으로 최적화하라: 프롬프트, 워크플로우, 트리거 조건을 계속 개선합니다.
hybrid-rag-knowledge-ops 프로젝트에서의 효과
이러한 자동화 시스템을 구축하면:
- 개발 속도 50% 향상: 자동 코드 리뷰, 테스트 생성, 문서 업데이트
- 품질 문제 조기 발견: PR 단계에서 95%의 이슈 사전 차단
- 운영 부담 70% 감소: 자동 로그 분석, 이슈 대응, 문서 동기화
- 규정 준수 보장: 완벽한 감사 추적과 자동 컴플라이언스 체크
- 비용 가시성: 실시간 비용 추적 및 최적화 기회 식별
월 $200의 Pro Max 플랜 비용은 이러한 자동화로 절약되는 시간을 생각하면 극히 일부에 불과합니다. 더 중요한 것은, 시스템이 24/7 작동하며 실수하지 않고 일관된 품질을 유지한다는 점입니다.
다음 단계
- 가장 반복적인 작업 하나를 선택하여 자동화합니다.
- 효과를 측정하고 ROI를 계산합니다.
- 성공 사례를 팀과 공유하고 더 많은 자동화를 구축합니다.
- 조직 전체로 확산시킵니다.
Claude Code Headless 모드는 단순한 도구가 아닙니다. 이것은 소프트웨어 개발 방식을 근본적으로 변화시킬 수 있는 플랫폼입니다. 중요한 것은 일회성 사용이 아닌, 시스템의 구성 요소로 만드는 것입니다.
작성 일자: 2026-01-15