GitHub Copilot 핵심 정리
GitHub Copilot은 GitHub에서 제공하는 AI 코딩 도우미입니다.
VS Code에 내장되어 있어서 코드나 문서를 입력하는 동안 다음 내용을 제안하고, 채팅으로 질문에 답하고, 파일을 만들고 명령을 실행하는 작업까지 대신 처리합니다.
먼저 챗봇과 에이전트의 차이를 짚고 시작합시다.
챗봇은 질문을 받으면 답변 하나를 돌려주고 끝납니다.
에이전트(Agent)는 목표를 받으면 무엇을 해야 할지 계획하고, 파일을 읽거나 명령을 실행하는 도구를 사용하고, 그 결과를 확인해서 다음 행동을 정하는 과정을 작업이 끝날 때까지 반복합니다.
Copilot은 두 가지를 모두 제공합니다.
질문만 하고 싶으면 Ask를 골라 챗봇처럼 사용하고, 파일을 만들고 스크립트를 실행하는 일을 맡기려면 Agent를 사용합니다.
이 글의 예제는 대부분 Agent에서 진행합니다.
Copilot을 사용하려면 GitHub 계정이 필요하니, 미리 회원가입 및 로그인을 해 두는 것이 좋습니다.
Free 플랜으로도 시작할 수 있으며, 플랜에 따라 매월 사용할 수 있는 인라인 제안 횟수, AI 크레딧, 고를 수 있는 모델이 다릅니다.
| 플랜 | 가격 | 특징 |
|---|---|---|
| Copilot Free | 무료 | 매월 인라인 제안 2,000회와 일정량의 크레딧, 모델은 Auto만 사용 |
| Copilot Pro | $10/월 | 매월 1,500 크레딧, 여러 모델 선택 가능 |
| Copilot Pro+ | $39/월 | 매월 7,000 크레딧, 상위 모델 사용 |
| Copilot Max | $100/월 | 매월 20,000 크레딧, 상위 모델 우선 사용 |
| Copilot Business | $19/사용자/월 | 조직 단위 관리, 사용자당 1,900 크레딧을 조직이 함께 사용 |
| Copilot Enterprise | $39/사용자/월 | 조직 단위 관리, 사용자당 3,900 크레딧을 조직이 함께 사용 |
크레딧은 채팅과 에이전트 요청에 사용되는 단위이며, 모델과 요청의 크기에 따라 소모량이 달라집니다.
크레딧을 다 쓴 뒤의 추가 사용은 달러로 예산을 정하며, 1 크레딧은 0.01달러로 계산됩니다.
플랜과 크레딧 정책은 자주 바뀌므로 플랜 안내 문서를 함께 확인하세요.
# 설치 및 로그인
VS Code를 설치하고 실행합니다.
Copilot은 VS Code에 내장되어 있어서 별도의 확장을 설치하지 않아도 됩니다.
처음 실행하면 Welcome to VS Code 화면이 표시됩니다.Continue with GitHub를 누르면 브라우저에서 GitHub 로그인 화면이 열리고, 로그인하고 승인하면 VS Code로 돌아옵니다.
구독이 없는 계정은 자동으로 Free 플랜에 가입됩니다.
처음 화면은 영어로 표시됩니다.
한국어 메뉴로 사용하려면 왼쪽 활동 막대의 확장 아이콘을 누르고(Cmd + Shift + X, Windows는 Ctrl + Shift + X), Korean을 검색해서 Korean Language Pack을 설치한 뒤 안내에 따라 VS Code를 다시 시작합니다.
이 글의 나머지 화면은 모두 한국어 언어 팩을 적용한 상태입니다.
언어 팩은 VS Code보다 늦게 갱신되므로, 새로 추가된 메뉴 일부는 한국어 UI에서도 영어로 표시됩니다.
이미 VS Code를 설치해서 로그인하지 않은 채로 사용하고 있었거나 처음 화면에서 Continue without Signing In을 눌렀다면, 이 로그인 안내는 다시 표시되지 않습니다.
이때는 먼저 VS Code를 최신 버전으로 업데이트합니다.
macOS는 위쪽 메뉴의 Code > 업데이트 확인..., Windows는 도움말 > 업데이트 확인...을 누르고, 새 버전이 있으면 안내에 따라 VS Code를 다시 시작합니다.
로그인하지 않은 상태에서는 위쪽 제목 표시줄의 검색 창 오른쪽에 파란색 로그인 버튼이 표시됩니다.
버튼을 누르면 GitHub Copilot을 사용하려면 로그인하세요. 대화상자가 열리고, GitHub(으)로 계속하기를 누르면 처음 설치할 때와 같이 브라우저에서 GitHub에 로그인하고 승인한 뒤 VS Code로 돌아옵니다.
같은 대화상자는 오른쪽 아래 상태 표시줄의 Copilot 아이콘을 누르거나, 왼쪽 아래 계정 아이콘을 누르고 GitHub Copilot을 사용하려면 로그인...을 선택해도 열 수 있습니다.
로그인하지 않은 채로 채팅에 요청을 보내면 응답 대신 Language model unavailable 오류가 표시될 수 있으니, 이 오류가 보이면 로그인 상태부터 확인합니다.
로그인이 끝나면 상태 표시줄의 Copilot 아이콘을 눌렀을 때 현재 플랜과 이번 달 크레딧 사용률, 사용량이 다시 설정되는 날짜가 표시됩니다.인라인 제안을 펼치면 제안 종류를 하나씩 켜고 끌 수 있고, 다시 알림을 누르면 5분 동안 제안을 숨깁니다.
왼쪽 아래 계정 아이콘을 누르면 연결된 GitHub 계정을 확인하거나 로그아웃할 수 있습니다.
회사 정책 등으로 AI 기능을 완전히 꺼야 하면 설정에서 chat.disableAIFeatures를 켭니다.
채팅과 인라인 제안이 모두 숨겨집니다.
반대로 로그인 버튼과 상태 표시줄의 Copilot 아이콘, 채팅 뷰가 모두 보이지 않는다면 이 설정이 켜져 있을 수 있습니다.
설정(Cmd + ,, Windows는 Ctrl + ,)에서 chat.disableAIFeatures를 검색해 체크를 해제하면 로그인 버튼이 다시 표시됩니다.
# 예제 프로젝트 준비
예제는 가상의 온도 센서 모듈 TS-100을 만드는 연구개발팀을 배경으로 합니다.
팀에는 반복해서 들어오는 질문, 노트북 신청, 회의록 정리, 이슈 접수와 판정, 주간 보고 같은 업무가 있고, 이 업무를 Copilot에게 맡기는 것이 목표입니다.
예제의 스크립트를 실행하려면 Node.js가 필요합니다.
Node.js는 .js 스크립트 파일을 실행하는 프로그램이며, 22 이상의 버전을 설치합니다.
설치 방법은 Node.js(NPM) 설치 및 NVM 버전 관리 가이드를 참고하세요.
스크립트는 Node.js 내장 기능만 사용하므로 별도의 패키지 설치가 없습니다.
예제 저장소는 두 가지 방법으로 받을 수 있습니다.
Git을 사용한다면 터미널에서 다음 명령을 실행합니다.
123git clone https://github.com/ParkYoungWoong/github-copilot-example.git cd github-copilot-example code .
Git이 익숙하지 않다면 저장소 페이지에서 Code > Download ZIP을 눌러 압축 파일을 받고, 압축을 푼 폴더를 VS Code의 파일 > 폴더 열기로 엽니다.
처음 여는 폴더는 이 폴더에 있는 파일의 작성자를 신뢰합니까?라고 묻는 대화상자가 표시됩니다.
직접 받은 예제이므로 예, 작성자를 신뢰합니다를 선택합니다.
대화상자를 닫아서 상태 표시줄에 제한 모드가 표시되면, 그 글자를 눌러 신뢰로 바꿀 수 있습니다.
저장소의 구조는 다음과 같습니다..github 폴더의 파일들은 Copilot의 행동을 정하는 설정이고, docs와 data는 비서가 참고할 기준 문서와 원본 데이터입니다.
123456789101112131415github-copilot-example/ ├── .github/ │ ├── copilot-instructions.md # 모든 요청에 적용되는 팀 규칙 │ ├── instructions/ # 특정 파일에만 적용되는 규칙 │ ├── agents/ # 이슈 판정 전용 커스텀 에이전트 │ ├── skills/ # team-faq, laptop-request, meeting-notes, issue-triage, │ │ # weekly-report, bug-report 스킬 │ └── hooks/ # 비밀 파일 읽기를 차단하는 Hook ├── .vscode/ │ └── settings.json # 작업 영역 설정 ├── docs/ # FAQ, 규정, 판정 규칙, 제품 스펙, 보고 템플릿 ├── data/ # 이슈 목록(CSV), 회의 메모 ├── scripts/ # 판정, 보고서, 검증 스크립트 ├── tests/cases.json # 검증셋 └── output/ # 비서가 만든 결과물
글의 순서는 다음 실습 순서와 같습니다.
| 단계 | 내용 | 관련 파일 |
|---|---|---|
| 1 | 팀 FAQ 비서 | .github/skills/team-faq/ |
| 2 | 노트북 신청 양식 작성 | .github/skills/laptop-request/ |
| 3 | 회의록 정리와 되묻기 | .github/skills/meeting-notes/ |
| 4 | 스펙 문서 질문과 출처 확인 | docs/spec-ts100.md |
| 5 | 버그 리포트 조사 계획 | .github/skills/bug-report/ |
| 6 | 이슈 판정표 생성 | scripts/triage.js, docs/issue-rules.md |
| 7 | 보고서 자동 생성 | scripts/report.js, .github/skills/weekly-report/ |
| 8 | 검증셋과 권한 | scripts/check.js, tests/cases.json, .github/hooks/ |
| 9 | 통합과 적용안 | docs/quality-checklist.md, docs/adoption-plan-template.md |
# 인라인 제안
편집기에서 코드나 문서를 입력하면 커서 위치에 회색 글씨로 다음 내용이 표시됩니다.
이것을 인라인 제안(Inline Suggestions) 또는 고스트 텍스트(Ghost Text)라고 합니다.Tab 키를 누르면 제안을 그대로 받아들이고, 계속 입력하면 제안은 사라집니다.
주석으로 무엇을 만들지 먼저 적으면 그 아래에 맞는 코드를 제안합니다.
다음은 scripts 폴더에 새 파일을 만들고 첫 줄에 주석만 입력한 상태입니다.
| 동작 | macOS | Windows |
|---|---|---|
| 제안 전체 수락 | Tab |
Tab |
| 한 단어씩 수락 | Cmd + 오른쪽 방향키 |
Ctrl + 오른쪽 방향키 |
| 다음 제안 보기 | Option + ] |
Alt + ] |
| 이전 제안 보기 | Option + [ |
Alt + [ |
| 제안 무시 | Esc |
Esc |
제안은 열려 있는 파일과 현재 파일의 내용을 참고해서 만들어지므로, 관련 파일을 함께 열어 두면 더 알맞은 제안이 나올 수 있습니다.
반대로 제안이 항상 맞는 것은 아닙니다.
위 화면에서도 예제 프로젝트는 import 문법을 사용하는데 require를 제안했습니다.
제안은 초안으로 보고, 받아들인 뒤에 내용을 확인하는 습관이 필요합니다.
받아들인 코드를 고치기 시작하면 다음 편집 제안(Next Edit Suggestions)이 동작합니다.
변수 이름을 하나 바꾸면 같은 이름을 쓰는 다른 줄도 바꿔야 한다는 것을 예측해서, 편집기 왼쪽 여백에 화살표를 표시하고 바꿀 내용을 미리 보여 줍니다.Tab 키를 누르면 해당 위치로 이동하고, 한 번 더 누르면 적용됩니다.
인라인 제안은 마크다운 파일에서 기본적으로 꺼져 있습니다.
문서 작업이 많다면 상태 표시줄 Copilot 메뉴의 인라인 제안에서 Markdown에 대한 고스트 텍스트 제안을 체크해서 켭니다.
예제 저장소는 작업 영역 설정에 이미 켜 두었습니다.
123456{ "github.copilot.enable": { "*": true, "markdown": true } }
# 인라인 채팅
편집기 안에서 바로 요청을 입력하는 방식입니다.
파일을 열고 Cmd + I(Windows는 Ctrl + I)를 누르면 커서 위치에 입력창이 표시됩니다.
코드 일부를 선택한 뒤에 열면 그 범위만 대상으로 요청할 수 있습니다.
앞에서 만든 파일에 다음과 같이 요청했습니다.
1require 대신 ES 모듈 import 문법으로 바꾸고, 우선순위별 건수를 표 형태로 출력해 줘
결과는 편집기 안에 변경 전후 비교(Diff) 형태로 표시됩니다.
초록색은 추가되는 줄, 빨간색은 삭제되는 줄입니다.유지를 누르면 적용되고 실행 취소를 누르면 원래대로 돌아갑니다.
터미널에서도 같은 단축키로 인라인 채팅을 열 수 있습니다.
명령어를 외우지 않아도 원하는 동작을 말로 설명하면 명령을 제안합니다.실행을 누르면 바로 실행되고, 삽입을 누르면 명령을 터미널에 넣기만 하므로 고쳐서 실행할 수 있습니다.
1output 폴더에 있는 파일 목록을 크기와 함께 보여 주는 명령
# 채팅 뷰
채팅 뷰(Chat View)는 Copilot과 대화하는 기본 화면입니다.Control + Cmd + I(Windows는 Ctrl + Alt + I)로 열고 닫을 수 있으며, 편집기 오른쪽의 보조 사이드바에 표시됩니다.
위쪽에는 지난 세션 목록이, 아래쪽에는 요청을 입력하는 입력창이 있습니다.
입력창과 그 아래에는 자주 쓰는 컨트롤이 모여 있습니다.
| 위치 | 이름 | 역할 |
|---|---|---|
입력창 왼쪽 + |
컨텍스트 추가 | 파일, 폴더, 이전 세션 등을 요청에 첨부 |
Agent |
에이전트 선택 | Agent, Ask와 커스텀 에이전트 중에서 선택 |
Auto |
모델 선택 | 응답을 만들 언어 모델 선택 |
Copilot |
하네스 선택 | 에이전트를 실행하는 방식 선택. 새 세션을 시작하기 전에만 표시 |
대화형 |
모드 선택 | 대화형, 계획, Autopilot 중에서 선택 |
Manual permissions |
권한 선택 | 도구를 실행하기 전에 승인을 받을지 정함 |
위쪽 + |
새 채팅 | 새 세션 시작 |
| 위쪽 사용자 지정 열기 | 에이전트 사용자 지정 | 지침, 스킬, 에이전트, Hook, MCP 서버, 도구 관리 |
# 하네스
하네스(Harness)는 언어 모델에 도구와 지침을 연결해서 실제로 일을 진행시키는 실행 방식입니다.
VS Code 1.143부터 새 세션은 기본으로 Copilot 하네스를 사용합니다.
Copilot 하네스는 Copilot CLI, GitHub Copilot 앱과 같은 기반(Copilot SDK)에서 동작하고, 작업 중에 VS Code 창을 닫아도 작업이 이어질 수 있습니다.
채팅 제목 앞에 Copilot이 붙어 있으면 Copilot 하네스를 사용하는 세션입니다.
하네스 메뉴에는 이전 버전의 방식인 로컬(Local), GitHub 서버에서 작업하는 클라우드, 다른 회사의 방식인 Claude와 Codex도 있습니다.
하네스에 따라 읽는 파일과 사용할 수 있는 기능이 다르므로, 이 글은 기본값인 Copilot 하네스를 기준으로 설명합니다.
특별한 이유가 없다면 바꾸지 않아도 되며, Claude와 Codex 하네스는 뒤의 Claude와 Codex 사용하기에서 따로 다룹니다.
# 에이전트와 모드
Agent 버튼을 누르면 기본 제공 에이전트 두 가지와 저장소에 정의된 커스텀 에이전트가 함께 표시됩니다.Shift + Cmd + I(Windows는 Ctrl + Shift + I)를 누르면 Agent를 바로 고를 수 있습니다.
| 에이전트 | 하는 일 | 이럴 때 |
|---|---|---|
| Ask | 질문에 답만 합니다. 읽기 도구만 사용하고 파일을 바꾸지 않습니다 | 개념 설명, 문서 내용 확인 |
| Agent | 파일을 읽고 만들고 고치며, 터미널 명령도 실행합니다 | 결과물을 만들어야 하는 대부분의 작업 |
입력창 아래의 대화형을 누르면 작업을 진행하는 방식(모드)과 권한을 함께 고르는 메뉴가 열립니다.
| 모드 | 하는 일 |
|---|---|
| 대화형 | 한 단계씩 사람과 함께 진행합니다. 기본값입니다 |
| 계획 | 파일을 바꾸지 않고 조사해서 계획을 먼저 세우고, 승인하면 실행합니다 |
| Autopilot | 작업이 끝났다고 판단할 때까지 스스로 진행합니다. 모든 도구를 승인 없이 실행합니다 |
입력창에 /plan과 할 일을 함께 입력해도 계획 모드로 시작합니다.
Autopilot은 확인 없이 파일을 고치고 명령을 실행하므로, 내용을 잘 아는 작업에서만 사용합니다.
권한은 뒤의 도구와 승인에서 다룹니다.
# 모델
모델 선택 메뉴에서는 응답을 만들 언어 모델을 고릅니다.
기본값 Auto는 작업과 시스템 상태에 맞춰 모델을 자동으로 고릅니다.Auto 옆의 Balance를 누르면 효율(Efficiency), 균형(Balance), 성능(Intelligence) 중 무엇을 우선할지 정할 수 있으며, 화면에는 Balance로 처리한 요청에 10% 할인이 적용된다고 표시됩니다.
플랜에 따라 고를 수 있는 모델이 다르고, 지금 플랜으로 쓸 수 없는 모델에는 Upgrade가 표시됩니다.
목록에 표시되는 모델 이름은 시간이 지나면 바뀔 수 있습니다.
Copilot은 자체 모델 하나로 동작하는 서비스가 아니라, 여러 회사의 모델을 빌려 와 한 메뉴에 모아 둔 서비스입니다.
그래서 메뉴에서 Claude 모델을 골라도 비용은 Copilot 크레딧에서 나갑니다.
이미 쓰고 있는 ChatGPT나 Claude 구독을 사용하는 방법은 뒤의 Claude와 Codex 사용하기에서 다룹니다.
응답이 끝나면 아래에 사용한 모델 이름과 소모한 크레딧이 표시됩니다.
이 글의 예제를 Auto로 실행했을 때는 요청 한 번에 대부분 0.1에서 0.5 크레딧이 들었고, Claude Sonnet 5.5를 직접 고르면 짧은 답 하나에 3에서 6.5 크레딧이 들었습니다.
간단한 요청은 Auto로 두고 결과가 부족할 때만 상위 모델을 지정하는 것이 좋습니다.
# 컨텍스트
Copilot은 요청과 함께 전달된 내용과, 에이전트가 직접 찾아 읽은 파일을 바탕으로 답합니다.
편집기에 열려 있는 파일은 입력창 위에 이름이 표시되며 자동으로 함께 전달되고, 다른 파일이나 폴더를 콕 집어 보게 하려면 직접 첨부합니다.
이렇게 요청에 딸려 가는 정보를 컨텍스트(Context)라고 합니다.
컨텍스트를 첨부하는 방법은 여러 가지입니다.
- 입력창 왼쪽의
+를 눌러 파일 및 폴더, 이전 세션, GitHub 이슈와 풀 리퀘스트를 고릅니다. - 탐색기에서 파일을 입력창으로 끌어다 놓습니다.
- 입력창에
#을 입력하고 파일 이름을 고릅니다.
첨부하지 않아도 에이전트는 필요하면 저장소를 검색해서 관련 파일을 스스로 찾아 읽습니다.
웹 페이지를 참고하게 하려면 주소를 요청에 그대로 적습니다.
요청 한 번에 함께 전달되는 것은 첨부한 파일만이 아닙니다.
뒤에서 다룰 지침 파일은 항상 함께 전달되고, 스킬은 필요할 때만 읽혀서 전달됩니다.
지금까지의 대화 내용도 매번 함께 전달되므로, 주제가 바뀌면 새 채팅을 시작하는 것이 결과도 좋고 크레딧도 아낍니다.
# 세션과 되돌리기
위쪽의 +를 누르면 새 세션이 시작되고, 이전 세션은 목록에 남아서 언제든 다시 열 수 있습니다.
세션 제목은 첫 요청을 바탕으로 자동으로 붙고, 파일을 바꾼 세션에는 바뀐 줄 수가 함께 표시됩니다.
Copilot 하네스는 파일을 고치면 바로 저장합니다.
변경이 생기면 입력창 위에 1 File +45 -0처럼 바뀐 파일 수와 줄 수가 표시되고, 이것을 누르면 이 세션에서 바뀐 내용을 한 화면에서 비교할 수 있습니다.
초록색은 추가된 줄, 빨간색은 삭제된 줄입니다.
결과가 마음에 들지 않으면 요청에 마우스를 올렸을 때 표시되는 버튼으로 되돌립니다.
첫 요청에서는 다시 시작으로 표시되며, 채팅을 지우고 그 요청 이후의 변경을 모두 되돌립니다.
다만 되돌리기는 파일과 대화만 되돌리고, 이미 실행한 명령이나 외부 서비스로 보낸 내용은 되돌리지 못합니다.
# 도구와 승인
Agent는 요청을 받으면 계획을 세우고, 도구를 사용하고, 결과를 확인하는 과정을 반복합니다.
사람은 중간에 승인을 하거나 방향을 바꾸는 역할만 합니다.
작업 중에 입력창에 메시지를 보내면 대기열에 쌓였다가 순서대로 반영되므로, 진행 중에도 방향을 바꿀 수 있습니다.
# 도구
에이전트가 사용할 수 있는 도구는 에이전트 사용자 지정 편집기의 도구에서 확인합니다.
채팅 뷰 위쪽의 사용자 지정 열기 아이콘을 누르고 도구를 고릅니다.Copilot 그룹은 Copilot 하네스에 들어 있는 기본 도구(명령 실행, 파일 읽기와 편집, 검색 등)로 항상 사용할 수 있고, 그 아래의 VS Code, 작업과 문제, 통합 브라우저 같은 그룹은 스위치로 켜고 끌 수 있습니다.
뒤에서 다룰 MCP 서버의 도구도 이 목록에 추가됩니다.
여기서 바꾼 설정은 지금 세션만이 아니라 이후의 모든 세션에 적용됩니다.
특정 작업에서만 도구를 줄이려면 Ask를 고르거나, 뒤에서 만들 커스텀 에이전트에 사용할 도구를 지정합니다.
# 승인
파일을 읽거나 검색하는 도구와 프로젝트 폴더 안의 파일을 고치는 도구는 승인 없이 실행됩니다.
터미널 명령처럼 컴퓨터에 영향을 줄 수 있는 도구는 실행 전에 무엇을 실행할지 보여 주고 승인을 기다립니다.
Copilot 하네스는 명령 실행을 보조 에이전트에게 맡기는 경우가 있어서, 승인 요청 제목 옆에 Subagent가 표시될 수 있습니다.
| 버튼 | 동작 |
|---|---|
이 세션에서 허용 |
이 채팅이 끝날 때까지 같은 도구(여기서는 터미널 명령 전체)를 묻지 않고 실행 |
화살표, 한 번 허용 |
이번 한 번만 실행 |
화살표, 이 작업 영역에서 정확한 명령줄 허용 |
이 폴더에서는 똑같은 명령을 다시 묻지 않고 실행 |
건너뛰기 |
실행하지 않고 다음으로 넘어감 |
파란색 기본 버튼이 이 세션에서 허용이라 그대로 누르기 쉽지만, 이후에 어떤 명령이 실행될지 미리 알 수 없습니다.
실습에서는 화살표를 눌러 한 번 허용을 고르는 것을 권합니다.
입력창 아래의 권한 메뉴에서 세션 전체의 승인 방식을 바꿀 수도 있습니다.
| 권한 | 동작 |
|---|---|
| Manual permissions | 기본값입니다. 자동 승인 규칙에 없는 동작은 확인을 받습니다 |
| Assisted permissions | 언어 모델이 도구 호출마다 위험도를 판단하고, 승인하지 않은 것만 확인을 받습니다 |
| Allow all | 모든 도구를 확인 없이 실행합니다 |
Allow all과 Autopilot은 파일 삭제 같은 위험한 동작도 묻지 않고 실행하므로, 내용을 잘 아는 폴더에서만 사용합니다.
설정으로 승인 규칙을 정하는 방법은 뒤의 검증과 권한에서 다룹니다.
에이전트는 결과물을 만든 뒤에 검증 명령을 실행하려고 승인을 요청하는 경우가 있습니다.
필요 없는 검증이라면 건너뛰기를 누르면 되고, 매번 반복되면 지침 파일에 "결과 파일을 만든 뒤 별도의 검증 명령을 반복해서 실행하지 않는다"처럼 규칙을 추가합니다.
# Claude와 Codex 사용하기
이미 Claude나 ChatGPT를 쓰고 있다면 VS Code에서도 그 구독을 쓸 수 있는지 궁금할 수 있습니다.
앞에서 본 것처럼 Copilot은 여러 회사의 모델을 빌려 쓰는 서비스이고, 입력창에서 고르는 것과 비용이 나가는 곳이 따로 움직여서 헷갈리기 쉽습니다.
다음 세 가지를 나눠서 보면 정리가 됩니다.
| 구분 | 뜻 | 고르는 곳 |
|---|---|---|
| 모델 | 답을 만드는 AI | 입력창의 모델 메뉴(Auto) |
| 하네스 | 모델에게 도구를 주고 일을 시키는 방식 | 입력창 아래의 하네스 메뉴(Copilot) |
| 결제 계정 | 비용이 나가는 곳 | 모델 메뉴 위쪽의 탭(Copilot, ChatGPT 등) |
가지고 있는 계정에 따라 다음처럼 사용합니다.
| 가진 계정 | 사용 방법 | 비용이 나가는 곳 |
|---|---|---|
| Copilot 플랜 | 모델 메뉴에서 Claude, GPT 등을 고르거나, 하네스를 Claude로 선택 |
Copilot 크레딧 |
| ChatGPT 계정 | 하네스를 Codex로 고르고, 모델 메뉴의 ChatGPT 탭에서 모델 선택 |
ChatGPT 구독 |
| Claude Pro, Max, Ultra 구독 | Copilot이 아닌 Claude Code 확장 사용 | Claude 구독 |
| 각 회사의 API 키 | 언어 모델 화면에서 키를 등록 | 해당 회사의 API 사용료 |
# Claude 하네스
Claude 하네스는 Claude Code와 같은 방식(Claude Agent SDK)으로 일하는 하네스입니다.
비용은 Copilot 크레딧에서 나가므로 Copilot 플랜만 있으면 사용할 수 있습니다.
- 채팅 뷰 위쪽의
+로 새 채팅을 엽니다. - 입력창 아래의
Copilot을 눌러 하네스 메뉴를 열고Claude를 고릅니다. - 처음 고르면
Download the Claude Agent안내가 표시되며,Download를 누르면 필요한 파일을 내려받습니다. - 모델 메뉴에서 Claude 모델을 고르고 요청을 보냅니다.
모델 메뉴에는 Copilot 탭만 표시됩니다.
Claude 하네스를 골라도 모델은 Copilot을 통해 빌려 쓰고, 비용도 Copilot 크레딧에서 나간다는 뜻입니다.
요청을 보내면 채팅 제목 앞에 Claude가 붙고, 응답 아래에 사용한 모델과 크레딧이 표시됩니다.
Claude 하네스를 쓸 때는 두 가지를 알아 둡니다.
- 크레딧이 더 들 수 있습니다. 이 글에서 시험한 짧은 질문 하나에 6.1 크레딧이 들어, 비슷한 FAQ 질문을 Copilot 하네스의
Auto로 물었을 때(0.2 크레딧)보다 훨씬 많았습니다. - Claude Code의 규칙을 따릅니다.
CLAUDE.md와.claude폴더를 읽고, 이 글 예제의.github스킬은/목록에 표시되지 않았습니다. 이 글의 비서 예제는 Copilot 하네스에서 진행합니다.
# Codex 하네스
Codex 하네스는 OpenAI의 Codex 방식으로 일하는 하네스입니다.
ChatGPT 계정을 연결하면 비용이 ChatGPT 구독에서 처리되며, 무료 ChatGPT 계정으로도 사용할 수 있습니다.
- 하네스 메뉴에서
Codex를 고릅니다. 처음 고르면Download the Codex Agent안내가 표시되며,Download를 누릅니다. - ChatGPT 계정을 연결합니다. Codex CLI에 이미 ChatGPT 계정으로 로그인되어 있다면 그 계정이 별도 로그인 없이 연결됩니다. 연결되어 있지 않다면 왼쪽 아래 계정 메뉴에서
Sign in to ChatGPT를 누릅니다. - 모델 메뉴를 열면
Copilot탭 옆에 ChatGPT 탭이 생깁니다. ChatGPT 탭에서 모델을 고르면 모델 이름 뒤에(ChatGPT)가 붙습니다. - 요청을 보냅니다.
응답 아래에는 크레딧 없이 모델 이름만 표시됩니다.
Copilot 크레딧이 아니라 ChatGPT 구독으로 처리되었다는 뜻입니다.
Codex 하네스는 .github 폴더의 스킬도 읽어서, 아래 화면처럼 team-faq 스킬의 규칙대로 출처를 붙여 답했습니다.
하네스 메뉴에 Codex가 없다면 설정에서 chat.agentHost.codexAgent.enabled와 chat.editor.codex.preferAgentHost를 켜고 VS Code를 다시 시작합니다.
아직 실험 기능이라 설정 이름과 방법이 바뀔 수 있으며, OpenAI의 Codex 확장을 설치해서 사용하는 방법도 있습니다.
Codex 하네스에서 Copilot 탭의 모델을 고르면 Copilot 크레딧으로 처리되며, 이때는 Copilot Pro+ 이상이 필요합니다.
# Claude 구독과 API 키
Claude Pro, Max, Ultra 구독은 Copilot에 연결할 수 없습니다.
VS Code 문서가 안내하는 Claude 하네스의 결제 방법은 Copilot 플랜과 API 키 두 가지뿐입니다.
Claude 구독으로 VS Code에서 작업하려면 Anthropic이 제공하는 Claude Code 확장을 설치합니다.
Copilot 채팅과는 별개의 패널로 동작하며, 자세한 내용은 Claude Code 핵심 정리를 참고하세요.
각 회사의 API 키가 있다면 모델 메뉴 위쪽의 +를 눌러 언어 모델 화면을 열고, 모델 추가에서 회사를 고른 뒤 키를 입력합니다.
Anthropic, Azure, Google, OpenAI, OpenRouter, xAI 등을 고를 수 있고, 등록한 모델은 해당 회사의 API 사용료로 처리됩니다.
이 화면에서는 모델별 크레딧 비용도 확인할 수 있는데, ChatGPT 계정으로 연결한 모델에는 크레딧 비용이 표시되지 않습니다.
API 키로 모델을 연결해도 인라인 제안과 저장소 의미 색인은 Copilot 서비스가 필요합니다.
Copilot 하네스에서 API 키 모델을 쓰려면 설정의 chat.agentHost.byokModels.enabled도 켜져 있어야 합니다.
# 사용자 지정 파일
여기까지는 Copilot을 그때그때 사용하는 방법이었습니다.
비서를 만든다는 것은 매번 설명하지 않아도 되도록 규칙과 절차를 파일로 남기는 일입니다.
Copilot은 저장소의 .github 폴더에서 다음 네 종류의 사용자 지정 파일을 읽습니다.
| 종류 | 파일 | 언제 적용되는가 |
|---|---|---|
| 지침 | .github/copilot-instructions.md, .github/instructions/*.instructions.md |
모든 요청에 자동으로(.instructions.md는 applyTo에 맞는 파일을 다룰 때) |
| 스킬 | .github/skills/*/SKILL.md |
요청과 관련 있다고 판단될 때, 또는 /이름으로 부를 때 |
| 커스텀 에이전트 | .github/agents/*.agent.md |
에이전트 메뉴에서 선택했을 때 |
| Hook | .github/hooks/*.json |
도구를 실행하기 직전처럼 정해진 시점마다 |
Hook을 제외하면 모두 마크다운 파일이므로 프로그래밍 지식 없이 작성할 수 있습니다.
채팅 뷰 위쪽의 사용자 지정 열기 아이콘을 누르면 이 파일들을 한곳에서 관리하는 에이전트 사용자 지정 편집기가 열립니다.
각 화면의 + 버튼으로 새 파일을 만들면 올바른 위치에 올바른 형식으로 만들어집니다.
한국어 UI에서 스킬은 기술, Hook은 후크로 표시됩니다.
같은 기능이니 혼동하지 마세요.
# 지침 파일
지침(Instructions)은 모든 요청에 자동으로 붙는 규칙입니다.
답변 언어, 결과물을 저장할 위치, 건드리면 안 되는 파일, 민감 정보 취급처럼 팀에서 매번 같은 말을 해야 하는 내용을 여기에 작성합니다.
예제의 지침 파일은 다음과 같습니다.
123456789101112131415161718192021222324252627282930# 연구개발팀 업무 비서 작업 규칙 이 저장소는 연구개발팀의 반복 업무를 GitHub Copilot에게 맡기기 위한 예제입니다. 아래 규칙은 모든 요청에 적용됩니다. ## 답변 방식 - 항상 한국어로 답합니다. 코드 주석도 한국어로 작성합니다. - 문서에 근거해서 답할 때는 어느 파일의 어느 항목을 참고했는지 함께 표시합니다. - 근거가 되는 문서가 없으면 추측하지 않고 "문서에 없는 내용"이라고 밝힌 뒤 담당자 확인을 권합니다. - 필요한 정보가 빠져 있으면 작업을 시작하기 전에 빠진 항목을 한 번에 모아서 물어봅니다. - 결과 파일을 만든 뒤에는 내용을 한 번만 다시 읽어 확인하고, 별도의 검증 명령을 반복해서 실행하지 않습니다. ## 파일 규칙 - 생성한 결과물(양식, 회의록, 판정표, 보고서)은 `output/` 폴더에 저장합니다. - `docs/` 폴더의 문서는 기준 문서입니다. 요청 없이 수정하지 않습니다. - `data/` 폴더의 원본 데이터는 수정하지 않습니다. ## 코드 규칙 - 스크립트는 Node.js 내장 모듈만 사용합니다. 외부 패키지를 설치하지 않습니다. - 판정 로직은 `docs/issue-rules.md`를 따르고, 규칙에 없는 기준을 임의로 만들지 않습니다. - 판정 결과에는 항상 근거를 함께 남깁니다. 확실하지 않으면 미판정으로 표기합니다. ## 민감 정보 - 결과물에 이름 전체, 사번, 연락처, 이메일을 적지 않습니다. 원본에 있는 그대로(`김OO`) 유지합니다. - 데이터를 외부 서비스로 보내거나 인터넷에 올리는 작업은 사용자에게 먼저 확인합니다. - `.env` 파일이나 비밀 값은 읽거나 출력하지 않습니다.
작성할 때 도움이 되는 기준은 다음과 같습니다.
- 규칙마다 이유를 함께 적습니다. 이유를 알면 예외 상황에서도 알맞게 판단할 수 있습니다.
- 도구가 이미 강제하는 것(들여쓰기, 따옴표 등)은 적지 않습니다. 사람이 말해 줘야만 알 수 있는 것에 집중합니다.
- 짧게 유지합니다. 모든 요청에 붙는 파일이므로 길어질수록 매번 크레딧을 더 소모합니다.
특정 파일에만 적용할 규칙은 .github/instructions 폴더에 .instructions.md 파일로 분리합니다.
머리말의 applyTo에 적은 패턴과 일치하는 파일을 다룰 때만 적용됩니다.
1234567891011--- name: 스크립트 작성 규칙 description: scripts 폴더의 Node.js 스크립트를 만들거나 고칠 때 적용하는 규칙 applyTo: "scripts/**/*.js" --- - ES 모듈(`import`) 문법을 사용하고, `node:fs`와 `node:path` 같은 내장 모듈만 사용합니다. - 입력 파일과 출력 파일 경로는 파일 상단에 상수로 둡니다. - 실행이 끝나면 처리 건수와 결과 파일 경로를 콘솔에 요약해서 출력합니다. - 입력 파일이 없으면 무엇을 먼저 실행해야 하는지 안내하고 종료합니다. - 함수마다 무엇을 하는지 한 줄 한국어 주석을 답니다.
지침 파일이 인식되었는지는 에이전트 사용자 지정 편집기의 지침 화면에서 확인할 수 있습니다.
예제에서는 위의 두 파일이 표시됩니다.
처음 시작하는 저장소라면 채팅에 /init을 입력해서 저장소를 분석한 지침 초안을 받을 수도 있습니다.
# 스킬
스킬(Skill)은 특정 업무의 절차와 참고 자료를 폴더 하나에 담아 두는 방식입니다.
지침이 "항상 이렇게 해"라면, 스킬은 "이런 요청이 오면 이 절차대로 해"에 가깝습니다..github/skills 아래에 스킬 이름으로 폴더를 만들고 그 안에 SKILL.md 파일을 둡니다.
1234567891011121314.github/skills/ ├── team-faq/ │ └── SKILL.md ├── laptop-request/ │ ├── SKILL.md │ └── form.md # 스킬이 참고하는 양식 ├── meeting-notes/ │ └── SKILL.md ├── issue-triage/ │ └── SKILL.md ├── weekly-report/ │ └── SKILL.md # /weekly-report로 부를 때만 실행 └── bug-report/ └── SKILL.md # /bug-report로 부를 때만 실행
SKILL.md는 머리말과 본문으로 나뉩니다.
머리말의 name은 /이름으로 부를 때 쓰는 식별자이고, description은 Copilot이 이 스킬을 언제 사용할지 판단하는 근거입니다.name은 영문 소문자, 숫자, 하이픈만 사용하고 폴더 이름과 같게 적습니다.
Copilot은 처음에는 모든 스킬의 이름과 설명만 읽습니다.
요청이 어떤 스킬의 설명과 맞으면 그때 본문을 읽고, 본문에서 참조한 파일은 실제로 필요할 때만 읽습니다.
스킬이 많아져도 요청마다 전달되는 양이 크게 늘지 않는 이유입니다.
그래서 description에는 "무엇을 하는지"와 "언제 사용하는지"를 구체적으로 적어야 합니다.
채팅에 /를 입력하면 기본 명령과 함께 저장소의 스킬이 설명과 함께 표시됩니다.
스킬 이름의 앞부분을 이어서 입력하면 목록이 좁혀집니다.
# 팀 FAQ 비서
첫 번째 스킬은 팀원이 반복해서 묻는 질문에 답하는 비서입니다.
답의 근거는 docs/faq.md 하나로 고정하고, 문서에 없는 내용은 지어내지 않도록 합니다.
1234567891011121314151617181920--- name: team-faq description: 팀 규칙, 장비 예약, 펌웨어 배포, 근무 신청처럼 팀원이 반복해서 묻는 질문에 docs/faq.md를 근거로 답할 때 사용합니다. --- # 팀 FAQ 비서 팀원의 질문에 `docs/faq.md`를 근거로 답합니다. ## 순서 1. `docs/faq.md`를 읽습니다. 1. 질문과 가장 가까운 항목을 찾아서 그 내용으로 답합니다. 1. 답 끝에 참고한 항목의 제목을 `출처: docs/faq.md > 항목 제목` 형식으로 표시합니다. ## 규칙 - FAQ에 없는 내용은 지어내지 않습니다. "FAQ에 없는 내용입니다"라고 밝히고 파트장 확인을 권합니다. - 질문이 여러 항목에 걸치면 항목별로 나누어 답합니다. - 절차를 묻는 질문에는 순서 목록으로 답합니다.
Agent에서 스킬 이름과 질문을 함께 입력합니다.
1/team-faq 환경 챔버 예약이 겹치면 누가 우선인가요? 그리고 예약은 최대 몇 시간까지 되나요?
Copilot이 스킬을 읽고, FAQ 문서를 근거로 항목별로 답하고, 끝에 출처를 표시합니다.
FAQ에 없는 질문도 던져 보세요.
"문서에 없는 내용"이라고 답하고 담당자 확인을 권하면 스킬이 규칙대로 동작하는 것입니다.
# 노트북 신청 양식 작성
두 번째 스킬은 요청에서 필요한 정보를 모아 양식을 채우고 파일로 저장합니다.
양식은 스킬 폴더 안의 form.md에 두고, 규정은 docs/laptop-policy.md를 참고합니다.
123456789101112131415161718192021222324252627--- name: laptop-request description: 노트북 신청, 교체, 고장 교체 요청을 받았을 때 규정을 확인하고 신청 양식을 채워서 output 폴더에 저장할 때 사용합니다. --- # 노트북 신청 양식 작성 사용자의 요청에서 필요한 정보를 모아 `form.md` 양식을 채웁니다. ## 순서 1. `docs/laptop-policy.md`에서 신청 대상과 필수 항목을 확인합니다. 1. 사용자의 요청에서 아래 필수 항목을 찾습니다. - 신청자 이름 - 부서(파트) - 신청 사유(신규 입사, 교체, 고장 중 하나) - 희망 모델(표준형 14인치, 고성능 16인치, 경량 13인치 중 하나) - 필요 시점 1. 빠진 항목이 있으면 양식을 만들지 않고, 빠진 항목만 한 번에 모아서 물어봅니다. 1. 모든 항목이 채워지면 이 폴더의 `form.md`를 읽어서 같은 형식으로 채웁니다. 1. `output/laptop-request-<신청자>.md` 파일로 저장하고, 규정과 어긋나는 점이 있으면 함께 알립니다. ## 규칙 - 사유가 교체인데 지급일이 4년 미만이면 규정 미달을 안내합니다. - 고성능 16인치는 파트장 사유서가 필요하다고 안내합니다. - 이름은 사용자가 준 그대로 적고, 사번이나 연락처는 요구하지 않습니다.
일부러 정보를 빠뜨리고 요청해 봅니다.
1/laptop-request 노트북 교체 신청하려고 합니다. 이름은 김OO이고 펌웨어 파트입니다.
스킬의 순서대로 규정을 읽고, 빠진 항목(희망 모델, 필요 시점)을 질문 카드로 한 번에 물어봅니다.
선택지가 있는 항목은 번호를 고르고, 나머지는 입력 칸에 직접 적은 뒤 제출을 누릅니다.
질문의 개수와 표시 방식은 실행할 때마다 조금씩 달라질 수 있습니다.
희망 모델은 고성능 16인치를 고르고, 필요 시점 칸에는 다음처럼 입력했습니다.
12026-11-20까지 필요합니다. 지금 쓰는 노트북은 2021-08-02에 받았습니다.
양식을 만들어 output 폴더에 저장하고, 규정 확인 결과를 함께 알립니다.
만들어진 파일은 다음과 같습니다.
고성능 모델이라 파트장 사유서 항목이 체크되지 않은 채로 남아 있습니다.
12345678910111213141516171819202122# 노트북 신청서 | 항목 | 내용 | | --- | --- | | 신청자 | 김OO | | 부서(파트) | 펌웨어 파트 | | 신청 사유 | 교체 | | 희망 모델 | 고성능 16인치 | | 필요 시점 | 2026-11-20 | | 현재 장비 지급일 | 2021-08-02 | ## 사유 설명 현재 사용 중인 노트북의 교체를 신청합니다. 2021-08-02 지급 장비로, 교체 기준인 지급 후 4년이 지났습니다. 펌웨어 업무를 위해 고성능 16인치 모델을 요청하며, 2026-11-20까지 지급을 희망합니다. ## 확인 사항 - [x] 규정의 신청 대상에 해당함 - [x] 필수 항목을 모두 작성함 - [ ] 고성능 모델은 파트장 사유서 첨부 승인: 파트장 ____________ (날짜: ________)
# 회의록 정리와 되묻기
세 번째 스킬은 회의 메모를 회의록으로 정리하되, 결정 사항, 담당, 기한이 빠진 안건을 찾아서 되묻습니다.
불완전한 입력을 다루는 방법이 이 스킬의 핵심입니다.
12345678910111213141516171819202122232425262728293031323334--- name: meeting-notes description: 회의 메모나 대화 내용을 회의록으로 정리할 때 사용합니다. 안건, 결정, 담당, 기한이 빠지면 되묻습니다. --- # 회의록 정리 회의 메모를 읽고 안건별로 결정 사항, 담당, 기한을 정리합니다. ## 순서 1. 메모에서 안건을 찾아 번호를 붙입니다. 1. 안건마다 아래 네 가지를 채웁니다. - 논의 내용 - 결정 사항 - 담당 - 기한 1. 결정은 있는데 담당이나 기한이 없는 안건, 논의만 하고 결정이 없는 안건을 따로 모읍니다. 1. 빠진 항목이 있으면 회의록을 저장하기 전에 아래 형식으로 한 번에 물어봅니다. > 확인이 필요한 항목 > - 안건 2 (환경 챔버 예약 규칙): 담당, 기한 > - 안건 3 (냉동 창고 현장 방문): 결정 사항 1. 답을 받으면 표를 완성하고 `output/meeting-<회의 날짜>.md`로 저장합니다. ## 회의록 형식 (회의록 마크다운 형식 생략) ## 규칙 - 메모에 없는 결정이나 담당을 추측해서 채우지 않습니다. - 참석자 이름은 메모에 적힌 그대로 사용합니다.
예제의 회의 메모 data/meeting-2026-09-01.md에는 담당과 기한이 하나도 적혀 있지 않습니다.
스킬을 실행하면 안건을 먼저 정리하고, 안건별로 무엇이 빠졌는지 되묻습니다.
1/meeting-notes data/meeting-2026-09-01.md 메모를 회의록으로 정리해 줘
스킬에는 질문 형식을 예시로 적어 두었지만, Copilot 하네스는 앞의 노트북 신청처럼 질문 카드로 묻는 경우가 많습니다.
형식은 달라도 빠진 항목을 안건별로 모아 한 번에 묻는다는 규칙은 지켜집니다.
질문 카드에는 다음과 같이 답했습니다.
| 질문 | 입력한 답 |
|---|---|
| 안건 1 (센서 값 0 고정) | 김OO, 9월 5일 |
| 안건 2 (환경 챔버 예약 규칙) | 박OO, 9월 8일 |
| 안건 3 (냉동 창고 통신 끊김) | 현장 방문 여부는 다음 회의에서 결정하기로 했습니다. 담당 최OO, 9월 8일 |
| 안건 4 (주간 보고서 형식) | 이OO, 9월 8일 |
답을 제출하면 회의록을 완성해서 저장합니다.
되묻기 로직을 설계할 때는 다음 세 가지를 정하면 됩니다.
| 정할 것 | 예제의 답 |
|---|---|
| 필수 항목 | 안건마다 결정 사항, 담당, 기한 |
| 빠졌을 때의 행동 | 저장하지 않고, 빠진 항목만 안건별로 모아서 한 번에 질문 |
| 추측 금지 범위 | 메모에 없는 결정과 담당은 채우지 않음 |
필수 항목은 스킬 본문에 목록으로 적고, 되묻는 형식은 예시를 그대로 보여 주면 Copilot이 그 내용을 따릅니다.
여러 번 나누어 묻지 않고 한 번에 모아서 묻도록 적어 두는 것도 중요합니다.
사용자가 답을 여러 번 해야 하면 비서를 쓰는 의미가 줄어듭니다.
# 지식 베이스 질문
팀의 기준 문서를 근거로 답하게 하는 것은 비서의 가장 기본적인 쓰임입니다.
이때 사용하는 방식이 검색 증강 생성(RAG, Retrieval-Augmented Generation)입니다.
문서 전체를 매번 모델에 전달하는 대신, 문서를 작은 조각으로 나누어 색인을 만들어 두고, 질문이 오면 관련 있는 조각만 찾아서 질문과 함께 전달합니다.
- 조각 나누기: 문서를 문단이나 제목 단위로 자릅니다.
- 임베딩과 색인: 각 조각의 의미를 숫자 벡터로 바꿔 저장합니다. 같은 뜻의 문장은 가까운 벡터가 됩니다.
- 검색: 질문도 같은 방식으로 벡터로 바꾸고, 가장 가까운 조각들을 찾습니다.
- 컨텍스트 주입: 찾은 조각을 질문과 함께 모델에 전달해서 근거 있는 답을 만들게 합니다.
VS Code는 저장소의 의미 색인(Semantic Index)을 만들어 두고, 에이전트가 질문과 관련 있는 파일을 찾을 때 사용합니다.
색인 상태는 상태 표시줄 Copilot 메뉴의 Codebase Semantic Index에서 확인하고 만들 수 있습니다.
예제처럼 문서가 몇 개 안 되는 저장소는 색인이 없어도, 에이전트가 텍스트 검색과 파일 읽기로 필요한 부분을 찾습니다.
에이전트를 Ask로 바꾸고 스펙 문서에 대해 질문해 봅니다.
어느 문서를 참고했는지도 함께 물어봅니다.
1TS-100의 측정 범위, 정확도, 동작 온도가 어떻게 되나요? 어느 문서의 어느 항목을 참고했는지도 알려 주세요.
응답 위쪽의 단계 목록을 펼치면 실제로 읽은 파일을 확인할 수 있고, 답에는 값마다 참고 항목이 붙습니다.
질문에 맞는 스킬(team-faq)을 스스로 골라 FAQ를 먼저 확인한 뒤 스펙 문서를 읽은 것도 볼 수 있습니다.
답이 맞는지는 반드시 원문과 대조합니다.
예제의 docs/spec-ts100.md에는 측정 범위가 -40°C에서 125°C, 동작 온도가 -40°C에서 85°C로 적혀 있고, 응답의 값과 참고 항목이 이와 같으면 통과입니다.
검증할 때는 다음 세 가지를 확인합니다.
- 숫자와 단위가 원문과 정확히 같은가
- 출처로 표시한 파일과 항목이 실제로 존재하는가
- 문서에 없는 질문에 "문서에 없다"고 답하는가
문서에 없는 내용을 그럴듯하게 지어내는 것을 환각(Hallucination)이라고 합니다.
지침 파일에 "근거가 없으면 추측하지 않는다"라고 적어 두고, 답에 출처를 붙이게 하는 것이 환각을 줄이는 가장 간단한 방법입니다.
# 직접 부르는 스킬
지금까지의 스킬은 Copilot이 요청을 보고 스스로 골라 쓸 수 있었습니다.
그런데 주간 보고서처럼 정해진 시점에 사람이 시작해야 하는 작업은 Copilot이 알아서 실행하면 곤란합니다.
이럴 때는 스킬 머리말에 disable-model-invocation: true를 추가해서, /이름으로 부를 때만 실행되게 합니다.
이전 버전에서 프롬프트 파일(Prompt Files)이 맡던 역할입니다.
1234567891011121314151617181920--- name: weekly-report description: 판정표를 바탕으로 주간 보고서를 만듭니다. 사용자가 /weekly-report로 부를 때만 사용합니다. argument-hint: 보고 기간이나 강조할 내용 disable-model-invocation: true --- # 주간 보고서 작성 `output/triage-result.md` 판정표를 읽고 `docs/report-template.md` 형식 그대로 주간 보고서를 작성합니다. - 보고 기간: 명령 뒤에 적은 기간을 사용합니다. 없으면 이번 주로 합니다. - 결과 파일: `output/weekly-report.md` ## 규칙 - 템플릿의 제목 순서와 표 형식을 바꾸지 않습니다. - 우선순위 높음 건은 담당을 `docs/issue-rules.md`의 담당자 배정 규칙대로 채웁니다. - 미판정 건은 접수자에게 무엇을 다시 물어야 하는지 한 줄로 적습니다. - 판정표에 없는 내용을 지어내지 않습니다.
| 머리말 항목 | 역할 |
|---|---|
name |
/ 뒤에 붙는 이름. 폴더 이름과 같아야 함 |
description |
슬래시 목록에 표시되는 설명 |
argument-hint |
이름 뒤에 무엇을 적으면 되는지 안내하는 문구 |
disable-model-invocation |
true면 Copilot이 스스로 고르지 않고, /이름으로 부를 때만 실행 |
/weekly-report 10월 넷째 주처럼 이름 뒤에 적은 내용은 요청에 함께 전달됩니다.
보고서 예제는 뒤의 보고 자동화에서 실행해 봅니다.
# 계획 먼저 세우기
버그 리포트처럼 조사가 먼저 필요한 작업은 계획 모드와 스킬을 함께 사용합니다.
계획 모드는 파일을 바꾸지 않고 저장소를 조사한 뒤 계획을 문서로 정리합니다.
123456789101112131415161718--- name: bug-report description: 이슈 한 건을 버그 리포트로 정리하기 전에 조사 계획을 먼저 세웁니다. 사용자가 /bug-report로 부를 때만 사용합니다. argument-hint: 이슈 번호 또는 증상 disable-model-invocation: true --- # 버그 리포트 조사 계획 명령 뒤에 적힌 이슈(번호 또는 증상)를 버그 리포트로 정리하려고 합니다. 바로 리포트를 쓰지 말고, 아래 순서로 조사 계획을 먼저 세웁니다. 1. `data/issues.csv`에서 해당 이슈의 제목, 내용, 접수일을 확인합니다. 1. `docs/spec-ts100.md`에서 증상과 관련된 스펙 항목(동작 범위, 인터페이스, 펌웨어 버전)을 찾습니다. 1. `docs/faq.md`에 비슷한 절차나 알려진 대응이 있는지 확인합니다. 1. 재현 조건, 영향 범위, 확인해야 할 질문을 목록으로 정리합니다. 계획에는 어떤 파일을 왜 읽을 것인지, 어떤 정보가 아직 부족한지를 적습니다.
입력창 아래의 대화형을 눌러 계획으로 바꾸고, 이슈 번호와 함께 실행합니다.
1/bug-report 4번 이슈
이슈 목록, 스펙 문서, FAQ를 차례로 읽고, 조사 범위처럼 정해야 할 것이 있으면 질문 카드로 먼저 묻습니다.
답을 제출하면 계획을 정리하고 입력창 위에 계획 검토 카드를 표시합니다.
| 버튼 | 동작 |
|---|---|
계획만 승인 |
계획을 승인하고 실행은 하지 않음 |
화살표, 계획 구현 |
계획을 승인하고 지금 세션에서 바로 실행 |
화살표, Autopilot으로 구현 |
계획을 승인하고 끝날 때까지 스스로 진행 |
거부 |
계획을 받아들이지 않음 |
한국어 UI에서는 이 카드의 제목이 요금제 검토로 표시되는데, 영어 Review Plan을 옮기면서 생긴 어색한 번역이고 계획 검토 카드가 맞습니다.
Open Full Plan을 누르면 계획이 편집기에 문서로 열립니다.
어떤 파일을 왜 읽었는지, 무엇을 아직 모르는지가 단계별로 적혀 있어서 에이전트가 문제를 어떻게 풀어 가는지 그대로 볼 수 있습니다.
고칠 점이 있으면 카드의 피드백 칸에 적고 피드백 제출을 누르면 계획을 다시 다듬습니다.
계획 문서는 저장소가 아니라 세션 폴더에 저장됩니다.
팀에서 버그 리포트 절차를 설명할 때 쓰려면 문서를 열어 별도의 파일로 저장해 둡니다.
# 커스텀 에이전트
커스텀 에이전트(Custom Agents)는 역할과 사용할 수 있는 도구를 정해 둔 전용 에이전트입니다.
"판정만 하고 파일은 건드리지 않는 담당자"처럼 역할을 좁히면 결과가 안정적이고, 실수로 파일을 고치는 일도 막을 수 있습니다..github/agents 폴더에 .agent.md 파일로 만들면 에이전트 메뉴에 표시됩니다.
12345678910111213141516171819202122--- name: 이슈 판정 description: 이슈 목록을 읽고 docs/issue-rules.md 규칙대로 판정만 합니다. 파일을 수정하지 않습니다. --- 당신은 연구개발팀의 이슈 판정 담당자입니다. 판정만 하고 파일을 만들거나 고치지 않습니다. ## 판정 순서 1. `docs/issue-rules.md`를 읽고 유형, 우선순위, 미판정 기준을 확인합니다. 1. 사용자가 준 이슈(또는 `data/issues.csv`의 특정 번호)를 규칙에 대조합니다. 1. 결과를 아래 표 형식으로 답합니다. | 번호 | 유형 | 우선순위 | 상태 | 근거 | | --- | --- | --- | --- | --- | ## 지켜야 할 것 - 규칙에 없는 기준으로 판정하지 않습니다. 애매하면 미판정으로 두고 이유를 적습니다. - 근거 칸에는 어떤 키워드나 조건에 걸렸는지 그대로 적습니다. - 담당자 배정이 필요하면 규칙 문서의 담당자 배정 표를 따릅니다.
에이전트 메뉴에서 이슈 판정을 고르고, 새로 들어온 이슈를 붙여 넣어 봅니다.
1새로 접수된 이슈를 판정해 주세요. 번호 13, 제목: 대시보드 로그인 후 흰 화면에서 멈춤, 내용: 고객사 데모용 계정으로 로그인하면 흰 화면에서 멈춥니다. 매번 재현되고 다른 계정은 정상입니다. 접수일: 2026-10-23
규칙 문서를 읽고 표 형식으로 판정 결과와 근거를 답합니다.
어떤 키워드에 걸려서 버그가 되었고, 왜 우선순위가 높음인지가 근거 칸에 그대로 적힙니다.
머리말에 tools 항목을 추가하면 사용할 도구를 목록으로 제한할 수 있습니다.
예를 들어 tools: ['read', 'search']처럼 읽기와 검색만 남기면 이 에이전트는 파일을 고치거나 명령을 실행할 수 없습니다.
도구 이름은 하네스마다 다를 수 있으므로, 지정한 뒤에는 실제로 원하는 동작만 하는지 확인합니다.
# 데이터 판정
이제 이슈 목록 전체를 한 번에 판정하는 일을 맡깁니다.
이런 작업은 Copilot이 매번 직접 판정하는 것보다, 규칙을 문서로 정하고 그 규칙대로 동작하는 스크립트를 만들어 실행하는 것이 낫습니다.
같은 입력에 항상 같은 결과가 나오고, 크레딧도 들지 않고, 규칙이 바뀌면 문서와 스크립트만 고치면 되기 때문입니다.
# 입력 데이터
예제의 입력은 data/issues.csv입니다.
번호, 제목, 내용, 접수자, 접수일 다섯 열이 있고 유형과 우선순위는 비어 있습니다.
엑셀에서 다른 이름으로 저장 > CSV UTF-8로 저장하면 같은 형식의 파일을 만들 수 있습니다.
1234번호,제목,내용,접수자,접수일 1,펌웨어 2.3 업데이트 후 센서 값이 0으로 고정됨,양산 라인 3번 설비에서 펌웨어 2.3.1로 올린 뒤 온도 값이 계속 0으로 표시됩니다. 2.2.4로 되돌리면 정상입니다.,김OO,2026-08-31 2,보고서 출력에 부서명 추가 요청,주간 보고서 상단에 부서명이 함께 나오도록 추가해 주세요.,이OO,2026-08-31 3,캘리브레이션 절차 문의,신규 입고된 TS-100 모듈의 캘리브레이션 절차가 어떻게 되는지 문의드립니다.,박OO,2026-09-01
12건 중에는 일부러 넣어 둔 문제 데이터가 있습니다.
내용이 "확인 부탁드립니다."뿐인 6번, 재현 조건이 없는 9번, 접수일이 2026-13-40인 10번입니다.
판정 로직이 이런 항목을 어떻게 다루는지가 이번 단계의 핵심입니다.
# 판정 규칙
규칙은 사람이 읽는 문서로 먼저 정합니다.
스크립트는 이 문서를 옮긴 것에 불과해야 하고, 문서에 없는 판단을 스크립트가 하면 안 됩니다.
1234567891011121314151617181920212223242526272829303132333435363738394041# 이슈 판정 규칙 ## 유형 제목과 내용에서 아래 키워드를 찾아 유형을 정합니다. 여러 유형에 해당하면 위에 있는 유형이 우선합니다. | 유형 | 키워드 | | --- | --- | | 버그 | 오류, 실패, 멈춤, 끊김, 고정, 안 됨, 안됨, 튐, 튀는, 깨짐, 가득, 만료, 손실 | | 기능요청 | 추가, 지원, 개선, 옵션 | | 문의 | 문의, 방법, 어떻게, 절차 | | 기타 | 위 키워드가 하나도 없는 경우 | ## 우선순위 | 우선순위 | 조건 | | --- | --- | | 높음 | 버그이면서 제목이나 내용에 양산, 고객, 전체, 데이터 손실, 안전 중 하나가 있는 경우 | | 중간 | 그 밖의 버그 | | 낮음 | 기능요청, 문의, 기타 | ## 미판정과 별도 표기 | 상황 | 처리 | 비고 표기 | | --- | --- | --- | | 내용이 15자 미만 | 미판정 | 근거 부족 | | 유형이 기타 | 미판정 | 유형 불명 | | 버그이지만 내용에 가끔, 모르, 불규칙 중 하나가 있는 경우 | 미판정 | 재현 조건 없음 | | 접수일이 YYYY-MM-DD 형식이 아니거나 실제 날짜가 아닌 경우 | 판정은 진행 | 접수일 형식 오류 | | 접수일이 오늘보다 미래인 경우 | 판정은 진행 | 접수일 미래 | ## 담당자 배정 | 조건 | 담당 | | --- | --- | | 우선순위 높음 | 파트장 | | 버그 | 개발 파트 | | 기능요청 | 기획 파트 | | 문의 | 기술지원 파트 | | 미판정 | 접수자에게 재확인 요청 |
근거가 부족한 항목은 억지로 판정하지 않고 미판정으로 남깁니다.
값이 이상한 항목은 판정은 하되 비고에 표기해서 사람이 확인하게 합니다.
이 두 가지 출구를 처음부터 규칙에 넣어 두어야 비서가 모르는 것을 아는 척하지 않습니다.
# 판정 스크립트
스크립트는 Copilot에게 만들게 합니다.
Agent에서 규칙 문서와 입력 파일을 첨부하고(입력창의 + 또는 #) 다음처럼 요청합니다.
123docs/issue-rules.md와 data/issues.csv를 바탕으로, 이슈 목록을 읽어서 규칙 문서대로 유형, 우선순위, 상태(판정 또는 미판정), 비고를 정하는 scripts/triage.js를 만들어 줘. 결과는 output/triage-result.csv와 output/triage-result.md(요약 표, 판정 결과 표, 미판정 목록, 별도 표기 목록, 판정 근거 표)로 저장하고, 콘솔에는 건수 요약만 출력해 줘. 외부 패키지 없이 Node.js 내장 모듈만 사용하고, 판정마다 어떤 키워드나 조건에 걸렸는지 근거를 남겨 줘.
지침 파일과 scripts.instructions.md의 규칙이 함께 적용되므로, 내장 모듈만 사용하고 한국어 주석을 단 스크립트가 만들어질 수 있습니다.
예제 저장소에는 완성본이 포함되어 있으니 직접 만든 것과 비교해 보세요.
코드를 읽지 못해도 괜찮습니다.
규칙 문서의 키워드 표가 스크립트 맨 위의 목록으로 그대로 옮겨졌는지만 확인하면 됩니다.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647// 유형 판정 키워드. 위에 있는 유형이 우선합니다. const TYPE_RULES = [ { type: '버그', keywords: ['오류', '실패', '멈춤', '끊김', '고정', '안 됨', '안됨', '튐', '튀는', '깨짐', '가득', '만료', '손실'] }, { type: '기능요청', keywords: ['추가', '지원', '개선', '옵션'] }, { type: '문의', keywords: ['문의', '방법', '어떻게', '절차'] } ] // 버그이면서 이 키워드가 있으면 우선순위 높음. const HIGH_KEYWORDS = ['양산', '고객', '전체', '데이터 손실', '안전'] // 버그이지만 재현 조건이 없다고 보는 표현. const UNCLEAR_KEYWORDS = ['가끔', '모르', '불규칙'] // 내용이 이 길이보다 짧으면 근거 부족으로 미판정. const MIN_LENGTH = 15 /** 이슈 한 건을 판정합니다. */ export function triage(issue, today = new Date()) { const text = `${issue.제목} ${issue.내용}` const notes = [] const { type, reason: typeReason } = judgeType(text) const { priority, reason: priorityReason } = judgePriority(type, text) let status = '판정' if (issue.내용.length < MIN_LENGTH) { status = '미판정' notes.push('근거 부족') } else if (type === '기타') { status = '미판정' notes.push('유형 불명') } else if (type === '버그' && includesAny(issue.내용, UNCLEAR_KEYWORDS)) { status = '미판정' notes.push('재현 조건 없음') } const dateNote = checkDate(issue.접수일, today) if (dateNote) notes.push(dateNote) return { 번호: issue.번호, 제목: issue.제목, 접수자: issue.접수자, 접수일: issue.접수일, 유형: status === '판정' ? type : '', 우선순위: status === '판정' ? priority : '', 상태: status, 비고: notes.join(', '), 근거: status === '판정' ? `${typeReason}, ${priorityReason}` : notes[0] } }
터미널에서 직접 실행할 수도 있습니다.
1234node scripts/triage.js ## 판정 완료: 12건 ## 높음 3, 중간 2, 낮음 5, 미판정 2, 별도 표기 1 ## 결과 파일: output/triage-result.md, output/triage-result.csv
# 판정 스킬
매번 명령을 입력하는 대신, 스크립트 실행과 결과 요약까지 맡기는 스킬을 하나 더 만듭니다.
1234567891011121314151617181920212223--- name: issue-triage description: 이슈 목록 전체를 판정하고 판정표를 만들 때 사용합니다. scripts/triage.js를 실행하고 미판정 건을 정리합니다. --- # 이슈 목록 판정 `data/issues.csv`의 이슈를 `docs/issue-rules.md` 규칙대로 판정합니다. ## 순서 1. `docs/issue-rules.md`를 읽고 규칙이 바뀌지 않았는지 확인합니다. 1. 터미널에서 `node scripts/triage.js`를 실행합니다. 1. `output/triage-result.md`를 읽고 아래 내용을 요약해서 답합니다. - 전체 건수와 우선순위별 건수 - 우선순위 높음 목록 - 미판정 목록과 각각 접수자에게 무엇을 물어야 하는지 1. 사용자가 규칙 변경을 요청하면 `docs/issue-rules.md`와 `scripts/triage.js`의 키워드 목록을 함께 고칩니다. ## 규칙 - 스크립트 결과를 임의로 바꾸지 않습니다. 결과가 이상하면 규칙이나 데이터의 문제를 설명합니다. - 판정 근거는 판정표의 근거 칸을 그대로 인용합니다.
1/issue-triage 이슈 목록을 판정해 주세요
규칙 문서를 확인한 뒤 스크립트 실행 승인을 요청하고, 허용하면 결과 파일을 읽어서 요약합니다.
미판정 건에는 접수자에게 무엇을 물어야 하는지가 함께 정리됩니다.
만들어진 판정표의 일부는 다음과 같습니다.
미판정 항목은 유형과 우선순위가 비어 있고 비고에 이유가 남습니다.
12345678| 번호 | 제목 | 유형 | 우선순위 | 상태 | 비고 | | --- | --- | --- | --- | --- | --- | | 1 | 펌웨어 2.3 업데이트 후 센서 값이 0으로 고정됨 | 버그 | 높음 | 판정 | | | 5 | 로그 파일이 디스크를 가득 채움 | 버그 | 중간 | 판정 | | | 6 | 확인 부탁 | | | 미판정 | 근거 부족 | | 9 | 측정값이 가끔 튐 | | | 미판정 | 재현 조건 없음 | | 10 | 펌웨어 다운로드 링크 만료 | 버그 | 중간 | 판정 | 접수일 형식 오류 | | 11 | 백업 스크립트 실패로 데이터 손실 위험 | 버그 | 높음 | 판정 | |
# 보고 자동화
판정이 끝나면 담당자에게 알리고 보고서를 만드는 일이 남습니다.
반복되는 보고는 템플릿을 먼저 정하고, 템플릿을 채우는 일을 스크립트나 스킬에 맡깁니다.
보고 템플릿은 docs/report-template.md에 있습니다.
제목의 순서와 표의 열을 고정해 두면 매주 같은 모양의 보고서가 나옵니다.
12345678# 이슈 판정 보고 (YYYY-MM-DD) ## 요약 ## 우선순위 높음 (즉시 통보) ## 미판정 (재확인 요청) ## 별도 표기 ## 통보 대상 ## 다음 조치
통보 항목은 조건과 대상을 표로 정합니다.
예제에서는 규칙 문서의 담당자 배정 표를 그대로 사용해서, 우선순위 높음 건은 파트장에게 즉시 통보하고 미판정 건은 접수자에게 재확인을 요청합니다.
판정 스크립트와 같은 방식으로 scripts/report.js도 Copilot에게 만들게 합니다.
12docs/report-template.md와 docs/issue-rules.md를 바탕으로, output/triage-result.csv를 읽어서 템플릿 형식 그대로 output/report.md를 만드는 scripts/report.js를 만들어 줘. 담당은 규칙 문서의 담당자 배정 표를 따르고, 다음 조치에는 높음 건과 미판정 건마다 한 줄씩 할 일을 적어 줘.
123node scripts/report.js ## 보고서 생성: output/report.md ## 높음 3건, 미판정 2건, 별도 표기 1건
스크립트는 정해진 형식을 정확히 지키지만, 미판정 건에 "무엇을 다시 물어야 하는지"처럼 문장을 만드는 일은 잘하지 못합니다.
그런 부분은 앞에서 만든 /weekly-report 스킬에 맡깁니다.
1/weekly-report 10월 넷째 주
판정표, 템플릿, 규칙 문서를 읽고 보고서를 만듭니다.
만들어진 보고서를 열어 보면 미판정 건의 비고에 접수자에게 요청할 내용이 문장으로 들어가 있습니다.
이메일이나 메신저로 실제 통보를 보내는 단계는 예제에 넣지 않았습니다.
외부로 무언가를 보내는 동작은 사람이 보고서를 검토한 뒤에 직접 하거나, 뒤에서 다룰 MCP로 연결하되 반드시 승인 단계를 두어야 합니다.
# MCP
지금까지 비서는 저장소 안의 파일만 다뤘습니다.
사내 시스템, 데이터베이스, 메신저 같은 외부 서비스와 연결하려면 MCP(Model Context Protocol)를 사용합니다.
MCP는 AI 도구가 외부 서비스의 기능을 도구로 사용할 수 있게 하는 표준 규약이고, 각 서비스는 MCP 서버라는 형태로 제공됩니다.
서버를 연결하면 그 서버의 도구가 에이전트의 도구 목록에 추가됩니다.
Copilot 하네스에는 GitHub 저장소의 이슈와 풀 리퀘스트를 다루는 GitHub MCP 서버가 기본으로 들어 있습니다.
에이전트 사용자 지정 편집기의 MCP 서버 화면을 열면 Built-In 아래에 github-mcp-server가 표시되며, 스위치로 끄고 켤 수 있습니다.
저장소가 GitHub에 있다면 채팅에서 "이 저장소의 열린 이슈를 가져와서 판정해 줘"처럼 요청할 수 있습니다.
CSV 파일 대신 이슈 트래커, 메신저, 사내 위키가 입력과 출력이 되는 것입니다.
Jira처럼 회사에서 쓰는 이슈 관리 도구를 MCP로 연결하는 방법은 GitHub Copilot 업무 자동화 실전에서 다룹니다.
다른 서버는 확장 뷰(Cmd + Shift + X)에서 @mcp를 검색해서 MCP 서버 갤러리로 설치하거나, 명령 팔레트(Cmd + Shift + P)에서 MCP: Add Server를 실행해서 추가합니다.
팀과 함께 쓸 서버는 저장소 최상위의 .mcp.json에 작성합니다.
123456789{ "mcpServers": { "context7": { "type": "http", "url": "https://mcp.context7.com/mcp", "tools": ["*"] } } }
tools의 "*"는 서버의 모든 도구를 사용한다는 뜻이며, 필요한 도구 이름만 적어서 범위를 좁힐 수 있습니다.
이전 버전에서 쓰던 .vscode/mcp.json(servers 형식)이 있으면 마이그레이션 안내가 표시되고, 이 형식으로 옮길 수 있습니다.
MCP 없이 쓸 수 있는 확장 지점도 있습니다.
- 웹 페이지 주소를 요청에 적으면 내용을 가져와 참고할 수 있습니다.
- 마크다운으로 변환한 문서를
docs폴더에 두면 그 자체로 지식 베이스가 됩니다. - 스크립트가 외부 API를 호출하게 만들 수도 있습니다. 이때 API 키는
.env파일에 두고 민감 정보 항목처럼 Hook으로 읽기를 차단합니다.
# 검증과 권한
비서를 팀에 공유하기 전에 두 가지를 확인합니다.
정해진 입력에 정해진 결과가 나오는지, 그리고 비서가 하면 안 되는 일을 못 하게 막았는지입니다.
# 검증셋
검증셋은 입력과 기대 결과를 짝지어 둔 목록입니다.
정상 케이스만 넣지 않고, 경계 케이스와 실패해야 하는 케이스를 함께 넣습니다.
1234567891011[ { "번호": "1", "구분": "정상", "상태": "판정", "유형": "버그", "우선순위": "높음" }, { "번호": "2", "구분": "정상", "상태": "판정", "유형": "기능요청", "우선순위": "낮음" }, { "번호": "3", "구분": "정상", "상태": "판정", "유형": "문의", "우선순위": "낮음" }, { "번호": "4", "구분": "정상", "상태": "판정", "유형": "버그", "우선순위": "높음" }, { "번호": "5", "구분": "경계", "상태": "판정", "유형": "버그", "우선순위": "중간" }, { "번호": "10", "구분": "경계", "상태": "판정", "유형": "버그", "우선순위": "중간", "비고": "접수일 형식 오류" }, { "번호": "11", "구분": "경계", "상태": "판정", "유형": "버그", "우선순위": "높음" }, { "번호": "6", "구분": "실패", "상태": "미판정", "비고": "근거 부족" }, { "번호": "9", "구분": "실패", "상태": "미판정", "비고": "재현 조건 없음" } ]
| 구분 | 뜻 | 예제 |
|---|---|---|
| 정상 | 규칙이 분명하게 적용되는 입력 | 양산 라인 버그는 높음 |
| 경계 | 규칙의 가장자리에 걸치는 입력 | 접수일이 이상하지만 판정은 해야 하는 10번 |
| 실패 | 판정하면 안 되는 입력 | 내용이 너무 짧은 6번, 재현 조건이 없는 9번 |
scripts/check.js는 판정 결과와 검증셋을 비교해서 불일치를 분류합니다.
판정 결과 파일(output/triage-result.csv)을 읽으므로, 규칙이나 스크립트를 고친 뒤에는 node scripts/triage.js를 먼저 실행합니다.
123456789node scripts/check.js ## 번호 구분 기대 결과 판정 ## 1 정상 판정 버그 높음 판정 버그 높음 일치 ## 2 정상 판정 기능요청 낮음 판정 기능요청 낮음 일치 ## ... ## 6 실패 미판정 근거 부족 미판정 근거 부족 일치 ## 9 실패 미판정 재현 조건 없음 미판정 재현 조건 없음 일치 ## ## 검증 9건: 일치 9
불일치는 무엇을 걸러 내려고 하는지를 기준으로 나눕니다.
이 예제에서 걸러 낼 대상은 근거가 부족해서 판정하면 안 되는 이슈입니다.
| 판정 | 뜻 |
|---|---|
| 오탐 | 걸러 내지 않아도 될 항목을 걸러 낸 경우. 판정해야 할 이슈를 미판정으로 남김 |
| 미탐 | 걸러 내야 할 항목을 놓친 경우. 미판정으로 남겨야 할 이슈를 그냥 판정함 |
| 오판정 | 판정은 했지만 유형이나 우선순위가 다른 경우 |
규칙을 고칠 때마다 판정 스크립트와 이 스크립트를 차례로 실행하면 고친 규칙이 다른 케이스를 망가뜨리지 않았는지 바로 알 수 있습니다.
예를 들어 "재현 조건 없음" 규칙이 없다면 9번은 버그로 판정되어 미탐이 됩니다.
이런 불일치를 보고 규칙을 추가하는 것이 한계 조건을 설계하는 과정입니다.
Copilot에게 "검증셋에 경계 케이스를 세 개 더 제안해 줘"라고 요청해서 케이스를 늘릴 수도 있습니다.
규칙을 일부러 빼서 오탐과 미탐이 실제로 표시되는 모습은 GitHub Copilot 업무 자동화 실전의 판정 검증에서 확인합니다.
# 권한 등급
비서가 할 수 있는 일은 읽기, 쓰기, 실행, 외부 전송 순으로 영향이 커집니다.
권한이 커질수록 승인 단계를 앞에 두고, 외부로 무언가를 보내는 일은 사람이 직접 확인한 뒤에만 하도록 합니다.
VS Code에서 이 등급을 조정하는 방법은 다음과 같습니다.
| 권한 | 조정 방법 |
|---|---|
| 읽기, 검색 | 기본적으로 승인 없이 허용. 특정 파일은 Hook으로 차단 가능 |
| 쓰기 | 프로젝트 폴더 안의 편집은 승인 없이 저장. 세션 변경 내용으로 검토하고 다시 시작으로 되돌림. 커스텀 에이전트의 tools에서 편집 도구 제외 가능 |
| 실행 | 명령마다 승인. chat.tools.terminal.autoApprove 설정으로 허용 목록 관리 |
| 외부 전송 | MCP 서버 신뢰와 인증 승인. 지침에 "먼저 확인" 규칙 추가 |
터미널 명령 승인 규칙은 설정(Cmd + ,)에서 autoApprove를 검색해서 조정합니다.
명령의 앞부분을 기준으로 자동 승인 여부를 정하며, rm처럼 위험한 명령은 기본 규칙에서 자동 승인되지 않고 승인을 요청합니다.
권한이 Manual permissions인 세션은 true 규칙에 맞는 명령만 묻지 않고 실행하고, 나머지 명령은 승인을 요청합니다.
예제처럼 node scripts/ 아래의 스크립트만 반복해서 실행한다면 그 명령만 허용 목록에 추가할 수 있습니다.
12345{ "chat.tools.terminal.autoApprove": { "node scripts/": true } }
# 민감 정보
업무 데이터에는 이름, 연락처, 고객 정보가 섞여 있기 쉽습니다.
예제는 다음 원칙을 데이터 준비 단계, 지침 파일, Hook에 나누어 적용했습니다.
- 원본 데이터부터 이름을
김OO처럼 가린 상태로 준비합니다. 비서가 가리는 것보다 확실합니다. - 지침에 결과물에 넣지 말아야 할 항목(이름 전체, 사번, 연락처, 이메일)을 명시합니다.
.env처럼 비밀 값이 포함된 파일은 Hook으로 읽기를 차단하고.gitignore에도 추가합니다.- 데이터를 외부로 보내는 작업은 지침에서 "사용자에게 먼저 확인"하도록 합니다.
지침에 ".env 파일을 읽지 않는다"라고 작성해도 그것은 모델에게 전달하는 권고일 뿐입니다.
모델이 규칙을 놓치거나 사용자가 "그래도 읽어 줘"라고 요청하면 파일은 그대로 읽힐 수 있습니다.
Copilot에는 Claude Code의 permissions.deny 설정처럼 특정 파일의 읽기를 설정 하나로 거부하는 옵션이 없습니다.
GitHub 저장소 설정의 콘텐츠 제외(Content exclusion)로 파일을 지정할 수는 있지만, Business와 Enterprise 플랜 전용이고 VS Code에서는 인라인 제안과 채팅 질문에만 적용되며 에이전트 작업에는 적용되지 않습니다.
에이전트 작업에서 한 겹 더 막으려면 Hook(훅)을 사용합니다.
Hook은 Copilot이 도구를 호출하기 직전과 직후 같은 시점에 실행되는 스크립트로, .github/hooks 폴더의 JSON 파일에 등록합니다.
도구 호출 직전에 실행되는 preToolUse Hook이 거부 결정을 출력하면 그 도구 호출은 취소되고, 함께 적은 이유가 모델에게 전달됩니다.
12345678{ "version": 1, "hooks": { "preToolUse": [ { "type": "command", "command": "node .github/hooks/protect-secrets.js", "timeoutSec": 10 } ] } }
Hook에서 실행할 스크립트는 다음과 같습니다.
차단할 경로는 BLOCKED 배열에 .gitignore와 같은 방식으로 나열합니다.
123456789101112131415161718192021222324252627282930313233343536373839404142// Copilot이 도구를 실행하기 직전에 호출됩니다. // 아래 목록의 파일이나 폴더를 건드리는 요청이면 거부 결정을 출력합니다. import fs from 'node:fs' // 차단할 경로 목록입니다. .gitignore처럼 적습니다. // 이름만 적으면 어느 폴더에 있어도 막고, 경로를 적으면 그 위치만 막습니다. // *는 이름 안의 아무 글자, **는 폴더 경계를 넘는 아무 글자를 뜻합니다. const BLOCKED = [ '.env*', // .env, .env.local, .env.production '*.pem', // 인증서와 개인 키 'secrets/**', // secrets 폴더 안의 모든 파일 'config/credentials.json', ] // 'config/*.json' 같은 패턴을 정규식으로 바꿉니다. function toRegExp(pattern) { const source = pattern .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // 정규식에서 특별한 뜻을 가진 문자는 글자 그대로 취급 .split('**') .map(part => part.replace(/\*/g, '[^/]*')) .join('.*') return new RegExp(`(^|/)${source}$`, 'i') } // 표준 입력으로 도구 이름(toolName)과 인수(toolArgs)가 전달됩니다. const { toolArgs } = JSON.parse(fs.readFileSync(0, 'utf8')) const input = typeof toolArgs === 'string' ? toolArgs : JSON.stringify(toolArgs ?? {}) // 파일 경로, 검색 패턴, 터미널 명령 어디에 있든 경로 단위로 잘라서 검사합니다. const paths = input .replace(/\\+/g, '/') // Windows 경로 구분자 통일 .split(/[\s"'`|;&<>(),=]+/) const matchers = BLOCKED.map(toRegExp) const blocked = paths.find(path => matchers.some(matcher => matcher.test(path))) // 거부할 때만 결정을 출력합니다. 아무것도 출력하지 않으면 평소의 승인 절차를 따릅니다. if (blocked) { console.log(JSON.stringify({ permissionDecision: 'deny', permissionDecisionReason: `${blocked} 경로는 읽거나 수정할 수 없습니다.` })) }
도구의 인수 전체를 문자열로 만든 뒤 공백이나 따옴표 같은 구분자로 잘라서 경로 후보를 얻고, 목록의 패턴과 하나라도 일치하면 거부합니다.
파일 읽기 도구의 경로뿐 아니라 검색 패턴과 터미널 명령에 포함된 경로까지 같은 방식으로 검사하므로, cat .env처럼 터미널로 우회하는 요청도 막힙니다.
다만 경로 글자를 비교하는 방식이라, config/./credentials.json처럼 같은 파일을 다르게 적거나 스크립트 안에서 경로를 조합하면 통과할 수 있습니다.
Hook은 실수를 줄이는 안전장치로 보고, 비밀 값은 처음부터 에이전트가 다루는 폴더 밖에 두는 것이 가장 확실합니다.
실제로 .env를 출력해 달라고 요청하면, 대부분 지침의 .env 규칙 때문에 모델이 도구를 호출하기 전에 먼저 거절합니다.
지침과 Hook이 두 겹으로 막고 있는 것입니다.
Hook이 동작하는 모습만 보려면 목록에 있는 다른 경로를 요청해 봅니다.
다음은 가짜 값을 넣은 config/credentials.json 파일을 만들어 두고, 어떤 항목이 있는지 알려 달라고 요청한 결과입니다.
도구의 출력에 Denied by preToolUse hook과 스크립트가 적은 이유가 표시됩니다.
Copilot은 요청 내용을 GitHub의 서버로 보내서 응답을 만듭니다.
회사 정책상 외부로 보내면 안 되는 데이터는 처음부터 저장소에 넣지 않아야 합니다.
# 통합
지금까지 만든 것을 한 저장소 안에서 연결하면 팀의 업무 비서가 됩니다.
지식(기준 문서와 검색), 판정(규칙과 스크립트), 보고(템플릿과 스킬)가 각각의 파일로 나뉘어 있고, Copilot이 요청에 따라 필요한 것을 골라 사용합니다.
전체 흐름을 한 번에 실행해 보면 다음 순서가 됩니다.
- Ask에서 스펙이나 규정을 질문하고 출처를 확인합니다.
- Agent에서
/issue-triage로 판정표를 만들고 미판정 건을 확인합니다. /weekly-report로 보고서를 만들고output폴더에서 내용을 검토합니다.node scripts/check.js로 검증셋을 실행해서 규칙이 유지되는지 확인합니다.- 보고서를 담당자에게 전달합니다.
공유 전에는 docs/quality-checklist.md의 항목을 직접 확인합니다.
답변 품질, 되묻기, 판정, 보고, 안전 다섯 영역으로 나뉘어 있으며 하나라도 통과하지 못하면 공유하지 않습니다.
1234567891011121314151617## 답변 품질 - [ ] FAQ 질문 3개에 출처(파일, 항목)를 붙여 답하는가 - [ ] FAQ에 없는 질문에 "문서에 없는 내용"이라고 답하는가 - [ ] 스펙 질문에 `docs/spec-ts100.md`의 값과 같은 숫자로 답하는가 ## 되묻기 - [ ] 노트북 신청에서 필수 항목이 빠지면 양식을 만들지 않고 물어보는가 - [ ] 회의록에서 담당, 기한이 빠진 안건을 따로 모아 물어보는가 - [ ] 빠진 항목을 여러 번 나눠 묻지 않고 한 번에 묻는가 ## 안전 - [ ] 결과물에 이름 전체, 사번, 연락처가 들어가지 않는가 - [ ] 외부로 데이터를 보내는 도구가 승인 없이 실행되지 않는가 - [ ] `.env` 같은 비밀 파일을 읽지 않는가
부서에 적용할 때는 docs/adoption-plan-template.md를 채워서 안내 문서로 사용합니다.
적용 범위, 준비 사항, 사용 방법, 한계와 주의, 운영 방법이 표와 목록으로 정리되어 있습니다.
특히 "규칙 문서에 없는 판단은 비서가 하지 않고, 결과물은 초안이며 사람이 검토한다"는 한계를 처음부터 분명히 적어 두는 것이 좋습니다.
자신의 팀에 맞게 바꾸려면 다음 순서를 권합니다.
docs폴더의 문서를 팀의 실제 규정과 FAQ로 교체합니다.data/issues.csv의 열 이름을 팀에서 쓰는 양식에 맞추고,docs/issue-rules.md의 키워드를 팀의 용어로 바꿉니다.- Copilot에게 "규칙 문서가 바뀌었으니 triage.js와 검증셋을 맞춰 줘"라고 요청합니다.
node scripts/triage.js와node scripts/check.js를 차례로 실행해서 모두 일치로 끝날 때까지 규칙과 검증셋을 다듬습니다.- 체크리스트를 통과하면 저장소를 팀에 공유합니다.
파일 몇 개와 스크립트 두세 개로 이루어진 작은 구성이지만, 문서에 근거해서 답하고, 모르는 것은 되묻고, 규칙대로 판정하고, 정해진 형식으로 보고하는 비서의 기본 구조는 모두 갖추고 있습니다.
이 구조로 실제 업무 하나를 처음부터 끝까지 자동화하는 방법은 GitHub Copilot 업무 자동화 실전에서 이어서 다룹니다.
시험 로그 판정, 그래프 보고서, Jira 결함 등록을 예제로 업무를 단계로 나누는 방법, 판정 검증, 사내 시스템 연결과 보안을 정리합니다.
더 자세한 내용은 다음 문서를 참고하세요.
끝까지 읽어주셔서 감사합니다.
좋아요와 응원 댓글은 블로그 운영에 큰 힘이 됩니다!