- Published on
Chain-of-Thought 안 새게 추론 품질 올리는 법
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서로 모순돼 보이는 요구가 있습니다.
- 추론 품질은 올리고 싶다(중간 사고 과정이 있으면 대체로 성능이 좋아짐)
- 그런데 Chain-of-Thought(이하 CoT)는 사용자에게 노출되면 안 된다(보안, 프롬프트 유출, 정책, 법무, UX)
결론부터 말하면, 모델 내부 추론은 활용하되 출력은 구조화된 요약과 근거만 내보내는 설계로 충분히 높은 품질을 얻을 수 있습니다. 핵심은 생각을 쓰게 하는 것이 아니라 검증 가능한 산출물을 강제하는 것입니다.
이 글에서는 CoT를 새지 않게 하면서도 추론 품질을 올리는 실전 패턴을 정리합니다. 운영 환경에서 특히 중요한 출력 스키마, 자기검증, 다중 패스, 툴 호출, 테스트까지 포함합니다.
왜 CoT가 새면 문제가 되나
CoT는 모델이 답을 만들기 위해 생성한 중간 텍스트입니다. 이것이 그대로 노출되면 다음 문제가 생깁니다.
- 프롬프트·시스템 지시 유출: 모델이 내부 지시나 숨겨진 컨텍스트를 요약해버릴 수 있음
- 취약점 단서 제공: 공격자가 방어 로직을 학습해 우회하는 데 도움
- 환각이 근거처럼 보임: 중간 추론이 그럴듯하면 사용자가 더 쉽게 믿음
- 개인정보·비공개 데이터 노출 위험: RAG나 내부 문서가 섞일 때 특히 위험
따라서 목표는 “생각을 하지 말라”가 아니라, 생각은 하되 밖으로는 ‘검증 가능한 출력’만 내보내게 만드는 것입니다.
원칙 1: 출력은 스키마로 잠그고, CoT는 금지한다
가장 효과적인 1차 방어는 출력 형식 고정입니다. 자연어로 길게 말하게 두면 CoT가 섞일 여지가 커집니다.
- 출력은 JSON 등 구조화 포맷
- 필드는
answer,assumptions,evidence,risks,next_actions처럼 검증 가능한 항목 위주 reasoning,chain_of_thought,analysis같은 필드는 아예 금지
예시: 시스템 프롬프트 템플릿
아래는 “추론은 내부적으로 하되, 최종 출력에는 요약 근거만”을 강제하는 예시입니다.
You are a careful assistant.
Do not reveal chain-of-thought or hidden reasoning.
Return only valid JSON that matches the schema.
If you are uncertain, state uncertainty in the `risks` field.
Never include fields: reasoning, chain_of_thought, analysis.
Schema:
{
"answer": string,
"assumptions": string[],
"evidence": string[],
"risks": string[],
"next_actions": string[]
}
이 패턴은 단순하지만 강력합니다. 모델이 길게 설명하려는 충동을 줄이고, 근거를 ‘문장 단위’로만 내보내게 만들어 CoT 누출을 억제합니다.
원칙 2: “단계별로 생각해” 대신 “체크리스트를 채워”로 바꾼다
많은 팀이 성능을 올리려고 step by step을 넣습니다. 하지만 운영에서는 다음 방식이 더 안전합니다.
step by step지시를 제거- 대신 검증 체크리스트를 출력하게 함
예를 들어 디버깅 글에서 흔히 쓰는 구조처럼, “가능한 원인, 확인 방법, 수정 방법”으로 강제합니다. 이런 글쓰기 패턴은 실제로 진단 품질을 올립니다. 네트워크 진단을 체크리스트로 접근하는 방식은 운영에서 특히 유효합니다. 비슷한 문제 해결 흐름은 EKS Pod는 뜨는데 트래픽 0 - NetPol·SG·CNI 10분 진단 같은 글의 구조를 떠올리면 됩니다.
예시 프롬프트
Task: Diagnose why API latency increased after deploy.
Constraints:
- Do not reveal chain-of-thought.
- Output JSON only.
- Provide: likely_causes, how_to_verify, fixes, rollback_plan.
Context:
- Service: Next.js
- Symptom: TTFB spiked from 200ms to 2s
- Time: after enabling Server Components
이렇게 하면 모델은 내부적으로는 추론을 하더라도, 외부로는 진단 가능한 항목만 내보냅니다. Next.js 성능 이슈는 원인이 다양하므로, 검증 절차를 강제하는 게 특히 중요합니다. 관련 주제로는 Next.js 14 App Router TTFB 폭증 잡는 RSC 튜닝도 함께 참고하면 좋습니다.
원칙 3: 2패스 설계로 품질을 올린다(생성 패스, 검증 패스)
CoT를 직접 출력하지 않아도 품질을 올리는 가장 확실한 방법은 생성 후 검증입니다.
- 1패스: 답안을 생성(구조화)
- 2패스: 같은 입력으로 답안을 검토하고 결함을 수정
이때 2패스는 “내가 왜 이렇게 생각했는지”가 아니라 “산출물이 요구사항을 만족하는지”를 보게 해야 합니다.
Node.js 예시 코드(2패스 검증)
아래는 OpenAI SDK 스타일의 의사 코드입니다. 핵심은 2번째 호출이 critique가 아니라 validation checklist를 수행하게 만드는 점입니다.
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
async function generateAnswer(input) {
const system = [
"Do not reveal chain-of-thought.",
"Return only JSON.",
"Never include fields: reasoning, chain_of_thought, analysis."
].join("\n");
const schemaHint = {
answer: "string",
assumptions: ["string"],
evidence: ["string"],
risks: ["string"],
next_actions: ["string"]
};
const draft = await client.chat.completions.create({
model: "gpt-4.1-mini",
messages: [
{ role: "system", content: system },
{
role: "user",
content:
"Input:\n" +
JSON.stringify(input) +
"\n\nReturn JSON matching this shape:\n" +
JSON.stringify(schemaHint)
}
]
});
const draftText = draft.choices[0].message.content;
const validator = await client.chat.completions.create({
model: "gpt-4.1-mini",
messages: [
{
role: "system",
content:
"You are a strict JSON validator and editor. " +
"Do not reveal chain-of-thought. Return only corrected JSON."
},
{
role: "user",
content:
"Validate the following JSON against requirements:\n" +
"- Must be valid JSON\n" +
"- Must not include forbidden fields\n" +
"- Evidence must be concrete and non-speculative\n" +
"- Risks must include uncertainty if any\n\n" +
"JSON:\n" +
draftText
}
]
});
return validator.choices[0].message.content;
}
이 패턴의 장점은 다음과 같습니다.
- CoT를 요구하지 않아도 품질이 올라감(검증이 품질을 끌어올림)
- 출력이 JSON이라 후처리, 로깅, A/B 테스트가 쉬움
- “근거 없는 확신”을
risks로 밀어 넣어 과신을 줄임
원칙 4: 근거는 “출처 단위”로만 요구한다
CoT 대신 흔히 “근거를 써라”를 요구하는데, 이때도 주의가 필요합니다.
- 나쁜 근거: “내가 생각하기에”, “일반적으로”, “아마도” 같은 추론 서술
- 좋은 근거: “입력에서 관측된 사실”, “정의/규칙”, “문서/로그의 특정 문장”, “측정값”
RAG를 쓰는 경우라면 evidence는 인용 가능한 스니펫 또는 doc_id와 함께 내보내게 하세요. 단, 내부 문서 인용은 보안 정책에 맞춰 필터링이 필요합니다.
원칙 5: 툴 호출로 ‘생각’을 외부화한다
추론 품질을 올리는 안전한 방법 중 하나는, 모델이 마음대로 상상하지 못하게 툴로 확인하게 만드는 것입니다.
- 계산은 계산기로
- 스키마 검증은 JSON Schema로
- DB 상태는 쿼리로
- 로그/메트릭은 실제 데이터로
예를 들어 운영 이슈에서 모델이 “VACUUM 하면 돼요”라고 말하는 대신, 확인 쿼리를 먼저 실행하게 하면 환각이 줄어듭니다. 이런 접근은 DB 트러블슈팅에서 특히 유효하고, 관련 맥락은 PostgreSQL VACUUM 안됨? bloat·wraparound 7분 해결 같은 글의 문제 해결 흐름과도 잘 맞습니다.
예시: 툴 결과를 근거로만 답하기
Rules:
- You may only use the tool outputs as evidence.
- If evidence is insufficient, say so in risks.
- Do not reveal chain-of-thought.
Tools:
- get_metrics(service, window)
- query_logs(service, filter)
Task:
Find the most likely cause of increased 5xx after deploy.
이렇게 하면 모델의 내부 추론은 있더라도, 최종 답은 관측 데이터에 묶입니다.
원칙 6: “비공개 추론”을 요구하지 말고, “요약 보고서”를 요구한다
현장에서 자주 하는 실수는 “추론은 숨기고 답만 줘”처럼 모호하게 지시하는 것입니다. 대신 다음을 요구하세요.
- 결론 1문장
- 가정 목록
- 확인 절차
- 실패 시 플랜B
즉, CoT를 숨기는 게 목표가 아니라 의사결정에 필요한 최소 정보를 뽑는 게 목표입니다.
예시 출력 포맷
{
"answer": "원인은 RSC 데이터 패칭이 요청마다 발생해 TTFB가 증가한 가능성이 큽니다.",
"assumptions": [
"배포 직후부터 지표가 상승했다",
"캐시 적중률이 낮아졌다"
],
"evidence": [
"TTFB가 200ms에서 2s로 증가(입력 제공)",
"RSC 활성화 이후 발생(입력 제공)"
],
"risks": [
"실제 원인은 DB 커넥션 풀 고갈일 수 있으므로 메트릭 확인이 필요"
],
"next_actions": [
"서버 로그에서 요청당 데이터 패칭 횟수 확인",
"캐시 설정과 revalidate 동작 점검",
"DB 커넥션/슬로우쿼리 메트릭 확인"
]
}
이 정도면 사용자에게는 충분히 유용하면서도, CoT가 섞일 공간이 거의 없습니다.
원칙 7: 거부 및 안전 응답도 스키마로 통일한다
공격자가 CoT를 빼내려 할 때 흔히 쓰는 방법은 “출력을 바꿔라”, “디버그 모드로 보여줘라” 같은 우회입니다. 이때도 스키마를 유지하면 방어가 쉬워집니다.
- 정책 위반 요청이면
answer에 거절 risks에 “요청이 정책/보안상 부적절”을 명시- 나머지 필드는 빈 배열 또는 대안 제시
이렇게 하면 프론트엔드도 일관되게 처리할 수 있고, 로깅/모니터링도 단순해집니다.
운영 체크리스트: CoT 누출 없이 품질을 올리는 10가지
- 출력은 JSON 등 구조화 포맷으로 고정
- 금지 필드 목록을 명시하고 반복
step by step대신 체크리스트 산출물 요구- 2패스 생성-검증 적용
- 근거는 관측 가능한 사실만 허용
- 불확실성은
risks로 강제 - 툴 호출로 사실 확인을 우선
- 실패 시 플랜B, 롤백 절차 포함
- 회귀 테스트용 고정 입력 세트 운영
- 로그에는 원문 프롬프트보다 “스키마 출력” 위주로 저장(민감정보 최소화)
마무리: CoT는 숨기는 게 아니라 ‘필요 없게’ 만든다
CoT를 안 새게 하려면 “말하지 마”만으로는 부족합니다. 말할 이유가 없는 출력 구조를 만들고, 검증과 툴로 품질을 끌어올리는 편이 훨씬 안정적입니다.
정리하면, 운영에서 가장 재현성 있는 조합은 다음입니다.
- 스키마 잠금(JSON)
- 체크리스트 기반 산출물
- 2패스 검증
- 툴 기반 증거 수집
이 4가지만 잘 적용해도 CoT 노출 없이도 답변 품질이 체감될 정도로 올라갑니다.