도구 시스템은 세 가지 질문에 답합니다. 도구는 어디 정의되는가 (레지스트리), 매 호출에 어떤 도구를 싣는가 (deferred loading), 서브에이전트에게 어떤 도구를 주는가 (툴킷)입니다.
레지스트리
core/tools/registry.py의 ToolRegistry가 네이티브 도구를 관리합니다. 정의의 SoT는 core/tools/definitions.json 하나입니다. 이름, 설명, 입력 스키마가 모두 여기 모이고, 핸들러는 카테고리 모듈에서 이름으로 연결됩니다. MCP 클라이언트(core/mcp/)가 발견한 외부 도구는 호출 시점에 네이티브 도구와 병합됩니다. MCP 서버 참고.
Deferred loading
모든 도구 스키마를 모든 호출에 실으면 턴마다 input 토큰을 크게 태웁니다. 프로바이더 어댑터가 core/llm/tool_defer.py의 공통 정책을 읽고, 공식 defer_loading 필드와 호스티드 tool_search 도구로 카탈로그를 나눕니다.
| 조건 | 동작 |
|---|---|
도구 수가 TOOL_DEFER_THRESHOLD(16) 이하 | 전부 즉시 로드 |
| 임계값 초과 | 호스티드 tool_search를 추가하고, core set만 즉시 싣고, 나머지는 defer_loading=True로 표시해 검색 후 로드 |
즉시 로드 core set은 TOOL_SEARCH_ALWAYS_LOADED입니다. 기억, 노트, 파일 읽기, 웹 탐색, 상태 확인처럼 검색 왕복을 치르면 손해인 고빈도 도구가 여기에 남고, 나머지는 에이전트가 tool_search로 찾아 그때 가져옵니다.
따라서 도구가 deferred loading 뒤로 밀렸다는 말은 모든 도구가 보이지 않는다는 뜻이 아닙니다. read_document, grep_files처럼 핵심 읽기 도구는 항상 적재됩니다. 이런 도구가 반복 호출된다면 보통 도구 수 제한 때문이 아니라 모델이 더 많은 근거 파일을 읽겠다고 판단한 결과입니다.
툴킷: 서브에이전트 도구 번들
서브에이전트는 도구 전체가 아니라 선언된 번들만 받습니다. 매니페스트는 core/tools/toolkits.toml, 해석기는 core/tools/toolkit_registry.py입니다.
- 에이전트 frontmatter의
toolkit:이름이 있으면 그 툴킷을 사용합니다.includes:는 재귀적으로 펼쳐집니다. - 레거시
tools:목록이 있으면 그대로 사용합니다. - 둘 다 없거나 이름이 틀리면 읽기 전용
_default(read_document,grep_files)로 폴백합니다.
조합용 leaf는 common_read와 common_write, 선언용 킷은 web_research, data_analysis, general_purpose 등입니다. 존재하지 않는 도구 이름은 스폰 시점에 경고를 내고 그 도구 없이 실행됩니다 (core/agent/worker.py).
대형 결과: 오프로드와 recall
도구 결과가 5000 토큰 임계값을 넘으면 core/orchestration/tool_offload.py의 ToolResultOffloadStore가 본문을 세션별 디렉터리 (.geode/tool-offload/ 아래)에 내려쓰고, 컨텍스트에는 요약과 ref_id만 남깁니다. 모델이 원본이 필요하면 recall_tool_result(ref_id)로 다시 가져옵니다. 오프로드마다 TOOL_RESULT_OFFLOADED 훅이 발화합니다.
접근 제어
어떤 도구를 누가 쓸 수 있는지는 core/tools/policy.py의 PolicyChain이 6단계로 해석합니다. Profile, Organization, Mode, Agent 레벨, Node-scope allowlist, 서브에이전트 자동 승인 위임 순서입니다. 권한 등급은 STANDARD(서브에이전트 자동 승인 가능), WRITE(승인 필요), DANGEROUS(항상 HITL. run_bash, computer)입니다. delegate_task는 별도 위임 경로로 실행되며, 사람이 없는 headless 세션에서는 denylist가 먼저 막습니다.
실패 모드
| 증상 | 원인 | 해법 |
|---|---|---|
| 모델이 분명히 있는 도구를 못 찾음 | deferred loading으로 스키마가 아직 적재되지 않음 | 정상 경로입니다. 모델이 tool_search로 찾으면 로드됩니다 |
read_document나 grep_files가 반복 호출됨 | 핵심 읽기 도구는 항상 적재됨. tool cap에 숨은 것이 아니라 모델의 탐색 판단일 가능성이 큼 | dialogue transcript에서 직전 grep_files 호출과 읽은 경로를 보고, 필요한 경우 질문에 파일 범위나 금지 경로를 명시합니다 |
| 서브에이전트가 도구 없이 동작 | frontmatter의 toolkit 이름 오타 | 스폰 로그의 경고를 확인하고 toolkits.toml의 이름과 맞춥니다 |
| 도구 결과가 잘려 보임 | 5000 토큰 초과로 오프로드됨 | recall_tool_result(ref_id)로 원본을 조회합니다 |
다음
- MCP 서버. 외부 도구가 합류하는 클라이언트 측.
- 서브에이전트 오케스트레이션. 툴킷이 적용되는 실행 주체.
- 커스텀 도구 만들기. definitions.json에 도구를 추가하는 절차.