아키텍처 제약은 AI가 규칙을 지키지 않았을 경우를 대비하여, 규칙을 어길 경우 잘못된 코드가 통과되지 못하도록 막는 역할을 합니다.

  • 정적 분석
  • 구조적 제약

린터 설정

린터는

python

# pyproject.toml
 
[tool.ruff]
line-length = 88
target-version = "py311"
 
[tool.ruff.lint]
select = [
    "E",   # pycodestyle 기본 규칙
    "F",   # pyflakes (미사용 변수 등)
    "I",   # isort (import 정렬)
    "N",   # 네이밍 규칙
]
ignore = []
 
# 절대 import만 허용 (상대 import 금지)
[tool.ruff.lint.flake8-tidy-imports]
ban-relative-imports = "all"
 

JS | TS

// .eslintrc.json
{
  "rules": {
    "no-console": "error",
    "no-unused-vars": "error",
    "prefer-const": "error"
  },
  "settings": {
    "import/no-restricted-paths": [
      {
        "zones": [
          {
            "target": "./src/api",
            "from": "./src/models",
            "message": "api 레이어에서 models 직접 참조 금지. services를 경유하세요."
          }
        ]
      }
    ]
  }
}
 

레이어 간 import 제약

코드 구조에서 가장 흔한 문제는 레이어를 건너뛰는 import입니다. import-linter(Python)나 eslint-plugin-import(JS)로 이를 구조적으로 차단합니다.

# .importlinter (Python)
 
[importlinter]
root_package = src
 
[importlinter:contract:레이어 규칙]
name = 레이어 간 의존성 규칙
type = layers
layers =
    src.api
    src.services
    src.models
# api → services → models 방향만 허용
# models에서 api를 참조하면 자동으로 오류 발생

Pre-commit 훅

에이전트가 코드를 커밋하기 전, 자동으로 검사를 실행합니다.

# .pre-commit-config.yaml
 
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.0
    hooks:
      - id: ruff          # 린트 검사
      - id: ruff-format   # 자동 포맷
 
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.9.0
    hooks:
      - id: mypy          # 타입 검사
# 최초 1회 설치 
pip install pre-commit 
pre-commit install

설치 후 에이전트가 커밋을 시도하면, 검사를 통과하지 못한 코드는 자동으로 차단됩니다.

아키텍처 제약의 원칙

규칙은 문서보다 코드로 강제할 때 더 잘 지켜진다.

# AGENTS.md 에 명시
## 자동 검사
- 커밋 전 `pre-commit` 자동 실행
- `ruff`, `mypy` 검사 통과 필수
- 검사 실패 시 커밋 불가