긴 세션에서 코드베이스 전체를 뒤지는 작업을 메인 대화에서 직접 시키면, grep 결과나 파일 내용이 그대로 컨텍스트에 쌓입니다. 정작 필요한 건 결론 한두 줄인데 탐색 과정 전체가 대화 기록에 남아서, 이후 턴에서 그 분량을 다시 읽고 넘어가야 하는 부담이 생깁니다. Claude Code의 Agent(서브에이전트) 도구로 탐색 단계를 분리해서 이 문제를 줄인 과정을 정리합니다.
어떤 작업이었나
여러 모듈에 흩어진 특정 함수 호출부를 전부 찾아서 새 API로 옮기는 작업이었습니다. 호출부가 commonMain, androidMain, iosMain에 걸쳐 스무 곳 넘게 퍼져 있었는데, 메인 세션에서 바로 grep을 여러 번 돌리면 매칭된 줄과 주변 코드가 그대로 대화에 쌓입니다. 탐색이 끝난 뒤 실제 수정 작업으로 넘어가면, 이미 쌓인 탐색 로그 때문에 다음 턴에서 필요한 파일을 다시 열어 확인하는 시간이 오히려 늘어났습니다.
AI를 어떻게 활용했나
탐색만 전담하는 서브에이전트를 따로 띄우고, 메인 세션에는 결과 요약만 받기로 했습니다. Claude Code의 Agent 도구는 읽기 전용 도구만 가진 Explore 타입을 지원하는데, 탐색 단계에서는 수정 권한이 아예 없는 편이 안전하기도 합니다.
Agent({
description: "OldLogger 호출부 전수 조사",
subagent_type: "Explore",
prompt: "commonMain, androidMain, iosMain 전체에서 OldLogger.log(...) 호출부를 모두 찾아줘. " +
"각 호출부의 파일 경로와 줄 번호, 그리고 어떤 로그 레벨로 호출하는지만 목록으로 보고해줘. " +
"파일 내용을 통째로 인용하지 말고 목록 형태로만 정리해줘."
})
응답으로는 파일 경로와 줄 번호, 로그 레벨이 정리된 목록만 돌아왔고, 그 목록을 보고 메인 세션에서 바로 Edit으로 하나씩 옮겼습니다. 탐색 과정에서 나온 중간 grep 결과나 파일 전체 내용은 서브에이전트 내부에서만 소비되고 메인 대화에는 남지 않았습니다.
처음에 걸렸던 부분
처음에는 탐색 에이전트와 별도로, 새 API의 정확한 시그니처를 확인하는 에이전트를 동시에 띄웠습니다.
Agent({ description: "호출부 조사", subagent_type: "Explore", prompt: "..." })
Agent({ description: "새 API 시그니처 확인", subagent_type: "Explore",
prompt: "위에서 찾은 호출부들이 새 Logger API로 옮겨갈 때 필요한 시그니처를 확인해줘." })
두 번째 프롬프트가 "위에서 찾은 호출부들"을 언급하고 있었지만, 두 에이전트는 같은 메시지 안에서 병렬로 시작되기 때문에 두 번째 에이전트는 첫 번째 에이전트의 결과를 알 수 없는 상태로 실행됐습니다. 결과적으로 두 번째 에이전트는 호출부 목록 없이 추측만으로 답을 냈고, 메인 세션에서 다시 확인해야 했습니다.
새 Agent 호출은 이전 실행에 대한 기억이 전혀 없는 상태로 시작된다는 점을 그제서야 확인했습니다. 서로 의존하는 작업이면 병렬이 아니라 순차로 호출하거나, 두 번째 프롬프트 자체에 필요한 정보를 전부 포함시켜야 했습니다. 이후로는 호출부 조사를 먼저 끝내고 그 결과를 두 번째 프롬프트에 직접 붙여 넣는 방식으로 바꿨습니다.
결과와 얻은 팁
- 서브에이전트 프롬프트는 이전 대화 맥락을 전혀 모른다고 가정하고, 필요한 정보를 전부 프롬프트 안에 적어야 합니다.
- 탐색만 필요한 작업에는
Explore처럼 읽기 전용 도구만 가진 타입을 쓰면, 수정 권한이 없어서 탐색 도중 실수로 파일이 바뀔 걱정이 없습니다. - 서브에이전트에게 "요약만 보고해달라"고 명시하지 않으면 탐색 중 나온 내용을 그대로 다시 늘어놓는 경우가 많습니다. 원하는 보고 형식(목록, 파일:줄 번호 등)을 프롬프트에 구체적으로 적어야 메인 컨텍스트가 실제로 줄어듭니다.
- 서로 결과를 참조해야 하는 작업들은 병렬로 띄우지 말고, 앞 작업의 결과를 받은 다음 그 내용을 다음 프롬프트에 직접 포함시켜 순차로 호출해야 합니다.