정책 커널(Policy Kernel), 프롬프트가 아니다
요약
본 글은 에이전트의 권한과 행동 범위를 '프롬프트'가 아닌 '정책 커널(Policy Kernel)'로 관리해야 한다고 주장합니다. Garu에서 구현된 이 시스템은 YAML 기반 규칙을 통해 어떤 도구 호출이 허용되는지, 그리고 그 조건(인자)까지 엄격하게 제어합니다. 특히 기본값(default)의 경우 침묵은 거부로 처리하여 안전성을 높입니다.
핵심 포인트
- 에이전트의 권한 관리는 프롬프트가 아닌 정책 커널을 사용해야 합니다.
- 정책 커널은 YAML 규칙으로 도구 호출과 인자 조건을 정의합니다.
- 규칙 불일치 시 기본값(default)은 '거부'로 처리하여 안전성을 확보합니다.
- 모델에게는 허용된 도구와 그 조건만 노출되어 논쟁할 수 없습니다.
Originally published on humbertovillanueva.dev.
내 이메일, 파일, 저장소에 접근하여 밤새 작동하는 에이전트라면 무엇보다 먼저 하나의 질문에 답해야 합니다. 그것은 '정확히 무엇을 만질 수 있는가?'입니다. 만약 그 답이 프롬프트의 한 단락이라면, 정직한 대답은 '그것이 결정하는 모든 것'일 것입니다. 모델은 지시사항을 말로 설득할 수는 있지만, 도구를 호출하지 않는 함수 앞에서는 넘어갈 수 없습니다.
이것이 제가 항상 작동하는 에이전트를 위해 만든 오픈 소스 런타임인 Garu의 정책 커널(policy kernel)에 담긴 전체 아이디어입니다. 다음은 이를 형성한 결정들입니다.
규칙은 에이전트 파일 안에 존재하며, 커널이 그것을 읽는다
에이전트는 하나의 YAML 파일입니다. 모델 옆에는 도구와 스케줄 목록이 있고, 그 옆에 규칙 목록이 있습니다. 각 규칙은 도구를 이름으로 지정하고, 선택적으로 인수에 대한 조건을 명시하며, 세 가지 행동(allow, ask, block) 중 하나를 지정합니다. 이것은 매주 월요일 아침 제 받은 편지함을 정리하는 에이전트인 Bea의 규칙을 간소화한 버전입니다:
policy:
- tool: gmail.search_threads # reading: always fine
action: allow
...
모델이 실행하려는 모든 도구 호출은 먼저 커널로 전달됩니다. 커널은 목록을 위에서 아래로 읽고, 일치하는 첫 번째 규칙이 결정합니다. 모델은 이 목록을 절대 볼 수 없습니다. 오직 결과만 봅니다: 도구가 실행되었는지, 도구가 사람을 기다리는지, 또는 도구가 거부되었는지입니다.
아무것도 일치하지 않으면 '질문'한다
기본값(default)이 어떤 단일 규칙보다 더 중요합니다. 호출에 규칙이 하나도 일치하지 않으면, 커널은 조용히 허용하지도 않고 조용히 거부하지도 않습니다. 그것은 질문합니다. 받은 편지함과 제 휴대폰에 카드가 나타나고 실행은 대기합니다. 30분 안에 아무도 답변하지 않으면, 그 답은 '아니오'입니다.
이 마지막 부분은 제가 받아들이는 데 시간이 걸렸습니다. 기본적으로 예(yes)를 받는 방치된 에이전트는 방치된 것이 아닙니다. 그것은 비감독적(unsupervised)입니다. 심지어 요청한 것이 아마 괜찮았을지라도, 침묵은 거부여야 합니다.
절대 허용될 수 없는 것은 숨긴다
만약 어떤 규칙이 모든 가능한 인자에 대해 도구를 차단한다면, 모델은 그 도구가 존재한다는 사실조차 알지 못해야 합니다. Garu는 이를 모델에게 제공되는 목록에서 제거합니다. GitHub의 호스팅 서버를 통해 제 저장소를 감시하는 에이전트인 Rook에게는 해당 서버가 가진 46개의 도구 중 3개만 제공됩니다. 따라서 요청을 열어보려고 시도하며 시간을 낭비할 수 없으며, 요청을 주입할 곳도 없습니다.
엔지니어링 규칙: 모델이 볼 수 없는 규칙은 모델이 논쟁할 수 없는 규칙입니다. 권한뿐 아니라 도구 자체를 숨겨야 합니다.
인자가 진짜 경계이다
도구 이름만으로는 너무 거칩니다. '파일 쓰기'는 에이전트 자신의 폴더에서는 무해하지만 다른 곳에서는 위험합니다. 그래서 규칙은 인자(arguments)에 대해서도 일치합니다. 경로가 briefs/ 뒤에 오늘 날짜와 일치할 때 쓰기가 허용되고, 네 개의 지정된 호스트에 대해 가져오기(fetch)가 허용되며, 수신자가 자동화된 발신자처럼 보일 때는 초안 작성이 차단됩니다. 아침 브리핑을 작성하는 에이전트인 Tomay는 정확히 하나의 쓰기 규칙만을 가지고 있으며 멈추지 않습니다. 왜냐하면 이 에이전트가 쓸 수 있는 유일한 것이 그 에이전트가 하는 일이기 때문입니다.
커널은 또한 이유(reason)를 설명합니다. 각 규칙은 이유를 담을 수 있고, 이 이유가 받은 편지함 카드에 표시되고 호출이 거부될 때 모델이 읽는 내용입니다. '자동화된 발신자에게 보내는 답장은 아무 데도 가지 않습니다'라는 문구는 단순한 오류 메시지보다 더 많은 것을 가르쳐 줍니다.
나머지 부분을 위한 샌드박스
정책(Policy)은 도구가 실행될지 여부를 결정합니다. 하지만 도구 서버가 실행되는 동안 무엇에 접근할 수 있는지는 결정하지 않습니다. 이를 위해 각 도구 서버는 자체 컨테이너에서 실행될 수 있습니다. 즉, 네트워크 연결이 없고, 읽기 전용 루트 디렉터리만 있으며, 에이전트의 작업 공간만 마운트되고, 실행 후 파괴됩니다. 정책과 샌드박스는 서로 다른 질문에 답하며, 하룻밤 동안 방치해도 되는 에이전트는 이 두 가지 모두가 필요합니다.
이것들이 막지 못하는 것들
커널은 차단된 도구를 막습니다. 하지만 모델이 사용할 수 있도록 허용된 도구에 대해 잘못된 인수를 선택하는 것을 막지는 못합니다. 이메일이나 웹페이지의 텍스트는 여전히 모델을 무언가로 유도할 수 있으며, 그 무언가가 허용된 규칙 내에 있다면 발생합니다. 방어책은 규칙의 형태입니다: 읽기를 허용하고, 에이전트 자신의 폴더에 쓰기를 허용하며, 기기를 벗어나는 모든 것은 질문하도록 만드세요. 좁은 허용(Narrow allows)은 우회책이 아니라 설계 자체입니다.
제가 가장 먼저 구축할 것들
- 모델과 도구 사이에 의사결정을 코드로 구현하고, 절대 프롬프트에 넣지 마십시오.
- '일치하는 항목 없음'을 질문으로 처리하게 하고, 답변되지 않은 질문은 거부(no)로 만드세요.
- 규칙이 절대로 허용할 수 없는 모든 도구는 숨기세요.
- 인수를 기준으로 일치시키고, 모든 규칙에 이유를 첨부하세요.
- 모든 결정을 기록하여, 새벽 3시에 발생한 행동을 아침에 다시 재생(replay)할 수 있게 하세요.
결과
제가 계속 적용하는 테스트는 간단합니다: 제가 자는 동안 이것을 실행하게 할까요? 규칙이 코드로 구현되고, 디스크에 기록되며, 모든 실행에 비용 상한선이 설정되자 답은 '예'가 되었습니다. 그것이 중요한 유일한 기능입니다.
Garu는 Apache-2.0 라이선스 하의 독립적인 오픈 소스 프로젝트이며, 저의 고용주와는 관련이 없습니다. 이 노트의 모든 내용은 공개 저장소 github.com/humbertovillanueva/garu에서 가져왔습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기