Claude Code의 settings.json은 작성 방식 하나에 따라 "조용히 손해를 보는" 설정이 될 수 있습니다. 동작은 하고 있기 때문에 알아차리기 어렵습니다. 제가 실제로 저질렀던(수정한) NG 사례 5가지를 나쁜 예와 해결 방법으로 나열하겠습니다.
설정 파일의 위치는 전체 설정이 ~/.claude/settings.json이며, 프로젝트 단위가 .claude/settings.json입니다. 아래 내용은 둘 다 사용할 수 있습니다.
- 모델을 고정하여, 폴백(fallback)을 준비하지 않음
- deny를 설정하지 않고, 위험한 명령어를 그대로 통과시킴
- CLAUDE.md에 너무 많은 내용을 작성함
- 모델 전환을 알아차리지 못함
- permissions를 너무 넓게 개방함
주 모델이 과부하나 제공 중단으로 다운되면 그대로 작업이 중단됩니다.
// ❌ NG: 주 모델만 설정. 다운되면 손이 멈춤
{
"model": "claude-fable-5"
...
// ✅ OK: fallbackModel로 폴백 대상을 준비함
{
"model": "claude-fable-5",
...
왜냐하면, fallbackModel은 주 모델이 응답할 수 없을 때, 배열 순서대로 시도하여 처음으로 통과한 모델로 계속 진행하기 때문입니다. 엔트리는 최대 3개까지이며, v2.1.166 이후의 기능입니다. 긴 에이전트 작업이나 CI 중에 주 모델이 막히는 상황을 한 줄로 구할 수 있습니다. 없다면 claude update를 하세요. 단, 인증이나 API 키 실패는 어떤 모델이라도 같은 이유로 다운되므로 이 방법으로는 구할 수 없습니다. 그 부분은 분리가 필요합니다.
한번 아찔한 경험을 한 뒤에 넣기보다, 미리 넣어두는 것이 안전합니다.
// ❌ NG: permissions를 그대로 둠. 무엇이든 실행될 수 있음
{
"permissions": {}
...
// ✅ OK: 파괴적인 명령을 deny로 막아둠
{
"permissions": {
...
왜냐하면, rm -rf나 force push는 한 번 실행하면 되돌릴 수 없습니다. deny에 넣어두면 그런 종류의 명령어는 실행 전에 멈춥니다. 자신의 환경에서 "이것만은 실행시키고 싶지 않다"를 사고가 나기 전에 언어화하는 작업이기도 합니다.
좋은 의도로 내용을 채울수록, 효과는 떨어집니다.
❌ NG: 수백 줄의 CLAUDE.md. 전부를 "중요"로 나열함
(우선순위가 전달되지 않고, 정작 중요한 전제 조건이 묻혀버림)
✅ OK: 짧은 전제 조건으로만 압축
・정말로 매번 적용하고 싶은 규칙만 남김
・예외나 세부 사항은 그때마다 프롬프트로 전달
...
왜냐하면, CLAUDE.md의 내용은 매 턴의 컨텍스트(context)에 포함됩니다. 길수록 토큰을 소비하며, 게다가 모델은 어떤 것을 우선해야 할지 알 수 없게 됩니다. 늘린다고 해서 더 잘 듣는 것이 아닙니다. 짧게 유지하는 편이 결과적으로 더 잘 작동했습니다.
fallback이나, Fable 5의 내용 기반 전환이 일어나도 알아차리지 못하면 "조용히 품질이 변했다"로 끝나버립니다.
// ❌ NG: 지금 어떤 모델로 동작하고 있는지 화면에서 알 수 없음
{
"model": "claude-fable-5"
...
// ✅ OK: 상태 표시줄(status line)에 모델을 상시 표시함
{
"model": "claude-fable-5",
...
왜냐하면, Fable 5는 안전 분류기(safety classifier)에 걸리면 해당 요청을 기본 Opus로 재실행하며, 이후 그대로 이어집니다. 세션의 첫 번째 요청이라도 CLAUDE.md나 git status의 내용으로 인해 발화할 수 있습니다. 전환이 시야에 들어와 있지 않으면, 지적의 정밀도가 달라진 것을 나중에야 깨닫게 됩니다. /status로도 확인할 수 있지만, 상시 표시하는 편이 놓치지 않습니다. 되돌릴 때는 /model fable입니다.
자동화를 우선하여 전부 허용하면, 편리함의 대가로 사고의 위험이 넓어집니다.
// ❌ NG: 확인 절차를 없애기 위해 넓게 allow 함
{
"permissions": {
...
// ✅ OK: 자주 쓰는 안전한 것만 allow, 위험한 것은 deny
{
"permissions": {
...
왜냐하면, Bash(*)와 같은 넓은 허용은 확인의 번거로움을 없애주지만, AI의 판단 실수나 외부로부터의 지시 혼입이 그대로 실행에 도달하게 됩니다. 자주 사용하는 안전한 명령어만 지목하여 허용하고, 위험한 것은 deny로 막습니다. 번거로움과 안전 사이에서 스스로 선을 긋는 것이 적당했습니다.
fallbackModel
fallbackModel로 복구 지점을 마련합니다 (최대 3개, v2.1.166~). 단, 인증 관련 시스템은 구제할 수 없습니다.
deny로 파괴적인 명령어를 먼저 차단합니다. (CLAUDE.md는 내용이 짧다는 전제하에 유효합니다. 내용이 많아질수록 효과가 떨어집니다.)
- 상태 표시줄(Status line)에 모델을 항상 표시합니다. 모델 전환을 즉시 인지하기 위함입니다.
permissions는 "안전한 것은 allow, 위험한 것은 deny"로 설정하여, 스스로 선을 긋습니다.
이 모든 설정은 적용 직후에는 차이를 느끼기 어렵습니다. 효과가 나타나는 시점은 모델이 다운된 날, 위험한 명령어가 실행될 뻔한 날, 혹은 품질이 조용히 변해버린 날입니다. 사건이 터지기 전에 한 번만 제대로 정돈해 두면, 나중의 자신을 구할 수 있습니다. 도움이 되었다면 저장해 두었다가, settings.json을 재검토할 때 다시 찾아와 주세요.
참고 (공식 문서):
평소에는 raplsworks.com에서 WordPress 플러그인 개발 및 Claude Code 관련 글을 쓰고 있습니다.