Ch.7 CS 키워드로 AI를 제어하는 법¶
< AI 코딩 도구의 작동 원리 | 유사 사례와 키워드 정리 >
앞에서 AI가 "확률적 다음 단어 예측"이라는 걸 봤다. 프롬프트가 넓으면 답도 넓고, 프롬프트가 좁으면 답도 좁다. 이번에는 실전에서 CS 키워드를 프롬프트에 녹이는 구체적인 패턴을 본다.
패턴 1: 현상이 아니라 원인을 말한다¶
가장 흔한 실수가 "현상"을 프롬프트에 쓰는 거다.
이러면 AI는 "느린 것에 대한 모든 가능한 원인"을 나열한다. 범위가 너무 넓다.
[원인 기반 프롬프트]
"EXPLAIN 결과 Full Table Scan이 나온다"
"Connection Pool이 고갈돼서 503이 뜬다"
"Race Condition으로 재고가 마이너스가 됐다"
원인을 프롬프트에 넣으면 AI는 해법에 집중한다. 그런데 원인을 쓰려면 원인을 알아야 한다. 원인을 알려면 CS 키워드가 필요하다. 순환이다.
Ch.2에서 "print가 느리다"라는 현상의 원인이 "System Call 횟수"라는 걸 배웠다. Ch.5에서 "데이터가 꼬인다"라는 현상의 원인이 "Race Condition"이라는 걸 배웠다. Ch.6에서 "서버가 응답 안 한다"라는 현상의 원인이 "Connection Pool 고갈"이라는 걸 배웠다.
이 키워드들이 프롬프트에 들어가는 순간, AI의 응답 품질이 달라진다.
패턴 2: 제약 조건(Constraint)을 명시한다¶
AI는 "하지 마"보다 "~로 해줘"에 더 잘 반응한다. 그리고 제약 조건이 구체적일수록 결과가 좋다.
이러면 AI는 Pillow를 쓸 수도 있고, OpenCV를 쓸 수도 있고, 심지어 ImageMagick 서브프로세스를 호출할 수도 있다.
[제약 있는 프롬프트]
"이미지 리사이즈 코드 짜줘.
- Pillow 사용
- CPU Bound 작업이니까 ProcessPoolExecutor로 병렬 처리
- 원본 파일은 수정하지 말고 새 파일로 저장
- EXIF 데이터는 제거"
Ch.3에서 "이미지 처리는 CPU Bound"라는 걸 배웠다. 그래서 "ProcessPoolExecutor"라는 키워드를 프롬프트에 넣을 수 있다. 이걸 모르면 "비동기로 해줘"라고 쓰게 되고, AI는 asyncio로 이미지를 처리하는 (Ch.3에서 봤듯이 오히려 느려지는) 코드를 만들어낸다.
패턴 3: 방향(Direction)을 키워드로 지정한다¶
"최적화해줘"라는 프롬프트가 넓은 이유는, 최적화의 방향이 여러 개이기 때문이다.
[방향이 없는 프롬프트]
"이 코드 최적화해줘"
→ AI: 캐시? 인덱스? 비동기? 알고리즘? 다 가능한데...
[방향이 있는 프롬프트]
"I/O Bound 구간을 async/await으로 바꿔줘"
"N+1 쿼리를 JOIN으로 합쳐줘"
"재귀를 반복문으로 바꾸고 Stack Overflow 위험을 없애줘"
각각 Ch.3, Ch.13, Ch.4에서 배운 키워드다. 방향을 정해주면 AI는 그 방향 안에서 최선의 답을 찾는다.
프롬프트에 방향을 줄 수 있느냐 없느냐는 결국 "어떤 키워드를 아느냐"에 달렸다. Part 1에서 배운 키워드만으로도 방향 지정이 가능한 사례를 몇 개 보자.
| 상황 | 키워드 없는 프롬프트 | 키워드 있는 프롬프트 | 사용한 키워드 |
|---|---|---|---|
| 로그가 너무 많아 느리다 | "로그 줄여줘" | "로깅 레벨을 WARNING으로 올리고, System Call 횟수를 줄여줘" | System Call (Ch.2) |
| 파일 업로드가 느리다 | "업로드 빠르게 해줘" | "CPU Bound 이미지 처리를 ProcessPool로 분리해줘" | CPU Bound, ProcessPool (Ch.3) |
| 서버가 간헐적으로 멈춘다 | "서버 안정화해줘" | "Deadlock이 의심된다. Lock Ordering을 적용해줘" | Deadlock, Lock Ordering (Ch.5) |
| DB 연결이 끊긴다 | "DB 에러 잡아줘" | "Connection Pool에 pool_pre_ping=True 설정하고, pool_recycle=3600으로 재활용 주기 설정해줘" | Connection Pool (Ch.6) |
패턴 4: 진단 결과를 프롬프트에 포함한다¶
이게 가장 강력한 패턴이다. AI한테 "문제가 뭔지 찾아줘"라고 하는 대신, 직접 진단하고 결과를 알려주는 거다.
[진단 없이]
"이 API가 느린데 왜 그런지 모르겠어"
[진단 후]
"k6로 부하 테스트 돌렸더니 Throughput이 50 req/s밖에 안 나온다.
htop으로 보니 CPU 사용률은 10%인데 iowait가 80%다.
I/O Bound 상태인 것 같다.
Blocking I/O를 Non-blocking으로 바꾸는 방법을 알려줘."
(iowait는 CPU가 I/O 장치의 응답을 기다리느라 놀고 있는 시간의 비율이다. iowait가 높고 CPU 사용률이 낮으면 "CPU는 할 일이 없는데 I/O를 기다리고 있다"는 뜻이니까, I/O Bound 상태라고 판단할 수 있다.)
진단 도구와 키워드를 알아야 이런 프롬프트를 쓸 수 있다:
- k6, Throughput (Ch.2) → 부하 테스트와 성능 지표
- htop, iowait → OS 레벨 진단. htop은 프로세스별 CPU/메모리 사용량을 실시간으로 보여주는 도구다
- I/O Bound, Blocking I/O (Ch.3) → 문제의 분류
- Non-blocking I/O (Ch.3) → 해결 방향
AI가 아무리 똑똑해도, 개발자의 로컬 환경에서 직접 프로파일링을 돌려주지는 못한다. 진단은 개발자가 해야 하고, 진단하려면 "뭘 측정해야 하는지"를 알아야 하고, 그걸 알려면 CS 키워드가 필요하다.
AI를 잘 쓰려면 CS가 더 필요하다¶
이 챕터에서 보여주고 싶은 결론은 단순하다.
"AI가 코드를 짜주는 시대니까 CS를 몰라도 된다"는 말은 정반대로 틀렸다. AI를 잘 쓰려면 CS를 더 알아야 한다.
CS 키워드를 모르면:
- 프롬프트가 넓어진다 → 엉뚱한 답이 나온다
- 진단을 못 한다 → 원인을 못 넣는다
- AI의 답을 검증 못 한다 → Hallucination에 당한다
CS 키워드를 알면:
- 프롬프트가 좁아진다 → 정확한 답이 나온다
- 진단할 수 있다 → 원인을 넣을 수 있다
- AI의 답을 검증할 수 있다 → 틀린 답을 걸러낸다
이건 Part 1에서 배운 것과 같은 이야기다. Ch.1에서 "키워드를 모르면 검색도 못 한다"고 했다. 2024년부터는 "키워드를 모르면 AI도 못 쓴다"가 추가됐을 뿐이다.