저도 이런 일을 여러 번 겪었습니다. 저녁에 팀과 함께 블록의 여러 버전을 살펴봤는데, 아침이 되면 누군가 왜 제목이 짧아졌냐고 묻습니다. 채팅에는 수십 개의 메시지가 남아 있고, 기억에는 "배경이 밝았던 것 같다" 정도만 남으며, 정확한 결정은 여러 수정 사이에서 흐릿해집니다.
이럴 때 requests.log가 도움이 됩니다. 일반 편집기에서 열어 위에서 아래로 읽을 수 있는 짧은 외부 작업 기록입니다. 줄 수가 많아서가 아니라, 요청과 실제로 남기기로 한 것을 연결할 수 있어서 가치가 있습니다.

외부 기록이 필요한 이유
오랜 시간 작업하면서 저는 요청, 결정, 채팅, 저장된 파일 버전, 이 네 가지를 구분하는 습관이 생겼습니다. 이들은 서로 다른 질문에 답하지만, 한 세션 안에서는 하나의 애매한 이야기로 쉽게 뒤섞입니다.
| 출처 | 알 수 있는 것 | 증명하지 못하는 것 |
|---|---|---|
requests.log | 무엇을 요청했고 언제 기록되었는지 | 변경이 실행되고 받아들여졌는지 |
| 결정 표시 | 어떤 안을 선택했고 누가 표시했는지 | 현재 저장된 파일이 어떤 모습인지 |
| 채팅 기록 | 논의 맥락과 답변 | 프로젝트의 현재 버전에 무엇이 반영되었는지 |
| 버전 관리 시스템 | 어떤 파일과 줄이 저장되었는지 | 왜 하필 이 안을 선택했는지 |
로그는 포인터처럼 작동합니다. 필요한 순간과 정확한 문구로 되돌아가게 해 줍니다. 코드 자체를 복원하지는 않습니다. 저장된 페이지 버전을 봐야 한다면 파일과 프로젝트의 버전 기록을 확인하세요.
여기에는 제가 잘못된 결론을 여러 번 목격한 중요한 경계가 있습니다. UserPromptSubmit 훅 이벤트는 Claude Code가 요청을 처리하기 전에 prompt 필드에 텍스트를 받습니다. 이런 기록은 텍스트가 전송되었다는 것을 확인해 줄 뿐, 그 시점에 작업 결과는 아직 알 수 없습니다.
도표에는 로그를 분석할 때 중요한 차이가 잘 드러납니다. 위쪽 단계들은 작업 흐름을 보여주고, 아래쪽은 로그에 남는 것을 보여줍니다. 자동 기록은 결과가 나오기 전에 생기고, 결정 표시는 확인 이후에만 나타납니다. 하나가 다른 하나를 대신하지 않습니다.
쓸모 있는 기록의 구성 요소
세 가지 기록 예시로 보여드리겠습니다. 실제 프로젝트에서 이 셋을 모두 본 적이 있습니다.
완료이런 줄은 거의 쓸모가 없습니다. 누가 무엇을 언제 했는지, 이 "완료"가 어떤 작업을 가리키는지 알 수 없습니다.
사용자: 카드 제목을 더 짧게 만들어 줘...
Claude: 알겠습니다, 먼저 컴포넌트를 살펴보겠습니다...
사용자: 그리고 여백도 줄여 줘...
Claude: 수정했습니다...반대로 이건 빠르게 찾아보기에는 너무 많습니다. 대화 전체 기록은 대화 히스토리 안에서는 유용하지만, 별도의 로그로 두면 금세 그 불편한 사본이 되어 버립니다. 저도 이렇게 해 봤다가 결국 스크롤에 시간을 낭비했습니다.
2026-09-08T14:32:11+03:00 | prompt_submitted | actor=user | ref=card-header | text="카드 제목을 한 줄로 줄여 줘"
2026-09-08T14:41:06+03:00 | decision_recorded | actor=user | ref=card-header | text="짧은 제목, 24px 크기로 확정"세 번째 방식이 저는 가장 마음에 듭니다. 짧은 사실, 시간대를 포함한 시각, 작성자, 줄을 연결하는 ref 태그가 남습니다. 여기 필드 이름은 학습 프로젝트를 위해 만든 것입니다. 이건 우리 파일의 형식일 뿐, Claude Code의 필수 스키마가 아닙니다. 이 예시에서는 ref 태그가 관련 줄에 수동으로 추가되었습니다. 훅은 요청이 어떤 블록에 속하는지 스스로 추측하지 않습니다. 기본 UserPromptSubmit 이벤트에는 그런 의미상 태그가 없습니다. 연결 필드가 없어도 로그에서 정확한 문구로 검색할 수는 있습니다.
기록 시점에 알려진 것
prompt_submitted 줄이 말해 주는 것은 딱 하나입니다. 세션에 이런 요청이 들어왔고 훅이 이를 기록했다는 것입니다. 보통은 여러분이 쓴 텍스트지만 항상 그렇지는 않습니다. UserPromptSubmit은 /loop의 다음 회차에도, 백그라운드 서브에이전트의 보고에도, 다른 세션에서 온 메시지에도 발생하므로, 우리 형식의 actor=user는 학습용 예제의 가정일 뿐입니다. 여기서 Claude Code가 페이지를 수정했다거나, 검증을 통과했다거나, 결과가 마음에 들었다는 것은 알 수 없습니다.
결과는 알려진 뒤에 기록하는 것이 맞습니다. 이 예시에서는 페이지를 확인한 뒤에 남긴 별도의 표시가 그 역할을 합니다. 여러분의 형식에 result나 error 필드가 있다면, 앞으로의 결과에 대한 추측이 아니라 실제로 관찰된 사실로 채우세요.
확정된 결정을 어디에 표시할지
결정은 누군가 명시적으로 기록했을 때만 나타납니다. 위 예시에서는 페이지를 확인한 뒤 사용자가 이 줄을 추가했습니다. 작성자는 actor에 표시되고, 요청과의 연결은 ref=card-header가 담당합니다.
표시는 수동으로 남겨도 괜찮습니다. 자동 기록은 입력을 저장하고, 사람은 결과의 의미를 확인해 줍니다. 작성자도 없고 연결도 없는 "완료" 줄은 신뢰하지 않는 편이 좋습니다.
요청 로그 읽기
다섯 줄짜리 작은 로그를 분석해 보겠습니다. 결정 과정을 복원해야 할 때 저는 보통 이런 짧은 조각부터 시작합니다.
2026-09-08T14:32:11+03:00 | prompt_submitted | actor=user | ref=card-header | text="카드 제목을 한 줄로 줄여 줘"
2026-09-08T14:36:20+03:00 | prompt_submitted | actor=user | ref=card-header | text="24px와 28px 두 가지 안을 보여 줘"
2026-09-08T14:41:06+03:00 | decision_recorded | actor=user | ref=card-header | text="짧은 제목, 24px 크기로 확정"
2026-09-08T15:03:44+03:00 | prompt_submitted | actor=user | ref=card-shadow | text="카드 그림자를 더 부드럽게 만들어 줘"
2026-09-08T15:08:17+03:00 | prompt_submitted | actor=user | ref=card-header | text="제목 색을 더 어둡게 해 봐"제목 형식에 대해 마지막으로 확정된 결정을 찾아야 한다고 해 봅시다. 편집기에서 card-header로 검색하는 것부터 시작합니다. 네 줄이 나옵니다. 마지막 줄에는 색에 대한 새 요청이 있지만 결정은 아닙니다. 그래서 결론은 14:41:06 줄에 근거합니다. 짧은 제목, 24px 크기로 확정되었습니다.
제가 로그를 읽는 순서는 단순합니다.
- 먼저 질문을 정합니다. 요청인지, 결정인지, 관찰된 오류인지를 찾습니다.
- 공통 태그, 컴포넌트 이름, 정확한 문구를 찾습니다.
- 필요한 유형의 기록만 남기고 시간순으로 읽습니다.
- 결론을 뒷받침하는 줄을 명시합니다. 나머지는 솔직하게 미확인으로 남깁니다.
이런 분석은 Claude Code를 실행하지 않고도 할 수 있습니다. 유용한 습관입니다. 먼저 직접 결론을 파일과 대조해 보고, 그다음에 같은 작업을 에이전트에게 맡기세요.
로그에 결정이 없을 때
이번에는 14:41:06 줄을 빼 보겠습니다. 두 가지 크기를 보여 달라는 요청과 나중에 색을 바꿔 달라는 요청만 남습니다. 어떤 크기로 확정됐을까요? 로그는 답하지 않습니다.
이럴 때는 처음 제안된 안이라는 이유로 24px를 고르고 싶은 유혹이 듭니다. 그러면 안 됩니다. 요청은 안을 검토하려는 의도를 보여줄 뿐, 최종 선택을 보여주지 않습니다. 여기서 정직한 결론은 하나뿐입니다. 크기에 대한 확정 결정은 로그에 기록되어 있지 않습니다.
갈림길은 요청의 순서가 아니라 찾은 기록의 종류에 따라 정해집니다. 명확한 결정 표시가 있으면 결론을 확인할 수 있습니다. 요청만 남아 있으면 미확인으로 기록하고 추측으로 빈틈을 메우지 않습니다. 이런 절제가 결국 많은 시간을 절약해 줍니다.
Claude Code가 로그를 분석할 때, 저는 결론이 어떤 기록에 근거하는지 정확히 말해 달라고 요청합니다. 뒷받침하는 줄이 없다면, 성공했으리라는 추측 없이 그 항목을 미확인 목록에 넣어야 합니다.
로그에 담지 말아야 할 것
저는 유용한 로그를 모든 것의 저장소로 만들려는 게 아닙니다. 기록의 구성은 나중에 풀어야 할 질문에 맞춰 선택해야 합니다. 결정을 찾는 데는 대개 시각, 이벤트 유형, 작성자, 연결 태그, 짧은 텍스트만으로 충분합니다.
- 키, 토큰,
.env내용, 개인정보는 복사하지 마세요. - 상태나 작업 식별자만 필요하다면 외부 서비스의 응답을 통째로 옮기지 마세요.
- 전체 프롬프트는 정말로 필요한 곳에만 남기세요. 이 글에서는 예시가 짧고 가상이기 때문에 전체를 실었을 뿐입니다.
- 파일 크기와 오래된 기록의 쓸모를 주기적으로 확인하세요. 모든 프로젝트에 공통되는 보관 기간은 없습니다.
줄을 100자로 자르면 가독성은 좋아지지만 비밀 정보가 자동으로 지워지지는 않습니다. 짧은 토큰은 처음 100자 안에도 얼마든지 들어갑니다. 먼저 애초에 어떤 데이터를 기록해도 되는지 정하세요. 시작은 줄 길이가 아니라 바로 이 규칙이어야 합니다.
Claude Code와 함께 로그 분석하기
Claude Code는 시간 순서를 잘 정리하고 관련된 줄을 빠르게 찾아냅니다. 하지만 그러려면 에이전트가 파일을 명시적으로 읽어야 합니다. 프로젝트에 requests.log가 있다는 사실만으로는 그 내용이 이미 컨텍스트에 들어와 있다는 뜻이 아닙니다.
에이전트에게 구체적인 작업을 주세요.
requests.log를 읽어 주세요. 카드 제목(card-header) 크기에 대해
명시적으로 확정된 마지막 결정을 찾아 주세요. 근거로 삼은 기록을 명시하세요.
로그에 요청만 있다면 그렇다고 말해 주세요.
미확인으로 남은 항목은 따로 나열해 주세요.좋은 답변은 사실과 결론을 구분합니다. 시각, 이벤트 유형, 결정 텍스트를 인용한 다음, 확인되지 않은 질문을 따로 나열합니다. 이 인용을 원본 줄과 대조해 보세요. 에이전트가 마지막 요청을 "확정된 안"이라고 부를 때 오류가 특히 눈에 띕니다.
지금 다룬 학습용 로그의 경우 답은 이렇습니다. 크기에 대한 결정은 2026-09-08T14:41:06+03:00 기록이 뒷받침하며, 이후 더 어두운 색에 대한 요청이 있었지만 색에 대한 확정 결정은 미확인입니다. 저는 바로 이런 답변을 신뢰할 만하다고 봅니다. 파일에 있는 것보다 더 많이 약속하지 않기 때문입니다.
- 훅은 요청을 처리하기 전에 저장하므로, 이 기록은 결과를 증명하지 않습니다.
- 별도의 표시가 시각이나 태그로 확정된 결정을 요청과 연결합니다.
- 검색은 구체적인 질문에서 시작해 원본 줄에 대한 참조로 끝납니다.
- 확인할 근거가 없으면 로그는 빈틈을 남깁니다. 그 빈틈을 임의로 채우면 안 됩니다.
이렇게 하면 requests.log는 작고 실용적인 작업 기록으로 남습니다. 논의의 필요한 전환점을 찾는 데는 도움이 되지만, 프로젝트의 백업이나 완료된 작업의 증거인 척하지는 않습니다. 로그가 정직하게 관리되면 정말로 다시 찾아보고 싶어집니다.
GO TO FULL VERSION