Filesystem 도구
Filesystem 도구 (Filesystem Tool)
에이전트가 코드베이스를 탐색하고 파일을 읽고 편집하며 새 파일을 만들고 디렉터리 구조를 다니는 방법을 설명해요.
출처: 문서
본문
filesystem 도구는 에이전트가 코드베이스를 탐색하고, 파일을 읽고 편집하며, 새 파일을 만들고, 파일을 검색하고, 디렉터리 구조를 탐색할 수 있게 해 줘요.
경로 해석
경로는 작업 디렉터리(에이전트 세션이 시작된 디렉터리, 또는 --workdir로 지정된 디렉터리) 기준으로 해석돼요:
- 상대 경로(예: src/main.go, ../README.md)는 작업 디렉터리와 결합돼요.
- 절대 경로는 호스트 운영체제와 일치해야 해요: Unix/Linux/macOS: /home/user/project/file.txt / Windows: C:\Users\user\project\file.txt 또는 C:/Users/user/project/file.txt
- 홈 디렉터리 확장:
~또는~/로 시작하는 경로는 사용자 홈 디렉터리로 확장돼요.
파일을 찾을 수 없으면 오류 메시지에 잘못된 기본 디렉터리나 경로 형식을 진단하는 데 유용한 해석된 절대 경로가 포함돼요.
중요 에이전트는 호스트 OS에 적합한 경로를 사용해야 해요. Unix 시스템의 Windows 절대 경로(예:
C:\file.txt)나 그 반대는 명확한 오류 메시지와 함께 거부돼요.
빈 디렉터리 감지
list_directory가 빈 디렉터리나 무시 패턴으로 모든 항목이 숨겨진 디렉터리(예: ignore_vcs: true일 때 .git 폴더만 있는 경우)를 만나면 상태를 명시적으로 보고해요:
- 빈 디렉터리: "Directory is empty: /path/to/dir"
- 모든 항목 무시: "Directory has no visible entries (N hidden by ignore patterns): /path/to/dir"
이렇게 하면 에이전트가 빈 디렉터리와 도구 실패를 구분해서 셸 명령으로 불필요하게 재시도하지 않아요.
사용 가능한 도구
| 도구 | 설명 |
|---|---|
read_file |
파일 내용 읽기(전체 파일, 또는 텍스트 파일의 줄 범위) |
read_multiple_files |
한 호출로 여러 파일 읽기(여러 read_file보다 효율적) |
write_file |
새 내용으로 파일 생성 또는 덮어쓰기 |
edit_file |
기존 파일에서 줄 기반 편집(찾기-바꾸기). 각 편집은 매칭·교체할 비어 있지 않은 oldText를 지정해야 함; 빈 oldText는 오류로 거부됨 |
list_directory |
주어진 경로의 파일과 디렉터리 나열(빈 디렉터리 명시적으로 보고) |
directory_tree |
디렉터리의 재귀 트리 뷰 |
create_directory |
새 디렉터리 생성(필요하면 부모 디렉터리 생성) |
remove_directory |
빈 디렉터리 제거 |
search_files_content |
여러 파일에서 텍스트 또는 정규식 패턴 검색 |
edit_file 검증
edit_file 도구는 일련의 찾기-바꾸기 편집을 메모리의 파일에 적용한 뒤 결과를 원자적으로 다시 써요. 각 편집은 비어 있지 않은 oldText 값을 제공해야 해요:
- 유효: {"oldText": "line one", "newText": "LINE ONE"}
- 무효: {"oldText": "", "newText": "INJECTED"} — 오류로 거부됨
빈 oldText는 의미 있는 편집이 절대 아니에요: Go의 strings.Contains(s, "")는 항상 true이고, strings.Replace(s, "", new, 1)는 오프셋 0에 조용히 삽입해요. 검증이 없으면 파일 앞에 내용을 붙이면서도 성공을 보고할 수 있어요. 이제 도구는 편집의 oldText가 비어 있으면 명시적 오류("oldText must not be empty")를 반환하고, 디스크에는 아무것도 쓰지 않아요.
시퀀스에 여러 편집이 있고 나중 것 중 하나가 거부되면 전체 작업이 실패하고 파일은 그대로 남아요 — 편집은 메모리에서 적용되고 끝에 한 번만 쓰이므로 부분 적용이 불가능해요.
구성
toolsets:
- type: filesystem
옵션
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
ignore_vcs |
boolean | true |
true(기본)일 때 .git 디렉터리와 .gitignore 패턴이 목록에서 제외됨. false로 설정하면 포함 |
post_edit |
array | [] |
경로 패턴과 일치하는 파일 편집 후 실행할 명령 |
post_edit[].path |
string | — | 파일용 글로브 패턴(예: *.go, src/*/*.ts) |
post_edit[].cmd |
string | — | 실행할 명령(${file}은 편집된 파일 경로에 사용) |
allow_list |
array | [] |
도구가 접근할 수 있는 디렉터리. 비어 있으면 무제한(기본값) |
deny_list |
array | [] |
도구가 접근하면 안 되는 디렉터리. allow_list보다 우선 |
경로 접근 제어
기본적으로 filesystem 도구는 무제한이에요: 상대 경로는 작업 디렉터리에서 해석되지만, 절대 경로와 .. 탐색은 에이전트 프로세스가 닿을 수 있는 어디든 도달할 수 있어요. 도구셋을 샌드박스하려면 allow_list 및/또는 deny_list를 구성하세요.
두 목록의 항목은 다음과 같이 확장돼요:
- "." — 에이전트의 작업 디렉터리
- "
" 또는 "/..." — 사용자 홈 디렉터리 - "$VAR" / "${VAR}" / "${env.VAR}" — 환경 변수 확장
- 절대 경로 — 그대로 사용
- 상대 경로 — 작업 디렉터리에 앵커
심볼릭 링크는 포함 검사 전에 해석되므로, 허용 루트 안의 심볼릭 링크로 그것을 탈출할 수 없어요. allow_list가 설정되면 각 항목이 Go *os.Root로 열려서 커널의 루트 고정 조회 의미론이 해석 시점이 아니라 I/O 시점에도 .. 및 심볼릭 링크 탈출을 거부해요.
toolsets:
- type: filesystem
# 모든 작업을 작업 디렉터리와 사용자 홈 폴더로 제한하고,
# 홈 폴더에서 자격 증명을 도려냄
allow_list:
- "."
- "~"
deny_list:
- "~/.ssh"
- "~/.aws"
에이전트가 제공한 경로가 거부되면 도구는 어떤 파일시스템 I/O도 수행하지 않고 구조화된 오류를 반환해요. 이렇게 하면 제한이 모델에 보여서 계획을 조정할 수 있어요.
Post-Edit 훅
에이전트가 파일을 편집한 후 포맷팅, 린팅, 기타 명령을 자동 실행해요. 명령은 각 편집 작업(write_file과 edit_file) 후 파일당 한 번 실행돼요. ${file}을 편집된 파일의 절대 경로 자리표시자로 사용하세요.
toolsets:
- type: filesystem
ignore_vcs: false
post_edit:
- path: "*.go"
cmd: "gofmt -w ${file}"
- path: "*.ts"
cmd: "prettier --write ${file}"
- path: "src/*/*.py"
cmd: "black ${file}"
| 속성 | 타입 | 설명 |
|---|---|---|
path |
string | 파일 경로와 매칭되는 글로브 패턴. *.go는 모든 .go 파일 매칭; src/*/*.ts는 src/ 안의 .ts 파일 매칭 |
cmd |
string | 실행할 셸 명령. ${file}은 방금 편집된 파일의 절대 경로로 확장 |
post-edit 명령은 에이전트와 같은 작업 디렉터리로 실행돼요. 명령이 0이 아닌 값으로 종료되면 오류가 로그되고 모델에 경고로 표시되지만, 편집은 롤백되지 않아요.
examples/post_edit.yaml에서 완전한 예시를 확인하세요.