3편 — 권한·커맨드·스킬·툴 설계하기

작성일:2026.05.21|조회수:32

3편 — 권한·커맨드·스킬·툴 설계하기

프롬프트에 “수정하지 마라”고 써도 에이전트는 수정할 수 있다. edit: allow가 열려 있으면 텍스트 지시는 의도일 뿐이고, 실행은 permission 설정이 결정하기 때문이다. 프롬프트는 에이전트를 설득하는 과정이지만, permission은 에이전트가 넘지 못하는 물리적인 경계다. 에이전트 설계에서 권한 설정이 프롬프트 작성보다 선행되어야 하는 이유가 바로 여기에 있다.

에이전트의 실행 표면을 설계한다는 것은 에이전트가 사용할 수 있는 도구의 범위와 호출 방식을 정의하는 작업이다. 이는 보안뿐만 아니라 에이전트의 성능과도 직결된다. 불필요한 도구를 차단하면 에이전트는 주어진 목표에 더 집중하게 되고, 필요한 도구를 정교하게 제공하면 에이전트의 문제 해결 능력은 비약적으로 상승한다.

권한(Permission): 안전의 마지노선

OpenCode의 권한 시스템은 allow, ask, deny 세 가지 값으로 동작한다. allow는 묻지 않고 실행하며, deny는 아예 차단한다. ask는 실행 전에 사용자에게 확인을 요구한다. 에이전트를 처음 만들 때는 deny에서 시작해 꼭 필요한 것만 하나씩 열어가는 최소 권한 원칙을 지키는 것이 가장 안전하다.

Permission Key설명권장 설정
read파일 내용 읽기대부분 allow
edit파일 내용 수정reviewer는 deny, builder만 allow
bash터미널 명령 실행기본 ask, 반복 검증만 제한 허용
webfetch외부 URL 조회librarian 계열에 제한 허용
MCP tool외부 시스템 연결역할별로 명시 허용

여기서 중요한 것은 도구 이름보다 권한의 방향이다. 리뷰어에게 edit를 열어두고 “수정하지 마”라고 쓰는 것보다, edit를 닫고 “필요한 수정안을 제안하라”고 쓰는 편이 훨씬 안전하다. 반대로 builder에게 모든 것을 닫아두면 에이전트는 매번 사용자에게 손을 벌리게 된다. 최소 권한은 아무것도 못 하게 만드는 것이 아니라, 필요한 일만 확실히 하게 만드는 기술이다.

커스텀 커맨드(Command): 반복의 단축

command는 사람이 반복해서 실행하는 절차를 하나의 진입점으로 묶는다. 예를 들어 블로그 글을 업데이트할 때 매번 “현재 글 조회, 수정안 생성, PATCH, 재조회 검증”을 말로 설명하면 빠뜨리는 단계가 생긴다. 이 절차를 /blog update 같은 command로 만들면 사람은 의도를 짧게 전달하고, command는 빠뜨리면 안 되는 순서를 고정한다.

TXT
/blog update opencode-omo-permission-command-skill-tool

1. GET /api/posts/[slug]로 현재 상태 조회
2. content 수정안 생성
3. PATCH /api/posts/[slug]에는 변경 필드만 전송
4. status가 바뀌지 않았는지 재조회
5. 토큰과 원문 credential은 출력하지 않음

command는 권한 그 자체가 아니라 절차의 형태다. 그래서 command 안에서 어떤 tool을 부를지, 어떤 skill을 로드할지, 어떤 검증을 요구할지를 명확히 써야 한다. 좋은 command는 버튼처럼 보이지만 내부는 작은 운영 매뉴얼이어야 한다. 버튼은 누구나 누를 수 있기 때문이다.

스킬(Skill): 판단 기준을 필요할 때 로드하기

skill은 특정 작업의 판단 기준을 담는다. 예를 들어 블로그 글을 작성할 때는 API endpoint보다 문체, 단락 호흡, 시리즈 규칙, excerpt 처리 방식이 더 중요할 때가 많다. 이 지식을 모든 에이전트 파일에 복사하면 금방 낡는다. skill로 분리하면 필요한 순간에만 로드하고, 규칙이 바뀌어도 한 곳만 고치면 된다.

TXT
blog-write skill
- 발행은 명시 요청이 있을 때만 한다
- PATCH에는 변경 필드만 보낸다
- title과 content의 중복 H1을 제거한다
- 토큰은 어떤 출력에도 포함하지 않는다
- 한국어 기술 글은 문제 -> 선택지 -> 해결 -> 의미 흐름을 따른다

skill은 에이전트를 더 똑똑하게 만들지만, 물리적 권한을 제한하지는 않는다. 그래서 skill과 permission은 항상 같이 생각해야 한다. “토큰을 출력하지 말라”는 skill 규칙은 필요하지만, token을 다루는 tool 자체가 로그에 값을 흘리지 않도록 command와 실행 방식도 함께 설계해야 한다.

Tool과 MCP: 실제 시스템에 닿는 손

tool은 에이전트가 세계를 바꾸는 손이다. 파일을 수정하는 tool도 있고, 브라우저를 여는 tool도 있고, API를 호출하는 tool도 있다. MCP는 이런 외부 도구를 OpenCode에 붙이는 표준 출입구에 가깝다. 로컬 프로세스로 실행되는 MCP도 있고, 원격 서버나 OAuth 인증이 필요한 MCP도 있다.

MCP를 붙일 때는 “연결됐다”에서 멈추면 안 된다. 다음 질문까지 답해야 한다.

  1. 이 MCP는 읽기 전용인가, 상태를 바꾸는가?
  2. 프로젝트 설정에 둘 것인가, 사용자 전역 설정에 둘 것인가?
  3. 인증은 누가 수행하고, 토큰은 어디까지 노출되는가?
  4. 어떤 에이전트가 이 MCP를 호출할 수 있는가?
  5. 실패했을 때 재실행해도 안전한가?

문서 검색 MCP는 explore나 librarian 계열에 넓게 열어도 비교적 안전하다. 반대로 배포, 결제, 발행, 삭제처럼 상태를 바꾸는 MCP는 command로 감싸고 좁은 permission 안에서 실행하는 편이 낫다. mcp debug로 연결을 확인하고, 인증이 필요한 경우에는 opencode mcp auth 같은 흐름을 통해 사람의 인증 단계를 분리해두는 식이다.

하나의 연결 예시: 블로그 업데이트

이 글에서 말하는 네 요소를 하나로 묶으면 아래처럼 설계할 수 있다.

TXT
AGENTS.md
  - 토큰 출력 금지
  - 발행 전 재조회 필수
  - 실패 시 같은 PATCH 반복 금지

command: /blog update <slug>
  - 현재 글 조회
  - 수정안 생성
  - 변경 필드만 PATCH
  - 재조회 검증

skill: blog-write
  - 문체와 시리즈 규칙
  - excerpt와 title 처리 규칙
  - API payload 최소화 규칙

tool / MCP
  - GET /api/posts/[slug]
  - PATCH /api/posts/[slug]
  - 인증 헤더는 내부에서만 사용

이 구조의 핵심은 에이전트가 “글을 잘 쓰는 것”과 “실제 발행 시스템에 손을 대는 것”을 분리한다는 점이다. 글을 잘 쓰는 능력은 skill에 가깝고, 안전하게 API를 호출하는 능력은 command와 tool의 책임이다. 둘을 한 프롬프트에 섞으면 처음에는 빨라 보이지만, 나중에는 어디서 실수했는지 찾기 어려워진다.

설계 순서

정리하면 실행 표면은 아래 순서로 설계하는 것이 안전하다.

TXT
1. 먼저 AGENTS.md에 공통 금지 규칙을 둔다.
2. 반복되는 사람의 호출은 command로 만든다.
3. 도메인 판단은 skill로 분리한다.
4. 실제 외부 연결은 tool/MCP로 붙인다.
5. 마지막으로 agent에 역할과 권한을 묶는다.

이 순서가 중요한 이유는 책임의 방향 때문이다. 에이전트는 마지막 조립품이어야 한다. 처음부터 에이전트를 만들고 그 안에 규칙, 절차, 지식, 도구 연결을 모두 넣으면 금방 거대한 만능 프롬프트가 된다. 만능 프롬프트는 처음에는 든든하지만, 운영에 들어가면 대체로 만능으로 실패한다.

댓글

댓글을 불러오는 중...