Claude Code 제품 소개 공식 이미지
이미지: claude.com (Claude Code)

예약 실행되는 세션 하나를 매일 아침 돌려두고 있는데, 이 세션이 끝날 때마다 분석 결과를 파일로 하나 남겨뒀습니다. 문제는 그 파일이 세션이 떠 있는 컨테이너 안에만 존재한다는 점이었습니다. 세션을 직접 열어서 대화 기록을 뒤져보지 않으면 그 파일이 있다는 사실조차 알 방법이 없었습니다.

어떤 작업이었나

매일 아침 실행되는 루틴이 체크 결과를 정리해서 로컬 경로에 파일로 저장하도록 되어 있었습니다. 세션 안에서는 Write로 파일을 만들고 끝이었는데, 실제로 그 세션을 다시 열어본 적이 거의 없다 보니 파일이 쌓여만 가고 실제로 읽어본 적은 손에 꼽았습니다. 세션 트랜스크립트에 파일 경로를 남기는 것만으로는 "만들었다"와 "사람이 봤다" 사이의 간극이 메워지지 않았습니다.

AI를 어떻게 활용했나

SendUserFile 도구를 찾아서 루틴 프롬프트에 "결과 파일을 만들었으면 반드시 SendUserFile로 전달해줘"라는 조건을 추가했습니다. 사용법은 단순합니다.

SendUserFile({
  files: ["/home/user/project/scratchpad/daily-check-2026-10-20.md"],
  caption: "오늘자 점검 결과",
  status: "proactive"
})

status에 "proactive"를 주면 사용자가 지금 그 세션을 보고 있지 않을 때도 알림이 가도록 되어 있습니다. 반대로 "normal"은 사용자가 방금 뭔가를 물어본 직후에 답으로 파일을 돌려줄 때 쓰는 값입니다. 매일 아침 혼자 깨어나서 도는 루틴이니 당연히 proactive를 썼습니다.

표시 방식도 고를 수 있습니다. display: "render"는 HTML이나 이미지처럼 바로 눌러서 볼 수 있는 파일을 화면에 띄워주고, "attach"는 다운로드 카드만 보여줍니다. 분석 결과를 마크다운 리포트로만 쌓고 있어서 처음엔 생략했는데, 생략하면 파일 종류에 따라 클라이언트가 알아서 고른다는 걸 알고 나서는 굳이 더 건드리지 않았습니다.

처음에 걸렸던 부분

처음엔 체크가 끝날 때마다 중간 결과를 계속 SendUserFile로 보내도록 프롬프트를 짰습니다. 그랬더니 분석 하나가 끝날 때마다 카드가 하나씩 떴고, 최종 리포트가 나올 때쯔음엔 같은 파일의 조금씩 다른 버전이 세 번 네 번 겹쳐서 떠 있었습니다. 도구 설명을 다시 읽어보니 "스크래치 파일이나 디버그 출력, 아직 작업 중인 조각은 보내지 말고, 완성된 산출물이나 의미 있게 갱신된 버전만 보내라"는 내용이 있었습니다. 매번 저장할 때마다 보내는 게 아니라, 사람이 실제로 볼 만한 시점에만 보내는 걸로 프롬프트를 고쳤습니다.

경로 문제도 한 번 있었습니다. SendUserFile은 URL을 가져오는 도구가 아니라 로컬 파일시스템에 이미 있는 파일만 보냅니다. 외부 사이트에서 받아온 이미지를 그대로 넘기려다가, 먼저 그 파일을 세션 안에 내려받아 로컬 경로로 만들어둬야 한다는 걸 뒤늦게 깨달았습니다. URL을 바로 집어넣으면 당연히 실패했습니다.

결과와 얻은 팁

  • 루틴이 만든 결과물은 세션 트랜스크립트에만 남겨두면 사람이 거의 안 봅니다. 파일을 실제로 전달하고 싶으면 SendUserFile로 명시적으로 보내야 한다는 걸 전제로 깔고 프롬프트를 짜는 게 낫습니다.
  • proactive와 normal을 구분해서 쓰면, 사람이 지금 대화를 보고 있지 않을 때만 알림이 울리게 할 수 있습니다. 매번 같은 걸 proactive로 보내면 알림 자체가 소음이 되어버립니다.
  • 중간 산출물까지 전부 보내지 말고, 완성된 결과나 눈에 띄게 바뀐 버전만 추려서 보내는 편이 카드가 쌓이는 걸 막습니다. "보낼지 말지"를 매번 판단하게 프롬프트에 조건을 넣어두는 게 효과적이었습니다.