역할별 권한 설계와 disabled가 삭제보다 철저한 이유

26년 06월 22일

확장은 스킬이 아니다

이날은 서브에이전트 권한을 체계적으로 정리한 날이다.

누가 어떤 도구를 쓸 수 있는지, 왜 그렇게 설계했는지를 하나씩 검토했다.

그러다

재귀 위험이 있는 에이전트를 발견하고 disabled 처리했다.

가장 먼저 정리한 건 확장이랑 스킬의 차이다.

researcher 에이전트에 웹 접근 확장이 있었다.

웹 검색 도구를 쓸 수 있다.

근데 사서 스킬이 없었다.

“도구가 있으니까 스킬도 있겠지”라고 생각하기 쉽다.

근데 틀렸다.

확장은 도구를 준다.

웹 검색을 할 수 있게 해준다.

근데 어떻게 검색해야 하는지, 출처를 어떻게 평가해야 하는지는 스킬이 알려준다.

도구랑 방법론은 다른 층이다.

도구만 있으면 할 수는 있다.

근데 잘할 수는 없다.

방법론까지 있어야 제대로 한다.

delegate를 disabled했다

가장 큰 결정은 delegate 에이전트를 disabled 처리한 거다.

delegate는 부모 에이전트를 복제하는 에이전트다.

부모의 프롬프트를 그대로 상속한다.

병렬 작업을 위해 만들어졌다.

근데 감사해보니까 5일 동안 313개 세션에서 7번밖에 안 쓰였다.

그것도 진짜 작업은 0건이었다.

전부 메타 확인이거나 위험한 권한 상태였다.

재귀 위험

더 심각한 건 재귀 위험이다.

delegate는 부모 프롬프트를 상속한다.

부모 프롬프트에는 “서브에이전트한테 위임하라”는 지시가 있다.

그러니까 delegate가 서브에이전트를 또 부른다.

서브에이전트가 또 서브에이전트를 부를 수 있다.

무한 재귀다.

7번 중 3번이 서브에이전트 도구를 가지고 있었다.

재귀가 가능한 상태였다.

매번 “참고용만” 경고를 넣어서 막았지만 이건 사람이 매번 기억해야 하는 밴드에이드다.

근본 해결이 아니다.

그래서 disabled했다.

disabled가 삭제보다 철저한 이유

여기서 중요한 발견이 있었다.

delegate를 삭제하면 안 된다.

파일을 지우면 내장 delegate가 다시 나타난다.

덮어쓰기가 사라지니까 원본이 복원되는 거다.

그래서 disabled: true를 써야 한다.

파일을 남겨두고 프론트매터에 disabled를 넣는다.

이러면 덮어쓰기가 유지된다.

덮어쓰기가 내장 에이전트까지 전파된다.

사용자 정의랑 내장 둘 다

무력화된다.

롤백도 간단하다.

disabled 한 줄을 지우면 된다.

근데 파일을 삭제하면 내장이 돌아온다.

역할별 도구 분배

pi-lens 도구 분배도 정리했다.

pi-lens는 6개 도구가 있다.

읽기 5개, 쓰기 1개다.

쓰기 도구는 worker에게만 줬다.

worker만 코드를 수정하니까. 다른 에이전트는 읽기만 한다.

읽기 도구는 역할에 비례해서 줬다.

코드를 직접 다루는 역할이 더 많이 가진다.

검증자가랑 planner는 3개, scout는 2개, researcher는 1개. “넓게 찾고 worker만 고친다”는 원칙이다.

발견은 분산, 수정은 집중.

임시 파일 정책 다섯 번째 전환

마지막으로 임시 파일 정책을 다섯 번째로 바꿨다.

에이전트한테 “임시 파일은 $HOME/.pi/tmp에 만들라”고 했다.

근데 도구는 셸이 아니다.

$HOME을 확장하지 않는다.

리터럴로 받아서 $HOME이라는 이름의 디렉토리를 만든다.

이 문제를 네 번이나 고치려 했다.

경로를 바꾸고 확장 절차를 적어주고 토큰을 치환하고. 근데 다섯 번째에서 근본적으로 바꿨다.

$HOME을 아예 안 쓰는 거다.

프로젝트 상대 경로 .pi/tmp를 쓴다.

셸 확장 토큰이 없으니까 비대칭 문제 자체가 사라진다.

올바른 토큰을 선택하면 절차를 안 적어도 된다.

문제를 만드는 토큰을 안 쓰면 문제가 안 생긴다.

마무리

내가 이날 배운 핵심은 다음과 같다.

이날의 핵심은 “확장은 스킬이 아니다”와 “disabled가 삭제보다 철저하다”다.

확장은 도구를 준다.

스킬은 방법론을 준다.

이 둘을 같은 걸로 보면 “도구가 있으니까 할 수 있겠지”라고 착각한다.

근데 방법론 없이는 제대로 못 한다.

역할에 맞는 도구랑 역할에 맞는 스킬을 둘 다

줘야 한다.

disabled는 삭제보다 철저하다.

삭제하면 덮어쓰기가 사라지고 원본이 돌아온다.

disabled는 덮어쓰기를 유지하면서 무력화한다.

무언가를 영구적으로 막을 때는 삭제가 아니라 disabled를 써야 한다.

그리고 “문제를 만드는 토큰을 안 쓰면 된다.” 셸 확장이 안 되면 확장이 안 되는 토큰을 안 쓰면 된다.

절차로 우회하는 것보다 근원에서 안 쓰는 게 더 낫다.