Published on

Chain-of-Thought 없이 추론력 올리는 5가지 프롬프트

Authors

서로 다른 LLM을 써보면 느끼는 공통점이 있습니다. 모델에게 추론 과정을 길게 쓰라고 요구한다고 해서 항상 더 정확해지지 않는다는 점입니다. 오히려 보안/정책 때문에 내부 추론을 노출하지 않도록 설계된 모델도 있고, 장황한 서술이 환각을 늘리거나(그럴듯한 이야기로 메우기) 검증 포인트를 흐리기도 합니다.

이 글에서는 Chain-of-Thought(이하 CoT) 없이도 결과의 품질을 올리는 실전 프롬프트 5가지를 소개합니다. 핵심은 “생각을 보여줘”가 아니라, 입력 구조화, 검증 루프, 실패 모드 차단, 출력 계약(Contract) 강제로 모델의 추론을 외부에서 유도하는 것입니다.

주의: 아래 예시는 모델에게 상세한 내부 추론을 쓰라고 요구하지 않습니다. 대신 요약 근거, 체크리스트, 테스트, 반례 등 검증 가능한 산출물을 요구합니다.

1) 출력 계약을 먼저 고정: JSON 스키마 + 금지 규칙

CoT 대신 가장 강력한 방법은 출력 형식을 먼저 고정하는 것입니다. 자유 서술을 줄이면 모델이 “그럴듯한 문장”으로 빠질 여지가 줄고, 당신이 후처리/검증하기도 쉬워집니다.

언제 쓰나

  • 장애 분석/원인 추정처럼 답이 길어지기 쉬운 작업
  • 정책/보안/품질 기준을 반드시 지켜야 하는 문서 생성
  • API 응답처럼 파싱 가능한 결과가 필요한 경우

프롬프트 템플릿

  • 산출물 필드 정의
  • 각 필드의 허용 범위
  • 금지 규칙(모르면 모른다고 말하기, 추측 금지)
역할: 당신은 SRE 겸 백엔드 엔지니어다.

목표: 입력 로그/상황을 바탕으로 가능한 원인을 도출하고, 검증 절차를 제안하라.

출력은 반드시 JSON 한 덩어리로만 응답하라.
스키마:
{
  "problem_summary": "한 문장",
  "hypotheses": [
    {
      "title": "가설 제목",
      "confidence": "low|medium|high",
      "evidence": ["관측된 사실만"],
      "counter_evidence": ["이 가설을 약화시키는 관측"],
      "next_checks": ["10분 내 확인 가능한 체크"],
      "fix": ["되돌리기/완화/근본해결" ]
    }
  ],
  "unknowns": ["추가로 필요한 정보"],
  "do_not_do": ["지금 하면 위험한 조치"]
}

규칙:
- 추측으로 로그/환경을 만들어내지 마라.
- evidence는 입력에서 확인된 사실만.
- 모르면 unknowns에 넣어라.

입력:
(여기에 상황/로그 붙여넣기)

포인트

  • CoT를 요구하지 않아도 evidence / counter_evidence / next_checks 구조가 사실-가설-검증을 강제합니다.
  • 특히 counter_evidence는 환각을 줄이는 데 효과적입니다.

관련해서 캐시 문제처럼 “그럴듯한 원인”이 너무 많은 주제는 구조화가 더 중요합니다. 예를 들어 GitHub Actions 캐시가 안 먹을 때 - cache-hit 0% 원인 정리 같은 케이스는 가설이 난립하기 쉬워서, 위 JSON 계약이 큰 도움이 됩니다.

2) “최소 근거”만 요구하는 근거 요약 프롬프트

CoT를 쓰지 말라고 하면, 어떤 사람은 “그럼 근거를 아예 못 받는 거 아닌가”라고 걱정합니다. 해결책은 **상세 추론 대신 최소 근거(minimal justification)**를 요구하는 것입니다.

언제 쓰나

  • 답의 신뢰도를 빠르게 판단해야 할 때
  • 법/보안/정책상 상세 추론을 받기 꺼려질 때
  • 리뷰어가 짧은 근거만 보고 승인/반려해야 할 때

프롬프트 템플릿

아래 질문에 답하되, 내부 추론을 길게 쓰지 말고 "근거 3줄"만 제공하라.

형식:
- 결론: ...
- 근거:
  1) ...
  2) ...
  3) ...
- 확인 필요(있다면): ...

질문:
(질문)

예시: Next.js 캐시 이슈 진단

결론과 근거 3줄만.

질문:
Next.js App Router에서 데이터가 갱신되지 않는다. revalidateTag를 썼는데도 반영이 느리다. 가장 먼저 확인할 설정/코드를 우선순위로 정리해줘.

이 패턴은 캐시/일관성 문제에서 특히 유용합니다. 캐시가 꼬이면 원인이 많아서 장황한 추론이 오히려 독이 됩니다. 필요하다면 Next.js App Router 캐시 꼬임, revalidateTag로 끝내기와 함께 체크리스트를 붙여 쓰면 좋습니다.

3) 반례 주도(Adversarial) 프롬프트: “깨지는 입력”을 먼저 찾아라

모델의 추론력을 끌어올리는 가장 현실적인 방법 중 하나는 반례를 먼저 찾게 하는 것입니다. CoT를 요구하지 않아도, 반례 탐색은 모델이 스스로 가정을 점검하게 만듭니다.

언제 쓰나

  • 파서/정규식/권한 로직/토큰 검증처럼 엣지 케이스가 중요한 기능
  • 장애 재발 방지(재현 조건 찾기)
  • 문서/가이드의 허점을 미리 찾기

프롬프트 템플릿

아래 설계/코드/규칙을 보고, 실패하거나 취약해지는 반례를 10개 제시하라.

출력 형식:
- 반례: ...
- 왜 실패하는가: 한 문장
- 최소 수정: 한 문장

대상:
(설계/코드/규칙)

예시: JWT 검증 로직

JWT는 “대충 맞겠지”가 가장 위험합니다. kid 선택, JWKS 캐시, 키 회전 타이밍 같은 반례가 실제 장애로 이어집니다.

대상: JWT 검증 미들웨어 설계
- kid로 JWKS에서 키를 찾고 캐시한다.
- 캐시 TTL은 10분.
- 서명 검증 실패 시 JWKS를 강제 갱신 후 1회 재시도.

요구: 실패/취약 반례 10개와 최소 수정안을 제시하라.

이때 모델이 찾은 반례를 실제 운영 가이드로 연결하려면 JWT 서명 검증 실패 - kid·JWKS 캐시·키회전처럼 이미 정리된 장애 패턴과 대조해보면 좋습니다.

4) “검증 가능한 산출물”로 추론을 외주: 테스트/체크리스트 생성

CoT 없이도 모델의 추론을 믿을 수 있게 만드는 방법은, 결과를 테스트나 체크리스트로 바꾸는 것입니다. 모델이 낸 결론이 맞는지 틀리는지, 사람이 혹은 CI가 검증할 수 있어야 합니다.

언제 쓰나

  • 코드 리뷰에서 논쟁이 길어질 때
  • 장애 원인 후보가 여러 개일 때
  • 재현 가능한 최소 케이스가 필요할 때

프롬프트 템플릿

다음 문제에 대해 결론을 설명하지 말고, "검증 체크리스트"와 "재현 테스트"만 작성하라.

출력:
1) 체크리스트(우선순위 순)
2) 재현 절차(명령어/설정 예시 포함)
3) 성공/실패 판정 기준

문제:
(문제 설명)

예시: 리눅스 파일 디스크립터 고갈

문제:
서버에서 간헐적으로 "Too many open files"가 발생한다. 원인 후보가 많아서 추론 설명은 필요 없다.

요구:
- 체크리스트
- 재현 절차(가능하면 간단한 스크립트)
- 판정 기준

이렇게 얻은 체크리스트는 그대로 런북이 됩니다. 같은 주제로는 리눅스 Too many open files 즉시 진단·해결처럼 “진단 순서”가 중요한 글과 궁합이 좋습니다.

5) 다중 관점 합의(Consensus) 프롬프트: 역할 분리로 품질 올리기

한 번의 답변에 모든 걸 맡기면 모델이 한 방향으로 쏠릴 수 있습니다. CoT 대신 역할을 분리한 다중 관점을 만들고, 마지막에 합의안을 내게 하면 결과가 안정됩니다.

핵심은 “긴 추론”이 아니라 서로 다른 평가 기준을 병렬로 적용하는 것입니다.

언제 쓰나

  • 아키텍처 의사결정(성능 vs 안정성 vs 비용)
  • 장애 대응(즉시 완화 vs 근본 원인)
  • 문서/가이드(초보자 관점 vs 운영자 관점)

프롬프트 템플릿

아래 주제에 대해 3명의 리뷰어가 각각 짧게 평가한 뒤, 최종 합의안을 작성하라.

리뷰어 역할:
- Reviewer A: 성능/확장성 관점
- Reviewer B: 운영/장애 대응 관점
- Reviewer C: 보안/컴플라이언스 관점

규칙:
- 각 리뷰는 5줄 이내
- 마지막 합의안은 "결정"과 "보류 항목"으로 구분

주제:
(설계/결정안)

예시: 병렬 처리 도입 여부

주제:
Java Stream 병렬처리로 배치 작업 시간을 줄이려 한다. parallelStream 적용을 표준으로 삼아도 되는가?

이런 결정을 내릴 때는 “병렬이면 빨라진다” 같은 단순 추론이 가장 위험합니다. 실제로는 데이터 크기, 스레드풀, 컨텍스트 스위칭, 공유 자원 경합 때문에 느려질 수 있습니다. 병렬 처리의 함정은 Java Stream 병렬처리가 느려지는 7가지 함정에 정리된 포인트를 체크리스트로 붙여 합의 프롬프트에 넣으면 품질이 더 올라갑니다.

실전 조합 레시피: 5가지를 한 번에 쓰는 방법

위 5가지는 단독으로도 좋지만, 운영/개발 현장에서는 조합이 더 강력합니다.

추천 플로우

  1. **출력 계약(JSON)**으로 결과를 구조화한다.
  2. 각 가설에 대해 최소 근거 3줄만 받는다.
  3. 상위 1~2개 가설에 대해 반례 10개를 뽑아 허점을 찾는다.
  4. 남은 가설에 대해 검증 체크리스트/재현 테스트를 만든다.
  5. 마지막으로 다중 관점 합의로 의사결정을 확정한다.

통합 프롬프트 예시(짧게)

아래는 실제로 많이 쓰는 “한 방 프롬프트”입니다. 길지만, CoT 없이도 결과가 꽤 단단해집니다.

역할: 당신은 SRE/백엔드/보안 리뷰어를 동시에 수행한다.

입력 사건을 분석하되, 내부 추론을 길게 서술하지 말고 아래 산출물을 순서대로 제공하라.

1) JSON 스키마로 가설 3개(각각 evidence/counter_evidence/next_checks 포함)
2) 가장 유력한 가설 1개에 대해 반례 8개
3) 검증 체크리스트(10분 내, 1시간 내, 1일 내)
4) 최종 합의안: 지금 당장 할 조치 / 보류 / 위험한 조치(do_not_do)

규칙:
- 입력에 없는 사실을 만들어내지 마라.
- 명령어/설정 예시는 백틱으로 감싸라.

입력:
(상황/로그)

마무리: CoT가 아니라 “검증 가능성”이 추론력을 만든다

CoT를 요구하지 않아도, 모델의 답을 더 정확하고 일관되게 만드는 방법은 충분합니다. 핵심은 다음 두 가지입니다.

  • 형식과 제약으로 사고를 유도한다: 스키마, 금지 규칙, 우선순위.
  • 검증 가능한 산출물로 바꾼다: 반례, 체크리스트, 재현 테스트, 합의안.

이 5가지 프롬프트는 “모델이 똑똑해지길 기대”하는 대신, 우리가 품질을 통제하는 방식입니다. 특히 장애 대응, 캐시/인증/병렬 처리처럼 함정이 많은 주제에서 효과가 큽니다.

원한다면 당신의 실제 업무(예: CI 캐시 미스, JWT 검증, Next.js 캐시, K8s Pull 실패 등)에 맞춰 위 템플릿을 그대로 적용한 맞춤형 프롬프트 세트로 재구성해줄 수도 있습니다.