unlazy skill Depth Tree 사용법과 설치 방법
unlazy skill이 agent의 조기 완료 선언을 막는 방법을 설명합니다. Depth Tree, gates 파일, PLAN.md 계약, 설치 단계와 depth별 비용을 version 2.0.0 기준으로 다룹니다.
unlazy skill의 기능
unlazy skill은 한 가지 실패를 막기 위해 만든 agent skill이다. 코딩 agent가 작업을 끝내기 전에 완료된 것으로 보고하는 문제다. 핵심은 Depth Tree다. 이 방법은 작업을 여러 계층으로 나누고, 가장 아래 계층만 실제 작업으로 취급한다. Version 2에서는 검증 기능을 설명문에서 파일로 옮겼다. 따라서 agent는 완료되었다고 주장하는 대신 실행 가능한 명령 목록을 기준으로 완료를 입증해야 한다.
이 skill은 Leonxlnx가 github.com/Leonxlnx/unlazy에서 MIT license로 공개했다. 이 가이드는 2026-08-10에 released된 version 2.0.0을 기준으로 작성했다. 이 분야의 skill은 빠르게 변경되므로, 계속 실행할 setup에 이 내용을 복사하기 전에 저장소의 CHANGELOG를 읽어야 한다.
여기서 skill은 일반적인 의미로 사용한다. 작업이 설명과 일치하면 harness가 model의 context에 로드하는 SKILL.md 파일을 뜻한다. 이 메커니즘이 익숙하지 않다면 agent skill이 무엇이며 harness가 이를 로드하는 방법부터 읽는다. unlazy는 일반 markdown과 몇 개의 Node script로 구성되므로 자체 server나 API key가 필요하지 않다.
에이전트가 80%에서 멈추고 세 번째 지시를 누락하는 이유
이 동작에는 알아볼 수 있는 패턴이 있다. 네 가지를 요청했는데 응답에는 첫 번째, 두 번째, 네 번째만 포함된다. 마지막 요약에는 네 가지가 모두 완료된 것으로 표시된다. 오류가 발생하지 않았으므로 이를 알리는 항목도 없다. 일주일 뒤에야 누락을 발견하게 된다.
unlazy README는 이를 모델의 태만함에 관한 공개 연구와 연결하며, "응답의 조기 중단과 여러 부분으로 구성된 요청에 대한 부분적 준수"를 인용한다. 인용 문헌은 arXiv 2512.20662이다. 같은 README는 설계 전제를 명확히 밝힌다. 설명문으로 설명문을 강제할 수는 없다. 에이전트에 더 노력하라고 지시하는 것은 부족한 결과를 만든 동일한 context에 설명문을 더 추가하는 것에 불과하다.
따라서 version 2는 상태를 파일에 저장한다. GATES.md의 확인란은 모델의 재량 밖에 있다. 확인란 아래에 이를 뒷받침하는 evidence line이 있거나 없으며, script는 에이전트에 묻지 않고 어느 쪽인지 확인할 수 있다.
깊이 트리, 계층별 이해
깊이 트리는 작업이 수행될 수 있는 위치에 대한 규칙을 포함한 분해 방식이다. 방법론 참고 문서에는 다음과 같이 설명되어 있다.
자연스러운 접점에서 나눈다. 자연스러운 접점에서 가능하면 이진 분할을 사용한다. N개 계층까지 깊게 나눈다.
실제 작업은 리프에서만 수행한다. 리프보다 위의 모든 계층은 분해와 통합을 담당한다.
리프는 글머리 기호 하나보다 큰 단위다. 참고 문서는 다음과 같이 최소 규모를 정한다.
리프는 실제 작업 단위다. 10분 이상 집중해서 수행할 수 있고, 일관된 하나의 결과물과 하나의 gates 파일을 포함해야 한다.
이 최소 규모가 깊은 트리를 단순한 형식적 작업으로 변질되지 않게 한다. 리프에 "변수 이름 변경"이라고 적혀 있다면 이 기준을 충족하지 못한다. 그러면 그 위의 분할이 한 계층 과도하게 진행된 것이다.
각 리프는 네 번의 패스를 거친다. 먼저 placeholder 없이 완전히 구현한다. 그런 다음 도메인 전문가의 관점에서 다시 읽는다. 결함을 찾아낸다. 마지막으로 적은 비용으로 개선할 수 있는 부분을 다듬는다. 리프에 최소 규모가 필요한 또 다른 이유가 여기에 있다. 2분짜리 변경에 네 번의 패스를 적용하는 것은 형식적인 작업에 불과하다.
skill을 호출할 때 깊이를 지정한다.
/unlazy tree 5 refactor the payment module일반 언어로 지정해도 된다. skill의 설명이 slash command가 아니라 의도를 기준으로 일치하기 때문이다.
tree 3 build the landing page and do not stop until every gate is checked참고 문서는 깊이 구간을 제시한다. tree 2 또는 3은 기능 추가, 버그 조사 또는 문서 작업에 해당한다. 한 세션에서 혼자 수행하며 리프는 2~4개다. tree 4 또는 5는 서브시스템, 리팩터링 또는 심층 검토에 해당한다. 이 경우 리프가 8~16개가 되며, 이는 "하나의 컨텍스트가 효율적으로 처리할 수 있는 범위를 넘는다". tree 6 또는 7은 전체 프로젝트에 해당한다. 오케스트레이션 모드로 실행하고 리프를 서로 겹치지 않는 작업 단위에 매핑한다.
깊이를 지정하지 않으면 skill은 "작업의 자연스러운 구성 요소에 맞는 리프를 만드는 가장 작은 N을 선택하라"는 지시를 받는다. 또한 기본적으로 한 단계 더 깊게 나누지 말라는 명시적인 지시도 받는다. 깊이는 작업의 특성을 설명하는 값이므로 숫자를 부풀려도 품질이 높아지지 않는다.
gates 파일의 형태
작업을 시작하기 전에 agent는 gates 파일에 acceptance criteria를 기록한다. 각 gate는 그 아래에 command가 있는 checkbox다.
# Gates: pricing section
- [ ] G1: three tiers render with real copy
CHECK: node check.js pricing --tiers
EXPECT: 3/3 tiers ok
EVIDENCE: pending
- [ ] G2: annual toggle changes both price and label
CHECK: node check.js pricing --toggle
EXPECT: toggle ok
EVIDENCE: pendingCHECK는 command다. EXPECT은 pass로 간주하는 output이다. EVIDENCE는 pending에서 시작하며, command가 실제로 출력한 내용으로 바꿔야 한다. 이 skill에는 해당 파일을 검사하고 아직 open 상태인 gate를 보고하는 scripts/gate-check.mjs이 포함되어 있으므로, transcript를 읽지 않고도 실행 결과를 감사할 수 있다.
이 철학은 한 줄로 요약할 수 있으며, SKILL.md에도 한 줄로 작성되어 있다.
보고서는 ledger로 뒷받침되는 claim의 집합이지, 완료되었다는 막연한 느낌이 아니다.
그다음 규칙은 "ledger가 가득 차기 전에는 보고하지 않는다"는 것이다. 최종 summary의 모든 숫자는 report 시점에 다시 측정하거나 unverified로 표시해야 한다는 reporting rule도 함께 적용한다. agent가 작업을 끝냈다고 느낀다고 해서 gate를 닫을 수는 없다. gate를 닫는다는 것은 output을 붙여 넣는 것이며, 그 output은 EXPECT와 일치하거나 일치하지 않아야 한다.
낯선 사람도 실행할 수 있는 gates를 작성한다. "Looks good"은 check가 아니다. test -s dist/index.html && echo ok이 ok을 출력하는 것은 check다. 빈 파일이나 없는 파일에서는 명확하게 실패하기 때문이다.
병렬 작업 전에 작성하는 PLAN.md 계약
트리가 충분히 넓어져 리프가 별도의 컨텍스트에서 실행되면 리프 간에 가정이 공유되지 않는다. 방법론 참조 문서는 분기 전에 계약을 먼저 둔다.
분기 전에 계약을 작성한다. 인터페이스, 데이터 소유권, 명명 규칙, 오류 처리 규칙은 모든 리프가 시작하기 전에 PLAN.md에 기록한다.
이유는 구체적이다. 두 subagent에 각각 "오류 처리를 추가하라"고 지시하면 서로 다른 오류 형식을 만든다. 두 리프 모두 자체 게이트를 통과할 수 있다. 각 리프의 구현은 해당 리프 안에서는 올바르기 때문이다. 문제는 두 리프가 만나는 지점에서만 나타난다. 브랜치 게이트는 바로 그 순간을 검증한다. 브랜치의 게이트는 "자식 작업이 병합되었고, 인터페이스가 일치하며, 종단 간 동작이 정상이고, 형제 리프의 회귀가 없다"는 사실을 증명한다.
오케스트레이션 모드에서 드라이버는 PLAN.md 전체와 드라이버 자체의 이력이 아니라 PLAN.md의 계약 섹션과 해당 리프의 gates 파일을 원문 그대로 각 subagent에 전달한다. subagent가 반환되면 드라이버가 검사를 직접 다시 실행한다. "증거 없이 자체 체크 항목만 확인한" subagent는 충족하지 못한 게이트를 구체적으로 지정해 다시 작업하게 한다.
오케스트레이션에는 하한이 있다. 실제 작업 시간이 대략 30분보다 짧다면 참조 문서는 단독 작업을 유지하라고 한다. 각 subagent가 작업을 처음부터 다시 이해해야 하므로, 설정에 드는 비용이 새롭게 얻는 집중력보다 커지기 때문이다.
unlazy skill을 어떻게 설치합니까?
지원되는 방법은 skills CLI를 사용하는 것입니다.
npx skills add Leonxlnx/unlazy수동으로 설치하려면 agent의 skills 디렉터리에 clone합니다.
git clone https://github.com/Leonxlnx/unlazy ~/.claude/skills/unlazygit clone https://github.com/Leonxlnx/unlazy ~/.codex/skills/unlazy그런 다음 제대로 설치되었는지 확인합니다.
ls ~/.claude/skills/unlazy/SKILL.md경로가 출력되면 파일이 디스크에 있다는 뜻입니다. No such file or directory는 clone이 다른 위치에서 수행되었다는 뜻입니다. 일반적으로 가정한 이름의 skills 디렉터리가 존재하지 않아 git이 새 디렉터리를 생성했기 때문입니다. agent의 말을 그대로 믿어서도 안 됩니다. README의 설치 안내도 같은 경고로 끝납니다. "파일이 디스크에 실제로 있는지 확인하기 전에는 설치되었다고 말하지 마십시오."
skill loader가 없는 harness에서는 SKILL.md의 내용을 system prompt 또는 rules 파일에 붙여 넣습니다. 이것이 문서에 명시된 대체 방법입니다. 따라서 일반 markdown 지침 파일을 읽는 Claude Code, Codex, Cursor 및 기타 도구에서도 이 방법을 사용할 수 있습니다. SKILL.md가 처음부터 안정적으로 로드되도록 하는 요소를 확인하려면 자체 agent skill 작성을 참조하십시오. 이 문서에서는 skill이 실제로 실행될지 결정하는 frontmatter와 description matching을 다룹니다.
Claude Code 외부에서도 Stop hook이 작동합니까?
아니요. 이 부분은 정확하게 구분해야 합니다. 위의 내용은 모두 지침이며, 지침은 무시될 수 있습니다. 구조적으로 강제하는 유일한 요소는 Stop hook이며, Stop hook은 Claude Code 기능입니다.
node <path-to-skill>/scripts/install-hooks.mjs # this project only (settings.local.json)
node <path-to-skill>/scripts/install-hooks.mjs --global # every project
node <path-to-skill>/scripts/install-hooks.mjs --uninstall에이전트가 자신의 턴을 종료하려는 순간 Stop hook이 실행됩니다. 이 Stop hook은 gates 파일을 검사하고 gates가 충족되지 않았으면 중지를 차단합니다. 따라서 확인하지 않은 항목이 남아 있는 상태로 턴을 종료할 수 없습니다. 파일을 읽기만 하고 모델 호출은 수행하지 않으므로 README에서 토큰을 0개 사용한다고 설명합니다. 일반적인 작동 방식과 연결할 수 있는 다른 이벤트는 Claude Code hook이 턴 전후에 실행되는 방식을 참조하십시오.
출구 장치도 있습니다. 이는 보이는 것보다 중요합니다. 에이전트가 연속으로 6번 중지가 차단되는 동안 gates를 한 단계도 진행하지 못하면, hook은 에이전트를 가두는 대신 경고와 함께 종료를 허용합니다. ABANDON: <gate> <reason> 줄은 항상 정상적인 종료 요청으로 처리됩니다. 이 두 가지 탈출 경로가 없다면 환경에서 해결할 수 없는 gate 때문에 직접 세션을 종료할 때까지 토큰이 계속 소모됩니다.
Codex, Cursor 또는 다른 harness에서는 install-hooks.mjs를 설치할 대상이 없습니다. gates 파일과 실행 가능한 검사는 그대로 사용할 수 있지만, 모델이 턴을 일찍 종료하지 못하도록 구조적으로 차단하는 기능은 없습니다. 이 환경에서는 gates 파일을 직접 읽어야 합니다.
unlazy와 ponytail 중 어느 것을 사용해야 하는가?
이 두 skill은 같은 시기에 유행했고, 작업량을 서로 반대 방향으로 조정하므로 혼동하기 쉽다.
ponytail은 코드가 애초에 필요한지부터 묻는 시니어 개발자처럼 agent가 동작하게 한다. 범위를 줄이고 standard library를 우선하며 diff를 축소한다. unlazy는 범위가 이미 합의되었다고 보고, 그 범위의 모든 부분을 완료하고 검증할 때까지 작업을 확장한다.
따라서 실제로 발생한 실패에 따라 선택해야 한다. agent가 작은 기능을 framework로 확장한다면 ponytail skill과 그 게으른 시니어 개발자 persona가 필요하다. 4개 항목으로 구성된 요청에서 세 번째 항목을 남겨 둔 채 성공했다고 보고한다면 unlazy가 필요하다.
두 skill을 함께 실행할 수도 있지만 순서가 중요하다. 먼저 ponytail의 질문으로 범위를 확정한 다음, 합의된 범위를 unlazy의 gate에 넘긴다. 반대로 실행하면 ponytail이 삭제했을 작업에 대한 leaf tree를 만들게 되고, 그 전체에 depth multiplier를 적용하게 된다. 이 순서는 내 권장 사항이며, 두 project 간에 문서화된 integration은 아니다.
VPS에서 실행하는 에이전트의 depth 비용은 얼마인가?
Depth는 작업량을 배율로 늘리며, 작업량은 토큰으로 측정된다. 자체 API key로 VPS에서 에이전트를 실행하면 이 배율이 곧 비용이 된다.
The data behind this chart
[
{
"label": "Skill run vs no skill, output tokens",
"low_multiplier": 1.6,
"high_multiplier": 3.9
},
{
"label": "tree 6 vs tree 3, total cost",
"low_multiplier": 1.0,
"high_multiplier": 1.5
}
]이 수치는 저자들이 2026-08-10에 직접 테스트하여 얻은 값이다. 우리는 이를 재현하지 않았으므로, 예측값이 아니라 비용 증가 양상의 참고 자료로 보아야 한다. Solo 규율을 적용하면 출력량이 baseline의 대략 1.6배에서 3.9배까지 증가했다. 반면 하나의 context 안에서 tree 3에서 tree 6으로 늘렸을 때의 증가는 1.0배에서 1.5배에 그쳤다. 이는 binary split을 3번 더 했을 때 예상되는 8배 증가에 크게 못 미친다.
Depth가 깊어져도 비용이 비례하여 증가하지 않는 이유는 depth가 context를 추가하는 대신 작업량을 재분배하기 때문이다. token economy에 관한 참고 자료는 실제 배율이 어디에서 발생하는지 명확히 설명한다. "비용을 배율로 늘리는 것은 orchestration이며, 각 leaf가 새로운 context를 확보하므로 비용이 배율로 늘어나는 것이 타당하다." Solo mode는 하나의 context 안에서 출력 토큰을 배율로 늘린다. Orchestrated mode는 context 수를 배율로 늘리며, 새 context가 유용한 작업을 시작하기 전에 contract와 gates 파일을 매번 다시 읽는다.
놓치기 쉬운 두 번째 비용도 있으며, 같은 참고 자료에서 이를 지적한다. 해당 테스트의 단일 monolithic deep run은 계속 커지는 하나의 context에 모든 내용이 누적되었기 때문에 "대략 58 million cached input tokens를 소비했다." Cached input은 토큰당 비용이 더 낮지만, 그 정도 규모가 되면 여전히 청구 금액에 반영된다.
이로부터 다음 4가지 설정을 적용할 수 있다.
- Leaf가 실제 작업 단위가 되는 가장 작은 depth를 선택한 뒤 중지한다. 필요하지 않은 depth는 필요하지 않은 지출이다.
- 30분 미만의 작업에서는 solo mode를 사용한다. 이 구간에서는 subagent 설정 비용이 새 context에서 얻는 이익보다 크기 때문이다.
- Claude Code를 사용한다면 Stop hook을 설치한다. 이 작업에서 무료로 실행되는 부분은 이것뿐이다.
- 오래 실행할 작업을 시작하기 전에 account 수준에서 엄격한 지출 한도를 설정한다.
마지막 항목이 핵심이다. 조기 중지를 거부하도록 설계된 skill은 설계상 계속 작업하는 skill이다. Budget과 alerting은 prompting과 별도의 운영 작업이며, VPS에서 에이전트 비용을 제어하는 방법에서는 먼저 설정할 가치가 있는 한도를 설명한다.
저자들이 측정한 항목과 그 결과가 입증하는 내용
이 저장소는 자체 테스트 결과를 공개한다. 이런 사례는 생각보다 드물다. README에서 인용한 테스트 구성은 다음과 같다. "처음부터 빌드하는 작업 2개(마케팅 사이트와 three.js 태양계), 각 작업당 3가지 조건(no skill, tree 3, tree 6), 실행마다 새 폴더와 새 세션 1개, 동일한 모델, 동일한 프롬프트 본문이다. 모든 출력은 독립 에이전트가 코드 리뷰하고, 적대적 방식으로 다시 검증했으며, 브라우저에서 실제로 테스트했다."
The data behind this chart
[
{
"label": "Self-found defects fixed, skill runs",
"low_count": 4,
"high_count": 10
},
{
"label": "Wrong numbers in report, skill runs",
"low_count": 1,
"high_count": 3
},
{
"label": "Wrong numbers in report, baseline runs",
"low_count": 0,
"high_count": 0
}
]가운데 행을 두 번 읽어야 한다. 저자들이 직접 수행한 테스트에서 skill을 사용하면 에이전트가 납품 전에 스스로 발견한 결함이 4개에서 10개로 고정된다. 이어서 모든 skill 실행은 최종 보고서에 잘못된 숫자를 1개에서 3개 포함했다. 기준 실행에서는 그 수가 0개였다. 더 많은 작업으로 빌드는 개선되었지만 요약은 악화되었다. 이것이 ledger 규칙과, 보고 시점마다 모든 숫자를 다시 측정하거나 검증되지 않은 값으로 표시하라는 지침의 근거다.
이 결과 중 하나는 더 기억해 둘 가치가 있다. "실제 실행에서 발생한 유일한 치명적 실패는 기준 빌드였지만, 해당 보고서는 그 사례가 처리되었다고 주장했다." 실패한 빌드 위에 자신 있게 작성된 요약은 바로 gates가 방지하려는 문제다.
이제 한계를 보자. 실행 6회, 빌드 작업 2개, 모델 1개이며, skill의 작성자 본인이 실행하고 보고했다. 여기에는 독립적인 재현이 없다. 따라서 이 내용은 2026-08-10 기준 저자들의 주장으로 인용한다. 대신 자신의 작업에서 테스트해야 한다. 동일한 작업을 2번 실행한다. 한 번은 일반 방식으로 실행하고, 한 번은 gates 파일을 사용한다. 그런 다음 직접 다시 실행할 수 있는 증거와 함께 종료된 gates의 수를 센다. 이 영역에서 자신에게 의미가 있는 유일한 숫자는 그 수다.
FAQ
unlazy skill의 Depth Tree란 무엇입니까?
분해 방법입니다. 작업은 N개 계층에 걸쳐 자연스러운 경계에서 분할되며, 가장 아래의 리프만 작업으로 계산합니다. 이 skill은 리프를 하나의 일관된 결과물과 하나의 gates 파일을 갖고 10분 이상 집중해서 수행하는 작업으로 정의합니다. 따라서 2분 만에 끝낼 수 있는 리프가 있다면 한 계층을 너무 깊게 분할한 것입니다. 리프보다 위에 있는 각 계층은 분해와 통합을 담당합니다. 각 브랜치에는 하위 작업이 병합되었고 인터페이스가 일치한다는 사실을 입증하는 자체 gates가 있습니다. 호출할 때 깊이를 선택할 수 있습니다. 예를 들어 tree 5를 사용합니다. 문서에 정의된 기본값은 리프가 실제 작업 단위가 되는 가장 작은 깊이입니다.
unlazy skill은 Claude Code 외부에서도 작동합니까?
부분적으로 작동합니다. 이 skill은 일반 markdown이므로 Codex, Cursor, 그리고 SKILL.md 또는 system prompt를 읽는 모든 도구에서 Depth Tree, gates 파일, 실행 가능한 검사, 리프별 4단계 작업을 사용할 수 있습니다. 그러나 강제 방식은 다릅니다. gates가 충족되지 않은 동안 턴 종료를 차단하는 Stop hook은 Claude Code 기능이며 node <path-to-skill>/scripts/install-hooks.mjs로 설치합니다. 그 밖의 환경에서는 모델이 턴을 일찍 종료하는 것을 구조적으로 막는 요소가 없습니다. 따라서 사용자가 gates 파일을 직접 확인하고 다시 전달해야 합니다.
unlazy skill을 사용하면 token 비용이 얼마나 증가합니까?
작성자들은 solo mode에서 skill을 사용하지 않은 실행의 출력 token 대비 1.6배에서 3.9배라고 보고합니다. 여기에 gates 파일 자체에 필요한 수백 token의 오버헤드가 추가됩니다. 하나의 context 안에서 더 깊이 분해하는 비용은 이에 비하면 거의 없으며, tree 3에서 tree 6으로 이동할 때 약 1.0배에서 1.5배입니다. Orchestrated mode가 비용이 가장 높습니다. 각 리프마다 새로운 context가 생성되고, 작업 전에 contract와 해당 gates를 다시 읽기 때문입니다. Stop hook은 파일을 스캔하기만 하므로 추가 비용이 없습니다. 이는 2026-08-10 기준 작성자들의 수치이며, 우리가 다시 측정한 결과는 아닙니다.
unlazy와 ponytail 중 무엇을 사용해야 합니까?
현재 발생한 실패 유형에 맞춰 skill을 선택해야 합니다. ponytail은 너무 많은 코드를 작성하는 agent에 적합합니다. 코드를 작성해야 하는지 묻는 senior developer 역할을 수행하고, 먼저 standard library를 사용하기 때문입니다. unlazy는 요청한 작업을 충분히 완료하지 않는 agent에 적합합니다. 작업을 강제로 분해하고 증거 없이 gate를 닫지 못하게 하기 때문입니다. 둘 다 사용하려면 먼저 ponytail로 범위를 정한 다음 그 범위를 unlazy에 전달해야 합니다. 이렇게 하면 삭제했어야 할 작업에 effort multiplier를 적용하지 않게 됩니다.
unlazy를 설치했는데도 agent가 여전히 일찍 중지하는 이유는 무엇입니까?
4가지를 확인해야 합니다. 첫째, ls ~/.claude/skills/unlazy/SKILL.md로 skill이 디스크에 설치되었는지 확인합니다. 존재하지 않던 디렉터리에 clone한 경우가 가장 흔한 누락 원인입니다. 둘째, 작업 시작 전에 gates 파일이 작성되었는지 확인합니다. hook은 gates 파일을 스캔하므로 GATES.md가 없으면 차단할 대상이 없습니다. 셋째, hook이 설치된 위치를 확인합니다. 일반적인 install-hooks.mjs 실행은 현재 프로젝트의 settings.local.json에만 기록하므로, 다른 프로젝트에는 --global가 필요합니다. 넷째, release valve가 설계대로 작동한다는 점을 기억해야 합니다. gate 진행 없이 6회 연속으로 차단된 중지가 발생하면 agent는 경고와 함께 계속 진행할 수 있습니다. 또한 ABANDON: <gate> <reason> 줄은 의도적으로 시도를 종료합니다.