사용자 정의 GitHub Copilot 구성
개요
프로젝트와 팀의 특성에 맞게 GitHub Copilot을 커스터마이징하여 생산성을 극대화하는 방법을 학습합니다.
참고: https://github.com/github/awesome-copilot/
.github/copilot-instructions.md 설정
기본 구조
프로젝트 루트에 .github/copilot-instructions.md 파일을 생성하면 Copilot이 프로젝트 컨텍스트를 이해하고 더 적절한 제안을 제공합니다.
---
description: 'MyProject 개발 지침'
applyTo: '**'
---
# MyProject Copilot 지침
## 프로젝트 개요
이 프로젝트는 Python + FastAPI 기반의 전자상거래 플랫폼입니다.
## 기술 스택
- Backend: Python 3.12, FastAPI, SQLAlchemy
- Database: PostgreSQL
- Testing: pytest, pytest-asyncio
- Frontend: React 18, Vite
## 코딩 규칙
1. 모든 API 엔드포인트는 async/await 사용
2. Pydantic 모델로 데이터 검증
3. 상태 관리는 Zustand 사용 (Frontend)
4. API 호출은 React Query 활용 (Frontend)
## 명명 규칙
- 모듈/클래스: PascalCase (예: ProductService.py)
- 함수: snake_case (예: format_price.py)
- 상수: UPPER_SNAKE_CASE (예: API_BASE_URL)
- CSS 클래스: kebab-case (예: product-card)
## 보안 요구사항
- 모든 API 엔드포인트는 JWT 인증 필수
- 사용자 입력은 반드시 검증
- XSS 방지를 위한 출력 이스케이프
- SQL 인젝션 방지를 위한 파라미터화된 쿼리
## 테스트 요구사항
- 모든 비즈니스 로직 함수는 단위 테스트 필수
- 컴포넌트는 렌더링 및 상호작용 테스트 작성
- 최소 80% 코드 커버리지 유지
언어별 지침
Python 프로젝트 예시
---
description: 'Python API 개발 지침'
applyTo: '**/*.py'
---
# Python API 개발 지침
## 스타일 가이드
- PEP 8 준수
- Type hints 필수 사용
- Docstring은 Google 스타일
## 예시
```python
from typing import List, Optional
def calculate_total(
items: List[dict],
tax_rate: float = 0.1
) -> float:
"""
항목 리스트의 총액을 계산합니다.
Args:
items: 가격 정보가 포함된 항목 리스트
tax_rate: 세율 (기본값 0.1)
Returns:
세금 포함 총액
Raises:
ValueError: items가 비어있는 경우
"""
if not items:
raise ValueError("항목 리스트가 비어있습니다")
subtotal = sum(item["price"] for item in items)
return subtotal * (1 + tax_rate)
프레임워크
- FastAPI 사용
- Pydantic으로 데이터 검증
- SQLAlchemy ORM
**.NET 프로젝트 예시**
```markdown
---
description: '.NET API 개발 지침'
applyTo: '**/*.cs'
---
# .NET API 개발 지침
## 스타일 가이드
- C# 12 이상 기능 활용
- Nullable reference types 활성화
- Async/await 패턴 사용
## 명명 규칙
- 인터페이스: IPascalCase
- 클래스: PascalCase
- 메서드: PascalCase
- private 필드: _camelCase
## 아키텍처
- Clean Architecture 패턴
- CQRS with MediatR
- Repository 패턴
- Dependency Injection
## 보안
- Input validation with FluentValidation
- JWT authentication
- Role-based authorization
VS Code 설정
settings.json 구성
{
"github.copilot.enable": {
"*": true,
"yaml": false,
"plaintext": false
},
"github.copilot.advanced": {
"authProvider": "github",
"inlineSuggestCount": 3,
"listCount": 10
},
"editor.inlineSuggest.enabled": true,
"editor.quickSuggestions": {
"comments": "on",
"strings": "on",
"other": "on"
},
// Copilot Chat 설정
"github.copilot.chat.localeOverride": "ko",
"github.copilot.chat.codeGeneration.instructions": [
{
"file": ".github/copilot-instructions.md"
}
]
}
키보드 단축키 커스터마이징
// keybindings.json
[
{
"key": "ctrl+shift+i",
"command": "github.copilot.generate",
"when": "editorTextFocus"
},
{
"key": "ctrl+shift+/",
"command": "workbench.action.chat.open",
"when": "!inChat"
},
{
"key": "alt+\\",
"command": "editor.action.inlineSuggest.trigger",
"when": "editorTextFocus && !editorHasSelection"
}
]
프로젝트별 템플릿
Python View 템플릿
.github/templates/python-view.md:
---
description: 'FastAPI View 생성 시 사용하는 표준 템플릿 - RESTful API 패턴 준수'
applyTo: 'src/views/**/*.py'
---
# Python View 템플릿
모든 API View는 다음 구조를 따릅니다:
```python
from typing import Dict, Any
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
router = APIRouter()
class [ViewName]Request(BaseModel):
"""요청 데이터 모델"""
# 필드 정의
pass
class [ViewName]Response(BaseModel):
"""응답 데이터 모델"""
# 필드 정의
pass
@router.post("/[resource]")
async def [view_name](
request_data: [ViewName]Request
) -> [ViewName]Response:
"""
[엔드포인트 설명]
Args:
request_data: 요청 데이터
Returns:
응답 데이터
Raises:
HTTPException: 에러 발생 시
"""
# 비즈니스 로직
return [ViewName]Response()
### API Endpoint 템플릿
`.github/templates/api-endpoint.md`:
```markdown
---
description: 'FastAPI 엔드포인트 생성 시 사용하는 표준 템플릿 - 유효성 검증 및 에러 처리 포함'
applyTo: 'src/api/**/*.py'
---
# API Endpoint 템플릿
```python
from typing import Any, Dict
from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel, Field, validator
router = APIRouter()
class [Action]Request(BaseModel):
"""[요청 설명]"""
field: str = Field(..., description="필드 설명")
@validator('field')
def validate_field(cls, v):
if not v:
raise ValueError('필드는 필수입니다')
return v
class [Action]Response(BaseModel):
"""[응답 설명]"""
success: bool
data: Dict[str, Any]
@router.post(
"/api/v1/[resource]",
response_model=[Action]Response,
status_code=status.HTTP_200_OK
)
async def [action]_endpoint(
request: [Action]Request
) -> [Action]Response:
"""
[엔드포인트 설명]
- **access**: [Public/Private/Admin]
"""
try:
# 비즈니스 로직
result = {}
# 응답
return [Action]Response(
success=True,
data=result
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e)
)
## 팀 스탠다드 적용
### .editorconfig
```ini
# .editorconfig
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.py]
indent_style = space
indent_size = 4
max_line_length = 88
[*.{yml,yaml,json}]
indent_style = space
indent_size = 2
[*.{md}]
trim_trailing_whitespace = false
pyproject.toml (Black 및 Ruff 설정)
# pyproject.toml
[tool.black]
line-length = 88
target-version = ['py312']
include = '\.pyi?$'
[tool.ruff]
line-length = 88
target-version = "py312"
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
]
ignore = [
"E501", # line too long (handled by black)
]
[tool.ruff.per-file-ignores]
"__init__.py" = ["F401"] # unused imports in __init__.py
[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]
고급 설정
Workspace별 설정
// .vscode/settings.json (프로젝트 전용)
{
"github.copilot.chat.codeGeneration.instructions": [
{
"text": "이 프로젝트는 마이크로서비스 아키텍처를 사용합니다. 각 서비스는 독립적으로 배포 가능해야 합니다."
},
{
"text": "모든 API는 FastAPI를 사용하고 OpenAPI 3.0 스펙을 자동으로 생성합니다."
},
{
"text": "에러 처리는 HTTPException을 사용하고 적절한 status code를 반환합니다."
},
{
"text": "모든 함수와 클래스에 Type hints를 필수로 사용하고 docstring을 작성합니다."
}
],
"python.formatting.provider": "black",
"python.linting.enabled": true,
"python.linting.ruffEnabled": true,
"editor.formatOnSave": true
}
파일 타입별 설정
{
"github.copilot.chat.codeGeneration.instructions": [
{
"file": ".github/copilot-instructions.md"
},
{
"file": ".github/copilot-python.md",
"applyTo": "**/*.py"
},
{
"file": ".github/copilot-tests.md",
"applyTo": "**/test_*.py"
}
]
}
실전 예제
프로젝트 초기 설정 체크리스트
- [ ] .github/copilot-instructions.md 작성
- [ ] 기술 스택 명시
- [ ] 코딩 컨벤션 정의
- [ ] 보안 요구사항 문서화
- [ ] 테스트 정책 수립
- [ ] .editorconfig 설정
- [ ] Linter/Formatter 설정
- [ ] VS Code 워크스페이스 설정
- [ ] 팀원과 설정 공유
- [ ] README에 Copilot 가이드 링크 추가
다음 단계
다음 섹션에서는 컨텍스트 엔지니어링을 통해 AI 에이전트에게 프로젝트 정보를 효과적으로 제공하는 방법을 학습합니다.
참고 자료