fe.resolver.ts
fe.resolver.ts

Powered by Notion & Next.js

Navigate

  • 개인정보처리방침

Connect

  • GitHub

© 2026 Hanul Lee. All rights reserved.

Powered by Notion & Next.js

목록으로
Development2026년 2월 18일

프로젝트 협업시 AI 에이전트가 n개일 때 간선 그려주기

Gemini Codex Claude 야 사이좋게 지내야한다

#AI

TL;DR

  1. 각 에이전트가 자동으로 읽는 파일/디렉토리를 정확히 파악하고, 적절하게 간선을 넣어준 이야기
  2. 핵심 문서는 딱 하나로만 관리하자. 나머지는 포인터로 충분하다. 에이전트 문서는 자주 바뀌기 마련이고, 그때마다 여러 파일을 수정해야하는건 최악이다.

개요

닥터팔레트 전체 모노레포로 통합 되고부터 FE 개발자가 서버 로직을, BE 개발자가 클라이언트 코드를 수정하는 일이 많아지고 있다.

사소한 여러 문제들이 있긴 하지만, 현 시점의 가장 큰 문제는 두 팀의 에이전트가 다르다는것.

모바일/웹 팀: Gemini (Antigravity)

백엔드 팀: Codex (Cursor or IntelliJ)

어느 날 BE 팀원분이 올려주신 웹 PR을 보다가 숨이 턱 막혔던 적이 있다.

Data Masking 패턴 무시는 기본, 레퍼런스까지 작성돼있는 Jotai 컨벤션은 온데간데 없었다. Form 컴포넌트에는 필드 하나하나 state와 onChange 함수가 원시적으로 그대로 드릴링되어 props가 30개를 넘어가고 있었다.

솔직히 반대 상황도 마찬가지긴 하다. 아무리 내가 꼼꼼하게 검증을 해달라고 요청해도, 작업한 코드는 백엔드 컨벤션인 @resolveField 대신 쌩뚱맞은 @Query와 @Mutation이 들어가고, TypeORM의 ILike 사용 같은 패턴은 전혀 안 지켜진 채 올라간다.

이런 코드가 한 번 올라오면 리뷰어가 문제를 파악하고, 다시 컨벤션을 설명하고, 수정 후 재리뷰를 하는 데 최소 반나절(또는 수 번의 코멘트 핑퐁)이 낭비된다. 이런 비효율을 시스템 레벨에서 막고 싶었다.

문제는 우리에겐 코드 컨벤션을 꼼꼼하게 작성해둔 AI 에이전트 규칙 문서가 있다는 점이다.

도대체 왜 AI는 이 문서들을 무시하고 세상의 지식으로만 코드를 짰을까?

에이전트별 규칙이 많이 다르다

우리 팀은 하나의 모노레포(`drpalette-workspace`)에서 프론트엔드, 백엔드, 모바일 개발자가 같이 일한다.

구조는 대략 이렇다.

plain text
drpalette-workspace/
├── apps/
│   ├── web/          ← FE 개발자 (Gemini CLI / Antigravity)
│   ├── server/       ← BE 개발자 (Codex)
│   └── mobile/       ← 모바일 개발자 (Gemini CLI / Antigravity)
│   └── ...
├── GEMINI.md         ← Gemini가 자동으로 읽는 파일
├── CLAUDE.md         ← Cluade 사용자를 위한 문서
└── .agent/           ← 공용 스킬/규칙 (Gemini CLI / Antigravity)

문제는 각 도구가 자동으로 인식하는 파일의 이름과 위치가 다르다는 것.

Gemini + Antigravity

Google Antigravity

Google Antigravity

Google Antigravity - Build the new way

faviconhttps://antigravity.google/docs/rules-workflows

Antigravity IDE는 기본적으로 GEMINI.md 를 우선으로 읽으며, .agent/ 디렉토리 구조를 네이티브하게 인식한다.

  • 글로벌 규칙: ~/.gemini/GEMINI.md — 모든 워크스페이스에 적용
  • 워크스페이스 규칙: .agent/rules/*.md — 워크스페이스(또는 git 루트) 기준 자동 탐지
  • 스킬: .agent/skills/*/SKILL.md — YAML frontmatter(name, description)까지 파싱해서 자동 인덱싱
  • 워크플로우: .agent/workflows/*.md — 슬래시 커맨드(/deploy 등)로 호출 가능

Rule 파일은 최대 12,000자까지 지원되고, 활성화 모드가 4가지(Manual, Always On, Model Decision, Glob)다. 즉, 특정 파일 패턴(src/**/*.ts)에만 적용되는 규칙도 가능하다.

핵심은 분산형 아키텍처다. 관심사별로 파일을 쪼개놓으면 IDE가 알아서 수집해서 에이전트 컨텍스트에 주입해준다.

plain text
apps/web/.agent/
├── rules/
│   ├── component-design-pattern.md
│   ├── gql-data-masking.md
│   ├── global-state-management-convention.md
│   ├── ...
│   └── cross-context-backend.md
├── skills/
│   ├── react-best-practices/SKILL.md
│   └── create-feature-module/SKILL.md
└── workflows/
    ├── fe-code-review.md
    └── test-code-tdd.md

Codex (OpenAI)

Codex

Codex

One agent for everywhere you code

faviconhttps://developers.openai.com/codex

Codex는 AGENTS.md를 진입점으로 읽는다. 디렉토리 기반 계층형(cascading) 방식이다.

  • 글로벌: ~/.codex/AGENTS.md — 모든 프로젝트에 적용 (최하위 우선순위)
  • 프로젝트 루트: ./AGENTS.md — 프로젝트 전체 규칙 (중간 우선순위)
  • 하위 디렉토리: subdirectory/AGENTS.md — 해당 폴더 전용 (최상위 우선순위)
  • 오버라이드: AGENTS.override.md — 어느 레벨이든 일반 AGENTS.md보다 우선

Codex가 작업을 시작하면, 편집 중인 파일에서 가장 가까운 AGENTS.md부터 루트까지 거슬러 올라가며 규칙 체인을 조립한다. 가까운 게 이긴다.

하지만 Gemini처럼 .agent/rules/**를 알아서 수집해주지는 않는다. AGENTS.md 안에서 명시적으로 참조해줘야 한다.

그래서 BE 팀은 CODEx.md(AGENTS.md의 역할을 할 수 있는 커스텀 네이밍)에 227줄짜리 올인원 규칙서를 만들었다.

그리고 Codex에는 Gemini에 없는 게 두 가지 더 있는데, 샌드박스 설정과 명령어 제어 규칙이다.

Config basics

Config basics

Learn the basics of configuring your local Codex client

faviconhttps://developers.openai.com/codex/config-basic

.codex/config.toml로 에이전트의 실행 환경 자체를 제어한다.

toml
approval_policy = "on-request"     # 위험한 작업만 승인 요청
sandbox_mode = "workspace-write"   # 워크스페이스 내부만 읽기/쓰기 허용

[sandbox_workspace_write]
network_access = false             # 네트워크 차단 (재현성/보안 우선)

Rules

Rules

Control which commands Codex can run outside the sandbox

faviconhttps://developers.openai.com/codex/rules

team.rules 에서 에이전트가 실행할 수 있는 셸 명령어를 패턴 매칭으로 제어한다:

plain text
# 읽기 전용 git 명령엔 즉시 허용
prefix_rule(
  pattern = ["git", ["status", "diff", "log", "show", "grep"]],
  decision = "allow",
)

# PR 생성/머지 같은 부수효과는 사용자 확인 필요
prefix_rule(
  pattern = ["gh", "pr", ["create", "merge", "close"]],
  decision = "prompt",
)

# 위험한 명령은 아예 차단
prefix_rule(
  pattern = ["rm", "-rf"],
  decision = "forbidden",
)

allow / prompt / forbidden 3단계로 명령어를 분류한다. Gemini 쪽에는 이런 세밀한 명령어 제어 레이어가 없다.

그래서 BE 팀의 에이전트 구조는 이렇게 생겼다.

plain text
apps/server/
├── AGENTS.md       ← "CODEx.md를 읽어라" 라고 안내
├── CODEx.md        ← 아키텍처/코딩규칙/트랜잭션/에러 전부 포함
└── .codex/
    ├── config.toml ← 샌드박스/승인 정책
    ├── team.rules  ← 명령어 허용/차단 규칙
    ├── rules/      ← 상세 규칙 (탐색용)
    └── skills/     ← 스킬 (nestjs, typeorm, redis 등)

요약하면

Gemini — 파일을 쪼개놓으면 알아서 읽는다 (분산형)

Codex — 한 파일에 모아놓거나, 경로를 명시적으로 알려줘야 한다 (중앙 집중형)

본론으로 돌아가서, 뭐가 문젠데?

BE 개발자가 UI 코드를 짤 때 Codex는 apps/server/CODEx.md만 달달 외운 상태였고, .agent/ 안에 정성스럽게 적어둔 FE 컨벤션은 그저 텍스트 파일일 뿐이었다.

FE 개발자가 서버 코드를 만질 때 Gemini도 마찬가지.

그렇다면 해결책은 Gemini 용으로 CODEx.md 내용을 복사하고, Codex 용으로 FE 룰을 복사해두는 것일까?

절대 아니다.

정책이나 컨벤션을 여러 파일에 복붙(Copy & Paste) 해두는 순간, Single Source of Truth(SSOT)가 깨진다.

나중에 룰이 하나 변경될 때마다 N개의 에이전트 문서를 돌아다니며 싱크를 맞춰야 한다.

코드 품질을 위해서라도, 각자 작성해놓은 에이전트 문서를 서로의 에이전트에게 떠먹여줘야 했다.

그리고 그 문서가 추후에 유지보수시 방해가 되어선 안된다.

내가 생각하기로 가장 좋은 해결 방법은, 이 서로 다른 두 세상 사이에 '간선(edge)'을 놓아주는 것이었다.

Cross-Context Bridge

거창하게 제목을 붙였지만, 사실 해결책 자체는 단순하다.

FE 팀의 안티그래비티 공식문서에 제시돼있는 문서에 ‘서버 코드 고쳐야돼? 그럼 이거부터 봐!’ 라고 명시해두기만 하면 된다.

이때 Skills 가 가장 적합하다고 생각했는데, AlwaysOn 규칙의 Rule은 불필요한 토큰을 소모하고, Manual은 작업시 Rule을 읽혀줘야한다. 아직 FE 작업만 집중하는 팀원들이 많고, 필요할 때만 호출되는 Skill 계층에 브릿지 설명을 넣어서 에이전트가 읽게 하면 되기 때문이다.

FE → BE 브릿지

apps/web/.agent/rules/cross-context-backend.md

markdown
# 🚧 컨텍스트 스위칭 규칙: 백엔드 (Server)

`apps/server` 내부의 코드를 수정할 때는,
반드시 서버 디렉토리에 정의된 규칙을 엄격히 따라야 합니다.


## 기준 문서 (Source of Truth)

1. **루트 설정**: `apps/server/CODEx.md`
2. **상세 규칙**: `apps/server/.codex/rules/*.md`

Gemini가 .agent/rules/를 자동으로 읽으니까, 이 브릿지 파일도 자동으로 컨텍스트에 들어온다. 서버 코드를 건드리려는 순간 에이전트가 알아서 CODEx.md를 추가 로딩하게 된다.

그리고 루트 .agent 에 스킬도 추가했다.

.agent/skills/cross-context-bridge/SKILL.md

plain text
---
name: cross-context-bridge
description: 모노레포에서 Antigravity(Gemini)와 Codex 에이전트 간 컨텍스트를 상호 참조하기 위한 브릿지 가이드. 풀스택 작업 시 자동 트리거됩니다.
---


# Cross-Context Bridge (Antigravity → Backend)

이 모노레포에서는 **Antigravity/Gemini CLI** (FE/Mobile)와 **Codex** (BE)가 서로 다른 에이전트 시스템을 사용합니다.

> ⚠️ 이 문서는 **Antigravity 전용**입니다.
> Codex는 `.agent/`를 읽지 못합니다. 역방향(Codex→FE)은 `apps/server/CODEx.md`에서 처리됩니다.


---

## 트리거 조건

다음 경로의 파일을 **수정하거나 생성**할 때 이 가이드가 적용됩니다:

- `apps/server/**`
- `apps/drpalette-server/**`
- `libs/**` (서버 공유 라이브러리)

---


## 필수: 서버 규칙 문서 읽기

**서버 코드를 작업하기 전에, 아래 문서를 반드시 먼저 읽고 그 규칙을 엄격히 따르세요.**

1. **루트 설정**: `apps/server/CODEx.md`
2. **상세 규칙**: `apps/server/.agent/rules/*.md`

> 확신이 없으면 즉시 실행: `read_file apps/server/CODEx.md`

BE → FE 브릿지

apps/server/CODEx.md 안에 섹션 추가

markdown
# ...

### 🚀 Full-Stack (Frontend) 개발 병행 시

Codex는 자동으로 Web 규칙을 읽지 못합니다.
**반드시 아래 경로의 문서를 직접 읽고 숙지한 뒤 작업을 시작하세요.**

1. `apps/web/FE_DEVELOPMENT_GUIDE.md`
2. `apps/web/.agent/rules/**`
3. `apps/web/.agent/skills/**`

Codex는 CODEx.md를 통째로 읽으니까, 풀스택 작업이 필요한 순간 이 안내를 발견하고 FE 문서를 추가로 로딩한다.

GEMINI.md는 의도적으로 얇게.

내용을 두 군데 복붙하면 sync가 깨지는 건 시간문제니까, 한쪽을 바이블로 삼고 나머지는 포인터만 두는게 핵심이라고 생각했다.

끝맺음

완벽하게 서로의 문맥을 이해하진 못하겠지만, 이런 조치만으로 최소한 AI 기본체급으로만 우리 프로젝트를 고치는 불상사는 줄어들 것이다.

실제로 어느정도 효과가 있다고 좋아해주시고 감사해주시는 분들이 계셔서 좋았다.

AI 툴이 일상이 된 시대다. 하지만 좋은 톱니바퀴를 가졌다고 무조건 기계가 잘 돌아가진 않는다.

내가 AI를 부리는 건지, AI가 토해내는 코드에 내가 질질 끌려가는 건지는 에이전트가 마음껏 뛸 수 있는 '상황과 문맥(Context)의 운동장'을 얼마나 정교하게 설계하느냐에 달려있는 것 같다.

만약 여러 AI 에이전트를 모노레포에서 혼용하고 있다면 이 세 가지를 꼭 기억하면 좋겠다.

  1. 에이전트마다 컨텍스트를 자동 수집하는 방식을 공식문서 등을 통해 정확히 파악하자.
  2. 핵심이 되는 지침 문서는 반드시 하나만 유지해라. 중복은 시간문제로 동기화가 깨진다.
  3. 나머지는 그 문서를 향하게 만드는 포인터(Bridge) 문서로 해결해라.
  • TL;DR
  • 개요
  • 에이전트별 규칙이 많이 다르다
  • Gemini + Antigravity
  • Codex (OpenAI)
  • 본론으로 돌아가서, 뭐가 문젠데?
  • Cross-Context Bridge
  • FE → BE 브릿지
  • BE → FE 브릿지
  • 끝맺음