- Published on
Chain-of-Thought 없이 추론 유도하는 5패턴
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
LLM을 업무에 붙이다 보면 한 번쯤 이런 고민을 합니다.
- 추론을 잘하게 만들고 싶은데, 모델에게 장황한 풀이(Chain-of-Thought)를 쓰게 하면 보안·정책·비용·토큰 측면에서 부담이 큽니다.
- 반대로 “정답만 말해”라고 하면 품질이 떨어지고, 디버깅이 어려워집니다.
핵심은 모델의 내부 추론은 유지하되, 출력은 구조화된 결과물로 제한하는 것입니다. 이 글에서는 Chain-of-Thought를 직접 출력하게 하지 않으면서도 추론을 유도하는 5가지 패턴을 소개합니다. 각 패턴은 프롬프트 템플릿과 함께, 실제 제품/운영 환경에서 자주 부딪히는 문제(재현성, 검증, 실패 처리, RAG 결합)까지 고려합니다.
아래 패턴들은 특히 RAG나 운영 자동화에 잘 맞습니다. 관련해서는 AutoGPT 메모리 팽창·환각 줄이는 RAG+벡터DB, Qdrant RAG 성능 2배 - HNSW 튜닝 체크리스트도 함께 참고하면 설계가 빨라집니다.
전제: “추론을 보여달라” 대신 “검증 가능한 산출물”을 요구
Chain-of-Thought를 출력으로 받는 이유는 보통 두 가지입니다.
- 모델이 건너뛰지 않고 생각하게 만들기
- 사람이 디버깅하기 쉽게 만들기
그런데 실제 운영에서는 2번이 더 중요합니다. 2번은 꼭 장황한 풀이가 아니라도 가능합니다. 예를 들어:
- 근거(인용/출처/문서 ID)
- 검증 가능한 체크리스트
- 가정/제약 조건의 명시
- 대안 비교표
- 테스트 케이스/재현 절차
이런 출력은 “추론 과정”을 노출하지 않으면서도, 결과를 검증하고 개선할 수 있게 해줍니다.
패턴 1) 결과-근거 분리: Answer + Evidence 포맷
언제 쓰나
- RAG에서 환각을 줄이고 싶을 때
- “왜 그렇게 말했는지”는 필요하지만, 장황한 풀이가 필요 없을 때
핵심 아이디어
모델에게 답변과 근거(증거) 를 분리해 출력하게 합니다. 근거는 Chain-of-Thought가 아니라, 인용 가능한 팩트 단위로만 제한합니다.
템플릿
- 답변은 짧게
- 근거는
문서ID,문장 인용,로그 라인,설정 키등으로 구성
역할: 당신은 SRE/백엔드 엔지니어다.
요구사항:
1) 결론은 5줄 이내로 작성
2) 근거는 아래 Evidence 배열에만 작성
3) Evidence에는 추론 과정/풀이를 쓰지 말고, 관찰 가능한 사실(인용/로그/설정/문서ID)만 나열
4) 근거가 부족하면 "INSUFFICIENT_EVIDENCE"로 표시
출력(JSON):
{
"answer": "...",
"evidence": [
{"source": "doc:123", "quote": "..."},
{"source": "log", "quote": "..."}
],
"confidence": "low|medium|high"
}
포인트
confidence를 강제하면 모델이 모르는 것을 “그럴듯하게” 채우는 경향이 줄어듭니다.- RAG에서는 evidence를 검색 결과 chunk의
id로 묶어두면, 사후에 품질 분석이 쉬워집니다.
패턴 2) 제약 기반 추론: “금지 목록”과 “필수 조건”을 먼저 고정
언제 쓰나
- 보안/컴플라이언스/정책 준수가 중요한 답변
- 운영 자동화에서 위험한 액션을 막아야 할 때
핵심 아이디어
추론을 “자유롭게” 시키는 대신, 가능한 해의 공간을 줄입니다. Chain-of-Thought 없이도 품질이 올라가는 이유는, 모델이 탐색해야 할 선택지가 줄어들기 때문입니다.
템플릿
문제: Kubernetes CrashLoopBackOff 원인 추정 및 조치 제안
필수 조건:
- 조치는 "관찰 -> 가설 -> 안전한 검증" 순서로만 제시
- 즉시 재배포/스케일 변경 등 위험 조치는 "옵션" 섹션에만 작성
- 각 조치는 kubectl 명령 1개 이상 포함
금지:
- 원인 단정 금지(로그/이벤트 없으면 단정하지 말 것)
- 임의의 설정값 제안 금지(근거 없으면 "예시"로만)
출력 마크다운:
- Summary
- Safe checks (우선순위)
- Optional actions
포인트
운영 디버깅 글을 쓸 때도 같은 원리가 적용됩니다. 예를 들어 CrashLoopBackOff 진단은 관찰(이벤트/로그) 없이는 단정하면 사고가 납니다. 이런 맥락에서는 K8s CrashLoopBackOff - OOMKilled·Probe·Exit 137 진단처럼 “안전한 체크 순서”를 요구하는 것이 효과적입니다.
패턴 3) 자기검증을 “체크리스트”로 외부화: Validation Checklist
언제 쓰나
- 답변은 짧게 받고 싶지만, 실수/누락을 줄이고 싶을 때
- 코딩/설계/운영 runbook 생성
핵심 아이디어
Chain-of-Thought처럼 길게 쓰게 하지 말고, 검증 항목을 강제합니다. 체크리스트는 추론 과정이 아니라 “결과물의 품질 조건”입니다.
템플릿
당신은 시니어 백엔드 리뷰어다.
아래 산출물을 생성하라:
1) 최종 답변(10줄 이내)
2) Validation checklist(최소 8개)
규칙:
- checklist는 예/아니오로 검증 가능해야 함
- checklist는 답변의 전제/엣지케이스/실패모드/관측지표를 포함
- 풀이 과정은 쓰지 말 것
예시 출력 형태
### Final
- ...
### Validation checklist
- [ ] 입력 데이터에 중복 키가 존재하는지 확인했다
- [ ] 조인 후 행 수가 증가하는 이유를 cardinality 관점에서 설명했다
- [ ] 재현 가능한 최소 예제를 포함했다
- [ ] ...
포인트
데이터 이슈(예: 조인 폭증)는 “원인 후보”를 늘어놓는 것보다, 검증 순서가 더 가치가 큽니다. 이런 류의 체크리스트는 pandas merge 후 행이 폭증할 때 - 중복키 진단법 같은 글의 구조와도 잘 맞습니다.
패턴 4) 다중 후보 생성 후 선택: N-best + Selection Criteria
언제 쓰나
- 설계/아키텍처/튜닝처럼 정답이 하나가 아닐 때
- 모델이 한 번에 “그럴듯한 하나”를 찍는 문제를 줄이고 싶을 때
핵심 아이디어
모델에게 후보를 여러 개 만들게 하고, 선택 기준을 명시한 뒤, 그 기준으로 최종안을 선택하게 합니다. 여기서 중요한 점은 “왜”를 길게 쓰게 하는 게 아니라, 평가 기준표로 제한하는 것입니다.
템플릿
문제: GitHub Actions CI 시간을 줄이는 전략 제안
1) 서로 다른 전략 3개를 제안
2) 각 전략은 아래 기준으로 점수화
- 구현 난이도(1-5)
- 기대 시간 절감(1-5)
- 캐시 안정성(1-5)
- 디버깅 용이성(1-5)
3) 점수표를 근거로 최종 1개를 추천
출력:
- Options (3)
- Score table
- Recommendation (5줄)
포인트
- “다중 후보”는 탐색을 강제합니다.
- “점수표”는 CoT를 대체하는 짧은 근거가 됩니다.
CI 최적화는 특히 이 패턴이 잘 먹힙니다. 매트릭스/병렬화/캐시 키 전략이 서로 얽혀 있어서, 한 방에 정답을 찍기 어렵기 때문입니다. 필요하면 GitHub Actions 매트릭스 빌드로 CI 50% 줄이기, GitHub Actions 캐시가 안 먹을 때 key 전략과 디버깅도 같이 보면서 점수 기준을 잡으면 좋습니다.
패턴 5) “의사결정은 모델, 실행은 도구”: Tool-first 플로우
언제 쓰나
- 로그/메트릭/설정 같은 외부 사실 확인이 필요한 문제
- 모델이 추측으로 채우기 쉬운 운영 이슈
핵심 아이디어
모델에게 추론을 길게 쓰게 하지 말고, 어떤 도구 호출이 필요한지만 결정하게 합니다. 그리고 실제 사실은 툴 결과로 채웁니다.
즉, LLM은 다음만 출력합니다.
- 다음에 실행할 명령
- 기대되는 관측 결과(어떤 키/필드/패턴을 볼지)
- 결과에 따른 분기(조건문)
예시: systemd 서비스 재시작 루프 진단
아래는 “추론을 보여달라” 대신 “다음 액션”을 강제하는 형태입니다.
역할: 리눅스 운영 자동화 에이전트
목표: systemd 서비스가 재시작되는 원인을 찾기 위한 최소 명령 시퀀스 생성
규칙:
- 출력은 단계별 명령만
- 각 단계는 "command", "expect", "if_found" 필드를 가짐
- 원인 추측 금지
출력(JSON array)
가능한 출력 예:
[
{
"command": "systemctl status my.service --no-pager",
"expect": "Active 상태, 최근 종료 코드, 재시작 카운터",
"if_found": "ExitCode가 비정상이면 다음 단계에서 journal 확인"
},
{
"command": "journalctl -u my.service -n 200 --no-pager",
"expect": "panic, OOM, permission denied, config parse error 키워드",
"if_found": "permission 관련이면 unit 파일과 실행 유저/권한 점검"
}
]
포인트
- 이 패턴은 모델이 “생각”을 길게 쓰지 않아도, 사실 기반 루프로 문제를 풀게 만듭니다.
- 운영 이슈에 특히 강력합니다. systemd 재시작 루프 같은 케이스는 systemd 서비스가 계속 재시작될 때 원인 추적법처럼 “관찰 가능한 증거”가 승부처입니다.
실전 적용 팁: 5패턴을 조합하는 방법
현업에서는 한 패턴만으로 부족한 경우가 많습니다. 추천 조합은 다음과 같습니다.
- RAG 기반 QnA: 패턴 1(Answer+Evidence) + 패턴 3(Validation checklist)
- 운영 장애 대응: 패턴 2(제약) + 패턴 5(Tool-first)
- 설계/튜닝: 패턴 4(N-best) + 패턴 1(근거를 수치/측정으로 제한)
특히 RAG에서는 “근거를 문서 chunk로 제한”하고, “근거 부족 시 INSUFFICIENT_EVIDENCE”를 허용하는 것만으로도 환각이 눈에 띄게 줄어듭니다.
마무리
Chain-of-Thought를 출력으로 강제하지 않아도, LLM의 추론 품질은 충분히 끌어올릴 수 있습니다. 핵심은 추론을 텍스트로 노출시키는 대신, 검증 가능한 산출물(근거, 체크리스트, 점수표, 도구 호출 계획) 로 바꾸는 것입니다.
정리하면:
- 패턴 1: 답변과 근거를 분리해 환각을 줄인다
- 패턴 2: 제약을 먼저 고정해 탐색 공간을 줄인다
- 패턴 3: 자기검증을 체크리스트로 외부화한다
- 패턴 4: 다중 후보와 점수표로 선택을 강제한다
- 패턴 5: 실행은 도구로, 모델은 다음 액션만 결정한다
이 5가지를 템플릿으로 만들어 팀에 배포하면, “프롬프트 장인”이 없어도 결과 품질이 안정적으로 올라갑니다.